#!/usr/bin/env bash # hypr-snap.sh # Move a window in a direction. If already touching that edge, snap to fill # the full usable area of the monitor (via fullscreen). Stays tiled. # Works across any monitor configuration. # # Usage: hypr-snap.sh # # Suggested binds in hyprland.conf: # bind = $mainMod SHIFT, left, exec, hypr-snap.sh l # bind = $mainMod SHIFT, right, exec, hypr-snap.sh r # bind = $mainMod SHIFT, up, exec, hypr-snap.sh u # bind = $mainMod SHIFT, down, exec, hypr-snap.sh d DIRECTION=$1 if [[ -z "$DIRECTION" ]]; then echo "Usage: hypr-snap.sh " exit 1 fi WIN=$(hyprctl activewindow -j) MON=$(hyprctl monitors -j | jq '.[] | select(.focused == true)') DATA=$(jq -n \ --argjson win "$WIN" \ --argjson mon "$MON" ' ($mon.width / $mon.scale | floor) as $mw | ($mon.height / $mon.scale | floor) as $mh | ($mon.reserved[2]) as $res_l | ($mon.reserved[3]) as $res_r | ($mon.reserved[0]) as $res_t | ($mon.reserved[1]) as $res_b | { win_x: $win.at[0], win_y: $win.at[1], win_r: ($win.at[0] + $win.size[0]), win_b: ($win.at[1] + $win.size[1]), use_x: ($mon.x + $res_l), use_y: ($mon.y + $res_t), use_r: ($mon.x + $mw - $res_r), use_b: ($mon.y + $mh - $res_b) } ') WIN_X=$(echo "$DATA" | jq '.win_x') WIN_Y=$(echo "$DATA" | jq '.win_y') WIN_R=$(echo "$DATA" | jq '.win_r') WIN_B=$(echo "$DATA" | jq '.win_b') USE_X=$(echo "$DATA" | jq '.use_x') USE_Y=$(echo "$DATA" | jq '.use_y') USE_R=$(echo "$DATA" | jq '.use_r') USE_B=$(echo "$DATA" | jq '.use_b') # How close (in pixels) the window edge must be to the monitor edge to trigger snap. TOLERANCE=50 case $DIRECTION in l) if [[ "$WIN_X" -le $((USE_X + TOLERANCE)) ]]; then hyprctl dispatch fullscreen 1 else hyprctl dispatch movewindoworgroup l fi ;; r) if [[ "$WIN_R" -ge $((USE_R - TOLERANCE)) ]]; then hyprctl dispatch fullscreen 1 else hyprctl dispatch movewindoworgroup r fi ;; u) if [[ "$WIN_Y" -le $((USE_Y + TOLERANCE)) ]]; then hyprctl dispatch fullscreen 1 else hyprctl dispatch movewindoworgroup u fi ;; d) if [[ "$WIN_B" -ge $((USE_B - TOLERANCE)) ]]; then hyprctl dispatch fullscreen 1 else hyprctl dispatch movewindoworgroup d fi ;; *) echo "Unknown direction: $DIRECTION. Use l, r, u, or d." exit 1 ;; esac