Skip to content

Feature query windows via hammerspoon#18

Merged
AdamWagner merged 35 commits intomasterfrom
feature__query-windows-via-hammerspoon
Aug 22, 2020
Merged

Feature query windows via hammerspoon#18
AdamWagner merged 35 commits intomasterfrom
feature__query-windows-via-hammerspoon

Conversation

@AdamWagner
Copy link
Owner

I just created this to have a place to note/discuss questionable changes. I expect this will remain open for at least another couple of weeks.

…ces bin/yabai-get-stacks.

The goal of this file is to eliminate the need to 'shell out' to yabai to query
window data needed to render stackline, which would address
#8. The main problem with relying
on yabai is that a 0.03s sleep is required in the yabai script to ensure that
the changes that triggered hammerspoon's window event subscriber are, in fact,
represented in the query response from yabai. There are probably secondary
downsides, such as overall performance, and specifically *yabai* performance
(I've noticed that changing focus is slower when lots of yabai queries are
happening simultaneously).

┌────────┐
│ Status │
└────────┘
We're not yet using any of the code in this file to actually render the
indiators or query ata — all of that is still achieved via the "old" methods.
However, this file IS being required by ./core.lua and runs one every window focus
event, and the resulting "stack" data is printed to the hammerspoon console.
The stack data structure differs from that used in ./stack.lua enough that it
won't work as a drop-in replacement. I think that's fine (and it wouldn't be
worth attempting to make this a non-breaking change, esp. since zero people rely
on it as of 2020-08-02.

┌──────┐
│ Next │
└──────┘
- [ ] Integrate appropriate functionality in this file into the Stack module
- [ ] Update key Stack module functions to have basic compatiblity with the new data structure
- [ ] Simplify / refine Stack functions to leverage the benefits of having access to the hs.window module for each tracked window
- [ ] Integrate appropriate functionality in this file into the Core module
- [ ] … see if there's anything left and decide where it should live

┌───────────┐
│ WIP NOTES │
└───────────┘
Much of the functionality in this file should either be integrated into
stack.lua or core.lua — I don't think a new file is needed.
Rather than calling out to the script ../bin/yabai-get-stacks, we're using
hammerspoon's mature (if complicated) hs.window.filter and hs.window modules to
achieve the same goal natively within hammerspon.
There might be other benefits in addition to fixing the problems that inspired
tracked by stackline, which will probably make it easier to implement
enhancements that we haven't even considered yet. This approach should also be
easier to maintain, *and* we get to drop the jq dependency!
…n be called in place of Window:process() to redraw a window.
…cators display on left/right edge of window based on which side of the screen the window resides. Known bug: changes broke multiple stacks on the same space.
… all stack-is-occluded functionality from Query to StackMgr and Stack modules.
…ndicators update when switching between windows of the same app.
@@ -0,0 +1,206 @@
-- luacheck: ignore (spaces isn't used, but augments hs.window module)
local spaces = require("hs._asm.undocumented.spaces")
Copy link
Contributor

@alin23 alin23 Aug 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be available on my machine:

2020-08-10 10:27:53: *** ERROR: ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: module 'hs._asm.undocumented.spaces' not found:
	no field package.preload['hs._asm.undocumented.spaces']
	no file '/Users/alin/.hammerspoon/hs/_asm/undocumented/spaces.lua'
	no file '/Users/alin/.hammerspoon/hs/_asm/undocumented/spaces/init.lua'
	no file '/Users/alin/.hammerspoon/Spoons/hs/_asm/undocumented/spaces.spoon/init.lua'
	no file '/usr/local/share/lua/5.3/hs/_asm/undocumented/spaces.lua'
	no file '/usr/local/share/lua/5.3/hs/_asm/undocumented/spaces/init.lua'
	no file '/usr/local/lib/lua/5.3/hs/_asm/undocumented/spaces.lua'
	no file '/usr/local/lib/lua/5.3/hs/_asm/undocumented/spaces/init.lua'
	no file './hs/_asm/undocumented/spaces.lua'
	no file './hs/_asm/undocumented/spaces/init.lua'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/hs/_asm/undocumented/spaces.lua'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/hs/_asm/undocumented/spaces/init.lua'
	no file '/Users/alin/.hammerspoon/hs/_asm/undocumented/spaces.so'
	no file '/usr/local/lib/lua/5.3/hs/_asm/undocumented/spaces.so'
	no file '/usr/local/lib/lua/5.3/loadall.so'
	no file './hs/_asm/undocumented/spaces.so'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/hs/_asm/undocumented/spaces.so'
	no file '/Users/alin/.hammerspoon/hs.so'
	no file '/usr/local/lib/lua/5.3/hs.so'
	no file '/usr/local/lib/lua/5.3/loadall.so'
	no file './hs.so'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/hs.so'
stack traceback:
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: in function 'require'
	/Users/alin/.hammerspoon/stackline/stackline/query.lua:2: in main chunk
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: in function 'require'
	/Users/alin/.hammerspoon/stackline/stackline/stackMgr.lua:5: in main chunk
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: in function 'require'
	/Users/alin/.hammerspoon/stackline/stackline/core.lua:4: in main chunk
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: in function 'require'
	/Users/alin/.hammerspoon/init.lua:13: in main chunk
	[C]: in function 'xpcall'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:648: in function 'hs._coresetup.setup'
	(...tail calls...)

I commented it and the code started running, but I can't see any indicators and on one space I got this:
stackbig

@@ -0,0 +1,15 @@
#!/usr/local/bin/dash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change this to /bin/dash?

Suggested change
#!/usr/local/bin/dash
#!/bin/dash

@alin23
Copy link
Contributor

alin23 commented Aug 10, 2020

@AdamWagner the code looks cleaner now, I like this approach! But I can't seem to get it working yet, I've left some comments about the issues I have.

Keep in mind that on multi-monitor setups, coordinates can also be negative for the window frame. I'm thinking this might be why I don't see the indicators at all on my external monitor but sometimes they appear on the built-in monitor.

While this approach is being reviewed, could we merge these two small improvements? #14 #17
I can work on porting the colors PR to the new branch when I can get it to work.

@AdamWagner
Copy link
Owner Author

While this approach is being reviewed, could we merge these two small improvements? #14 #17

I'm so sorry for missing both of these! I will do a quick review and get these merged tonight.

I'm especially impressed with the upstream change to Hammerspoon. We may want to take a similar route with Hammerspoon/hammerspoon#2400, which is pretty problematic for stackline, and resulted in a lot of "workaround logic".

@AdamWagner
Copy link
Owner Author

Re: dual monitors - I have an extra monitor that I can use to test that case. Thanks for calling it out.

Re: the "full screen icon" bug - I have encountered that on even a single monitor after switching spaces. It appears intermittent, which led me to letting it slide in this draft. I'll prioritize it for the next fix, tho.

@AdamWagner
Copy link
Owner Author

@alin23 Apologies for missing another dependency. Can you install https://github.com/asmagill/hs._asm.undocumented.spaces and try this again?

Here's a teaser for motivation. Snappy!

stackline-snappy-indicators

@alin23
Copy link
Contributor

alin23 commented Aug 12, 2020

@alin23 Apologies for missing another dependency. Can you install https://github.com/asmagill/hs._asm.undocumented.spaces and try this again?

Here's a teaser for motivation. Snappy!

stackline-snappy-indicators

Oh wow, that looks awesome! I can't seem to get hs._asm.undocumented.spaces working. The latest version requires Hammerspoon with Lua 5.4 and that has not been released yet as far as I can tell. How does it work for you?

I see it uses the sharedWithState method of LuaSkin which doesn't yet exist in the latest Hammerspoon version: http://www.hammerspoon.org/docs/LuaSkin/Classes/LuaSkin/index.html

@AdamWagner
Copy link
Owner Author

Shoot. I'm definitely using an older version of hs._asm.undocumented.spaces that does not have the incompatibilities you listed.

I think I'll need to rework this so that it does not depend on the undocumented spaces module. It should be possible, given that hs.spaces.watcher exists. The undocumented module is convenient - it enhances the hs.window module with space-related methods – but I don't think it's essential.

@alin23
Copy link
Contributor

alin23 commented Aug 12, 2020

Shoot. I'm definitely using an older version of hs._asm.undocumented.spaces that does not have the incompatibilities you listed.

I think I'll need to rework this so that it does not depend on the undocumented spaces module. It should be possible, given that hs.spaces.watcher exists. The undocumented module is convenient - it enhances the hs.window module with space-related methods – but I don't think it's essential.

I see, I thought that could be the difference so I tried older versions but I gave up after 2 versions that didn't work 😅 Probably should have just kept trying 2-3 more.

But yes, if we could work without it, it would be much easier for users to install it. I think we should strive for a 2-step installation process: git clone and echo require inside init.lua

@AdamWagner
Copy link
Owner Author

AdamWagner commented Aug 12, 2020

I think we should strive for a 2-step installation process: git clone and echo require inside init.lua

I support this.

@AdamWagner
Copy link
Owner Author

@alin23 – I'm hopeful that you'll be able to get this branch running more easily now. Do you think you'll have time to test it out this week?

@alin23
Copy link
Contributor

alin23 commented Aug 18, 2020

@AdamWagner I finally got it working and it was very snappy for moving through the stack. 😄
But it made every other yabai stack action slow (things like resizing, changing gap and padding, moving a window out of a stack). The dynamic colors thing also does this in a way, it makes the stack creation slow, but it doesn't seem to affect the yabai window actions speed as much as this.

I had to revert because I'm in a very busy period at my daily job and didn't have the time to debug it.

I can try this again when things slow down at my job.

@AdamWagner
Copy link
Owner Author

I had to revert because I'm in a very busy period at my daily job and didn't have the time to debug it.

I totally understand this. I assumed you have been busy with work, so thanks for trying it out again.

Re: slow yabai actions… I'm surprised that the changes in this branch would have any (further) negative effect on yabai actions. Just curious – did you comment out the signals from .yabairc and restart the service before testing this branch? That might be a factor, although I've forgotten to deactivate the signals when switching branches before, and didn't personally notice any slowdowns in that case, either.

Some general observations:

  1. resizing yabai stacks is kind of slow even when stackline/hammerspoon isn't running
  2. resizing yabai stacks isn't any slower when stackline (any version) is running (for me)
  3. creating yabai stacks have never been slow for me when running (or not running) any version of stackline. Note that I'm referring to the actual creation of the stack - not the appearance of the indicators.
  4. One of the key changes in this branch is to debounce invocations to yabai -m query, so if anything, it should have less of an impact on yabai actions. I have noticed that yabai actions can be slowed down when tons and tons of yabai -m query invocations are running in the background.

All of this said, I believe you and will take a closer look at stack resizing / creation speed. I'll try to quantify it so we can compare.

@AdamWagner
Copy link
Owner Author

Here's a quick recording just to give you a sense of what I'm seeing so we can calibrate:

The clip starts by resizing a space with 5 total windows (2 2x stacks, 1 solo window) without stackline running.
Then, stackline is started and resizing is repeated (at about the same speed as before, to my eye).
Finally, the solo window is added to the stack with 2 windows, and which occurs instantly … although I now realize this doesn't come across in the clip b/c I trigger the stack creation with a keyboard shortcut you can't see :-)

stackline-resize-speed

@alin23
Copy link
Contributor

alin23 commented Aug 19, 2020

It's possible that when I tested this the first time, I had a GPU terminal window that took more time to redraw its contents on resize and I assumed it was caused by this branch. When testing it now, the resize looks the same in both setups, only the stack creation is slower so I perceive it to be slower overall. This shouldn't be a problem as it is not an action that will happen often.

Yabai Signals

stackline_yabai_signals

Hammerspoon Window Filter

stackline_hs_window_filter

I had to add a small check because some windows didn't have the stackIdx property and I was getting nil errors: alin23@dcb7a29

Overall, it looks good to go! There's a lot of work put into this so I'd love to see this merged and build on top of it.

Some questions I have before the merge:

  1. Can we make the hotkey optional by default?
  • I want the hotkey, it is very useful, but I'd like to have my own binding for it
  • Maybe it is a good idea to have it in the readme under a Key Bindings section so that users have to copy paste it in their own init.lua file? I know it requires another step but I think we should have less surprise for a first setup.
  1. How hard would it be to merge this with the dynamic background code?
  • Is it actually needed anymore? I see we have shadows now, maybe this is enough?
  1. This could be done after the merge, but I think it would be useful to limit the stack left/right side to the screen boundary so it doesn't go off screen, even if it overlaps the window. What do you think?

@AdamWagner
Copy link
Owner Author

AdamWagner commented Aug 20, 2020

Some questions I have before the merge:
Can we make the hotkey optional by default? I want the hotkey, it is very useful, but I'd like to have my own binding for it. Maybe it is a good idea to have it in the readme under a Key Bindings section so that users have to copy paste it in their own init.lua file? I know it requires another step but I think we should have less surprise for a first setup.

Yes, definitely. I forgot that I added the binding into stackline and not my own init.lua. I'll remove that from the branch and add to the readme.

How hard would it be to merge this with the dynamic background code?

I don't know how hard it will be. A lot of the indicator draw/redraw/color attribute building has changed, but it should be fairly straightforward to plug into / customize.

Is it actually needed anymore? I see we have shadows now, maybe this is enough?
No way! Still "wanted", for sure! And the shadows don't look very good with the pill-style indicators (and so are toned way down)

This could be done after the merge, but I think it would be useful to limit the stack left/right side to the screen boundary so it doesn't go off screen, even if it overlaps the window. What do you think?

Yes, I've had the same thought. I'll create an issue to address this after merging the changes here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants