dotfiles/sway/window_dimensions.py

74 lines
2.3 KiB
Python
Raw Normal View History

2023-12-23 20:13:59 -07:00
#!/usr/bin/env python3
# Return the dimensions of the current window[s] as selected in sway.
#
# Non-zero exitcode if something unexpected comes up.
#
# The printed dimensions will match the slup regex below:
# /[0-9]+,[0-9]+ [0-9]+x[0-9]+/
import json
from subprocess import run, PIPE
from typing import Optional
def get_sway_tree() -> dict:
swaymsg = run(["swaymsg", "-t", "get_tree"], stdout=PIPE)
swaymsg.check_returncode()
return json.loads(swaymsg.stdout)
def format_window_coords(window: dict, rect: dict) -> str:
if sum(window.values()) == 0: # Multiple windows selected
x = rect['x']
y = rect['y']
w = rect['width']
h = rect['height']
elif window['y'] + window['height'] == rect['height']: # Account for border
x = rect['x'] + window['x']
y = rect['y']
w = window['width']
h = window['height'] - window['y']
else:
x = rect['x'] + window['x']
y = rect['y'] + window['y']
w = window['width']
h = window['height']
return f"{x},{y} {w}x{h}"
# Return dict indexing path to the first entry with "key" matching "val"
# For example, it may return
# ['nodes', 1, 'nodes', 1, 'nodes', 0, 'nodes', 0]
# Which can then be used to index the original js:
# js['nodes'][1]['nodes'][1]['nodes'][0]['nodes'][0][find_key] == find_val
def trace_json_path(js, find_key, find_val) -> Optional[list]:
if isinstance(js, dict):
for key, val in js.items():
if key == find_key and val == find_val:
return [] # Base case
elif isinstance(val, list):
trace = trace_json_path(val, find_key, find_val)
if trace is not None:
return [key] + trace
elif isinstance(js, list):
for i, item in enumerate(js):
trace = trace_json_path(item, find_key, find_val)
if trace is not None:
return [i] + trace
return None
def focused_sway_area():
tree = get_sway_tree()
trace = trace_json_path(tree, 'focused', True)
if trace is None:
print('No focused window was found')
exit(1)
for i in trace:
tree = tree[i]
return format_window_coords(tree['window_rect'], tree['rect'])
if __name__ == '__main__':
print(focused_sway_area())