-
Notifications
You must be signed in to change notification settings - Fork 0
fix: remap framework copy for editors #1534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f804f62
4450030
2817d0e
94cb399
f855e57
cd3a34c
c9f7b1c
64186c6
45b053c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # keyd-application-mapper normalizes classes/titles to lowercase | ||
| # with punctuation collapsed to '-'. Slack's class becomes `slack`. | ||
| [slack] | ||
| leftmeta = layer(control) | ||
| prog1 = layer(control) | ||
| f13 = layer(control) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,17 +80,23 @@ let | |
| value = "${ctrlPrefix}${key}"; | ||
| }) keys | ||
| ); | ||
| # Framework+key → Ctrl+key for all apps (macOS-style shortcuts) | ||
| # Framework+key -> Ctrl+key for all apps (macOS-style shortcuts) | ||
| globalRemap = mkRemap remapKeys; | ||
| # Ghostty: Framework+C/V → Ctrl+Shift+C/V (terminal convention: Ctrl+C = SIGINT) | ||
| ghosttyRemap = globalRemap // { | ||
| # Terminal/editor clipboard convention: Framework+C/V -> Ctrl+Shift+C/V so | ||
| # copy/paste does not collide with SIGINT or app-specific bare Ctrl+C handlers. | ||
| terminalClipboardRemap = globalRemap // { | ||
| "C-c" = "C-Shift-c"; | ||
| "${hyperPrefix}c" = "C-Shift-c"; | ||
| "${hyperPrefix}v" = "C-Shift-v"; | ||
| }; | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| # Slack: same mapping as global but isolated so Slack-specific workarounds | ||
| # (modifier leak, thread mark-as-read on bare `c`/`Esc`) can be tuned here | ||
| # without affecting other apps. See commits e60e0df, 95679b8, 48ad8f5. | ||
| codeEditorAppIds = [ | ||
| "cursor" | ||
| "Cursor" | ||
| "code" | ||
| "Code" | ||
| ]; | ||
|
Comment on lines
+92
to
+97
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Wayland, Electron-based applications like VS Code and Cursor often use specific
Comment on lines
+92
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: find . -name "default.nix" -path "*/xremap/*" | head -20Repository: shunkakinoki/dotfiles Length of output: 106 🏁 Script executed: git ls-files | grep -i xremap | head -20Repository: shunkakinoki/dotfiles Length of output: 104 🏁 Script executed: find . -name "*.nix" -path "*xremap*" | head -20Repository: shunkakinoki/dotfiles Length of output: 106 🏁 Script executed: cat -n home-manager/modules/xremap/default.nix | head -140Repository: shunkakinoki/dotfiles Length of output: 4914 🌐 Web query:
💡 Result: In Visual Studio Code, the default keybinding Ctrl+Shift+C (⇧⌘C on macOS) when the integrated terminal is focused is "Terminal: Copy Selection" (command ID: workbench.action.terminal.copySelection). This copies the currently selected text in the terminal to the system clipboard. It is included in terminal.integrated.commandsToSkipShell by default, so it is handled by VS Code rather than passed to the shell. Note that globally (outside the terminal), Ctrl+Shift+C is bound to "Open New External Terminal" (workbench.action.terminal.openNativeConsole). This behavior follows platform standards for terminals: on Linux, Ctrl+Shift+C is standard for copy in terminals (to avoid conflicting with Ctrl+C for interrupt), while Windows uses Ctrl+C. Citations:
🌐 Web query:
💡 Result: xremap supports application filtering using the application field in modmap and keymap configurations. This allows key remappings to apply only to specific applications (using only) or exclude them (using not). Application names are matched exactly or via regex (e.g., /regex/). For integrated terminals: - xremap detects the host application's class/name, not the shell inside. - VSCode integrated terminal uses VSCode's class: "code.Code" (X11) or similar on Wayland (e.g., "code" or "Code"). - Standalone terminals: "Gnome-terminal" (X11), "gnome-terminal-server" (GNOME Wayland), "Kitty", "Alacritty", "foot" (app_id on wlroots). To find exact names: - X11: wmctrl -x -l (use 3rd column, full or last part). - GNOME Wayland: busctl --user call org.gnome.Shell /com/k0kubun/Xremap com.k0kubun.Xremap WMClasses (requires xremap-gnome extension). - KDE Wayland: Trigger a filter; logs "class". - Sway: swaymsg -t get_tree (app_id). - Fallback: Config with application: {not: []} or window: {not: []}; press key to log active app/window. Example config for terminals: shared: terminals: &terminals - Gnome-terminal - Kitty - code.Code # VSCode incl. integrated terminal keymap: - application: only: *terminals remap: # terminal-specific remaps xremap integrates with X11/Wayland via feature flags (e.g., --features x11, --features gnome). Filters evaluate via WMClient querying current_application. Citations:
Remove VS Code/Cursor from terminal clipboard remapping—it breaks editor copy behavior. When the Code Editors remapping applies Either remove lines 92–97 and 124–128, or configure terminal-specific copy/paste through VS Code's keybindings with terminal focus conditions instead. 🤖 Prompt for AI Agents |
||
| # Slack-specific Framework->Ctrl behavior is handled by keyd's | ||
| # application mapper on hosts that enable ~/.config/keyd/app.conf. | ||
| slackRemap = globalRemap; | ||
| in | ||
| { | ||
|
|
@@ -109,10 +115,16 @@ in | |
| keypress_delay_ms = 10; | ||
| keymap = [ | ||
| { | ||
| # Ghostty: Framework+C/V → Ctrl+Shift+C/V (terminal convention: Ctrl+C = SIGINT) | ||
| # Ghostty: Framework+C/V -> Ctrl+Shift+C/V (terminal convention: Ctrl+C = SIGINT) | ||
| name = "Framework Command (Ghostty)"; | ||
| application.only = [ "com.mitchellh.ghostty" ]; | ||
| remap = ghosttyRemap; | ||
| remap = terminalClipboardRemap; | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||
| } | ||
| { | ||
| # Cursor/VS Code: terminal-style clipboard shortcut, not bare Ctrl+C. | ||
| name = "Framework Command (Code Editors)"; | ||
| application.only = codeEditorAppIds; | ||
| remap = terminalClipboardRemap; | ||
| } | ||
|
Comment on lines
+123
to
128
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Applying Since |
||
| { | ||
| # Slack: isolated block so modifier-leak / thread mark-as-read | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| { | ||
| config, | ||
| lib, | ||
| pkgs, | ||
| ... | ||
| }: | ||
| let | ||
| cfg = config.services."keyd-application-mapper"; | ||
| in | ||
| { | ||
| options.services."keyd-application-mapper" = { | ||
| enable = lib.mkEnableOption "keyd application mapper user service"; | ||
| }; | ||
|
|
||
| config = lib.mkIf (pkgs.stdenv.isLinux && cfg.enable) { | ||
| assertions = [ | ||
| { | ||
| assertion = config.xdg.configFile ? "keyd/app.conf"; | ||
| message = "services.keyd-application-mapper requires xdg.configFile.\"keyd/app.conf\""; | ||
| } | ||
| ]; | ||
|
|
||
| systemd.user.services.keyd-application-mapper = { | ||
| Unit = { | ||
| Description = "keyd application mapper"; | ||
| After = [ "graphical-session.target" ]; | ||
| PartOf = [ "graphical-session.target" ]; | ||
| }; | ||
| Service = { | ||
| Type = "simple"; | ||
| # Force a unit restart on switch when app.conf changes. | ||
| Environment = [ | ||
| "KEYD_APP_CONF_HASH=${builtins.hashFile "sha256" config.xdg.configFile."keyd/app.conf".source}" | ||
| ]; | ||
| # User managers can start before refreshed supplementary groups | ||
| # are visible in the login session. Enter the keyd group | ||
| # explicitly so the mapper can always reach /var/run/keyd.socket. | ||
| ExecStart = "${pkgs.bash}/bin/bash -lc 'exec /run/wrappers/bin/sg keyd -c \"KEYD_BIN=${pkgs.keyd}/bin/keyd ${pkgs.keyd}/bin/keyd-application-mapper\"'"; | ||
| Restart = "on-failure"; | ||
| RestartSec = 3; | ||
| }; | ||
| Install = { | ||
| WantedBy = [ "graphical-session.target" ]; | ||
| }; | ||
| }; | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
terminalClipboardRemapdefinition includes a remap for the bareC-ckey (line 88). This causes the physicalCtrl+Ckey to sendCtrl+Shift+C.In terminal applications, this effectively breaks the ability to send the
SIGINT(interrupt) signal, which is usually bound toCtrl+C. If your goal is to haveCmd+C(Framework+C) perform a copy while keepingCtrl+Cas the interrupt signal, you should remove theC-centry. This is particularly relevant given the comment on line 119 which acknowledges theCtrl+C = SIGINTconvention.