Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 8 additions & 35 deletions default/hypr/bindings/clipboard.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,19 @@
-- 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.
-- synthetic key state stuck/repeating. Keep both events in the same callback
-- so Hyprland resolves them against the same keyboard device and layout. Use
-- Insert/Delete chords so letter keys cannot translate through another XKB
-- layout in Electron/Chromium applications.
-- https://github.com/hyprwm/Hyprland/discussions/14099
local function send_shortcut_once(mods, key)
return function()
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

-- Lean on the terminal tag from default/hypr/apps/terminals.lua so there's one
-- definition of what counts as a terminal. Dynamic tags carry a trailing "*".
local function active_window_is_terminal()
local window = hl.get_active_window()
if not window then
return false
end

for _, tag in ipairs(window.tags or {}) do
if tag:gsub("%*$", "") == "terminal" then
return true
end
end

return false
end

local function universal_clipboard_shortcut(default_mods, default_key, terminal_mods, terminal_key)
return function()
if active_window_is_terminal() then
send_shortcut_once(terminal_mods, terminal_key)()
else
send_shortcut_once(default_mods, default_key)()
end
hl.dispatch(hl.dsp.send_key_state({ mods = mods, key = key, state = "up" }))
end
end

o.bind("SUPER + C", "Universal copy", universal_clipboard_shortcut("CTRL", "C", "CTRL", "Insert"))
o.bind("SUPER + V", "Universal paste", universal_clipboard_shortcut("CTRL", "V", "SHIFT", "Insert"))
o.bind("SUPER + X", "Universal cut", send_shortcut_once("CTRL", "X"))
o.bind("SUPER + C", "Universal copy", send_shortcut_once("CTRL", "Insert"))
o.bind("SUPER + V", "Universal paste", send_shortcut_once("SHIFT", "Insert"))
o.bind("SUPER + X", "Universal cut", send_shortcut_once("SHIFT", "Delete"))
o.bind("SUPER + CTRL + V", "Clipboard manager", "omarchy-shell shell toggle omarchy.clipboard")
16 changes: 16 additions & 0 deletions test/shell.d/hyprland-default-config-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ grep -F 'hl.dsp.send_key_state({ mods = mods, key = key, state = "down" })' "$RO
fail "universal clipboard shortcuts send explicit mods to the focused surface"
pass "universal clipboard shortcuts send explicit mods to the focused surface"

grep -F 'hl.dsp.send_key_state({ mods = mods, key = key, state = "up" })' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null ||
fail "universal clipboard shortcuts release the injected key"

if grep -F 'hl.timer' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null; then
fail "universal clipboard shortcuts resolve press and release in the same keymap"
fi
pass "universal clipboard shortcuts resolve press and release in the same keymap"

grep -F 'o.bind("SUPER + C", "Universal copy", send_shortcut_once("CTRL", "Insert"))' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null ||
fail "universal copy uses a layout-independent chord"
grep -F 'o.bind("SUPER + V", "Universal paste", send_shortcut_once("SHIFT", "Insert"))' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null ||
fail "universal paste uses a layout-independent chord"
grep -F 'o.bind("SUPER + X", "Universal cut", send_shortcut_once("SHIFT", "Delete"))' "$ROOT/default/hypr/bindings/clipboard.lua" >/dev/null ||
fail "universal cut uses a layout-independent chord"
pass "universal clipboard shortcuts avoid layout-sensitive letter keys"

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
Expand Down