Skip to content

Instantly share code, notes, and snippets.

@jyc
Created February 4, 2023 19:34
Show Gist options
  • Save jyc/fdf5962977943ccc69e44f8ddc00a168 to your computer and use it in GitHub Desktop.
Save jyc/fdf5962977943ccc69e44f8ddc00a168 to your computer and use it in GitHub Desktop.
--------------------
-- Window Chooser -- 🚻
--------------------
-- Originally: https://github.com/dmgerman/dmg-hammerspoon/blob/f8da75d121c37df40c0971336eb3f67c73d67187/dmg.spoon/init.lua#L115-L224
WC = {}
WC.wf = hs.window.filter.new()
WC.wf:setDefaultFilter{}
WC.currentWindows = {}
for i, v in ipairs(WC.wf:getWindows()) do
table.insert(WC.currentWindows, v)
end
local function on_window_event(w, appName, event)
if event == "windowDestroyed" then
for i, v in ipairs(WC.currentWindows) do
if v == w then
table.remove(WC.currentWindows, i)
return
end
end
return
end
if event == "windowCreated" then
table.insert(WC.currentWindows, 1, w)
return
end
if event == "windowFocused" then
-- Hack: move `w` to the beginning of the table when it's focused.
on_window_event(w, appName, "windowDestroyed")
on_window_event(w, appName, "windowCreated")
end
end
WC.wf:subscribe(hs.window.filter.windowCreated, on_window_event)
WC.wf:subscribe(hs.window.filter.windowDestroyed, on_window_event)
WC.wf:subscribe(hs.window.filter.windowFocused, on_window_event)
local function list_window_choices()
local windowChoices = {}
for i, w in ipairs(WC.currentWindows) do
if w ~= hs.window.focusedWindow() then
local app = w:application()
if not app then
-- Not sure why `app` is sometimes nil.
table.remove(WC.currentWindows, i)
end
-- `text` is the label we'll show for this window.
-- If the window has a title, e.g. "Sandbox", then prepend it to the app
-- name to get "Sandbox - Microsoft Excel".
local text = app:name()
if w:title() ~= "" and w:title() ~= text then
text = w:title() .. " — " .. text
end
table.insert(windowChoices, {
text = text,
subText = app:name(),
uuid = i,
image = hs.image.imageFromAppBundle(app:bundleID()),
win = w
})
end
end
return windowChoices;
end
WC.chooser = hs.chooser.new(function (choice)
if not choice then
return
end
local v = choice["win"]
if v then
v:focus()
end
end)
hs.hotkey.bind({"alt"}, "Tab", function ()
local choices = list_window_choices()
WC.chooser:choices(choices)
WC.chooser:query('')
WC.chooser:show()
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment