fc6866668a2480e7282046a9b12c318d8618b6ca
[distro-setup] / i3-set-layout
1 #!/usr/bin/python3
2
3 import sys
4 from i3ipc import Connection, Event
5
6
7 def find_parent(i3, window_id):
8 """
9 Find the parent of a given window id
10 """
11
12 def finder(con, parent, gp):
13 if con.id == window_id:
14 return (parent, gp)
15 for node in con.nodes:
16 res = finder(node, con, parent)
17 if res:
18 return res
19 return None
20
21 return finder(i3.get_tree(), None, None)
22
23
24 def set_layout(i3):
25 """
26 Set the layout/split for the currently
27 focused window to either vertical or
28 horizontal, depending on its width/height
29 """
30
31 win = i3.get_tree().find_focused()
32 parent, gp = find_parent(i3, win.id)
33
34
35 # We never want to set the layout of a single window container,
36 # there are already keys for that. I don't know why i3 even does
37 # this, it is stupid. So, eliminate single window container if we
38 # are focused on one.
39 #
40 # Alternatively, we could first focus the parent, but I think when
41 # layout changes, we expect new windows to be created within that
42 # layout.
43 #
44 # Todo: if the direction we are moving has a split/tabbed container
45 # as a peer to parent, this will move our window into that container
46 # instead of what we want. And in fact, the whole logic below is
47 # incorrect and based on testing which did not realize that fact.
48 #
49 if (parent and gp and len(parent.nodes) == 1):
50 # https://unix.stackexchange.com/questions/173754/how-to-move-a-window-up-to-the-level-of-its-parent-window-in-i3wm
51 i3.command('mark i3ha')
52 i3.command('focus parent')
53 i3.command('focus parent')
54 i3.command('mark i3hb')
55 i3.command('[con_mark="i3ha"] focus')
56 i3.command('move window to mark i3hb')
57 i3.command('unmark i3ha')
58 i3.command('unmark i3hb')
59 i3.command('layout ' + sys.argv[1])
60
61 def main():
62 i3 = Connection()
63 set_layout(i3)
64
65
66 if __name__ == "__main__":
67 main()