i think this fixes i3 issues
[distro-setup] / i3-split-push
1 # I, Ian Kelling, follow the GNU license recommendations at
2 # https://www.gnu.org/licenses/license-recommendations.en.html. They
3 # recommend that small programs, < 300 lines, be licensed under the
4 # Apache License 2.0. This file contains or is part of one or more small
5 # programs. If a small program grows beyond 300 lines, I plan to change
6 # to a recommended GPL license.
7
8 # Copyright 2024 Ian Kelling
9
10 # Licensed under the Apache License, Version 2.0 (the "License");
11 # you may not use this file except in compliance with the License.
12 # You may obtain a copy of the License at
13
14 # http://www.apache.org/licenses/LICENSE-2.0
15
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS,
18 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 # See the License for the specific language governing permissions and
20 # limitations under the License.
21
22 #!/usr/bin/python3
23
24 # There are only 2 cases where I want single window split containers.
25 #
26 # * just before creating a new window in it.
27 #
28 # * When I want to make 1 window a split container and bring an existing
29 # window into it. In vanilla i3, this is super awkward. Usually, you are
30 # starting out focused on the window you want to move into the
31 # container. So, you focus the window which is to become a container,
32 # split it, focus the window you want to join the container, move it
33 # into that container. 4 actions, totally annoying. Lets simplify this
34 # to 2 actions, a key to say what split we want, then a key to say which
35 # direction to move the current window. Since we have a hook that erases
36 # all single window split containers on focus change, we can consider a
37 # single window split container to indicate the split we want.
38 #
39 #
40 import sys
41 from i3ipc import Connection, Event
42 # for debugging
43 from pprint import pprint
44 import os
45
46
47 def find_parent(i3, window_id):
48 """
49 Find the parent of a given window id
50 """
51
52 def finder(con, parent, gp):
53 if con.id == window_id:
54 return (parent, gp)
55 for node in con.nodes:
56 res = finder(node, con, parent)
57 if res:
58 return res
59 return None
60
61 return finder(i3.get_tree(), None, None)
62
63
64 def set_layout(i3):
65 """
66 Set the layout/split for the currently
67 focused window to either vertical or
68 horizontal, depending on its width/height
69 """
70
71 direction = sys.argv[1]
72
73 win = i3.get_tree().find_focused()
74 parent, gp = find_parent(i3, win.id)
75 layout = parent.layout
76
77 if (parent and gp and len(parent.nodes) == 1):
78 exists = False
79 if os.path.exists('/tmp/iank-i3-no-auto'):
80 exists = True
81 else:
82 open('/tmp/iank-i3-no-auto', 'a')
83 i3.command('focus ' + direction)
84
85
86 if (layout == 'splith'):
87 i3.command('split horizontal')
88 elif (layout == 'splitv'):
89 i3.command('split vertical')
90 elif (layout == 'tabbed'):
91 i3.command('split vertical')
92 i3.command('layout tabbed')
93
94 i3.command('[con_id=%s] focus' % win.id)
95 i3.command('move ' + direction)
96 if (not exists):
97 os.remove('/tmp/iank-i3-no-auto')
98 else:
99 i3.command('move ' + direction)
100
101
102 def main():
103 i3 = Connection()
104 set_layout(i3)
105
106
107 if __name__ == "__main__":
108 main()