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

Question: Can I make all non-resizeable windows float (preference windows, autosuggestion windows etc)? #1317

Open
donaldhubduck opened this issue Jul 6, 2022 · 24 comments

Comments

@donaldhubduck
Copy link

donaldhubduck commented Jul 6, 2022

I have searched a lot for this but can't find any real answer to how to do this. I'm a bit new to this – sorry if this is a noob question with obvious answer. I really like Yabai so far and this is absolutely not a big issue for me.

For some small non-resizable windows it seems to work that they become float but some are not.

Example
When I have a finder window and calendar window open – then the both window share the space which is great.
working layout

But if I for example open the finder preferences window – then the preferences window is not floating which results in the calendar window is pushed down and a lot of space is unused plus that the layout becomes "broken".
broken layout

My try to resolve this
I use the finder preferences window as an example here but this happens to some other small windows (for example the autosuggestion box inside calendar app or the finder file transfer window).

I have tried writing this code in the yabairc but it dont seem to work:
yabai -m rule --add can-resize="^false$" manage=off

This is my yabairc

#!/usr/bin/env sh

# sudo yabai --load-sa
# yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa"

# global settings
yabai -m config mouse_follows_focus          off
yabai -m config focus_follows_mouse          off
yabai -m config window_origin_display        default
yabai -m config window_placement             second_child
yabai -m config window_topmost               off
yabai -m config window_shadow                off
yabai -m config window_opacity               off
yabai -m config window_opacity_duration      0.0
yabai -m config active_window_opacity        1.0
yabai -m config normal_window_opacity        0.80
yabai -m config window_border                on
yabai -m config window_border_width          6
yabai -m config active_window_border_color   0xffbf616a
yabai -m config normal_window_border_color   0xff4c566a
yabai -m config insert_feedback_color        0xffebcb8b
yabai -m config split_ratio                  0.50
yabai -m config auto_balance                 off
yabai -m config mouse_modifier               fn
yabai -m config mouse_action1                move
yabai -m config mouse_action2                resize
yabai -m config mouse_drop_action            swap

# general space settings
yabai -m config layout                       bsp
yabai -m config top_padding                  0
yabai -m config bottom_padding               0
yabai -m config left_padding                 0
yabai -m config right_padding                0
yabai -m config window_gap                   10

# apps to not manage (ignore)
yabai -m rule --add app="^System Preferences$" manage=off
yabai -m rule --add app="^Archive Utility$" manage=off
yabai -m rule --add app="^Wally$" manage=off
yabai -m rule --add app="^Pika$" manage=off
yabai -m rule --add app="^balenaEtcher$" manage=off
yabai -m rule --add app="^Creative Cloud$" manage=off
yabai -m rule --add app="^Logi Options$" manage=off
yabai -m rule --add app="^Alfred Preferences$" manage=off

yabai -m rule --add can-resize="^false$" manage=off

echo "yabai configuration loaded.."

Do I need to have the SIP disabled and scripting-addition loaded?

Does anyone know a way to do this? Thanks!

If there is no way to do this to all windows then it is fine. Yabai seems really great and I love how powerful it seems to be!

@carlos-gtz
Copy link

I'm still new, but something I noticed here is that can-resize isn't a valid argument

Maybe you could try to query yabai -m query --windows and see if there are other things you could get that can match the rules arguments. For the moment is what I'm doing per-app

@TiagoDamascena
Copy link

You can do this using signals, isn't perfect but works. Maybe this comment can help:

#924 (comment)

@koekeishiya
Copy link
Owner

Ideally signals should be allowed to run and override certain parts of yabai's event handler logic. That would in theory make it possible to run a signal on window_created and make the window float without having it first be tiled, avoiding a change in dimensions and the visual flicker.

@donaldhubduck
Copy link
Author

I'm still new, but something I noticed here is that can-resize isn't a valid argument

Maybe you could try to query yabai -m query --windows and see if there are other things you could get that can match the rules arguments. For the moment is what I'm doing per-app

Thanks for the input! Yeah, you are totally right. Unfortunately it seems like there is no valid argument that I can use when I query the windows. It seems like using signals might do the trick!

@donaldhubduck
Copy link
Author

You can do this using signals, isn't perfect but works. Maybe this comment can help:

#924 (comment)

Wow! That seems to be exactly what I am looking for! Thanks a lot for finding it.

Unfortunately it does not seem to work for me when I add the signal which seem to work for them.

As I said in the opening post – this is not a big deal as I love how Yabai works as is. But it would be nice if it worked.

I have tried the following (between each step I restarted the yabai service):

  1. added the signal-code yabai -m signal --add event=window_created action='yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".resizable == 0 and .floating == 0" && yabai -m window $YABAI_WINDOW_ID --toggle float' from the link you gave me. which seems to work for them.
  2. Installed the program JQ with homebrew.
  3. Added label='test' active='yes' to the end of the signal-code above in this list. This was to see if the signal seemed to be active with the command yabai -m signal --list. It seemed like it was active.

This is now my .yabairc file:

#!/usr/bin/env sh

# sudo yabai --load-sa
# yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa"

# global settings
yabai -m config mouse_follows_focus          off
yabai -m config focus_follows_mouse          off
yabai -m config window_origin_display        default
yabai -m config window_placement             second_child
yabai -m config window_topmost               off
yabai -m config window_shadow                off
yabai -m config window_opacity               off
yabai -m config window_opacity_duration      0.0
yabai -m config active_window_opacity        1.0
yabai -m config normal_window_opacity        0.80
yabai -m config window_border                on
yabai -m config window_border_width          6
yabai -m config active_window_border_color   0xffd8dee9
yabai -m config normal_window_border_color   0xff4c566a
yabai -m config insert_feedback_color        0xffbf616a
yabai -m config split_ratio                  0.50
yabai -m config auto_balance                 off
yabai -m config mouse_modifier               fn
yabai -m config mouse_action1                move
yabai -m config mouse_action2                resize
yabai -m config mouse_drop_action            swap

# general space settings
yabai -m config layout                       bsp
yabai -m config top_padding                  0
yabai -m config bottom_padding               0
yabai -m config left_padding                 0
yabai -m config right_padding                0
yabai -m config window_gap                   24

# Space labels
yabai -m space 1 --label "Start"
yabai -m space 2 --label "Browser"
yabai -m space 3 --label "Code"
yabai -m space 4 --label "Misc"

# Start
yabai -m rule --add app="Finder" space="Start"
yabai -m rule --add app="Filezilla" space="Start"
yabai -m rule --add app="Activity Monitor" space="Start"
yabai -m rule --add app="Todoist" space="Start"

# Browser
yabai -m rule --add app="Firefox" space="Browser"
yabai -m rule --add app="Brave" space="Browser"
yabai -m rule --add app="Safari" space="Browser"
yabai -m rule --add app="iTerm" space="Browser"

# Programming
yabai -m rule --add app="Visual Studio Code" space="Code"

# Misc
yabai -m rule --add app="Calendar" space="Misc"
yabai -m rule --add app="Discord" space="Misc"
yabai -m rule --add app="App Store" space="Misc"

# apps to not manage (ignore)
yabai -m rule --add app="^System Preferences$" manage=off
yabai -m rule --add app="^Archive Utility$" manage=off
yabai -m rule --add app="^Wally$" manage=off
yabai -m rule --add app="^Pika$" manage=off
yabai -m rule --add app="^balenaEtcher$" manage=off
yabai -m rule --add app="^Creative Cloud$" manage=off
yabai -m rule --add app="^Logi Options$" manage=off
yabai -m rule --add app="^Alfred Preferences$" manage=off
yabai -m rule --add label="Finder" app="^Finder$" title="(Co(py|nnect)|Move|Info|Pref)" manage=off
yabai -m rule --add label="Safari" app="^Safari$" title="^(General|(Tab|Password|Website|Extension)s|AutoFill|Se(arch|curity)|Privacy|Advance)$" manage=off
yabai -m rule --add label="macfeh" app="^macfeh$" manage=off
yabai -m rule --add label="App Store" app="^App Store$" manage=off
yabai -m rule --add label="Activity Monitor" app="^Activity Monitor$" manage=off
yabai -m rule --add label="KeePassXC" app="^KeePassXC$" manage=off
yabai -m rule --add label="Calculator" app="^Calculator$" manage=off
yabai -m rule --add label="Dictionary" app="^Dictionary$" manage=off
yabai -m rule --add label="mpv" app="^mpv$" manage=off
yabai -m rule --add label="Software Update" title="Software Update" manage=off
yabai -m rule --add label="About This Mac" app="System Information" title="About This Mac" manage=off

echo "yabai configuration loaded.."

yabai -m signal --add event=window_created action='yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".resizable == 0 and .floating == 0" && yabai -m window $YABAI_WINDOW_ID --toggle float' label='test' active='yes'

When I query the windows I get the following for the Calendar-window and the Calendar settings-window:

{
	"id":710,
	"pid":7693,
	"app":"Calendar",
	"title":"General",
	"frame":{
		"x":908.0000,
		"y":0.0000,
		"w":537.0000,
		"h":539.0000
	},
	"role":"AXWindow",
	"subrole":"AXStandardWindow",
	"display":1,
	"space":4,
	"level":0,
	"opacity":1.0000,
	"split-type":"vertical",
	"stack-index":0,
	"can-move":true,
	"can-resize":false,
	"has-focus":false,
	"has-shadow":true,
	"has-border":true,
	"has-parent-zoom":false,
	"has-fullscreen-zoom":false,
	"is-native-fullscreen":false,
	"is-visible":false,
	"is-minimized":false,
	"is-hidden":false,
	"is-floating":false,
	"is-sticky":false,
	"is-topmost":false,
	"is-grabbed":false
},{
	"id":706,
	"pid":7693,
	"app":"Calendar",
	"title":"Calendar",
	"frame":{
		"x":-0.0000,
		"y":0.0000,
		"w":884.0000,
		"h":1120.0000
	},
	"role":"AXWindow",
	"subrole":"AXStandardWindow",
	"display":1,
	"space":4,
	"level":0,
	"opacity":1.0000,
	"split-type":"vertical",
	"stack-index":0,
	"can-move":true,
	"can-resize":true,
	"has-focus":false,
	"has-shadow":true,
	"has-border":true,
	"has-parent-zoom":false,
	"has-fullscreen-zoom":false,
	"is-native-fullscreen":false,
	"is-visible":false,
	"is-minimized":false,
	"is-hidden":false,
	"is-floating":false,
	"is-sticky":false,
	"is-topmost":false,
	"is-grabbed":false
},

@koekeishiya
Copy link
Owner

The property name is is-floating and can-resize now, so the posted signal is incorrect. I also think $YABAI_WINDOW_ID needs to be escaped, \$YABAI_WINDOW_ID.

@donaldhubduck
Copy link
Author

The property name is is-floating and can-resize now, so the posted signal is incorrect. I also think $YABAI_WINDOW_ID needs to be escaped, \$YABAI_WINDOW_ID.

I see! Thanks a lot for pointing it out! Maybe this was changed in yabai since they (here) wrote that signal.

When I write the following command in my terminal (I am a complete noob to scripting) it seems to check if the current active window (the terminal window) is can-resize: true and if that is correct it will make the window toggle float.:

yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er '."can-resize" == true' && yabai -m window $YABAI_WINDOW_ID --toggle float

And when I run the following command with the same active window (the terminal window) it doesnt make it float which makes me believe it works as I intend.

yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er '."can-resize" == 0' && yabai -m window $YABAI_WINDOW_ID --toggle float

But when I use this signal it doesnt seem to work. I probably have a typing error or missunderstood something:

yabai -m signal --add event=window_created action='yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".'can-resize' == true" && yabai -m window $YABAI_WINDOW_ID --toggle float'

I also tried to escape the $YABAI_WINDOW_ID with this:

yabai -m signal --add event=window_created action='yabai -m query --windows --window \$YABAI_WINDOW_ID | jq -er ".'can-resize' == true" && yabai -m window \$YABAI_WINDOW_ID --toggle float'

I need to go to bed now but I will continue to experiment with this tomorrow! :)

@carlos-gtz
Copy link

carlos-gtz commented Jul 21, 2022

@donaldhubduck

How about:

yabai -m query --windows --window $YABAI_WINDOW_ID | jq -e '."can-resize"' || yabai -m window $YABAI_WINDOW_ID --toggle float

Btw, since you have your yabairc with yabai -m config layout bsp, you will notice a flickering as it will tile the window created and then it will float it. That happens because you are toggling the layout.

So, maybe a solution would be to not have yabai -m config layout at all, then have one signal to tile those who can resize. I don't know what should be the solution, but maybe @koekeishiya could tell us and we could add it in the wiki (maybe we could gather some of these in the examples/tricks part)

@MuhammedZakir
Copy link

@carlos-gtz: you forgot to pass -e flag to jq. :-)

@carlos-gtz
Copy link

Thanks, adding that up to my answer :)

@donaldhubduck
Copy link
Author

@carlos-gtz

I really appreciate all the help! :)

How about:

yabai -m query --windows --window $YABAI_WINDOW_ID | jq -e '."can-resize"' || yabai -m window $YABAI_WINDOW_ID --toggle float

Wouldn't I need to check if can-resize is true or not for it to work? I tried to add the code to the signal so it looks like this:

yabai -m signal --add event=window_created action='yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er '."can-resize"' || yabai -m window $YABAI_WINDOW_ID --toggle float'

But it doesn't seem to do anything unfortunately. I also tried to check if can-resize is false with the following signal:

yabai -m signal --add event=window_created action='yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er '."can-resize" == 0' || yabai -m window $YABAI_WINDOW_ID --toggle float'

But no luck.

I tried changing some here and there but I can't seem to get the signals to work. Maybe my scripting-addition is not loaded correctly.

Btw, since you have your yabairc with yabai -m config layout bsp, you will notice a flickering as it will tile the window created and then it will float it. That happens because you are toggling the layout.

So, maybe a solution would be to not have yabai -m config layout at all, then have one signal to tile those who can resize. I don't know what should be the solution, but maybe @koekeishiya could tell us and we could add it in the wiki (maybe we could gather some of these in the examples/tricks part)

Love this idea!

I tried and commented out the layout bsp in my yabairc. Then I reloaded yabai (which I always do inbetween changes). All windows are now floating (which is intended). Then I wrote the following command in my terminal just to try it out:

yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er '."can-resize" == true' && yabai -m window $YABAI_WINDOW_ID --toggle float

But the terminal window stay float somehow.

I guess I do quite many obvious mistakes when I try stuff :D

Right now I am thinking of leaving it be, because it is not that annoying that very few windows that cannot resize "tries" to take up half of the screen.

@carlos-gtz
Copy link

Wouldn't I need to check if can-resize is true or not for it to work?
It should be fine as you will get the true/false result and use it on the || comparison for the -toggle float part.

It works for me when I do it on the terminal 🤔

My terminal is float, then I do this to tile it.
yabai -m query --windows --window $YABAI_WINDOW_ID | jq -e '."can-resize"' && yabai -m window $YABAI_WINDOW_ID --toggle float

If the window can't be resized, then I do this:
yabai -m query --windows --window $YABAI_WINDOW_ID | jq -e '."can-resize"' || yabai -m window $YABAI_WINDOW_ID --toggle float

Here is one trick for you to try this without using signals. You can sleep the command before execute it.

  • write this in your terminal:
    sleep 1; yabai -m query --windows --window $YABAI_WINDOW_ID | jq -e '."can-resize"' || yabai -m window $YABAI_WINDOW_ID --toggle float
  • press enter and focus a non-resizable window (About this Mac can be a good example)
  • profit (?)

How about you comment all your current rules and signals? Then try this and see if it works.

@koekeishiya
Copy link
Owner

You need to escape the $YABAI_WINDOW_ID variable properly, so that it is not evaluated in the config script. See my earlier comment.

@XA21X
Copy link

XA21X commented Sep 21, 2022

Thanks for the tips. This works nicely for me:

yabai -m signal --add event=window_created action='yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".\"can-resize\" or .\"is-floating\"" || yabai -m window $YABAI_WINDOW_ID --toggle float'

Edit^: Blindly toggling it was undoing my manage=off rules, so I added the is-floating check as well. A workaround for the lack of #945.

Note that $ does not need to be escaped with \ because of the single quotes. It makes sense in the few examples above when invoking the commands directly.

It would be great if we could have floating turned on by default and have the reversed rule to avoid flickering etc, but I couldn't get that to work - it doesn't seem to be supported at the moment.

@BlkPingu
Copy link

How can I avoid that the new window jumps to the parent window instead of staying in the middle of the screen? @XA21X

@kabeersvohra
Copy link

kabeersvohra commented Aug 8, 2023

I have added some changes to your command @XA21X which make it on the top layer and centred in the screen:

yabai -m signal --add event=window_created action='
  yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".\"can-resize\" or .\"is-floating\"" || \
  yabai -m window $YABAI_WINDOW_ID --toggle float && \
  yabai -m window $YABAI_WINDOW_ID --layer above && \
  yabai -m window $YABAI_WINDOW_ID --grid 3:3:1:1:1:1
'

@jqtmviyu
Copy link

I have some changes for above command

yabairc

systemApp='^(System Preferences|System Information|Finder|Calendar|Mail|App Store|Activity Monitor|Dictionary)$'

manageOffApp='^(IINA|Stats|LICEcap)$'

yabai -m rule --add app="${systemApp}|${manageOffApp}" manage=off

yabai -m signal --add event=window_created \
  action='yabai -m query --windows --window $YABAI_WINDOW_ID \
  | jq -er ".\"can-resize\" or .\"is-floating\"" || \
  yabai -m window $YABAI_WINDOW_ID --toggle float' \
  app!="${systemApp}|${manageOffApp}"

skhdrc

alt + ctrl - i : json_text=$(yabai -m query --windows --window mouse | jq -r tostring | tr -d '{}"' | tr ',' '\n') ; \
                 appName=$(echo "$json_text" | sed -n 's/^app:\(.*\)/\1/p') ; \
                 result=$(osascript -e "display dialog \"$json_text\" buttons {\"Close\", \"manageOff\"} default button \"Close\"") ; \
                 echo "$result" | grep -q "manageOff" && \
                 perl -i -pe "s/manageOffApp\=\'\^\(/manageOffApp\=\'\^\($appName\|/g" ~/.config/yabai/yabairc && \
                 yabai --restart-service

@gshpychka
Copy link

How can I avoid that the new window jumps to the parent window instead of staying in the middle of the screen? @XA21X

Doesn't seem like this is possible, since the signal is executed after the windows is spawned. Unless anyone else has figured out a better way.

@CassandraCat
Copy link

CassandraCat commented Jan 29, 2024

child windows all have 'can resize' set to true in yabai.

@hakusaro
Copy link

I have some changes for above command

@jqtmviyu can you elaborate more on why you approached it this way?

@ubuntudroid
Copy link

I have added some changes to your command @XA21X which make it on the top layer and centred in the screen:

yabai -m signal --add event=window_created action='
  yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".\"can-resize\" or .\"is-floating\"" || \
  yabai -m window $YABAI_WINDOW_ID --toggle float && \
  yabai -m window $YABAI_WINDOW_ID --layer above && \
  yabai -m window $YABAI_WINDOW_ID --grid 3:3:1:1:1:1
'

@kabeersvohra That's lovely! 😍 The only part which doesn't seem to work is the centering. For me the window always appears in the bottom left edge... 🤔

@benvp
Copy link

benvp commented May 21, 2024

I have added some changes to your command @XA21X which make it on the top layer and centred in the screen:

yabai -m signal --add event=window_created action='
  yabai -m query --windows --window $YABAI_WINDOW_ID | jq -er ".\"can-resize\" or .\"is-floating\"" || \
  yabai -m window $YABAI_WINDOW_ID --toggle float && \
  yabai -m window $YABAI_WINDOW_ID --layer above && \
  yabai -m window $YABAI_WINDOW_ID --grid 3:3:1:1:1:1
'

@kabeersvohra That's lovely! 😍 The only part which doesn't seem to work is the centering. For me the window always appears in the bottom left edge... 🤔

Had the same issue. For now I somewhat solved it with putting it into a single command. Getting a little flickering, though.

yabai -m signal --add event=window_created action='
  yabai -m query --windows --window $yabai_window_id | jq -er ".\"can-resize\" or .\"is-floating\"" || \
  yabai -m window $yabai_window_id --toggle float --layer above --grid 4:4:1:1:2:2
'

@OfficialCRUGG
Copy link

OfficialCRUGG commented May 21, 2024

@benvp Thanks for that snippet! Do you by any chance know how I'd add manual exceptions to this? One of my programs is identified was not resizable, due to it doing some hacky workarounds, even though it can be resized just fine.

@benvp
Copy link

benvp commented May 21, 2024

I'm not experienced with jq but I think you can query for the app or title of the json returned from the windows query.

I'd filter out the apps by checking the app or title field and exclude them.

jq -er "(.\"can-resize\" or .\"is-floating\") and (.app | contains(\"Alacritty\" | not)

This would be the final snippet. Didn't test it, but maybe it points into the right direction.

 yabai -m signal --add event=window_created action='
  yabai -m query --windows --window $yabai_window_id | jq -er "(.\"can-resize\" or .\"is-floating\") and (.\"app\" | contains(\"Alacritty\") | not)" || \
  yabai -m window $yabai_window_id --toggle float --layer above --grid 4:4:1:1:2:2
'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests