Target ~/.config/hypr/usr/monitors.lua (the config Hyprland actually
loads) so `hyprctl reload` applies layouts immediately; the Dotfiles
repo copy stays the deploy source and is no longer written.
Add overlap geometry helpers and integrate them into the apply flow:
- block moves that would drive a monitor into a neighbor (TUI coords)
- snap positions to the MOVE_STEP_FINE grid to avoid frozen digits
- auto-resolve snap-induced collisions by re-reading the live layout
and nudging the moved monitor clear, up to MAX_RESOLVE_ITERS
- warn on residual overlap after apply and after save/reload
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
logical_width/height now divide physical pixels by scale so the canvas
correctly represents the compositor's coordinate space (e.g. 3840px @1.5x
is 2560 logical px wide, not 3840).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces fixed 0.25 increments with mathematically valid scales p/q
(lowest terms, q≤6) where both width/s and height/s are integers.
For 1920x1200 this gives 25 steps including 2.4, matching what
Hyprland actually applies — no more mismatch between TUI display
and live value.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hyprctl returns mirrorOf:"none" (string) for non-mirrored monitors.
Python treated it as truthy, causing apply_monitor to always emit a
mirror command, resetting resolution and scale on every keypress.
Also restores monitors.lua with correct mode/scale/transform fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Python curses TUI for managing Hyprland monitors interactively:
- Canvas shows monitors as boxes at their real relative positions
- Tab/Shift+Tab to cycle selection; hjkl/HJKL to move (50/10 px)
- u/i to rotate CCW/CW; n/N to cycle display modes live
- m to mirror (pick target with Tab, confirm with Enter)
- s saves to hypr/usr/monitors.lua atomically
- Scale cached and only recomputed on resize or viewport overflow
- Bound to Super+Shift+M as a centered-L floating kitty popup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>