Improve sway window dimension script

This commit is contained in:
Akemi Izuko 2023-12-23 20:13:59 -07:00
parent 2043d7d315
commit fcb2dd8f31
Signed by: akemi
GPG key ID: 8DE0764E1809E9FC
4 changed files with 77 additions and 28 deletions

View file

@ -87,6 +87,9 @@ export IGNOREEOF=8
# Ripgrep needs this manually set # Ripgrep needs this manually set
export RIPGREP_CONFIG_PATH=~/.config/ripgrep/config export RIPGREP_CONFIG_PATH=~/.config/ripgrep/config
# Prevent __pycaches__ form forming
export PYTHONDONTWRITEBYTECODE=1
# Coloring ========================================================== # Coloring ==========================================================
# Truecolor support gives full rgb support. This looks something like: # Truecolor support gives full rgb support. This looks something like:
# \033[${bg};2;${red};${green};${blue};${special}m] # \033[${bg};2;${red};${green};${blue};${special}m]

View file

@ -2,6 +2,7 @@
*~ *~
*.swp *.swp
Session.vim Session.vim
__pycache__
# macOS # macOS
.DS_Store .DS_Store

73
sway/window_dimensions.py Executable file
View file

@ -0,0 +1,73 @@
#!/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())

View file

@ -1,28 +0,0 @@
#!/usr/bin/env bash
# Gets a slurp-like output for the focused window with sway borders cropped
declare -a a=( $(swaymsg -t get_tree | jq '..
| (.nodes? // empty)[] | select(.focused==true)
| .rect.x, .window_rect.x, .rect.y, .window_rect.y, .window_rect.width, .window_rect.height, .rect.height') )
if [[ ${#a[@]} -eq 0 ]]; then
a=( $(swaymsg -t get_tree | jq '..
| (.floating_nodes? // empty)[] | select(.focused==true)
| .rect.x, .window_rect.x, .rect.y, .window_rect.y, .window_rect.width, .window_rect.height, .rect.height') )
fi
if [[ ${#a[@]} -ne 7 ]]; then
printf 'Failed to find window\n'
exit 1
elif [[ $((${a[5]} + ${a[3]})) -eq ${a[6]} ]]; then
printf '%d,%d %dx%d\n' \
"$((${a[0]} + ${a[1]}))" \
"${a[2]}" \
"${a[4]}" \
"$((${a[5]} - ${a[3]}))"
else
printf '%d,%d %dx%d\n' \
"$((${a[0]} + ${a[1]}))" \
"$((${a[2]} + ${a[3]}))" \
"${a[4]}" \
"${a[5]}"
fi