From ea9473ce8f21873ad95fdf3a8bf4f7832707e8e7 Mon Sep 17 00:00:00 2001 From: Akemi Izuko Date: Mon, 21 Nov 2022 01:27:49 -0700 Subject: [PATCH] Improve sway window dimension script --- bash/.bash_env | 3 ++ git/.gitignore_global | 1 + sway/window_dimensions.py | 73 +++++++++++++++++++++++++++++++++++++++ sway/window_dimensions.sh | 28 --------------- 4 files changed, 77 insertions(+), 28 deletions(-) create mode 100755 sway/window_dimensions.py delete mode 100755 sway/window_dimensions.sh diff --git a/bash/.bash_env b/bash/.bash_env index 6a85003..44a59e4 100644 --- a/bash/.bash_env +++ b/bash/.bash_env @@ -87,6 +87,9 @@ export IGNOREEOF=8 # Ripgrep needs this manually set export RIPGREP_CONFIG_PATH=~/.config/ripgrep/config + # Prevent __pycaches__ form forming +export PYTHONDONTWRITEBYTECODE=1 + # Coloring ========================================================== # Truecolor support gives full rgb support. This looks something like: # \033[${bg};2;${red};${green};${blue};${special}m] diff --git a/git/.gitignore_global b/git/.gitignore_global index 02850da..b74aa8e 100644 --- a/git/.gitignore_global +++ b/git/.gitignore_global @@ -2,6 +2,7 @@ *~ *.swp Session.vim +__pycache__ # macOS .DS_Store diff --git a/sway/window_dimensions.py b/sway/window_dimensions.py new file mode 100755 index 0000000..aca3ee4 --- /dev/null +++ b/sway/window_dimensions.py @@ -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()) diff --git a/sway/window_dimensions.sh b/sway/window_dimensions.sh deleted file mode 100755 index 8cae310..0000000 --- a/sway/window_dimensions.sh +++ /dev/null @@ -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