Best for
- User wants a macro-pad button, mouse button, or any external key to trigger:
- Typeless push-to-talk (pushToTalk: "Fn" by default)
- macOS dictation (Fn Fn double-tap, or single-Fn in System Settings)
terrylica/cc-skills/plugins/macro-keyboard/skills/emit-fn-key-on-macos/SKILL.md
Emit a real Fn key on macOS (for Typeless push-to-talk, macOS dictation, screenshot shortcuts, emoji picker, Spotlight via.
Decision brief
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/terrylica/cc-skills --skill "plugins/macro-keyboard/skills/emit-fn-key-on-macos"Inspect the Agent Skill "emit-fn-key-on-macos" from https://github.com/terrylica/cc-skills/blob/05f53c5b24a445c1895e9b0590212e66cd70f39e/plugins/macro-keyboard/skills/emit-fn-key-on-macos/SKILL.md at commit 05f53c5b24a445c1895e9b0590212e66cd70f39e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Review the “Verification” section in the pinned source before continuing.
User wants a macro-pad button, mouse button, or any external key to trigger:
Review the “Prerequisite Check” section in the pinned source before continuing.
test -d /Applications/Karabiner-Elements.app && echo OK || brew install --cask karabiner-elements
Review the “2. Karabiner has Input Monitoring + Accessibility?” section in the pinned source before continuing.
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 61 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
Macos's Fn key (also called the "globe" key on modern MacBooks) is special. It's not a regular modifier — it carries kCGEventFlagMaskSecondaryFn, a flag that macOS's input subsystem discards if set from userland via CGEventPost. Many "remap anything" tools assume Fn behaves like Cmd / Option / Ctrl and try to emit it via CGEventPost — and silently fail for dictation, Typeless, macOS's dictation shortcut, Spotlight-via-globe, emoji picker, etc.
The only userland path that emits a Fn the kernel accepts is a DriverKit VirtualHIDDevice. Karabiner-Elements ships one. That's why Karabiner is the only FOSS tool for this job in 2026.
pushToTalk: "Fn" by default)Fn Fn double-tap, or single-Fn in System Settings)Fn+E)Fn)hidutil property --set with Fn mappings and sees no effect# 1. Karabiner-Elements installed (the only userland tool that can emit real Fn)?
test -d /Applications/Karabiner-Elements.app && echo OK || brew install --cask karabiner-elements
# 2. Karabiner has Input Monitoring + Accessibility?
# System Settings → Privacy & Security → Input Monitoring → Karabiner = ON
# System Settings → Privacy & Security → Accessibility → Karabiner = ON
# 3. On macOS Sequoia+: privileged daemon approved in Login Items?
# System Settings → General → Login Items → Allow in the Background
# → Karabiner-Elements Privileged Daemon = ON
# Without this, Karabiner's DriverKit VirtualHIDDevice won't load and
# your Fn remap will silently do nothing.
If Fn already works when pressed on your built-in keyboard but not via a remap, the DriverKit daemon is loaded but the remap rule is wrong — jump to "The One Magic Incantation" below. If even the built-in Fn stops working, re-check prerequisite 3.
┌───────────────────────────┐ ┌───────────────────────────┐
│ Real Fn (from keyboard) │ │ Fn via CGEventPost(...) │
│ Hardware → DriverKit → │ │ Userland app → Quartz → │
│ HIDEvent with │ │ kCGEventFlagMaskSecon- │
│ NX_DEVICE_CAPABILITY_ │ │ daryFn flag is DROPPED │
│ INPUTKEYBOARD_FUNCTION │ │ before reaching input │
│ flag set │ │ subsystem. │
│ │ │ │
│ ✅ Typeless / dictation │ │ ❌ Typeless / dictation │
│ accept it. │ │ never fire. │
└───────────────────────────┘ └───────────────────────────┘
Karabiner-Elements registers a DriverKit VirtualHIDDevice. When its remap rule says "emit Fn", it does so through the same kernel path a hardware keyboard uses. The NX_DEVICE_CAPABILITY_INPUTKEYBOARD_FUNCTION flag survives and Typeless/dictation accept it.
In a Karabiner manipulator's to block:
{ "apple_vendor_top_case_key_code": "keyboard_fn" }
Not:
{"key_code": "fn"} — no such key_code, silently ignored{"modifiers": ["fn"]} — modifier flag without a key-down, doesn't trigger Fn semantics{"consumer_key_code": "..."} — wrong HID usage page{"key_code": "function"} — not a Karabiner keywordThe apple_vendor_top_case_key_code namespace is Karabiner's mapping for HID Usage Page 0x00FF (Apple Top Case) with Usage 0x03 (Keyboard Fn). That's the descriptor Apple's own internal keyboard uses.
Remap the Caps Lock key (on a specific external keyboard only — adjust VID/PID) to emit real Fn:
{
"description": "Caps Lock → Fn (on external keyboard)",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "caps_lock" },
"to": [{ "apple_vendor_top_case_key_code": "keyboard_fn" }],
"conditions": [
{
"type": "device_if",
"identifiers": [{ "vendor_id": 19530, "product_id": 16725 }]
}
]
}
]
}
Drop into ~/.config/karabiner/karabiner.json → profile 0 → complex_modifications.rules.
# Open Karabiner-EventViewer
open -a "Karabiner-EventViewer"
# Press your remapped key; the Main tab should show:
# name: fn (not apple_vendor_top_case_key_code)
# ↑ Karabiner normalizes the display back to "fn" but under the hood it's emitting
# the Apple-Top-Case variant that carries the kernel flag.
# Then test the real consumer (e.g., Typeless with pushToTalk: "Fn"):
# Press and hold → mic opens
# Release → mic closes, transcript appears
If EventViewer shows the right event but Typeless doesn't fire:
pushToTalk in Typeless app-settings.json is set to "Fn" (not "fn", not "Function")Attempted pattern: "tap top button → Return, hold top button → Fn" using Karabiner's to_if_alone + to_if_held_down.
This breaks Fn system-wide. Verified failure 2026-04-21: after loading a rule with to_if_held_down: [{"apple_vendor_top_case_key_code": "keyboard_fn"}], macOS's native Fn key stopped producing Fn even when pressed directly on the built-in keyboard. Full rollback required.
The reason is still unclear — possibly Karabiner's held-down state-machine holds the Fn-flag in a way that conflicts with real hardware Fn events. Until Karabiner upstream fixes it, use a separate button for Fn.
BTT's "Trigger Key Sequence" and "Send Shortcut" actions go through CGEventPost with CGEventCreateKeyboardEvent + CGEventSetFlags. The flag kCGEventFlagMaskSecondaryFn is accepted by CGEventSetFlags (no error) but dropped by the input event manager before delivery. Apple has never documented this constraint; it's consistent across macOS 13 / 14 / 15.
hidutil property --set '{"UserKeyMapping":[...]}' operates at the HID report level and can swap keycodes, but it cannot synthesize the Fn flag. The flag is set by the keyboard driver (DriverKit or Apple's internal keyboard driver) based on which key was pressed — you can't forge it at the HID report level because it's a per-event computed property, not a persisted one.
A QMK board with NKRO + Apple Fn keycode on an actual USB HID report descriptor that advertises Usage Page 0x00FF, Usage 0x03 can emit Fn natively. The kernel accepts it because it's a real hardware report.
But cheap Jieli/Realtek/CH57x pads are not flashable — their firmware is burned in and exposes a fixed HID descriptor (usually standard keyboard Usage Page 0x07). No amount of reflashing with QMK/VIA/Vial works because the bootloader won't accept new firmware.
For flashable boards see: https://github.com/qmk/qmk_firmware → APPLE_FN_ENABLE.
../configure-macro-keyboard/references/03-patterns.md — "Apple vendor Fn encoding" pattern with full rule excerpt../configure-macro-keyboard/references/04-anti-patterns.md — BTT CGEventPost failure, tap-vs-hold Fn failure, QMK/VIA-on-Jieli failure./references/failed-approaches.md — condensed failure catalog for this specific taskconfigure-macro-keyboard — the end-to-end setup workflow that uses this skill as one step (wiring an external macro pad's button to Fn inside a larger Karabiner rule)diagnose-hid-keycodes — use this FIRST if you don't yet know which keycode your hardware emits; only then come back here to remap it to FnAfter this skill completes, reflect before closing the task:
04-anti-patterns.md row) with trigger, fix, evidence.Do NOT defer. The next invocation inherits whatever you leave behind.
Frequently asked questions
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
The source record exposes this install command: npx skills add https://github.com/terrylica/cc-skills --skill "plugins/macro-keyboard/skills/emit-fn-key-on-macos". Inspect the command and pinned source before running it.
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
coreyhaines31/marketingskills
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o
prowler-cloud/prowler
PostgreSQL indexing best practices for Prowler: index design, partial indexes, partitioned table indexing, EXPLAIN ANALYZE validation, concurrent operations, monitoring, and maintenance. Trigger: When creating or modifying PostgreSQL indexes, analyzing query performance with EXPLAIN, debugging slow queries, reviewing index usage statistics, reindexing, dropping indexes, or working with partitioned table indexes. Also trigger when discussing index strategies, partial indexes, or index maintenance
oaustegard/claude-skills
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre