Skip to content

Fix slow Control + arrow desktop switching - #14

Open
eriko13 wants to merge 2 commits into
rileycx:mainfrom
eriko13:fix/native-control-arrow-switching
Open

eriko13 wants to merge 2 commits into
rileycx:mainfrom
eriko13:fix/native-control-arrow-switching

Conversation

@eriko13

@eriko13 eriko13 commented Sep 29, 2026 •

Copy link
Copy Markdown

Fixes #15

What this does

Control + Left/Right now switches Spaces instantly, like a three-finger swipe. Before, it used macOS's slow slide animation.

  • On by default. Toggle in the menu, or run strafe control-arrows off.
  • Uses the Accessibility permission strafe already has.
  • Keep macOS's "Move left/right a space" shortcuts enabled in System Settings.
  • Replaces the old Control+Option+arrow shortcuts and the strafe hotkeys command. Use strafe control-arrows [on|off] instead.

How it works

  1. While you hold Control, strafe pauses macOS's two Space shortcuts in memory.
  2. A hotkey on Control+Left/Right runs strafe's instant switch.
  3. When you release Control, the macOS shortcuts come back.

The pause is needed because macOS handles Control+arrow before any app sees it, so a hotkey alone never fires (tested).

What strafe can see

  • The Control watcher only receives modifier changes. Letters, numbers and arrow keys never reach strafe. Nothing is stored or logged.
  • The hotkey fires only for the exact Control+Left/Right combo.
  • System Settings and com.apple.symbolichotkeys are never edited.

Trade-offs

  • Uses the private WindowServer call CGSSetSymbolicHotKeyEnabled.
  • If strafe crashes or is force-quit while Control is held, the two macOS shortcuts stay off until strafe relaunches (it repairs this at launch) or you log out.
  • A held arrow key does not repeat the switch. Skipped while Mission Control is open.

Tested

  • 13 unit tests plus the hotkey test scripts pass.
  • Manually: instant in both directions, swipes still work, typing unaffected.
  • Not tested: Fn/Globe combos, external keyboards, Accessibility revoked mid-session.

Changed since the earlier revision

The first version tapped all key-down/up events. Now it is modifier-only, so strafe receives no keystrokes. README and SECURITY.md updated to match.

Replace the key-down/up event tap with a flagsChanged-only tap plus
RegisterEventHotKey on Control+Left/Right. While Control is held, the native
"Move left/right a space" shortcuts are paused in memory
(CGSSetSymbolicHotKeyEnabled) so the hotkey wins; they come back on Control
release, stop, quit, or tap timeout. The symbolic hotkeys preference file is
never edited, and a crash while Control is held is repaired at next launch.

Letters, numbers and arrow keys are never delivered to strafe. Also drops the
captured-key state (no stuck key-up bit), skips the pause during Mission
Control, and confirms only when enabling from the menu.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Control + Left/Right Space switching is slow (native slide animation)

1 participant