From 1220a031b366fb36f06943ebb6a29193ee193b09 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 29 Jun 2026 13:19:14 -0500 Subject: [PATCH] Limit monitor scale stepping to normal range --- bin/omarchy-hyprland-monitor-scaling | 30 +++++++++---- test/shell.d/monitor-scaling-test.sh | 65 ++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 test/shell.d/monitor-scaling-test.sh diff --git a/bin/omarchy-hyprland-monitor-scaling b/bin/omarchy-hyprland-monitor-scaling index 004a2743..51c00211 100755 --- a/bin/omarchy-hyprland-monitor-scaling +++ b/bin/omarchy-hyprland-monitor-scaling @@ -5,6 +5,7 @@ # omarchy:examples=omarchy hyprland monitor scaling | omarchy hyprland monitor scaling 1.6 | omarchy hyprland monitor scaling up | omarchy hyprland monitor scaling down SCALES=(1 1.25 1.6 2 3 4) +STEP_SCALES=(1 1.25 1.6 2) usage() { echo "Usage: omarchy-hyprland-monitor-scaling [up|down|1|1.25|1.6|2|3|4]" @@ -42,24 +43,37 @@ set_scale() { scale_from_current() { local direction="${1:-}" + local scale_list="${2:-${SCALES[*]}}" - # Find the preset closest to the current scale (Hyprland may snap fractional - # scales to nearby values, so we can't match exactly). - awk -v direction="$direction" -v list="${SCALES[*]}" ' + awk -v direction="$direction" -v list="$scale_list" ' NR == 1 { scale = $0; found = 1 } END { if (!found) exit 1 n = split(list, scales, " ") + if (direction == "next") { + for (i = 1; i <= n; i++) { + if (scale < scales[i]) { print scales[i]; exit } + } + print scales[n] + exit + } + + if (direction == "previous") { + for (i = n; i >= 1; i--) { + if (scale > scales[i]) { print scales[i]; exit } + } + print scales[1] + exit + } + + # Find the preset closest to the current scale. best = 1; best_diff = 1e9 for (i = 1; i <= n; i++) { diff = scale - scales[i]; if (diff < 0) diff = -diff if (diff < best_diff) { best_diff = diff; best = i } } - if (direction == "next" && best < n) best++ - else if (direction == "previous" && best > 1) best-- - print scales[best] }' } @@ -72,10 +86,10 @@ case "${1:-}" in usage ;; up) - set_scale "$(focused_monitor_scale | scale_from_current next)" + set_scale "$(focused_monitor_scale | scale_from_current next "${STEP_SCALES[*]}")" ;; down) - set_scale "$(focused_monitor_scale | scale_from_current previous)" + set_scale "$(focused_monitor_scale | scale_from_current previous "${STEP_SCALES[*]}")" ;; 1 | 1.25 | 1.6 | 2 | 3 | 4) set_scale "$1" diff --git a/test/shell.d/monitor-scaling-test.sh b/test/shell.d/monitor-scaling-test.sh new file mode 100644 index 00000000..a7636fd8 --- /dev/null +++ b/test/shell.d/monitor-scaling-test.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +stub_bin="$test_tmp/bin" +eval_out="$test_tmp/hyprctl-eval" +home_dir="$test_tmp/home" +monitor_lua="$home_dir/.config/hypr/monitors.lua" + +mkdir -p "$stub_bin" "$home_dir/.config/hypr" + +cat >"$stub_bin/hyprctl" <<'SH' +#!/bin/bash + +if [[ $1 == "monitors" && $2 == "-j" ]]; then + printf '[{"name":"eDP-1","focused":true,"scale":%s,"width":2880,"height":1800,"refreshRate":120.0}]' "${OMARCHY_TEST_MONITOR_SCALE:-2}" +elif [[ $1 == "eval" ]]; then + printf '%s\n' "$2" >"$OMARCHY_TEST_HYPRCTL_EVAL_OUT" +else + exit 1 +fi +SH +chmod +x "$stub_bin/hyprctl" + +write_monitor_config() { + cat >"$monitor_lua" <<'LUA' +local omarchy_gdk_scale = 2 +local omarchy_monitor_scale = 2 +LUA +} + +run_scaling() { + HOME="$home_dir" \ + PATH="$stub_bin:$PATH" \ + OMARCHY_TEST_HYPRCTL_EVAL_OUT="$eval_out" \ + OMARCHY_TEST_MONITOR_SCALE="${OMARCHY_TEST_MONITOR_SCALE:-2}" \ + "$ROOT/bin/omarchy-hyprland-monitor-scaling" "$@" +} + +write_monitor_config +OMARCHY_TEST_MONITOR_SCALE=2 run_scaling up +grep -F 'scale = 2' "$eval_out" >/dev/null || fail "monitor scaling up stops at 2x" +grep -Fx 'local omarchy_monitor_scale = 2' "$monitor_lua" >/dev/null || fail "monitor scaling up does not persist 3x from 2x" +pass "monitor scaling up stops at 2x" + +write_monitor_config +OMARCHY_TEST_MONITOR_SCALE=3 run_scaling down +grep -F 'scale = 2' "$eval_out" >/dev/null || fail "monitor scaling down recovers 3x to 2x" +grep -Fx 'local omarchy_monitor_scale = 2' "$monitor_lua" >/dev/null || fail "monitor scaling down persists 2x from 3x" +pass "monitor scaling down recovers 3x to 2x" + +write_monitor_config +OMARCHY_TEST_MONITOR_SCALE=2 run_scaling 3 +grep -F 'scale = 3' "$eval_out" >/dev/null || fail "monitor scaling explicit 3x remains available" +grep -Fx 'local omarchy_monitor_scale = 3' "$monitor_lua" >/dev/null || fail "monitor scaling explicit 3x persists" +pass "monitor scaling explicit 3x remains available" + +scale=$(OMARCHY_TEST_MONITOR_SCALE=3 run_scaling) +[[ $scale == "3" ]] || fail "monitor scaling reports explicit 3x scale" "actual: $scale" +pass "monitor scaling reports explicit 3x scale"