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

Addition of layout options #658

Closed
sbobadilla8 opened this issue Sep 8, 2020 · 32 comments
Closed

Addition of layout options #658

sbobadilla8 opened this issue Sep 8, 2020 · 32 comments
Labels
suggestion Request for new feature or some form of enhancement

Comments

@sbobadilla8
Copy link

Hello,

I just got an ultra wide monitor, and was wondering if Yabai has the option to manage a layout of 3 columns, since for the aspect ratio is ideal, or event the option to create several columns. And if it's not enabled, how could I enable it or add code for it?

Thanks.

@Just-Insane
Copy link

Would also like to know if this is possible. It would be especially nice to have a "priority" window that is larger than the two windows on either side.

@koekeishiya
Copy link
Owner

koekeishiya commented Sep 14, 2020

To decide how a node is split, use yabai -m window --insert ..

To change a split after it has already been created, use yabai -m window --toggle split

OR

Drag a window and drop it inside the edge of some other window by using the mouse

To make all nodes occupy the same amout of area, use yabai -m space --balance

You can automate this process by combining signals and queries.

All of this is mentioned (and inferred) in the documentation/wiki

@Just-Insane
Copy link

That works to get three evenly sized windows, however, it doesn't work for making one of the windows larger than the others.

I think this is going to be an issue with #180 and #643. If my understanding of resize is correct, I should be able to set the focused window (in this case the middle window) to an absolute width, which would then automatically set the other windows to fit. However, I am getting the error mentioned in #643 when trying to use the resize command.

Running yabai -m window --resize abs:1280:1417 on the left-most window in the space:

"frame":{
                "x":0.0000,
                "y":23.0000,
                "w":1707.0000,
                "h":1417.0000
}

image

I would expect this command to work because it shouldn't need to find a node to set an absolute width of the left-most monitor if my understanding of the error message is correct anyways.

If you are unable to resize a window in the middle of the tree, then the next best solution would be to set the split ratio for each visible window, which as mentioned in #180 is difficult to do.

@koekeishiya
Copy link
Owner

Running yabai -m window --resize abs:1280:1417 on the left-most window in the space

I would expect this command to work because it shouldn't need to find a node to set an absolute width of the left-most monitor if my understanding of the error message is correct anyways.

That error message is just garbage. Absolute resizing only works for floating windows, the same as the grid command. Opened issue #661 to track that.

You'd have to use relative resizing to expand the middle window in both directions:

yabai -m window --resize left:-20:0 && yabai -m window --resize right:20:0 

@Just-Insane
Copy link

Ah, absolute values only working for floating windows makes sense. Maybe this line should be updated to reflect that.

Resize the selected window by moving the given handle \fIdx\fP pixels horizontally and \fIdy\fP pixels vertically. If handle is \fIabs\fP the new size will be \fIdx\fP width and \fIdy\fP height.

I guess my other question would be if it's possible to define a layout using floating windows? It likely would not be ideal though.

@koekeishiya
Copy link
Owner

Maybe this line should be updated to reflect that.

Noted in the created issue, thanks.

I guess my other question would be if it's possible to define a layout using floating windows? It likely would not be ideal though.

So, the grid and abs commands in general was implemented so that I would not have to use spectacle/shiftit/hammerspoon or w/e for such simple functionality.

I have not tried to make custom layouts, but I think it would be possible using signals and queries. For example let's say you configure space 3 to be floating. Then you can hook a script up to the window_created signal, query the current space and check if it is floating, query information about the newly created window and check its title/app to decide whatever dimensions you want to assign it. Probably not the most efficient thing in the world, it was never really intended to be used like this.

@Just-Insane
Copy link

Yea, that's fair, it's kind of an odd use-case.

Trying out the example command, and it seems to be opperating funny.

For context, my monitor is 5120 pixels wide. I want the middle monitor to be 2560 pixels wide.

Setting the space to balanced results in each of the three windows being 1707px wide, therefore I would need to increase the size of the middle monitor by 426.5 pixels in each direction to get 2560.

1707 + (426.5*2) = 2560

When I run alt - r : yabai -m window --resize left:-426.5:0 && yabai -m window --resize right:426.5:0 I end up with the left-most window being 1280px wide (correct), the middle window being 2346px wide (incorrect), and the right-most window being 1493px wide (incorrect). There is about 200 pixel difference between the result and the expected outcome, and I'm not sure where that is happening.

Running alt - r : yabai -m window 12744 --resize left:-426.5:0 && yabai -m window 12744 --resize right:426.5:0 results in the same, 12744 being the ID of the middle window. I suspect this might be a bug?

@koekeishiya
Copy link
Owner

I don't use this very frequently, but it does seem to work fine with my hardware. The code responsible for translating coordinates to ratio is here: https://github.com/koekeishiya/yabai/blob/master/src/window_manager.c#L379 and 384 if you want to try and investigate further.

@Just-Insane
Copy link

Just to clarify, are these values absolute when using the right/left syntax, or percentages?

I don't know C at all unfortunately.

@sbobadilla8
Copy link
Author

sbobadilla8 commented Sep 14, 2020

It is nice to see such fast and kind responses from both the creator a really active member. Thanks for your time. And well, since all the code is in C... I am wondering, would't it be possible to define layouts the way dwm does? Or even further... import dwm code for the layouts? This way we could have different modes for yabai, a column mode, bsp mode, and leave the possibility for even more growth, we could even borrow the status bar. Not sure if this is far fetched, but is just an idea.

@Just-Insane
Copy link

Just to clarify, I am wondering if it is possible to create a priority window layout like FancyZones (https://github.com/microsoft/PowerToys/wiki/FancyZones-Overview), in which a monitor in the middle of the display is (generally) larger and windows can be tiled off to the sides.

image

https://github.com/microsoft/PowerToys/wiki/FancyZones-Overview

The screenshot of layouts in the link above only shows 3 windows, but if you were to set it to 4 windows, you would get a horizontal split either on the left or right side of the priority window, and 5 would add another split on the opposite side, and so on as you add more splits.

This is an ideal setup for ultrawide monitors, or when you want to focus on one task but still have utility windows (chat/music) open to the side.

I've tried using the ratio and resize commands, however, these always end up with the priority window not centred or require a lot of shortcut presses to get an approximation of the center.

I've also tried this, and although it looks like it should work, it doesn't seem to actually evenly resize the window.

:: default : yabai -m config window_border off
:: resize @ : yabai -m config window_border on
alt - r ; resize
resize < escape ; default
resize < return ; default
resize < h : yabai -m window --resize left:100:0  ; yabai -m window --resize right:-100:0
resize < l : yabai -m window --resize left:-100:0 ; yabai -m window --resize right:100:0
resize < j : yabai -m window --resize top:0:-100  ; yabai -m window --resize bottom:0:100
resize < k : yabai -m window --resize top:0:100   ; yabai -m window --resize bottom:0:-100

This might be better off for a new issue? I think the original issue was about getting windows into three columns, which is possible by toggling the split option.

@Liquidmantis
Copy link

I think this is going to be an issue with #180 and #643. If my understanding of resize is correct, I should be able to set the focused window (in this case the middle window) to an absolute width, which would then automatically set the other windows to fit. However, I am getting the error mentioned in #643 when trying to use the resize command.

I'm tracking this issue as I'm debating between replacing my 24" 4k monitor with a 16:9 27" 5k or a 5k ultrawide, but I haven't parsed this whole thread yet. However, #643 was user error on my part 👎 and can be ignored.

@sbobadilla8
Copy link
Author

sbobadilla8 commented Sep 14, 2020

This might be better off for a new issue? I think the original issue was about getting windows into three columns, which is possible by toggling the split option.

Actually there is no problem, the issue can continue active with the new topic, if you are all confortable with it I can rename the issue into the addition of a more flexible layout option.

@Just-Insane
Copy link

As a side note, the ability to create placeholder entities would be nice, then you could use something like i3-layout-manager to build your preferred layout even if you don't open all the windows right away.

Would solve some issues with wanting a priority window with only 1-2 windows open.

@sbobadilla8 sbobadilla8 changed the title Wide monitors Addition of layout options Sep 15, 2020
@sbobadilla8
Copy link
Author

Actually yes. I was suggesting the usage of dwm-like patches for adding or creating layouts since it is also written in C, and also would avoid having to store and load different sessions, and with just a keybinding we switch through the different layouts we added.

@Just-Insane
Copy link

Just-Insane commented Sep 15, 2020

Looking at DWM (I’ve not used it before), but this patch is what I’m looking for. https://dwm.suckless.org/patches/centeredmaster/

I can do centeredfloatingmaster by setting a floating window to center:

alt - t : yabai -m window --toggle float;\
          yabai -m window --grid 4:4:1:0:2:4

Which is pretty nice.

@koekeishiya
Copy link
Owner

koekeishiya commented Sep 16, 2020

While technically there is no reason why you could not create something that would support multiple layouts as described above - this would not be a good fit for yabai due to the way it is designed (on purpose) to be bsp-only. You cannot just simply add layout logic without having to also reimplement basically all windowing operations that currently exist, because all the existing ones do is navigate and manipulate the bsp-tree.

I understand why such layouts are popular and the need for them, but that does unfortunately not align with the goals that I have. IIRC the design of Amethyst is a better fit towards that goal.

The difficult part of writing window managers for macOS is retrieving and managing OS state, which I think yabai does in a very robust way, and so I would rather encourage someone to build on the core of yabai and just write their own layout system from scratch. If someone is interested in doing so I would be more than happy to answer questions regarding the codebase and its structure.

@Just-Insane
Copy link

Just-Insane commented Sep 16, 2020

Maybe I'm miss-understanding, but since the bsp-tree seems to support window resizing, could the "layout" system not be just resizing the windows the same way each time, while maintaining the bsp-tree, instead of floating?

I see some drawbacks to this, mainly it not working on spaces with fewer windows than the resize is expecting, and the need for a lot of querying in order to do it properly, however, I have seen some of the commands/scripts that people come up with for window management and it seems like it may be possible. I know you had mentioned doing this with floating windows, but I suspect it could be done with managed windows as well.

I still suspect there is something funky going on with the resize commands though, as I've tried both of the below commands.

yabai -m window --resize left:-100:0 ; yabai -m window --resize right:100:0
yabai -m window --resize left:-20:0 && yabai -m window --resize right:20:0

I'm not sure if this is because a window is refusing to resize any smaller, or (more likely) an issue with using ratios for the window resizing. Is there a reason that windows are resized using a ratio in the bsp-tree? Window size seems to be based on pixel count, so could you not increase/decrease height/width by pixel count rather than a ratio?

Note: running yabai -m window --resize left:-20:0 && yabai -m window --resize right:20:0 once results in a balanced window layout (3 windows at 1707px wide) changing to windows that are (from left to right) 1697, 1737, and 1687 px wide.

Running yabai -m window --resize left:20:0 && yabai -m window --resize right:-20:0 once results in a balanced window layout changing to (left to right) 1717, 1677, and 1727 px wide.

It seems like the resize left command is dividing the resize value in half. I think that maybe a bug.

I suspect this is due to using ratios for the resizing, I can get right:20/left:-30 working evenly for a few commands, but then it gets out of sync again after more than 5-6 runs.

@sbobadilla8
Copy link
Author

The difficult part of writing window managers for macOS is retrieving and managing OS state, which I think yabai does in a very robust way, and so I would rather encourage someone to build on the core of yabai and just write their own layout system from scratch. If someone is interested in doing so I would be more than happy to answer questions regarding the codebase and its structure.

Well that is completely understandable, and in fact I do believe yabai is quite robust as you mention. Perhaps it could be posible to create some sort of implementation of i3 o dwm over the core of yabai? I'm not so proficient in C, I've taken the path of web and app development, but I could help a bit with tying to make this addition. I reckon it would be quite the blast to have a dwm like tiling window manager built over yabai for Mac OS, and perhaps draw even more users to it.

@koekeishiya koekeishiya added the suggestion Request for new feature or some form of enhancement label Nov 14, 2020
@jordan-da
Copy link

I too have an ultra wide monitor and find myself yabai -m space --balance 100 times a day to fix the layout. What I am trying to do now actually (which lead me to this issue) is attempt to toggle yabai -m config auto_balance with a single shortcut and keep it on by default. This way, when I get into super window mode I can flip it off and fine tune my window placement.

@koekeishiya
Copy link
Owner

The following will toggle auto_balance:

ctrl + alt + cmd - c : if [ $(yabai -m config auto_balance) = "on" ]; then; yabai -m config auto_balance off; else; yabai -m config auto_balance on; fi

@jordan-da
Copy link

[ "$(yabai -m config auto_balance)" == 'on' ] && yabai -m config auto_balance off || { yabai -m config auto_balance on; yabai -m space --balance; }

But.. I think it is too aggressive... after playing around with it some more, I think what folks with ultrawide monitors really want is just a max width for all windows. We never want a window to ever be greater than 30% of the total width of the monitor.

@dominiklohmann
Copy link
Collaborator

We never want a window to ever be greater than 30% of the total width of the monitor.

You can achieve this by changing the padding for the current space when signals trigger for added/removed windows/applications.

@jordan-da
Copy link

lol @koekeishiya, you jinxed me

I think what this issue is really about is, bsp layouts are tricky with ultrawide monitors.

It is a binary tree after all and it isn't gonna play nice when you are working with 5120 pixels wide. You are either gonna get mega wide windows with autobalace on, or mega wide windows when you close children in some some containers.. and then have to hit yabai -m space --balance, and resize everything again.

Personally I don't think you can keep autobalce on, esp with ultra wides. Resizing is important and you don't want to blow that state every time you add or move a window.

I wonder how hard it would be to add a 4th layout for a generic, non-binary, tree, ie GSP. Considering how everything is focused around this notion of a single child I would image very challenging. It would be fun to try though...

@jordan-da
Copy link

We never want a window to ever be greater than 30% of the total width of the monitor.

You can achieve this by changing the padding for the current space when signals trigger for added/removed windows/applications.

oh that is very interesting... so whenever a window attempts to breach the threshold you set, you instead makeup the difference with padding so the desktop comes through instead of having one mega wide window. Then you can resize and adjust the reminding windows to your needs. I am gonna try that... THANKS!

@koekeishiya
Copy link
Owner

I did experiment with some layout serialization (and deserialization) in chunkwm, which allowed you to pre-configure a bsp tree (with for example 3-columns). I had the concept of allowing empty nodes, and a new window would be placed in an empty node rather than causing a split, when available.

It was pretty decent imo, but had some annoyances as well. I would be willing to iterate on that system, but it won't be for quite some time. I'm not actively working on yabai for now, and there is a huge backlog of things that I want to do when I get started again.

This has simply not been a priority for me as I still use 1080p displays, and so I have not given this problem enough thought to be able to provide an adequate solution.

@Liquidmantis
Copy link

Liquidmantis commented Feb 12, 2021

This has honestly been a major deciding factor for me in my next monitor, as well as the lack of true Retina type resolution in ultrawide monitors. Right now I'm waiting for news on the rumored Apple 5k monitor as I think the combination of less streamlined window management and lower pixel density would make me disappointed in an UW for normal desktop usage. I imagine gaming is an entirely different story.

I dream of a future with an 8k horizontal, 5k vertical ultrawide monitor with a ultrawide-aware Yabai. :)

@Just-Insane
Copy link

@jordan-da Sorry to bring up this old topic, but were you able to come up with something for automatically padding spaces so that windows were a certain size?

@Sulfyderz
Copy link

@jordan-da Sorry to bring up this old topic, but were you able to come up with something for automatically padding spaces so that windows were a certain size?

Hello,
Same case, I bought an ultrawide and I wanted to do the 3 column layout.
Currently, I don't find a correct way to do it with yabai and padding. I'll think about it more. If I find a possible solution, I'll get back to you.

Best.

@rachelgraves
Copy link

I have a three column layout more or less working with this.

I also played around with moving floating windows with:

# make floating window fill screen
shift + alt - up     : yabai -m window --grid 1:1:0:0:1:1

# make floating window fill left-third of screen
shift + alt - left   : yabai -m window --grid 1:3:0:0:1:1

# make floating window fill right-third of screen
shift + alt - right   : yabai -m window --grid 1:3:3:0:1:1

# make floating window fill right-third of screen
shift + alt - down   : yabai -m window --grid 1:3:1:0:1:1

Although I've quickly discovered shift + alt - left/right are casing problems with text editing. Time to treat myself to that elgato stream deck.

@leonsilicon
Copy link

Just wanted to share an example of how you could “add” a custom layout option to Yabai without needing to edit the Yabai codebase itself: I’ve built my own “plugin” for Yabai that basically leverages Yabai’s incredibly powerful signal system to emulate the dwm-style master-stack layout (https://github.com/leonzalion/yabai-master-stack-plugin).

(Note that it’s written in TypeScript because that’s the language I’m most comfortable with)

Thank you koekeishiya for building this incredible project!

@nipunravisara
Copy link

Is there a way to apply the layout only to current space. for ex:
space 0 - bsp
space 1 - stack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
suggestion Request for new feature or some form of enhancement
Projects
None yet
Development

No branches or pull requests

10 participants