Skip to content

Commit 9257ffe

Browse files
authoredMay 18, 2021
Merge pull request #4 from abstractlyZach/window-management
Add basic window management
2 parents 04b677c + 011d704 commit 9257ffe

File tree

7 files changed

+90
-2
lines changed

7 files changed

+90
-2
lines changed
 

‎.flake8

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ select = ANN,B,B9,BLK,C,E,F,I,S,W
33
ignore = E203,E501,W503,ANN101
44
max-complexity = 10
55
max-line-length = 90
6-
application-import-names = "magic_tiler,tests"
6+
application-import-names = magic_tiler,tests
77
import-order-style = google
88
per-file-ignores = tests/*:S101,ANN

‎mypy.ini

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[mypy]
2+
3+
[mypy-i3ipc]
4+
ignore_missing_imports = True

‎pyproject.toml

+9-1
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,16 @@ source = ["src", "*/site-packages"]
3333
[tool.coverage.run]
3434
branch = true
3535
source = ["magic_tiler"]
36-
omit = ["src/magic_tiler/interfaces.py"]
36+
omit = [
37+
"src/magic_tiler/interfaces.py",
38+
"src/magic_tiler/subprocess_runner.py",
39+
"src/magic_tiler/sway.py",
40+
"src/magic_tiler/main.py",
41+
]
3742

3843
[tool.coverage.report]
3944
show_missing = true
4045
fail_under = 100
46+
47+
[tool.isort]
48+
profile = "google"

‎src/magic_tiler/interfaces.py

+7
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ def resize_width(self, window_title_regex: str, container_percentage: int) -> No
1717
@abc.abstractmethod
1818
def resize_height(self, window_title_regex: str, container_percentage: int) -> None:
1919
pass
20+
21+
22+
class Runner(object):
23+
@abc.abstractmethod
24+
def run_and_disown(self, command: str) -> None:
25+
"""Run a command and don't wait for it to finish"""
26+
pass

‎src/magic_tiler/main.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import logging
2+
3+
from magic_tiler import subprocess_runner
4+
from magic_tiler import sway
5+
6+
logging.basicConfig(level=logging.INFO)
7+
swaywm = sway.Sway(subprocess_runner.SubprocessRunner())
8+
swaywm.make_horizontal_sibling("Alacritty:v", 'alacritty -e sh -c "ls | fzf"')
9+
# how do we make alacritty hang around after running the initial command?
10+
swaywm.make_horizontal_sibling("Alacritty:poetry", 'alacritty -e zsh -c "ls"')

‎src/magic_tiler/subprocess_runner.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import shlex
2+
import subprocess # noqa: S404
3+
4+
from magic_tiler import interfaces
5+
6+
7+
class SubprocessRunner(interfaces.Runner):
8+
def run_and_disown(self, command: str) -> None:
9+
"""Run a command without waiting for it to exit"""
10+
# split a command into tokens for the shell
11+
args = shlex.split(command)
12+
subprocess.Popen(args) # noqa: S603

‎src/magic_tiler/sway.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import logging
2+
import time
3+
4+
import i3ipc
5+
6+
from magic_tiler import interfaces # pragma: nocover
7+
8+
"""We need to sleep for a short time since processes take time to start.
9+
If we don't sleep, then we may be focusing on a different window by the
10+
time that the current window is spawning, which would put it in the wrong
11+
split.
12+
"""
13+
SLEEP_TIME = 0.25
14+
15+
16+
class Sway(interfaces.TilingWindowManager): # pragma: nocover
17+
def __init__(self, runner: interfaces.Runner) -> None:
18+
self._sway = i3ipc.Connection()
19+
self._runner = runner
20+
21+
def make_horizontal_sibling(self, window_title_regex: str, command: str) -> None:
22+
self._focus_window(window_title_regex)
23+
self._runner.run_and_disown(command)
24+
time.sleep(0.25)
25+
26+
def make_vertical_sibling(self, window_title_regex: str, command: str) -> None:
27+
pass
28+
29+
def resize_width(self, window_title_regex: str, container_percentage: int) -> None:
30+
pass
31+
32+
def resize_height(self, window_title_regex: str, container_percentage: int) -> None:
33+
pass
34+
35+
def _focus_window(self, window_title_regex: str) -> None:
36+
tree = self._sway.get_tree()
37+
windows = tree.find_named(window_title_regex)
38+
logging.debug(f"windows are {windows}")
39+
if len(windows) > 1:
40+
raise RuntimeError(
41+
f'There is more than 1 window that matches the regex "{window_title_regex}"'
42+
)
43+
if len(windows) < 1:
44+
raise RuntimeError(
45+
f'There are no windows that matches the regex "{window_title_regex}"'
46+
)
47+
windows[0].command("focus")

0 commit comments

Comments
 (0)