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