-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathi3_cycle.py
102 lines (79 loc) · 2.54 KB
/
i3_cycle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Cycle through i3 containers
"""
from argparse import ArgumentParser
from i3_tree import i3Tree
import i3
def find_focusable(node):
"""
Search for the first focusable window within the node tree
"""
if not node.children:
return node
if node.focus:
return find_focusable(node.children_dict[node.focus[0]])
def find_parent_split(node, orientation):
"""
Find the first parent split relative to the given node
according to the desired orientation
"""
if (node and node.orientation == orientation
and len(node.children) > 1):
return node
if not node or node.type == "workspace":
return None
return find_parent_split(node.parent, orientation)
def cycle_windows(tree, direction):
"""
Cycle through windows of the current workspace
"""
wanted = {
"orientation": ("vertical" if direction in ("up", "down")
else "horizontal"),
"direction": (1 if direction in ("down", "right")
else -1),
}
split = find_parent_split(tree.focused.parent, wanted["orientation"])
if split:
# Get the next child given the direction
child_ids = [child.id for child in split.children]
focus_idx = child_ids.index(split.focused_child.id)
next_idx = (focus_idx + wanted['direction']) % len(child_ids)
next_node = split.children[next_idx]
return find_focusable(next_node)
return None
def cycle_outputs(tree, direction):
"""
Cycle through directions
"""
direction = 1 if direction == "next" else -1
outputs = [output for output in tree.root.children
if output.name != "__i3"]
focus_idx = outputs.index(tree.root.focused_child)
next_idx = (focus_idx + direction) % len(outputs)
next_output = outputs[next_idx]
return find_focusable(next_output)
def main():
"""
Entry point
"""
parser = ArgumentParser()
parser.add_argument("direction",
choices=(
"up", "down", "left", "right",
"next", "prev"
),
help="Direction to put the focus on")
args = parser.parse_args()
tree = i3Tree()
con = None
if args.direction in ("next", "prev"):
con = cycle_outputs(tree, args.direction)
else:
con = cycle_windows(tree, args.direction)
if con:
i3.focus(con_id=con.id)
if __name__ == '__main__':
main()