Files
dotfiles/scripts/bin/winselect
T

79 lines
1.9 KiB
Bash
Executable File

#!/bin/bash
# focus-dir.sh - focus the nearest window in a given direction (h/j/k/l)
# Usage: focus-dir.sh h|j|k|l (or left/down/up/right)
DIR=$1
if [ -z "$DIR" ]; then
echo "Usage: $0 h|j|k|l"
exit 1
fi
# --- get current desktop ---
CUR_DESKTOP=$(xdotool get_desktop)
# --- get focused window geometry ---
FOCUSED=$(xdotool getactivewindow)
read -r FX FY FW FH < <(xdotool getwindowgeometry --shell "$FOCUSED" | awk -F= '
/^X=/ {x=$2} /^Y=/ {y=$2} /^WIDTH=/ {w=$2} /^HEIGHT=/ {h=$2}
END {print x, y, w, h}
')
FCX=$((FX + FW / 2))
FCY=$((FY + FH / 2))
# --- get list of normal windows on current desktop ---
ALL_WINDOWS=$(wmctrl -l -x | awk '$2!="-1" {print $1}')
BEST=""
BEST_DIST=""
for w in $ALL_WINDOWS; do
wid=$(printf "%d" "$w")
[ "$wid" = "$FOCUSED" ] && continue
win_desktop=$(xdotool get_desktop_for_window "$wid" 2>/dev/null) || continue
[ "$win_desktop" = "$CUR_DESKTOP" ] || continue
read -r WX WY WW WH < <(xdotool getwindowgeometry --shell "$wid" | awk -F= '
/^X=/ {x=$2} /^Y=/ {y=$2} /^WIDTH=/ {w=$2} /^HEIGHT=/ {h=$2}
END {print x, y, w, h}
')
WCX=$((WX + WW / 2))
WCY=$((WY + WH / 2))
DX=$((WCX - FCX))
DY=$((WCY - FCY))
case "$DIR" in
h|left)
[ "$DX" -ge 0 ] && continue
;;
l|right)
[ "$DX" -le 0 ] && continue
;;
k|up)
[ "$DY" -ge 0 ] && continue
;;
j|down)
[ "$DY" -le 0 ] && continue
;;
*)
echo "Invalid direction: $DIR"
exit 1
;;
esac
# Manhattan distance, weighted to prefer windows roughly in line
DIST=$(( (DX<0?-DX:DX) + (DY<0?-DY:DY) ))
if [ -z "$BEST_DIST" ] || [ "$DIST" -lt "$BEST_DIST" ]; then
BEST_DIST=$DIST
BEST=$wid
fi
done
if [ -n "$BEST" ]; then
xdotool windowactivate "$BEST"
fi