AdamWagner / stackline

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

yabai -m display --focus does not work for the displays with stacks #67

Open Fouer opened 3 years ago

Fouer commented 3 years ago

Hey guys, just found an annoying issue. Once I create a stack at any monitor, I can no longer focus it with -m display --focus command, focus just disappears. Any solutions?

narze commented 3 years ago

I encountered this issue too, and disabling Hammerspoon via yabai does not resolve this.

rohni commented 3 years ago

I have just started with yabai and stackline. So far this is what I've found:

I don't know if there is a way to make hammerspoon run in a daemon mode, or not as a mac app, but that might help. But until there is a solution, I'm going to have to say sayonara to hammerspoon and hackline, and guess at what is in each stack.

AdamWagner commented 3 years ago

Thanks for the report @Fouer .

Aha… I never use yabai -m display --focus, so didn't encounter this.

I will try to reproduce this weekend, and might be able to exclude Hammerspoon from the window filter in Stackline to resolve this.

AdamWagner commented 3 years ago

Bad news everyone: I don't see a clear path toward fixing this.

I can reproduce it when using multiple displays. That said, I don't think I can fix this at the "stackline" level – the issue appears to live at the intersection between yabai & hammerspoon.

Things I tried:

  1. Using yabai -m signal --add to listen for display_changed to focus the largest window on the display after it is focused. When hammerspoon is running & the current space has a stack, it's as if no display is focused after running yabai -m display --focus N
  2. Using Hammerspoon's hs.spaces.watcher module to listen for changes in the active space and focus the largest window on the active space. This event isn't even triggered when the space is changed using yabai -m display focus N.

I really appreciate the detail notes @rohni. While this doesn't fix this issue, I thought you might like to know that you can hide Hammerspoon in the doc and from cmd+tab by unchecking "Show doc icon"

Screenshot 2021-06-10 at 20 44 03@2x
blefevre commented 2 years ago

I was able to work around this by sending Hammerspoon below everything else:

yabai -m rule --add app="Hammerspoon" manage=off layer="below"

but note this makes using the Hammerspoon console difficult as it will appear under every other window.

jacktuck commented 2 years ago

@AdamWagner I have also hit this issue. If I remove stackline from ~/.hammerspoon/init.lua the issue goes away, so does not look to be solely a HS issue.

jacktuck commented 2 years ago

I think @rohni was on to something. I have hammerspoon disabled in the dock and menu but when focusing a space on first display the focus changes to hammerspoon (which is not open on this space).

I set hs.logger.setGlobalLogLevel("verbose") to get this output

2022-03-06 13:02:45:                          emitting windowFocused 11145 (Hammerspoon)
2022-03-06 13:02:45:                              iTerm2 <= deactivated (app event)

I have @blefevre's Yabai rule but didn't seem to help.

diocletiann commented 2 years ago

I wrote a workaround with @koekeishiya's help. If you focus on window ID and not display you avoid the bug where Stackline steals focus.


ctrl - left: yabai -m window --focus west || \
             yabai -m window --focus $(yabai -m query --spaces --display west | jq '.[] | select(."is-visible" == true) | ."last-window"')

ctrl - right: yabai -m window --focus east || \
              yabai -m window --focus $(yabai -m query --spaces --display east | jq '.[] | select(."is-visible" == true) | ."first-window"')

ctrl - up: yabai -m window --focus north || \
           yabai -m window --focus stack.prev || \
           yabai -m window --focus stack.last

ctrl - down: yabai -m window --focus south || \
             yabai -m window --focus stack.next || \
             yabai -m window --focus stack.first
diocletiann commented 2 years ago

You can also use this method to stack across displays:

ctrl + alt + cmd - left : yabai -m window west --stack $(yabai -m query --windows --window | jq -r '.id') || \
    yabai -m window $(yabai -m query --spaces --display west | jq '.[] | select(."is-visible" == true) | ."last-window"') --stack $(yabai -m query --windows --window | jq -r '.id')

ctrl + alt + cmd - right : yabai -m window east --stack $(yabai -m query --windows --window | jq -r '.id') || \
    yabai -m window $(yabai -m query --spaces --display east | jq '.[] | select(."is-visible" == true) | ."first-window"') --stack $(yabai -m query --windows --window | jq -r '.id')
devnoname120 commented 2 years ago

None of the solutions from here worked for me, but adding the following to ~/.config/yabai worked for me:

# focus window after active space changes
yabai -m signal --add event=space_changed action="yabai -m window --focus \$(yabai -m query --windows --space | jq .[0].id)"

# focus window after active display changes
yabai -m signal --add event=display_changed action="yabai -m window --focus \$(yabai -m query --windows --space | jq .[0].id)"

Source: https://github.com/koekeishiya/yabai/issues/719#issuecomment-728140216

diocletiann commented 2 years ago

So the first index in the array is always the most recent window in in that space?

devnoname120 commented 2 years ago

@restfuladi It's not explicitly documented but in my limited testing it seems to work.

devnoname120 commented 2 years ago

So the first index in the array is always the most recent window in in that space?

@restfuladi I can confirm that my command does not always solve the issue :(

diocletiann commented 2 years ago

So the first index in the array is always the most recent window in in that space?

@restfuladi I can confirm that my command does not always solve the issue :(

You can "yabai -m query --spaces --display (direction)" then focus on "first-window" or "last-window". That's what I do and it works well.

devnoname120 commented 2 years ago

@restfuladi

I have two issues when using your approach:

Here is my code

# focus window after active space changes
yabai -m signal --add event=space_changed action="yabai -m window --focus \$(yabai -m query --spaces | jq '.[] | select(.\"is-visible\" == true) | .\"first-window\"')"

# focus window after active display changes
yabai -m signal --add event=display_changed action="yabai -m window --focus \$(yabai -m query --spaces | jq '.[] | select(.\"is-visible\" == true) | .\"first-window\"')"
devnoname120 commented 2 years ago

I built upon @blefevre's solution and I can confirm that everything works perfectly now 👌

yabai -m signal --add event=window_created title="Hammerspoon Console" action="yabai -m window \$(yabai -m query --windows | jq -e '.[] | select(.app==\"Hammerspoon\" and .title==\"Hammerspoon Console\") | .id') --minimize"
yabai -m rule --add app="Hammerspoon" title="" manage=off layer="above" sticky=on

Explanations:


If it doesn't work for you, you can alternatively use this solution:

yabai -m rule --add title="Hammerspoon Console" manage=off layer="below"
yabai -m rule --add app="Hammerspoon" title="" manage=on layer="above" sticky=on