Fix multi-monitor workspace routing regression, add laptop auto-detect

- Restore desktop DP-3=primary/DP-2=secondary workspace mapping that
  broke when workspace routing switched from name-matching to raw
  geometric ordering.
- Extract shared laptop/desktop detection + output ranking into
  lib-outputs.sh (battery presence selects the profile automatically),
  sourced by both select-workspace.sh and the new apply-outputs.sh, so
  keybind routing and monitor placement can never disagree.
- Add apply-outputs.sh: on the laptop, automatically positions whatever
  external display is plugged in (and re-runs on hotplug via swaymsg
  -t subscribe), making it primary. No-op on the desktop, which keeps
  its static fixed-arrangement config.
This commit is contained in:
2026-08-21 23:08:01 -05:00
parent 5c57ee20f7
commit f1275e7870
5 changed files with 106 additions and 12 deletions
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Laptop-only dynamic monitor placement: whenever a display is plugged or
# unplugged, arrange active outputs left-to-right in output_order() order
# (external display(s) first, internal panel last), so a newly connected
# external monitor gets a sensible position automatically without any
# manual config. On the desktop this exits immediately — that monitor
# pair has a fixed physical arrangement set statically in
# conf.d/10-appearance.conf.
set -Eeuo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib-outputs.sh"
is_laptop || exit 0
apply_layout() {
local outputs_json x=0 name width
outputs_json=$(swaymsg -t get_outputs -r)
mapfile -t ordered < <(output_order)
for name in "${ordered[@]}"; do
width=$(jq -r --arg n "$name" '.[] | select(.name==$n) | .rect.width' <<<"$outputs_json")
swaymsg output "$name" position "$x" 0 >/dev/null 2>&1 || true
x=$((x + width))
done
}
apply_layout
swaymsg -t subscribe -m '["output"]' | while read -r _; do
apply_layout
done