Skip to content

Commit 84a597b

Browse files
ChipWolfclaude
andcommitted
docs(hammerspoon): document ⌥0 window consolidation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent d8874b9 commit 84a597b

1 file changed

Lines changed: 2 additions & 1 deletion

File tree

.agents/skills/hammerspoon/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ description: "Hammerspoon macOS Space-switching config for this chezmoi repo. Co
77

88
**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`.
99

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:
1111

1212
- **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.
1313
- **`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.
1415
- **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.
1516
- **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).
1617
- **`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

Comments
 (0)