131 lines
4.2 KiB
Bash
131 lines
4.2 KiB
Bash
#!/bin/sh
|
||
set -eu
|
||
|
||
# 1️⃣ Presets
|
||
PRESETS=" 0.15 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00"
|
||
|
||
# Per-window saved-proportion directory
|
||
PROPORTION_DIR="${XDG_RUNTIME_DIR:-/tmp}/mango-resize"
|
||
|
||
# 2️⃣ Helper: abort with a clear message if a required binary is missing
|
||
need_cmd() {
|
||
command -v "$1" >/dev/null 2>&1 || {
|
||
printf "❌ Required command '%s' not found in PATH. Install it first.\n" "$1" >&2
|
||
exit 127
|
||
}
|
||
}
|
||
need_cmd mmsg
|
||
need_cmd jq
|
||
need_cmd awk
|
||
need_cmd wc
|
||
need_cmd sed
|
||
|
||
# 3️⃣ Get the *currently focused* client.
|
||
client_json=$(mmsg get focusing-client || true)
|
||
|
||
# 3a️⃣ Extract the window's unique id (used as the per-window state key)
|
||
win_id=$(printf '%s' "$client_json" | jq -r '.id // empty' || true)
|
||
if [ -z "$win_id" ]; then
|
||
printf "⚠️ Could not determine window id – aborting.\n" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# Per-window state file
|
||
PROPORTION_FILE="$PROPORTION_DIR/$win_id"
|
||
|
||
# 3b️⃣ Extract current client width
|
||
current=$(printf '%s' "$client_json" | jq -r '.width // empty' || true)
|
||
|
||
if [ -z "$current" ]; then
|
||
printf "⚠️ No focusing client reported – using monitor width as current size.\n"
|
||
current=$(mmsg get all-monitors | jq -r '
|
||
if type == "array" then
|
||
(map(select(.active == true))[0].width)
|
||
else
|
||
(.monitors | map(select(.active == true))[0].width)
|
||
end
|
||
' || true)
|
||
fi
|
||
|
||
# 4️⃣ Get the *usable* work‑area width
|
||
usable_width=$(mmsg get workarea 2>/dev/null || true)
|
||
if [ -n "$usable_width" ]; then
|
||
usable_width=$(printf '%s' "$usable_width" | jq -r '.width // empty')
|
||
fi
|
||
if [ -z "$usable_width" ]; then
|
||
usable_width=$(mmsg get all-monitors | jq -r '
|
||
if type == "array" then
|
||
(map(select(.active == true))[0].width)
|
||
else
|
||
(.monitors | map(select(.active == true))[0].width)
|
||
end
|
||
')
|
||
fi
|
||
|
||
# 5️⃣ Compute the proportion
|
||
approx=$(awk -v cw="$current" -v uw="$usable_width" '
|
||
BEGIN {
|
||
if (uw <= 0) { print "0.50"; exit }
|
||
printf "%.4f\n", cw / uw
|
||
}')
|
||
|
||
# 6️⃣ Find the nearest preset index
|
||
nearest_index=$(awk -v target="$approx" '
|
||
BEGIN {
|
||
split("'"$PRESETS"'", a, " ");
|
||
best_i = 1;
|
||
best_d = 999;
|
||
for (i = 1; i <= length(a); i++) {
|
||
d = a[i] - target;
|
||
if (d < 0) d = -d;
|
||
if (d < best_d) {
|
||
best_d = d;
|
||
best_i = i;
|
||
}
|
||
}
|
||
print best_i;
|
||
}')
|
||
|
||
# 7️⃣ Apply the direction argument
|
||
case "${1:-}" in
|
||
up) new_index=$((nearest_index + 1)) ;;
|
||
down) new_index=$((nearest_index - 1)) ;;
|
||
fullscreen)
|
||
# Check if currently fullscreen (approx >= 0.95 → treat as fullscreen)
|
||
is_fullscreen=$(awk -v a="$approx" 'BEGIN { print (a >= 0.95) ? "1" : "0" }')
|
||
if [ "$is_fullscreen" = "1" ]; then
|
||
# Currently fullscreen → restore this window's saved proportion
|
||
if [ -f "$PROPORTION_FILE" ]; then
|
||
saved=$(cat "$PROPORTION_FILE")
|
||
mmsg dispatch "set_proportion,$saved"
|
||
printf "✅ [win %s] Restored proportion to %s (fullscreen toggle off)\n" "$win_id" "$saved"
|
||
rm -f "$PROPORTION_FILE"
|
||
else
|
||
printf "⚠️ [win %s] No saved proportion – defaulting to 0.50\n" "$win_id" >&2
|
||
mmsg dispatch "set_proportion,0.50"
|
||
fi
|
||
else
|
||
# Not fullscreen → save this window's proportion & go fullscreen
|
||
saved=$(printf '%s\n' $PRESETS | sed -n "${nearest_index}p")
|
||
mkdir -p "$PROPORTION_DIR"
|
||
printf '%s' "$saved" > "$PROPORTION_FILE"
|
||
mmsg dispatch "set_proportion,1.00"
|
||
printf "✅ [win %s] Saved proportion %s, set to 1.00 (fullscreen toggle on)\n" "$win_id" "$saved"
|
||
fi
|
||
exit 0
|
||
;;
|
||
*) printf "❌ Usage: %s [up|down|fullscreen]\n" "$0" >&2; exit 1 ;;
|
||
esac
|
||
|
||
# 8️⃣ Clamp
|
||
count=$(printf '%s\n' $PRESETS | wc -l)
|
||
if [ "$new_index" -lt 1 ]; then new_index=1; fi
|
||
if [ "$new_index" -gt "$count" ]; then new_index=$count; fi
|
||
|
||
# 9️⃣ Resolve the new preset value
|
||
new_value=$(printf '%s\n' $PRESETS | sed -n "${new_index}p")
|
||
|
||
# 🔟 Dispatch
|
||
mmsg dispatch "set_proportion,$new_value"
|
||
printf "✅ Set proportion to %s (preset %s of %s)\n" "$new_value" "$new_index" "$count"
|