stackline icon indicating copy to clipboard operation
stackline copied to clipboard

[Feature Request] Can this somehow work with Amethyst?

Open dlvhdr opened this issue 2 years ago • 1 comments

I'm using the WM https://github.com/ianyh/Amethyst. Can this be easily adapted to use with it?

dlvhdr avatar Jan 23 '22 21:01 dlvhdr

Much like yourself, I don't use yabai stacks. So, I wanted to try hacking it since a stack is nothing but overlapping windows (i.e windows with same coordinates and dimensions).

I tried two versions but neither of them seem to be working. But my idea was to tell stackline that a set of overlapping windows belong to a same stack. I tried 2 methods but in vain:

  1. Use hammerspoon's built-in tools to query windows (which makes stackline completely independent from yabai)
  2. Query windows configs from yabai (which is running in float mode so stack-index will not be set)

For me it shows the stackline but with only a single icon. I'm unsure if it's an issue with Monterey? Either way, here's the patch for the yabai hack if you want to give it a shot.

diff --git a/stackline/query.lua b/stackline/query.lua
index d5287f0..bae31d1 100644
--- a/stackline/query.lua
+++ b/stackline/query.lua
@@ -130,6 +130,15 @@ local function shouldRestack(new) -- {{{
     log.i('Should not redraw.')
 end -- }}}
 
+local function getPseudoStackId(yabaiWin)
+  local frame = yabaiWin.frame
+  local x = math.floor(frame.x)
+  local y = math.floor(frame.y)
+  local w = math.floor(frame.w)
+  local h = math.floor(frame.h)
+  return table.concat({x, y, w, h}, '|')
+end
+
 local function run(opts) -- {{{
     opts = opts or {}
     local byStack, byApp = groupWindows(stackline.wf:getWindows()) -- set byStack & self.appWindows
@@ -141,10 +150,27 @@ local function run(opts) -- {{{
 
     if shouldRefresh or opts.forceRedraw then
         log.i('Refreshing stackline')
+
         -- TODO: if there's only 1 space, use 'query --windows --space' to reduce chance that parsing fails
         local yabai_cmd = 'query --windows'
 
         yabai(yabai_cmd, function(yabaiRes)
+            -- u.p(yabaiRes)
+
+            local winIdsToPseudoStackId = {}
+            for _, win in ipairs(yabaiRes) do
+              winIdsToPseudoStackId[win.id] = getPseudoStackId(win)
+            end
+
+            local pseudoStackIdToIdx = {}
+            for _, pseudoStackId in pairs(winIdsToPseudoStackId) do
+              pseudoStackIdToIdx[pseudoStackId] = pseudoStackIdToIdx[pseudoStackId] or u.length(pseudoStackIdToIdx) + 1
+            end
+
+            u.each(yabaiRes, function(win)
+              win['stack-index'] = pseudoStackIdToIdx[winIdsToPseudoStackId[win.id]]
+            end)
+
             local winStackIdxs = stackIdMapper(yabaiRes)
             stackline.manager:ingest( -- hand over to stackmanager
                 mergeWinStackIdxs(byStack, winStackIdxs), -- Add the stack indexes from yabai to byStack

harsilspatel avatar Feb 08 '22 15:02 harsilspatel