Created
September 20, 2021 17:56
-
-
Save DavidMikeSimon/1f449fd5b80f2117fe93782ab7878436 to your computer and use it in GitHub Desktop.
Hammerspoon script for switching between screens
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
| -------- | |
| -- Window switching | |
| -------- | |
| screenWindowFilters = {} | |
| previewSequences = {} | |
| log = hs.logger.new("WAT") | |
| hs.window.animationDuration = 0 | |
| function resetPreviewSequences() | |
| for k in pairs(previewSequences) do | |
| previewSequences[k] = nil | |
| end | |
| end | |
| altReleaseListener = hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, function(event) | |
| if (not event:getFlags()['alt']) then | |
| resetPreviewSequences() | |
| end | |
| end) | |
| altReleaseListener:start() | |
| function focusMonitorFn(idx) | |
| return function() | |
| local screen = hs.screen.find({x=idx, y=0}) | |
| if not screen then | |
| return | |
| end | |
| local screenId = screen:id() | |
| local wf = screenWindowFilters[screenId] | |
| if wf == nil then | |
| wf = hs.window.filter.new(nil):setScreens(screenId) | |
| screenWindowFilters[screenId] = wf | |
| end | |
| local windows = wf:getWindows() | |
| local focusedWindow = hs.window.focusedWindow() | |
| local focusedWindowId = focusedWindow and focusedWindow:id() | |
| local previewSequence = previewSequences[screenId] | |
| local focusSequenceId = previewSequence and hs.fnutils.indexOf(previewSequence, focusedWindowId) | |
| -- Recalculate sequence if focus changes screens, so that we jump to most recently focused window on that screen | |
| if previewSequence == nil or focusSequenceId == nil then | |
| previewSequence = hs.fnutils.map(windows, function (w) return w:id() end) | |
| previewSequences[screenId] = previewSequence | |
| focusSequenceId = hs.fnutils.indexOf(previewSequence, focusedWindowId) | |
| end | |
| if focusSequenceId == nil or focusSequenceId == #previewSequence then | |
| focusSequenceId = 0 | |
| end | |
| local targetWindowId = previewSequence[focusSequenceId + 1] | |
| local targetWindow = hs.fnutils.find(windows, function (w) return w:id() == targetWindowId end) | |
| if targetWindow == nil then | |
| targetWindow = windows[1] | |
| end | |
| if targetWindow then | |
| targetWindow:focus() | |
| end | |
| end | |
| end | |
| hs.hotkey.bind('alt', "'", focusMonitorFn(0)) | |
| hs.hotkey.bind('alt', ',', focusMonitorFn(1)) | |
| hs.hotkey.bind('alt', '.', focusMonitorFn(2)) | |
| -- FIXME Can't seem to escape Zoom window | |
| -- FIXME When one app has windows on two screens, this doesn't work properly | |
| -- FIXME Send mouse? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment