You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agents/skills/hammerspoon/SKILL.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,10 +7,11 @@ description: "Hammerspoon macOS Space-switching config for this chezmoi repo. Co
7
7
8
8
**Scope:**`home/dot_hammerspoon/*` (`init.lua`, `spaces.lua`, `space_indicator.lua` → `~/.hammerspoon/`). The mru-spaces stability rule below also drives `home/.chezmoiscripts/run_onchange_after_macos_defaults.sh.tmpl`.
9
9
10
-
Hammerspoon provides direct macOS Space switching: `⌥1`–`⌥5` (Option, matching Komorebi's `alt`+number on Windows) jump to the Nth Space on the focused screen, including full-screen-app spaces, and create a new empty Space when the target position does not exist yet. Cask in `home/.chezmoidata/brew/00-base.yaml` (macOS-gated); config at `home/dot_hammerspoon/{init.lua,spaces.lua,space_indicator.lua}` (→ `~/.hammerspoon/`), gated to darwin in `home/.chezmoiignore`. A menu bar badge (`space_indicator.lua`) shows the active Space's position. Gotchas that have bitten us:
10
+
Hammerspoon provides direct macOS Space switching: `⌥1`–`⌥5` (Option, matching Komorebi's `alt`+number on Windows) jump to the Nth Space on the focused screen, including full-screen-app spaces, and create a new empty Space when the target position does not exist yet. `⌥0` consolidates every standard window onto each screen's focused Space, un-full-screening any full-screen apps first. Cask in `home/.chezmoidata/brew/00-base.yaml` (macOS-gated); config at `home/dot_hammerspoon/{init.lua,spaces.lua,space_indicator.lua}` (→ `~/.hammerspoon/`), gated to darwin in `home/.chezmoiignore`. A menu bar badge (`space_indicator.lua`) shows the active Space's position. Gotchas that have bitten us:
11
11
12
12
-**Bind number-row Space switches with `hs.eventtap`, not `hs.hotkey.bind`.** The keys are `⌥1`..`⌥5` (Option, matching Komorebi's `alt`+number). Two reasons the tap is needed: (1) on macOS `⌥`+number normally types special characters (`¡™£¢∞`), and the tap returns `true` to swallow the keystroke before the input system inserts the character, so the Space switches and nothing is typed (verified by reading a focused text field after a synthetic `⌥1`); (2) `⌃`+number can't go through `hs.hotkey` at all: macOS reserves `⌃1`..`⌃N` as Carbon hotkeys for "Switch to Desktop" by the number of Mission Control *user* desktops even when the System Settings checkboxes are off, so `RegisterEventHotKey` rejects them (`hs.hotkey:enable()` returns nil, console logs `-9878 ... already registered`). Diagnose hotkey issues with `hs -c 'return #hs.hotkey.getHotkeys()'` plus the Hammerspoon console.
13
13
-**`hs.spaces` reaches full-screen spaces.**`hs.spaces.spacesForScreen(uuid)` lists every Space (user and full screen/tiled, per `hs.spaces.spaceType`) in Mission Control order, and `hs.spaces.gotoSpace(id)` activates one by driving its Mission Control thumbnail, so it can land on full-screen spaces (the native `⌃`+number shortcuts cannot). Map "Space N" by indexing that list by position.
14
+
-**Window consolidation (`⌥0`) is per-screen because `hs.spaces.moveWindowToSpace` cannot cross displays.** It retargets a window's Space only on the *same* screen, so the consolidate action resolves each screen's `activeSpaceOnScreen` and collects that screen's windows onto it. `hs.window.allWindows()` does reach windows on non-focused Spaces (the AX API only enumerates the current Space, but Hammerspoon works around it — verified live: it listed a window on Space 1 while another Space was active), and `hs.spaces.windowSpaces(win)` reports a window's Space(s) so already-placed windows are skipped. Un-full-screen via `win:setFullScreen(false)` first (it collapses the app's dedicated full-screen Space back to a normal window), then wait ~1s before moving so macOS has torn the full-screen Space down. Filter to `win:isStandard()` to skip Notification Centre and other non-app windows.
14
15
-**Space positions are not stable while "rearrange by most recent use" is on.** With `com.apple.dock``mru-spaces` unset or true (the macOS default), visiting a full-screen space reorders it in Mission Control, so the index `⌥N` and the menu bar indicator use drifts (the order is stable only while idle). `defaults write com.apple.dock mru-spaces -bool false && killall Dock` gives stable positions; this is applied declaratively by `home/.chezmoiscripts/run_onchange_after_macos_defaults.sh.tmpl` (darwin-guarded, restarts the Dock only when it is running). The indicator (`hs.menubar` badge driven by `hs.spaces.watcher`) recomputes ~0.25s after a change so it reads the settled order, not a mid-transition one; the watcher fires before `activeSpaceOnScreen` settles otherwise.
15
16
-**Auto-reload works.**`hs.pathwatcher` uses FSEvents (path-based), so it survives chezmoi's atomic-rename writes (new inode each apply). By contrast, Finicky's `fsnotify`/kqueue watcher is inode-based and loses the watch on every chezmoi write, so Finicky needs a manual restart (see the `finicky` skill).
16
17
-**`hs.ipc` is enabled** in `init.lua`, so the running config is queryable from the `hs` CLI (`hs -c '...'`), the main way to debug Spaces and hotkeys.
0 commit comments