fix(macOS): make Mission Control and Spaces hotkeys work - #154
Open
sethdmoore wants to merge 1 commit into
Open
sethdmoore wants to merge 1 commit into
sethdmoore wants to merge 1 commit into
Conversation
Control+Up, Control+Down, and Control+Left/Right did nothing on a macOS host, so a streaming client could not open Mission Control, show the app's windows, or switch desktops (Spaces), while every other shortcut worked - macOS reports physical arrow, navigation, and function keys with the secondary-Fn flag, and arrow and keypad keys with the numeric-pad flag. The built-in hotkeys are registered as Control+Fn+Arrow and are matched against those flags - The backend posted key events with only the tracked modifier flags, so its Control+Up never matched the Mission Control hotkey - Applications accept an arrow key either way, so cursor movement and Control+letter shortcuts worked and hid the bug The backend now adds the flags a physical key would carry, per event - Arrows get secondary-Fn and numeric-pad, Home/End/Page Up/Page Down/ Forward Delete/Help and F1-F20 get secondary-Fn, keypad keys get numeric-pad - The flags are not stored in the shared modifier state, so they do not leak onto later key or mouse events - Event construction moves out of submit() into create_keyboard_event() so tests can inspect the CGEvent without posting it - Unit tests build the events for a Control+Up, Control+A, and keypad sequence and check the flags and the tracked modifier state; both fail against the previous code Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
sethdmoore
force-pushed
the
fix/macos-implicit-key-flags-upstream
branch
from
September 22, 2026 21:48
1ecb938 to
e846e17
Compare
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
On macOS, keyboard events injected through the CoreGraphics backend carry only the tracked modifier flags. Physical keyboards report arrow, navigation (Home, End, Page Up, Page Down, Forward Delete, Help/Insert) and function keys with
kCGEventFlagMaskSecondaryFn, and arrow and keypad keys withk¢∞∞CGEventFlagMaskNumericPad. Since macOS Mojave the system hotkey layer matches on those flags, so an injected Control+Up never triggers Mission Control and Control+Left/Right never switch Spaces, even though Control+letter shortcuts work and arrow keys type fine in applications. The same limitation is documented for other synthetic-input tools, for example Hammerspoon/hammerspoon#1946, where adding the Fn flag is the confirmed fix.This change adds an
implicit_key_flags()table to the macOS backend and ORs its result into the flags of each posted key event:SecondaryFn | NumericPadSecondaryFnNumericPadThe flags are applied per event only and are not stored in the shared modifier state, so they do not leak onto later key or mouse events.
Event construction moves from
MacosKeyboard::submit()into acreate_keyboard_event()helper so tests can inspect the builtCGEventwithout posting it. New unit tests:AddsImplicitFlagsForFunctionAndKeypadKeyschecks the per-key flag table.BuildsControlArrowEventsWithFnFlagsbuilds the events for Control down, Up down/up, A down/up, Control up and checks that the arrow events carryControl | SecondaryFn | NumericPad, the A events carry onlyControl, and the shared modifier state never picks up the per-key flags.BuildsKeypadEventsWithNumericPadFlagchecks a keypad key against Return.Both event tests fail against the previous code (the Control+Up event carried
0x40000, Control only, instead of0xA40000).test_libvirtualhidpasses on macOS 26.6 arm64 (109 passed, 2 Linux-only smoke tests skipped). The behavior is documented indocs/platform-support.md.After the changes, all control+arrow hotkeys now work.
Screenshot
Issues Fixed or Closed
Roadmap Issues
Type of Change
Checklist
AI Usage
See our AI usage policy.