From fa2b997513d04a1fa20a1f94e23c6ba8a4ab345a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 18 Jul 2026 15:42:01 -0700 Subject: [PATCH] Keep software-composited cursors out of screenshots Hyprland falls back to compositing the cursor into the frame on GPUs without working hardware cursors, so grim would capture it. Force hardware cursors for the duration of the capture and restore after. Closes #6142 Co-Authored-By: Claude Fable 5 --- bin/omarchy-capture-screenshot | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/bin/omarchy-capture-screenshot b/bin/omarchy-capture-screenshot index c59e3884..663b04a5 100755 --- a/bin/omarchy-capture-screenshot +++ b/bin/omarchy-capture-screenshot @@ -40,11 +40,24 @@ PROCESSING="${2:-slurp}" # The picker leaves the screen freeze running (PID on its first output line) # so grim captures the frozen overlay rather than live content shifting # during teardown. -cleanup_freeze() { - [[ -n $FREEZE_PID ]] && kill $FREEZE_PID 2>/dev/null -} -trap cleanup_freeze EXIT +# +# Software-composited cursors (Hyprland's fallback on GPUs without working +# hardware cursors) are baked into the frames grim captures, so force +# hardware cursors until after grim runs and restore the setting on exit. +NO_HW_CURSORS=$(hyprctl getoption cursor:no_hardware_cursors -j | jq '.int') +set_no_hw_cursors() { + hyprctl eval "hl.config({ cursor = { no_hardware_cursors = $1 } })" &>/dev/null || + hyprctl keyword cursor:no_hardware_cursors "$1" &>/dev/null +} + +cleanup() { + [[ -n $FREEZE_PID ]] && kill $FREEZE_PID 2>/dev/null + set_no_hw_cursors "$NO_HW_CURSORS" +} +trap cleanup EXIT + +set_no_hw_cursors 0 { read -r FREEZE_PID; read -r SELECTION; } < <(omarchy-capture-region "$MODE" --keep-freeze) [[ -z $SELECTION ]] && exit 0