AdamWagner / stackline

Visualize yabai window stacks on macOS. Works with yabai & hammerspoon.
944 stars 47 forks source link

Multiple displays (monitors) issues #106

Open hamir-suspect opened 2 years ago

hamir-suspect commented 2 years ago
Not sure how to replicate this issue yet, but I suspect it has to do with restarting and reopening windows on login. I am using multiple displays that are arranged like this +----------------+

+----------------+ +------+ | | +------+ where lower one is my macbooks display. In case I have a stack on upper display, clicking in the area (on lower display) where stacklike creates clickable app images to change window results in changing the window on that upper display.

acdifran commented 2 years ago

I think I'm having the same issue you're describing. Clicking the upper left corner of single window on my top monitor registers as clicking one of the stack icons, even though there aren't any, and so it moves my mouse focus. For example if I have a chrome window on my top monitor and I click the "back" button, I can see this in the logs:

Clicked window at hs.geometry.point(-441.77093505859,-1379.7335205078)

which move focus away from chrome instead of "clicking" back.

Seems to be the same issue as https://github.com/AdamWagner/stackline/issues/100#issue-1188347867 as well.

kiryph commented 2 years ago

@hamir-suspect, @acdifran, @pomdtr

Can you try following fix?

diff --git a/stackline/stack.lua b/stackline/stack.lua
index a664063..0977a60 100644
--- a/stackline/stack.lua
+++ b/stackline/stack.lua
@@ -66,32 +66,24 @@ function Stack:deleteAllIndicators() -- {{{
 end -- }}}

 function Stack:getWindowByPoint(p)
-   if p.x < 0 or p.y < 0 then
-      -- FIX: https://github.com/AdamWagner/stackline/issues/62
-      -- NOTE: Window indicator frame coordinates are relative to the window's screen.
-      -- So, if click point has negative X or Y vals, then convert its coordinates
-      -- to relative to the clicked screen before comparing to window indicator frames.
-      -- TODO: Clean this up after fix is confirmed
+  -- Get the screen with frame that contains point 'p'
+  local function findClickedScreen(_p) -- {{{
+     return table.unpack(
+        u.filter(hs.screen.allScreens(), function(s)
+           return _p:inside(s:frame())
+        end)
+     )
+  end -- }}}

-      -- Get the screen with frame that contains point 'p'
-      local function findClickedScreen(_p) -- {{{
-         return table.unpack(
-            u.filter(hs.screen.allScreens(), function(s)
-               return _p:inside(s:frame())
-            end)
-         )
-      end -- }}}
-
-      local clickedScren = findClickedScreen(p)
-      p = clickedScren
-         and clickedScren:absoluteToLocal(p)
-         or p
-   end
+  local clickedScreen = findClickedScreen(p)
+  p = clickedScreen
+     and clickedScreen:absoluteToLocal(p)
+     or p

    return table.unpack(
          u.filter(self.windows, function(w)
           local indicatorFrame = w.indicator and w.indicator:canvasElements()[1].frame
-          if not indicatorFrame then return false end
+          if not indicatorFrame or w.screen:id() ~= clickedScreen:id() then return false end
           return p:inside(indicatorFrame) -- NOTE: frame *must* be a hs.geometry.rect instance
       end)
    )
ispringle commented 2 years ago

@kiryph that worked for me! Thanks

Edit:

Actually, this just moved the issue, with this patch the top menu bar is now unclickable if there is a stack visible on any display.

ispringle commented 2 years ago

@kiryph Try this instead, I guess hammerspoon doesn't count the top menu bar as part of the screen, so when you click up there clickedScreen is nil which errors when trying to access clickedScreen:id()

if not clickedScreen or not indicatorFrame or w.screen:id() ~= clickedScreen:id() then return false end