-
Notifications
You must be signed in to change notification settings - Fork 9
/
common.py
103 lines (71 loc) · 3.67 KB
/
common.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
103
import enum
import logging
import math
from typing import Optional
import i3ipc
import move_counter
def get_workspaces(i3: i3ipc.Connection) -> list[i3ipc.Con]:
return [i3.get_tree().find_by_id(reply.ipc_data["id"]).workspace()
for reply in i3.get_workspaces()]
def get_focused_workspace(i3: i3ipc.Connection) -> i3ipc.Con:
for reply in i3.get_workspaces():
if reply.focused:
return i3.get_tree().find_by_id(reply.ipc_data["id"]).workspace()
raise Exception("No workspaces were focused. This should never happen")
def get_focused_window(i3: i3ipc.Connection) -> i3ipc.Con:
# Should never return None because we start with the focused workspace.
return get_focused_workspace(i3).find_focused()
def get_window_of_event(i3: i3ipc.Connection, event: i3ipc.Event) -> Optional[i3ipc.Con]:
return i3.get_tree().find_by_id(event.container.id)
def get_workspace_of_window(window: Optional[i3ipc.Con]) -> Optional[i3ipc.Con]:
return window.workspace() if window is not None else None
def get_workspace_of_event(i3: i3ipc.Connection, event: i3ipc.Event) -> Optional[i3ipc.Con]:
return get_workspace_of_window(get_window_of_event(i3, event))
def refetch_container(i3: i3ipc.Connection, container: i3ipc.Con) -> i3ipc.Con:
return i3.get_tree().find_by_id(container.id)
def tree_str(container: i3ipc.Con, indent: str = "") -> str:
out = f"{indent} {container.id} {container.layout}\n"
for node in container.nodes:
out += tree_str(node, indent + " ")
return out
def move_container(con1: i3ipc.Con, con2: i3ipc.Con) -> None:
move_counter.increment()
con2.command("mark __swaymonad__mark");
con1.command("move window to mark __swaymonad__mark")
con2.command("unmark __swaymonad__mark");
def reverse_nodes(i3: i3ipc.Connection, container: i3ipc.Con, starting_idx: int = 0) -> None:
logging.debug(f"Reversing nodes in container {container.id} from index {starting_idx} onward.")
for i, node in enumerate(container.nodes[starting_idx:math.ceil(len(container.nodes)/2)]):
target_node_id = container.nodes[-i-1].id
logging.debug(f"Swapping node {i} (container id {node.id}) with "
f"node {len(container.nodes) - i - 1} (container id {target_node_id})")
if node.id != target_node_id:
node.command(f"swap container with con_id {target_node_id}")
def insert_node_at_index(i3: i3ipc.Connection,
container: i3ipc.Con,
node: i3ipc.Con,
index: int) -> None:
logging.debug(f"Inserting node {node.id} into container {container.id} at index {index}.")
move_container(node, container)
# We haven't refreshed our view of container, so it still only contains the
# old nodes and does not include the new node at the end.
for old_node in container.nodes[::-1]:
node.command(f"swap container with con_id {old_node.id}")
def add_node_to_front(i3: i3ipc.Connection, container: i3ipc.Con, node: i3ipc.Con) -> None:
insert_node_at_index(i3, container, node, 0)
def ensure_split(container: i3ipc.Con, split: str) -> list[i3ipc.replies.CommandReply]:
if container.layout != split:
return container.command(split)
else:
return []
def is_floating(container: i3ipc.Con) -> bool:
# TODO: replace first clause with container.is_floating() when the next
# version of i3ipc-python is released.
return container.floating in ['user_on', 'auto_on'] or container.type == "floating_con"
# https://docs.python.org/3/library/enum.html#using-automatic-values
class AutoName(enum.Enum):
value: str
# https://github.com/python/mypy/issues/7591
@staticmethod
def _generate_next_value_(name: str, start: int, count: int, last_values: list[str]) -> str:
return name