Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Focusing on space does not focus on window in that space #160

Closed
amanjitsk opened this issue Jul 26, 2019 · 6 comments
Closed

Focusing on space does not focus on window in that space #160

amanjitsk opened this issue Jul 26, 2019 · 6 comments
Labels
help wanted Community help appreciated question Request for information or help, not an issue undetermined Not sure if this is considered a real bug

Comments

@amanjitsk
Copy link

I launch two windows in the current space and then move one of them into a new space using the following keybind

# create desktop, move window and follow focus - uses jq for parsing json (brew install jq)
shift + cmd - n : yabai -m space --create && \
                  index="$(yabai -m query --displays --display | jq '.spaces[-1]')" && \
                  yabai -m window --space "${index}" && \
                  yabai -m space --focus "${index}"

or alternatively, creating a desktop first using

# create desktop and follow focus - uses jq for parsing json (brew install jq)
cmd + alt - n : yabai -m space --create;\
                  index="$(yabai -m query --displays --display | jq '.spaces[-1]')" && \
                  yabai -m space --focus "${index}"

and then moving the window to the newly created space. The weird thing that I notice is that focusing on the newer space does not the focus on the window in that space. So if now switch between spaces using

cmd + alt - 1 : yabai -m space --focus 1
cmd + alt - 2 : yabai -m space --focus 2

I find that the window in space 1 is correctly focused on using the above keybind, but when I focus on space 2, it does not focus on the window there.

This issue is however resolved when mission control is activated i.e. It focuses on the window in space 2 only once mission control has been activated (using the 4-finger swap to switch spaces), but not solely using the yabai space keybindings. Is this an expected issue or am I experiencing/doing something silly ?

I am on MacOS 10.14.6 and have disabled SIP and also followed every item in mentioned here

@dominiklohmann
Copy link
Collaborator

dominiklohmann commented Jul 27, 2019

The underlying issue is that focusing a space focuses the most recently focused window on that space, and that obviously does not exist for a newly created space.

If you want to follow a window, you can use this keybinding instead, which focuses the moved window instead of the newly created space.

shift + cmd - n : yabai -m space --create \
	&& wid="$(yabai -m query --windows --window | jq -r '.id')" \
	&& sidx="$(yabai -m query --spaces --display | jq -r 'map(select(."native-fullscreen" == 0))[-1].index')" \
	&& yabai -m window "${wid}" --space "${sidx}" \
	&& yabai -m window --focus "${wid}"

Another, more general fix is to always try to focus the window under the cursor after switching a space or destroying a window, but only if no window is focused.

#! /usr/bin/env sh

# save this as a file somewhere, then run:
#     chmod +x path/to/this/script
# now execute this file from your yabairc:
#    ./path/to/this/script

if [ $# -ne 0 ]; then 
	for event in window_destroyed space_changed; do
		yabai -m signal --add label="${0}_${event}" \
			event="${event}" action="${0}"
	done
	exit
fi

{ 
	yabai -m query --windows --window \
		|| yabai -m window --focus mouse 
} > /dev/null 2>&1

@amanjitsk
Copy link
Author

Thanks for the reply. Although the alternate keybinding for shift + cmd - n works, the script you posted above has no effect. What I'd like to add is that if I have 2 windows, lets say a w1 and w2 in s1 and if I decide to move w2 to a new space s2 using the keybind

shift + alt - 2   : yabai -m window --space  2; yabai -m space --focus 2

where s2 was created using

# create desktop and follow focus - uses jq for parsing json (brew install jq)
cmd + alt - n : yabai -m space --create;\
                  index="$(yabai -m query --displays --display | jq '.spaces[-1]')" && \
                  yabai -m space --focus "${index}"

what actually happens is that w1 in s1 is retaining focus i.e. even though I am on s2 now, shift + alt - 2 does not actually focus on w2 in s2, rather w1 is still focused on (can see this from the status bar) even though I am on s2. So the logic

always try to focus the window under the cursor after switching a space or destroying a window, but only if no window is focused.

may not work as expected, since there is a window focused, only problem is that its in the wrong space i.e. w1 on s1.

Essentially, I would like for the keybind shift + alt - 2 to work identically to i3wm, where moving a window to a space would automatically switch focus to that window on that space.

@dominiklohmann
Copy link
Collaborator

dominiklohmann commented Jul 28, 2019

I'm on mobile currently so I cannot test, but this should work:

@amanjitsk I updated the below post with a more detailed reply.

In the script, instead of yabai -m query --windows --window, test whether there are any focused windows on the current space.

# 1. grab all windows on the current space
# 2. filter for focused windows
# 3. if the length of the array returned by step 2 is 0, focus the window under the cursor
yabai -m query --windows --space | jq -er 'map(select(.focused == 1)) | length > 0' \
	|| yabai -m window --focus mouse

This could additionally be improved by trying to focus any window on that space by id if this fails.

Essentially, I would like for the keybind shift + alt - 2 to work identically to i3wm, where moving a window to a space would automatically switch focus to that window on that space.

You need to save the window id of the window then and have your keybind focus it. After all, you're looking to focus a specific window instead of a specific space. This can be implemented, but it's not trivial. This is also what the updated move window to space and follow along command does, but it's quite a bit harder to implement when you want this across multiple keybindings.


Side note: The way you're grabbing the index of the created space is wrong.

where s2 was created using

# create desktop and follow focus - uses jq for parsing json (brew install jq)
cmd + alt - n : yabai -m space --create;\
                  index="$(yabai -m query --displays --display | jq '.spaces[-1]')" && \
                  yabai -m space --focus "${index}"

A new space is created after the last existing non-fullscreen space on the current display. What you're doing (I know, it's the sample binds... that's for another day) is grabbing the last space on the current display.

This is how you correctly get the index:

index="$(yabai -m query --spaces --display | jq -r 'map(select(."native-fullscreen" == 0))[-1].index')"

@koekeishiya koekeishiya added help wanted Community help appreciated question Request for information or help, not an issue labels Jul 28, 2019
@amanjitsk
Copy link
Author

Thanks for the side note; I have fixed that in my skhdrc. However, the replacement snipped above still has no effect, in particular yabai -m query --windows --space | jq -er 'map(select(.focused == 1)) | length > 0' returns false for s2 (since w1 on s1 is focused), but it still fails to focus on w2 (on s2).

For now, I guess I could augment the bind for shift + alt - 2 with the snipped you provided above for shift + cmd - n, so that it also creates a space 2 (if not already present), and then moves the window to space 2 and focuses on it. So my keybind looks like

shift + alt - 2   : (yabai -m window --space  2; yabai -m space --focus 2) || yabai -m space --create \
	&& wid="$(yabai -m query --windows --window | jq -r '.id')" \
	&& sidx="$(yabai -m query --spaces --display | jq -r 'map(select(."native-fullscreen" == 0))[-1].index')" \
	&& yabai -m window "${wid}" --space "${sidx}" \
	&& yabai -m window --focus "${wid}"

I do agree that this is not elegant for multiple keybindings.

Also, maybe this I can open another issue for this, but is there a way to replicate i3-like space numbering, so for ex. having a space 1 and space 3 present, without a space 2. From what I have understood so far, there is no way for me to create a space 3 (named 3 that is) without having to create a space named "space 2" (so that would be 3 spaces instead of 2). Or also things like renaming space 1 to space 5, whilst only having one actual space. Simply speaking, a space-renumbering functionality!

@dominiklohmann
Copy link
Collaborator

Thanks for the side note; I have fixed that in my skhdrc. However, the replacement snipped above still has no effect, in particular yabai -m query --windows --space | jq -er 'map(select(.focused == 1)) | length > 0' returns false for s2 (since w1 on s1 is focused), but it still fails to focus on w2 (on s2).

Note that the code snippet you posted only returns true of there are no focused windows on the current space. It does not actually focus anything. You'd still have to use a || b or if ! a ; then b; fi of some sort, where a is the condition and b is the part where you focus a window.

The keybinding you presented for shift+alt-2 is not reliable in any way sadly.

Simply speaking, a space-renumbering functionality!

You can create files that associate space ids (not the indices!) with tags to do this, then grab the space id from the tag and then grab the space index from the space id. Or just wait for #119 of some sort, which will make this easier. This is not a simple thing to implement.

@amanjitsk
Copy link
Author

Right, I had the || yabai -m window --focus mouse after that snippet. Is there a better alternative to shift + alt - 2 keybinding that does what I want i.e. create a space first if not already existing and then move and follow focus of the window to that space ? Thanks for the quick response though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Community help appreciated question Request for information or help, not an issue undetermined Not sure if this is considered a real bug
Projects
None yet
Development

No branches or pull requests

3 participants