Skip to content

Commit cb92957

Browse files
committed
Workaround hammerspoon bug (Hammerspoon/hammerspoon#2400) to ensure indicators update when switching between windows of the same app.
1 parent d8c88fa commit cb92957

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

stackline/core.lua

+30-7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ end)
6565
-- ┌──────────────────────────────────┐
6666
-- │ Query window state subscriptions │
6767
-- └──────────────────────────────────┘
68+
69+
local options = {fixSameAppHammerspoonBug = true}
70+
6871
-- callback args: window, app, event
6972
wfd:subscribe(added_changed, function()
7073
queryWindowState:start()
@@ -81,21 +84,41 @@ stacksMgr:update()
8184
-- │ Update indicators subscriptions │
8285
-- └─────────────────────────────────┘
8386

84-
-- DONE: rather than subscribing to windowFocused here, do it only for
85-
-- windows within a stack. This will shorten the update process for focus
86-
-- changes, since we *only* need to update the indicators, not query for new
87-
-- window state entirely.
88-
-- wf.windowFocused,
89-
-- wf.windowUnfocused,
87+
function unfocusOtherAppWindows(win) -- {{{
88+
-- Fix HS bug: windowUnfocused event not fired for same-app windows
89+
-- https://github.com/Hammerspoon/hammerspoon/issues/2400
90+
-- NOTE: substantially slows down indicator redraw when focus changes :<
91+
-- So much so that it probably makes sense to store a "has >1 win
92+
-- from app" field on each stack
93+
94+
-- Related:
95+
-- ./stack.lua:22
96+
-- ./stack.lua:30
97+
98+
-- v1: Search for stack by window:
99+
-- E.g., local stack = stacksMgr:findStackByWindow(stackedWin)
100+
-- v2: Lookup stack from window instead of searching by window ID:
101+
-- local stack = stackedWin.stack
102+
-- v3: Store `otherAppWindows` directly on window:
90103

91-
-- DONE: Parameterize Activate / Deactivate by reading event
104+
-- See ./stack.lua:22
105+
each(win.otherAppWindows, function(w)
106+
w:drawIndicator({shouldFade = false})
107+
end)
108+
109+
end -- }}}
92110

93111
function redrawWinIndicator(hsWin, appName, event)
94112
local id = hsWin:id()
95113
print(event:gsub('window', ''), appName, id)
96114
local stackedWin = stacksMgr:findWindow(id)
97115
if stackedWin then -- if not found, then focused win is not stacked
98116
stackedWin:drawIndicator({shouldFade = false}) -- draw instantly on focus change
117+
118+
if options.fixSameAppHammerspoonBug then
119+
unfocusOtherAppWindows(stackedWin)
120+
end
121+
99122
end
100123
end
101124

stackline/stack.lua

+22
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ local Stack = Class("Stack", nil, {
1818

1919
new = function(self, stackedWindows) -- {{{
2020
self.windows = stackedWindows
21+
22+
each(self.windows, function(w)
23+
-- Cache reference to stack on window for easy lookup
24+
-- TODO: research cost of increased table size vs better stack lookup speed
25+
-- Added to fix annoying HS bug detailed here: ./core.lua
26+
w.otherAppWindows = self:getOtherAppWindows(w)
27+
28+
-- NOTE: Can store other helpful references, like stack, too
29+
-- I don't understand the perf. tradeoffs of size vs lookup speed, tho
30+
-- w.stack = self
31+
end)
32+
33+
self.id = stackedWindows[1].stackId
2134
end, -- }}}
2235

2336
get = function(self) -- {{{
@@ -44,6 +57,15 @@ local Stack = Class("Stack", nil, {
4457
end
4558
end, -- }}}
4659

60+
getOtherAppWindows = function(self, win) -- {{{
61+
-- NOTE: may not need when HS issue #2400 is closed
62+
return filter(self:get(), function(w)
63+
_.pheader('window in getOtherAppWindows')
64+
_.p(w)
65+
return w.app == win.app
66+
end)
67+
end, -- }}}
68+
4769
redrawAllIndicators = function(self) -- {{{
4870
self:eachWin(function(win)
4971
print('calling redraw indicator')

stackline/stackMgr.lua

+12-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ function StacksMgr:ingest(stacks, shouldClean) -- {{{
6767
for _stackId, stack in pairs(stacks) do
6868
_.pheader('new stack')
6969
_.p(stack)
70+
7071
table.insert(self.tabStacks, Stack(stack))
71-
_.pheader('stacksMngr.tabStacks afterward')
72-
_.p(self.tabStacks)
72+
7373
self:redrawAllIndicators()
7474
end
7575
end -- }}}
@@ -148,6 +148,16 @@ function StacksMgr:findWindow(wid) -- {{{
148148
end
149149
end -- }}}
150150

151+
function StacksMgr:findStackByWindow(win) -- {{{
152+
-- NOTE: may not need when HS issue #2400 is closed
153+
-- NOTE 2: Unused, since I'm storing reference to "otherAppWindows" directly on each window
154+
for _stackId, stack in pairs(self.tabStacks) do
155+
if stack.id == win.stackId then
156+
return stack
157+
end
158+
end
159+
end -- }}}
160+
151161
function StacksMgr:getShowIconsState() -- {{{
152162
return self.showIcons
153163
end -- }}}

0 commit comments

Comments
 (0)