ArchLabs Linux

Vertical / horizontal auto-tiling on sway & i3

This script uses the i3ipc python module to switch the layout splith / splitv for the currently focused window, depending on its dimensions. It works on both sway and i3 window managers.

Does any sway or i3 user miss the way dwm tiles the screen? In the depths of hell r/i3wm I’ve found a script capable of doing this on i3. Based on the i3-py module, it works with i3 only, but it’s easy to do the same with python-i3ipc. For now I added such a feature to my wsdnames, but it would be easy to make a standalone script, if someone finds it funny.

As @natemaia pointed out, this resembles (to some degree) the fibonacci layout ‘dwindle’ in dwm.

You may find the script and some further info here. The simplest way to install is the AUR package.

3 Likes

Top job again @nwg

Nice pimping in there !

1 Like

Nice find, but the layout is wrong that is the fibonacci patch’s dwindle layout. Instead of the classic master/stack

----------------------------------------------------------------
|                               |                              |
|                               |             S1               |
|                               |------------------------------|
|               M1              |                              |
|                               |             S2               |
|                               |------------------------------|
|                               |                              |
|                               |             S3               |
----------------------------------------------------------------
1 Like

Well, I’m not familiar enough with dwm… This code just measures the layout dimensions and sets splitting accordingly. Seems reasonable to me.

new_layout = 'splitv' if con.parent.rect.height > con.parent.rect.width else 'splith'
i3.command(new_layout)

The thread title should be changed, if so. :slight_smile:

Yea I forgot i3 uses tree based tiling so it’s much easier to do switches like that, I made a small PR with the change to master/stack to your repo but as I said in my notes I’m note sure if it’s implemented properly but the concept is correct so feel free to close it if you’re not interested.

Excellent! However, at the moment I think that it should not be included into the wsdnames script. It uses the same method on too many events, while Event.WINDOW_FOCUS and Event.WINDOW_NEW seem to be enough. In result changing splith / splitv manually triggers Event.BINDING, which results in setting the value automagically once again.

I separated what’s necessary for the auto-tiling to work into a shorter script. It would be not bad to apply your changes to it.

1 Like

That was what I meant in my notes, I’ll check it out

For what I proposed the function needs to loop over every client on the current workspace, I’m pretty sure right now it only handles the client related to the event, just giving a read over the python i3ipc docs.

The script is going to be much longer, when finished. :smiley:

BTW: are you sure that implementing the dwm master / stack behavior in i3 is worth of effort? You’d have to store info on each window placement somewhere (for every workspace), and re-arrange all windows every single bindsym $mod+Shift+Right move right and bindsym $mod+Shift+Left move left. Also, in i3 they all may be easily resized, which may get you in trouble. Isn’t it better to use dwm instead? :wink:

Yea I’m not on i3, haven’t used it in a long time lol.

1 Like

I happen to have an affair with other wm sometimes, but I keep getting back to sway.

from i3ipc import Connection, Event

i3 = Connection()

def switch_splitting(i3, e):
    cur = 0
    try:
        for c in i3.get_tree().find_focused().workspace().leaves():
            if not c.type == 'floating_con' or c.floating and '_on' in c.floating:
                c.command('splith' if cur == 0 else 'splitv')
                cur += 1
    except Exception as e:
        print(e)
        pass

def main():
    i3.on(Event.WINDOW_FOCUS, switch_splitting)
    i3.on(Event.WINDOW_NEW, switch_splitting)
    i3.main()

if __name__ == "__main__":
    main()

Like you said though it’s not worth it, there’s so many unhandled corner cases and the way i3 uses a tree model doesn’t do the layout any favours either because at any point you can close one of the parents and it may or may not keep the layout correct.

Yes, it doesn’t work very well. It’s enough to focus the ‘master’ container for the script to start dividing it side by side. IMO you’d need a list to hold all containers layout and loop over it every time. It doesn’t make much sense.

Couldn’t agree more, i3 really isn’t meant to tile like this.

1 Like

The latest version published in its own GitHub repository and also in AUR.

Thx for sharing @nwg

python 3.8 note

If you’ve just updated to python 3.8, the script most likely stopped working. Uninstall both autotiling and python-i3ipc packages and install autotiling again.

Thx for the info @nwg

1 Like

Already out of date. Maximbaz has just bumped python-i3ipc to 2.1.1-2, so it should update automagically. :smiley:

1 Like