Warping to a target window's center selects the wrong window when a smaller
one covers that center: slurp keeps highlighting the coverer, so Tab could
never leave it. Navigation now warps to the most central point that resolves
back to the target, and skips windows that hovering could not reach either.
Unbinding the picker's transient keys by name also took a same-key binding
out of the user's own config with it; the bind handles are now kept and
removed individually.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Keyboard window capture in the region picker: Ctrl+Return, Tab, arrows
Return already captures the entire focused monitor while slurp is open,
but grabbing a single window required the mouse: hover highlights a
window, a click captures it. Now the keyboard can do the same.
Ctrl+Return captures the selected window — the one under the cursor,
falling back to the focused window. Tab and Ctrl+Tab cycle that
selection through the workspace's windows in reading order, and the
arrow keys move it spatially; both warp the cursor to the target
window's center, so slurp's own hover highlight tracks the selection.
Ctrl+Return is implemented like --take-fullscreen: a layer-scoped bind
flags the intent via a marker file and dismisses slurp, and the picker
resolves the window under the cursor. On an empty workspace the pick
resolves to nothing and exits as cancelled.
Ctrl is the chord modifier because slurp reacts to held Shift by
squaring the selection's aspect ratio, which visibly reshapes the
hover highlight mid-chord. None of the keys slurp itself uses (Escape,
held Space to move a selection, held Shift) are bound, so its own
keyboard behavior is unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Resolve overlapping windows the way slurp highlights them
slurp highlights the smallest box under the cursor, but the capture and
selection hit-tests returned the first geometric match in hyprctl
clients order. With a floating window over a tiled one, Ctrl+Return
could capture the window underneath the visibly highlighted one. Track
the smallest containing window instead, in both the capture resolution
and the selection-movement origin.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Document the region picker's keyboard modes in its usage line
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Resolve keyboard capture and navigation from one rectangle list
Duplicate window geometry (tabbed groups, stacked floating windows) stalled
the Tab cycle on the first copy, and the smallest-window-under-cursor
tie-break was applied to two differently ordered lists, so navigation could
cycle from one window while Ctrl+Return captured another. Ctrl+Return over a
gap or an empty workspace also ignored the monitor rectangle slurp was
highlighting.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Capture the highlighted window with Return, the display with Ctrl+Return
The picker highlights a window under the cursor far more often than a whole
display, so the unmodified key takes the highlighted rectangle.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
A previous submap attempt was brittle because the script owned the
keyboard state: if it died between enter and exit, the submap stuck.
This version lets the compositor own both edges. The Lua config binds
plain Return when a layer surface with slurp's "selection" namespace
opens and unbinds it when the last one closes, so the bind exists
exactly while a pick is on screen. slurp dying for any reason (cancel,
crash, pkill, SIGKILL of the picker) fires layer.closed and the bind
evaporates — there is no code path where it leaks.
Return invokes omarchy-capture-region --take-fullscreen, which flags a
marker in XDG_RUNTIME_DIR and dismisses slurp; the picker treats an
empty slurp result with a fresh marker as the focused monitor, reusing
the existing fullscreen path. Since monitor focus follows the cursor,
that is the monitor under the slurp crosshair. The recording flow gets
monitor:NAME from the existing match, so Return during a recording
pick starts a native full-monitor capture.
The signal mode no-ops unless slurp is actually running, and both the
signal protocol and the layer-scoped bind lifecycle are verified live:
bind present only while slurp is open, real picks resolved by the
signal on both the screenshot and recording paths, no leftover binds.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>