diff --git a/default/hypr/bindings/clipboard.lua b/default/hypr/bindings/clipboard.lua index 0e10fdfe..ce70fe46 100644 --- a/default/hypr/bindings/clipboard.lua +++ b/default/hypr/bindings/clipboard.lua @@ -1,10 +1,17 @@ --- Send through the virtual keyboard so universal clipboard shortcuts reach --- both normal windows and focused layer-shell surfaces such as Omarchy panels. --- Hyprland's send_key_state with window = "activewindow" cannot target layers. +-- Send with explicit mods to the focused surface by omitting the window target, +-- so universal clipboard shortcuts reach both normal windows and focused +-- layer-shell surfaces such as Omarchy panels. A virtual keyboard (wtype) won't +-- do: the physically held SUPER merges into the injected chord at the seat. +-- The down/up split works around Hyprland send_shortcut sometimes leaving +-- synthetic key state stuck/repeating. +-- https://github.com/hyprwm/Hyprland/discussions/14099 local function send_shortcut_once(mods, key) return function() - local modifier = mods:lower() - hl.dispatch(hl.dsp.exec_cmd("wtype -M " .. modifier .. " -k " .. key:lower() .. " -m " .. modifier)) + hl.dispatch(hl.dsp.send_key_state({ mods = mods, key = key, state = "down" })) + + hl.timer(function() + hl.dispatch(hl.dsp.send_key_state({ mods = mods, key = key, state = "up" })) + end, { timeout = 50, type = "oneshot" }) end end diff --git a/test/shell.d/hyprland-default-config-test.sh b/test/shell.d/hyprland-default-config-test.sh index c0bf70b7..e9cabd17 100644 --- a/test/shell.d/hyprland-default-config-test.sh +++ b/test/shell.d/hyprland-default-config-test.sh @@ -105,15 +105,20 @@ grep -Fq $'SUPER + RETURN Terminal' <<<"$fresh_output" || fail "default applicat grep -Fq $'SUPER + SHIFT + A ChatGPT' <<<"$fresh_output" || fail "default application bindings include preinstalled web apps" pass "default application bindings load from package defaults" -grep -F 'hl.dsp.exec_cmd("wtype -M " .. modifier .. " -k " .. key:lower() .. " -m " .. modifier)' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null || - fail "universal clipboard shortcuts use the virtual keyboard" -pass "universal clipboard shortcuts reach focused layer-shell fields" +grep -F 'hl.dsp.send_key_state({ mods = mods, key = key, state = "down" })' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null || + fail "universal clipboard shortcuts send explicit mods to the focused surface" +pass "universal clipboard shortcuts send explicit mods to the focused surface" -if grep -F 'hl.dsp.send_key_state' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null; then +if grep -E 'send_key_state\(\{[^}]*window' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null; then fail "universal clipboard shortcuts do not target only normal windows" fi pass "universal clipboard shortcuts do not exclude layer-shell fields" +if grep -F 'wtype -M' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null; then + fail "universal clipboard shortcuts avoid the virtual keyboard so held SUPER cannot merge in" +fi +pass "universal clipboard shortcuts avoid virtual keyboard modifier merging" + removed_home="$tmpdir/removed-home" mkdir -p "$removed_home/.local/state/omarchy" touch "$removed_home/.local/state/omarchy/preinstalls-removed"