Files
arthur-os/bin/omarchy-hyprland-window-width
T

169 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
# omarchy:summary=Save or restore the focused Hyprland window width
# omarchy:args=<save|restore>
# omarchy:examples=omarchy hyprland window width save | omarchy-hyprland-window-width restore
set -euo pipefail
STATE_DIR="$HOME/.local/state/omarchy/windows"
usage() {
echo "Usage: omarchy-hyprland-window-width save|restore" >&2
exit 1
}
active_window() {
hyprctl activewindow -j 2>/dev/null
}
window_key() {
jq -r '[.class, .initialClass, .title] | map(select(. != null and . != "")) | first // empty' <<<"$1"
}
workspace_key() {
jq -r '.workspace.id // .workspace.name // empty' <<<"$1"
}
state_file_for() {
local key="$1"
local workspace="$2"
local filename="workspace-${workspace}-${key}"
filename="${filename//\//_}"
filename="${filename//$'\n'/_}"
printf '%s/%s.width' "$STATE_DIR" "$filename"
}
notify_missing_width() {
local key="$1"
local workspace="$2"
omarchy-notification-send -g  "No saved width found for $key on workspace $workspace" "Use Super + Alt + Home to save one for this workspace."
}
notify_saved_width() {
local key="$1"
local workspace="$2"
omarchy-notification-send -g  "Saved width for $key on workspace $workspace" "Restore using Super + Home on this workspace."
}
hypr_dispatch() {
local lua="$1"
shift
hyprctl dispatch "$lua" >/dev/null 2>&1 || hyprctl dispatch "$@" >/dev/null
}
window_width() {
local address="$1"
hyprctl clients -j | jq -er --arg address "$address" '.[] | select(.address == $address) | .size[0]'
}
resize_width_by() {
local window="$1"
local delta="$2"
hypr_dispatch "hl.dsp.window.resize({ window = \"$window\", x = $delta, y = 0, relative = true })" resizeactive "$delta" 0 "$window"
}
save_width() {
local active="$1"
local key="$2"
local workspace="$3"
local state_file="$4"
local tmp=""
local width=""
width=$(jq -er '.size[0]' <<<"$active")
mkdir -p "$STATE_DIR"
tmp=$(mktemp "$STATE_DIR/.width.XXXXXX")
printf '%s\n' "$width" >"$tmp"
mv "$tmp" "$state_file"
notify_saved_width "$key" "$workspace"
echo "Saved width for $key on workspace $workspace"
}
restore_width() {
local active="$1"
local key="$2"
local workspace="$3"
local state_file="$4"
local address=""
local current_width=""
local delta=""
local direction=""
local next_width=""
local probe=""
local probe_delta=""
local width=""
local window=""
if [[ ! -f $state_file ]]; then
notify_missing_width "$key" "$workspace"
exit 1
fi
width=$(<"$state_file")
[[ $width =~ ^[0-9]+$ ]] || exit 1
address=$(jq -r '.address // empty' <<<"$active")
[[ -n $address ]] || exit 1
window="address:$address"
current_width=$(window_width "$address")
((current_width == width)) && return
for probe in 10 -10; do
resize_width_by "$window" "$probe"
next_width=$(window_width "$address")
if ((next_width != current_width)); then
if (((next_width - current_width) * probe > 0)); then
direction=1
else
direction=-1
fi
current_width=$next_width
break
fi
done
[[ -n $direction ]] || exit 1
for _ in {1..6}; do
delta=$((width - current_width))
((delta == 0)) && break
probe_delta=$((delta * direction))
resize_width_by "$window" "$probe_delta"
next_width=$(window_width "$address")
((next_width == current_width)) && break
current_width=$next_width
done
}
action=${1:-}
[[ $action == "save" || $action == "restore" ]] || usage
active=$(active_window)
key=$(window_key "$active")
[[ -n $key ]] || exit 1
workspace=$(workspace_key "$active")
[[ -n $workspace ]] || exit 1
state_file=$(state_file_for "$key" "$workspace")
case "$action" in
save) save_width "$active" "$key" "$workspace" "$state_file" ;;
restore) restore_width "$active" "$key" "$workspace" "$state_file" ;;
esac