i3a 2.2.2__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {i3a-2.2.2 → i3a-2.3.0}/PKG-INFO +11 -1
- {i3a-2.2.2 → i3a-2.3.0}/README.md +10 -0
- {i3a-2.2.2 → i3a-2.3.0}/pyproject.toml +2 -1
- i3a-2.3.0/src/i3a/cycle_focus.py +64 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/master_stack.py +12 -4
- {i3a-2.2.2 → i3a-2.3.0}/LICENSE +0 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/__init__.py +0 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/move_to_empty.py +0 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/resize_compass.py +0 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/scale_cycle.py +0 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/swallow.py +0 -0
- {i3a-2.2.2 → i3a-2.3.0}/src/i3a/swap.py +0 -0
{i3a-2.2.2 → i3a-2.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: i3a
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Automatic manager for i3 tiling
|
|
5
5
|
Home-page: https://git.goral.net.pl/i3a.git
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -128,6 +128,16 @@ bindsym $mod+Right exec i3a-resize-compass right 2ppt
|
|
|
128
128
|
bindsym $mod+Left exec i3a-resize-compass left 2ppt
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
+
### i3a-cycle-focus
|
|
132
|
+
|
|
133
|
+
Change the currently focused window up or down, cycling the tiled windows
|
|
134
|
+
within the current workspace.
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
bindsym $mod+j exec i3a-cycle-focus down
|
|
138
|
+
bindsym $mod+k exec i3a-cycle-focus up
|
|
139
|
+
```
|
|
140
|
+
|
|
131
141
|
### i3a-scale-cycle
|
|
132
142
|
|
|
133
143
|
**sway-specific**
|
|
@@ -99,6 +99,16 @@ bindsym $mod+Right exec i3a-resize-compass right 2ppt
|
|
|
99
99
|
bindsym $mod+Left exec i3a-resize-compass left 2ppt
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
### i3a-cycle-focus
|
|
103
|
+
|
|
104
|
+
Change the currently focused window up or down, cycling the tiled windows
|
|
105
|
+
within the current workspace.
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
bindsym $mod+j exec i3a-cycle-focus down
|
|
109
|
+
bindsym $mod+k exec i3a-cycle-focus up
|
|
110
|
+
```
|
|
111
|
+
|
|
102
112
|
### i3a-scale-cycle
|
|
103
113
|
|
|
104
114
|
**sway-specific**
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "i3a"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.3.0"
|
|
8
8
|
description = "Automatic manager for i3 tiling"
|
|
9
9
|
authors = ["Michal Goral <dev@goral.net.pl>"]
|
|
10
10
|
license = "GPL-3.0-or-later"
|
|
@@ -36,3 +36,4 @@ i3a-move-to-empty = "i3a.move_to_empty:main"
|
|
|
36
36
|
i3a-swap = "i3a.swap:main"
|
|
37
37
|
i3a-resize-compass = "i3a.resize_compass:main"
|
|
38
38
|
i3a-scale-cycle = "i3a.scale_cycle:main"
|
|
39
|
+
i3a-cycle-focus = "i3a.cycle_focus:main"
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2024 DjejDjej
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import asyncio
|
|
6
|
+
|
|
7
|
+
from i3ipc.aio import Connection
|
|
8
|
+
|
|
9
|
+
FLOATING_MODES = ("auto_on", "user_on")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def move_stack(direction: str):
|
|
13
|
+
"""
|
|
14
|
+
Move the focused window up or down the stack in the current workspace.
|
|
15
|
+
:param direction: 'up' to move up, 'down' to move down.
|
|
16
|
+
"""
|
|
17
|
+
i3 = await Connection(auto_reconnect=True).connect()
|
|
18
|
+
tree = await i3.get_tree()
|
|
19
|
+
focused = tree.find_focused()
|
|
20
|
+
|
|
21
|
+
if not focused:
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
ws = focused.workspace()
|
|
25
|
+
if not ws:
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
# Collect all tiled (non-floating) windows
|
|
29
|
+
tiled_windows = [
|
|
30
|
+
n
|
|
31
|
+
for n in ws.leaves()
|
|
32
|
+
if n.floating not in FLOATING_MODES
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
if len(tiled_windows) < 2:
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
idx = tiled_windows.index(focused)
|
|
40
|
+
if direction == "up":
|
|
41
|
+
target_idx = (idx - 1) % len(tiled_windows)
|
|
42
|
+
elif direction == "down":
|
|
43
|
+
target_idx = (idx + 1) % len(tiled_windows)
|
|
44
|
+
else:
|
|
45
|
+
raise ValueError("Invalid direction; use 'up' or 'down'.")
|
|
46
|
+
|
|
47
|
+
target_window = tiled_windows[target_idx]
|
|
48
|
+
await i3.command(f'[con_id="{target_window.id}"] focus')
|
|
49
|
+
except ValueError:
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def main():
|
|
54
|
+
parser = argparse.ArgumentParser(
|
|
55
|
+
description="Move the focused window up or down the stack."
|
|
56
|
+
)
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"direction",
|
|
59
|
+
choices=["up", "down"],
|
|
60
|
+
help="Direction to move the window in the stack.",
|
|
61
|
+
)
|
|
62
|
+
args = parser.parse_args()
|
|
63
|
+
|
|
64
|
+
asyncio.run(move_stack(args.direction))
|
|
@@ -129,9 +129,16 @@ class Autotiler:
|
|
|
129
129
|
await self.cmd('[con_id="{}"] resize set {} ppt 0 ppt'.format(curr.id, self.args.stack_size))
|
|
130
130
|
else:
|
|
131
131
|
await self.cmd('[con_id="{}"] mark --add {}'.format(stack[-1].id, STACKMARK))
|
|
132
|
-
|
|
132
|
+
|
|
133
|
+
# Compound command are A LOT faster than separate ones; running
|
|
134
|
+
# additional focus after "intermove" left a visible visual glitch
|
|
135
|
+
# of "jumping" window when new window was spawned when focus was on
|
|
136
|
+
# a master window. There's still a minor artifact with compound command,
|
|
137
|
+
# but it's more bearable now
|
|
138
|
+
move_cmd = 'move window to mark {}'.format(STACKMARK)
|
|
133
139
|
if curr.workspace() == tree.find_focused().workspace():
|
|
134
|
-
|
|
140
|
+
move_cmd += ", focus"
|
|
141
|
+
await self.intermove(curr, move_cmd)
|
|
135
142
|
|
|
136
143
|
async def win_close(self, i3, e):
|
|
137
144
|
log.debug('called win_close()')
|
|
@@ -211,8 +218,9 @@ class Autotiler:
|
|
|
211
218
|
|
|
212
219
|
async def intermove(self, node, cmd):
|
|
213
220
|
movemark = INTERNAL_MOVE_MARK + '_{}'.format(node.id)
|
|
214
|
-
|
|
215
|
-
|
|
221
|
+
# Note: compound commands separated with a colon retain their criteria
|
|
222
|
+
# ("con_id"); compound commands separated with semicolon don't.
|
|
223
|
+
await self.cmd('[con_id="{}"] mark --add {}, {}'.format(node.id, movemark, cmd))
|
|
216
224
|
|
|
217
225
|
async def rmmovemarks(self, node):
|
|
218
226
|
removed = False
|
{i3a-2.2.2 → i3a-2.3.0}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|