fix(keyd): stop asserting Alt on Framework key, remove xremap entirely - #2019
Conversation
The [cmd_hyper:C-A-S-M] modifier layer asserted Ctrl+Alt+Shift+Super the moment the Framework key was held. Slack treats Alt+Click as 'mark unread', so a held Alt plus a stray trackpad tap (tap-to-click) kept marking the hovered chat unread whenever Framework+C/V was pressed. Rework the layer as Super-only ([cmd_hyper:M]) with an explicit atomic macro per key: Framework+key emits Ctrl+key (or the Hyper chord for Hyprland binds) in one clean event, and no Ctrl/Alt/Shift is ever held speculatively. Framework+Tab falls through as genuinely held Super+Tab for hyprshell hold-to-cycle. With keyd emitting final combos directly, xremap had no job left: delete the module, home-manager imports, flake input, and the Hyprland restart hook. Ghostty now handles clipboard natively: performable ctrl+c copies only when a selection exists (restoring Ctrl+C SIGINT, which the xremap remap had eaten) and ctrl+v pastes.
|
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (7)
Disabled knowledge base sources:
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR removes the xremap dependency entirely: the flake input, home-manager module, and its imports are deleted, and Hyprland's startup no longer restarts xremap but instead restarts xdg-desktop-portal services. Key remapping functionality moves to a rewritten keyd cmd_hyper layer and new Ghostty native clipboard keybinds. Changesxremap removal and native remapping migration
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request removes xremap from the configuration and migrates macOS-style command key remappings directly into keyd under the [cmd_hyper:M] layer. It also introduces copy/paste keybindings in Ghostty. Feedback on these changes highlights two main issues: first, mapping the arrow keys to C-left/C-right in keyd conflicts with Hyprland's workspace switching shortcuts and does not accurately replicate macOS-style line navigation; second, binding ctrl+v globally in Ghostty intercepts all Ctrl+V keystrokes, which breaks native terminal features like Vim's blockwise visual mode.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| left = C-left | ||
| right = C-right | ||
| up = C-up | ||
| down = C-down |
There was a problem hiding this comment.
In macOS, Cmd+Left and Cmd+Right are used to navigate to the start and end of the line (which map to home and end in Linux), while Cmd+Up and Cmd+Down navigate to the top and bottom of the document (which map to Ctrl+Home and Ctrl+End in Linux).
Currently, you have mapped them to C-left, C-right, C-up, and C-down. However, in config/hyprland/hyprland.conf (lines 343-344), you have bound CTRL, left and CTRL, right globally to switch workspaces:
bind = CTRL, left, workspace, e-1
bind = CTRL, right, workspace, e+1As a result, pressing Framework+Left or Framework+Right will trigger a workspace switch instead of cursor navigation.
Mapping them to home, end, C-home, and C-end instead will perfectly replicate macOS-style line and document navigation while avoiding the conflict with Hyprland's workspace switching.
left = home
right = end
up = C-home
down = C-end
| # Framework+C/V arrive as plain Ctrl+C/V (keyd, see config/keyd/default.conf). | ||
| # performable: copy only when a selection exists; otherwise Ctrl+C stays SIGINT. | ||
| keybind = performable:ctrl+c=copy_to_clipboard | ||
| keybind = ctrl+v=paste_from_clipboard |
There was a problem hiding this comment.
Binding ctrl+v globally in Ghostty to paste_from_clipboard will intercept all Ctrl+V keystrokes.
Because keyd maps the Framework key to Ctrl (v = C-v), both physical Ctrl+V and Framework+V will emit Ctrl+V and trigger a paste. This completely disables the terminal's native Ctrl+V functionality, such as blockwise visual mode in Vim/Neovim or quoted-insert in bash/zsh.
Since ctrl+q is also bound to quit (line 52), Vim users won't easily be able to fall back to Ctrl+Q for visual block mode either. Consider keeping the default paste shortcut (ctrl+shift+v) or using a different non-conflicting key combination if you rely on terminal applications that require raw Ctrl+V input.
| # Framework+C/V arrive as plain Ctrl+C/V (keyd, see config/keyd/default.conf). | ||
| # performable: copy only when a selection exists; otherwise Ctrl+C stays SIGINT. | ||
| keybind = performable:ctrl+c=copy_to_clipboard | ||
| keybind = ctrl+v=paste_from_clipboard |
There was a problem hiding this comment.
In-terminal Ctrl-V is now hijacked as paste. Unlike the performable:ctrl+c line above, keybind = ctrl+v=paste_from_clipboard is unconditional, and there is no way to distinguish a keyd-emitted Framework+V from a real user Ctrl-V — both arrive at Ghostty as bare Ctrl+V. So:
vimnormal-modeCtrl-V(visual-block) now pastes instead of entering block-select.bash/ readlineCtrl-V(quoted-insert, used to type raw^M,^[, etc.) now pastes.- Any TUI that binds
Ctrl+Vloses it inside Ghostty.
The old xremap flow avoided this because the Ghostty-only keymap rewrote Framework's Ctrl+V to Ctrl+Shift+V, leaving real Ctrl+V for TUIs. With xremap gone that distinction is lost.
Options:
- Keep
Ctrl+V=pasteonly in Ghostty on macOS (macos-scoped keybind) and rely onCtrl+Shift+Von Linux where TUI conflicts matter. - Or accept the trade-off and note it in a comment (some users won't mind).
performable:ctrl+v=paste_from_clipboarddoes not help here —performable:for paste keys is based on clipboard non-emptiness, not TUI focus, so it would still swallow Ctrl-V any time there's clipboard content.
Summary
[cmd_hyper:C-A-S-M]layer asserted Ctrl+Alt+Shift+Super the moment the Framework key was held, and Slack treats Alt+Click as "mark unread" - a stray trackpad tap (tap-to-click) while Alt was held triggered it[cmd_hyper:M]) with an explicit atomic macro per key: Framework+key emits Ctrl+key (or the Hyper chord for Hyprland binds) in one clean event; Ctrl/Alt/Shift are never held speculativelyperformable:ctrl+ccopies only when a selection exists (restoring Ctrl+C SIGINT, which the xremap remap had eaten) andctrl+vpastesTest plan
make switch(keyd restarts via restartTriggers; xremap user service disappears)Summary by cubic
Reworked the Framework key in
keydto emit atomic shortcuts without asserting Ctrl/Alt/Shift. This fixes Slack marking chats unread on copy/paste and lets us removexremap; Ghostty now handles clipboard natively and Ctrl+C SIGINT is restored.Bug Fixes
Refactors
xremap: deleted module, Home Manager imports, flake input, and the Hyprland restart hook.performable:ctrl+ccopies only with a selection;ctrl+vpastes; Ctrl+C remains SIGINT.Written for commit 4106936. Summary will update on new commits.