-
Notifications
You must be signed in to change notification settings - Fork 0
Add xremap module integration with home-manager #768
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
af77005
6be207b
d0f8bc2
500cf20
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 |
|---|---|---|
|
|
@@ -5,5 +5,6 @@ | |
| ./npm-globals | ||
| ./tailscale | ||
| ./uv-globals | ||
| ./xremap | ||
| ./yek | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| { | ||
| config, | ||
| lib, | ||
| pkgs, | ||
| inputs, | ||
| ... | ||
| }: | ||
| let | ||
| inherit (inputs.host) isDesktop; | ||
| inherit (pkgs.stdenv) isLinux; | ||
|
|
||
| # Hyper = Framework key (keyd: [cmd_hyper:C-A-S-M]) → remapped to Ctrl for macOS-style shortcuts | ||
| hyperPrefix = "C-Alt-Shift-Super-"; | ||
| ctrlPrefix = "C-"; | ||
| # "f" is excluded — passes through as Hyper+F for Hyprland fullscreen bind. | ||
| # See: config/hyprland/hyprland.conf (Window Management section) | ||
| letters = [ | ||
| "a" | ||
| "b" | ||
| "c" | ||
| "d" | ||
| "e" | ||
| "g" | ||
| "h" | ||
| "i" | ||
| "j" | ||
| "k" | ||
| "l" | ||
| "m" | ||
| "n" | ||
| "o" | ||
| "p" | ||
| "q" | ||
| "r" | ||
| "s" | ||
| "t" | ||
| "u" | ||
| "v" | ||
| "w" | ||
| "x" | ||
| "y" | ||
| "z" | ||
| ]; | ||
| # Numbers 3, 4, 5 are intentionally excluded — they pass through as | ||
| # Hyper+3/4/5 for Hyprland screenshot/recording bindings. | ||
| # See: config/hyprland/hyprland.conf (screenshot section) | ||
| numbers = [ | ||
| "0" | ||
| "1" | ||
| "2" | ||
| "6" | ||
| "7" | ||
| "8" | ||
| "9" | ||
| ]; | ||
| symbols = [ | ||
| "semicolon" | ||
| "dot" | ||
| "comma" | ||
| "slash" | ||
| "grave" | ||
| "backslash" | ||
| "leftbrace" | ||
| "rightbrace" | ||
| "apostrophe" | ||
| ]; | ||
| navigation = [ | ||
| "tab" | ||
| "backspace" | ||
| "left" | ||
| "right" | ||
| "up" | ||
| "down" | ||
| ]; | ||
| remapKeys = letters ++ numbers ++ symbols ++ navigation; | ||
| mkRemap = | ||
| keys: | ||
| builtins.listToAttrs ( | ||
| map (key: { | ||
| name = "${hyperPrefix}${key}"; | ||
| value = "${ctrlPrefix}${key}"; | ||
| }) keys | ||
| ); | ||
| # 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 // { | ||
| "${hyperPrefix}c" = "C-Shift-c"; | ||
| "${hyperPrefix}v" = "C-Shift-v"; | ||
| }; | ||
| in | ||
| { | ||
| config = lib.mkIf (isDesktop && isLinux) { | ||
| services.xremap = { | ||
| enable = true; | ||
| withWlroots = true; | ||
| watch = true; | ||
| # Only intercept keyd output — SUPER (CapsLock/RightAlt) goes straight to Hyprland | ||
| deviceNames = [ "keyd virtual keyboard" ]; | ||
| config = { | ||
| keymap = [ | ||
| { | ||
| name = "Framework Command (Ghostty)"; | ||
| application.only = [ "com.mitchellh.ghostty" ]; | ||
| remap = ghosttyRemap; | ||
| } | ||
| { | ||
| name = "Framework Command (Global)"; | ||
| application.not = [ "com.mitchellh.ghostty" ]; | ||
| remap = globalRemap; | ||
| } | ||
| ]; | ||
| }; | ||
| }; | ||
|
|
||
| # Upstream module already sets After/PartOf/Restart; only add extras. | ||
| systemd.user.services.xremap = { | ||
| Unit.StartLimitIntervalSec = 0; | ||
| Service.RestartSec = 3; | ||
| }; | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,12 +33,6 @@ inputs.nixpkgs.lib.nixosSystem { | |
| # Kolide launcher | ||
| ./kolide.nix | ||
|
|
||
| # Keyd configuration | ||
| ../../config/keyd | ||
|
|
||
| # Xremap module | ||
| inputs.xremap.nixosModules.default | ||
|
|
||
| # Base system configuration | ||
| ( | ||
| { config, lib, ... }: | ||
|
|
@@ -76,127 +70,25 @@ inputs.nixpkgs.lib.nixosSystem { | |
|
|
||
| security.sudo.wheelNeedsPassword = false; | ||
|
|
||
| # Keyd configuration (Linux desktop only) | ||
| services.keyd.enable = true; | ||
|
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. P2: This configuration duplicates the existing Prompt for AI agents |
||
| users.groups.keyd = { }; | ||
| systemd.services.keyd.serviceConfig = { | ||
| CapabilityBoundingSet = [ "CAP_SETGID" ]; | ||
| AmbientCapabilities = [ "CAP_SETGID" ]; | ||
| }; | ||
| systemd.services.keyd.restartTriggers = [ | ||
| (builtins.hashFile "sha256" ../../config/keyd/default.conf) | ||
| ]; | ||
| environment.etc."keyd/default.conf".source = ../../config/keyd/default.conf; | ||
|
Comment on lines
+73
to
+83
|
||
|
|
||
| # Input remapping (xremap) | ||
| hardware.uinput.enable = true; | ||
| services.udev.extraRules = '' | ||
| KERNEL=="uinput", GROUP="input", TAG+="uaccess", MODE:="0660", OPTIONS+="static_node=uinput" | ||
| KERNEL=="event*", ATTRS{name}=="keyd virtual keyboard", GROUP="input", MODE:="0660" | ||
| KERNEL=="event*", ATTRS{name}=="keyd virtual pointer", GROUP="input", MODE:="0660" | ||
| ''; | ||
| services.xremap = | ||
| let | ||
| hyperPrefix = "C-Alt-Shift-Super-"; | ||
| ctrlPrefix = "C-"; | ||
| letters = [ | ||
| "a" | ||
| "b" | ||
| "c" | ||
| "d" | ||
| "e" | ||
| "f" | ||
| "g" | ||
| "h" | ||
| "i" | ||
| "j" | ||
| "k" | ||
| "l" | ||
| "m" | ||
| "n" | ||
| "o" | ||
| "p" | ||
| "q" | ||
| "r" | ||
| "s" | ||
| "t" | ||
| "u" | ||
| "v" | ||
| "w" | ||
| "x" | ||
| "y" | ||
| "z" | ||
| ]; | ||
| # Numbers 3, 4, 5 are intentionally excluded — they pass through as | ||
| # Hyper+3/4/5 for Hyprland screenshot/recording bindings. | ||
| # See: config/hyprland/hyprland.conf (screenshot section) | ||
| numbers = [ | ||
| "0" | ||
| "1" | ||
| "2" | ||
| "6" | ||
| "7" | ||
| "8" | ||
| "9" | ||
| ]; | ||
| symbols = [ | ||
| "semicolon" | ||
| "dot" | ||
| "comma" | ||
| "slash" | ||
| "grave" | ||
| "backslash" | ||
| "leftbrace" | ||
| "rightbrace" | ||
| "apostrophe" | ||
| ]; | ||
| navigation = [ | ||
| "tab" | ||
| "backspace" | ||
| "left" | ||
| "right" | ||
| "up" | ||
| "down" | ||
| ]; | ||
| remapKeys = letters ++ numbers ++ symbols ++ navigation; | ||
| mkRemap = | ||
| keys: | ||
| builtins.listToAttrs ( | ||
| map (key: { | ||
| name = "${hyperPrefix}${key}"; | ||
| value = "${ctrlPrefix}${key}"; | ||
| }) keys | ||
| ); | ||
| globalRemap = mkRemap remapKeys; | ||
| # Override copy/paste to Ctrl+Shift (terminal convention: Ctrl+C = SIGINT). | ||
| # All other keys (including z for undo) inherit from globalRemap. | ||
| ghosttyRemap = globalRemap // { | ||
| "${hyperPrefix}c" = "C-Shift-c"; | ||
| "${hyperPrefix}v" = "C-Shift-v"; | ||
| }; | ||
| in | ||
| { | ||
| enable = true; | ||
| serviceMode = "user"; | ||
| userName = username; | ||
| withWlroots = true; | ||
| watch = true; | ||
| deviceNames = [ "keyd virtual keyboard" ]; | ||
| config = { | ||
| keymap = [ | ||
| { | ||
| name = "Framework Command (Ghostty)"; | ||
| application.only = [ "com.mitchellh.ghostty" ]; | ||
| remap = ghosttyRemap; | ||
| } | ||
| { | ||
| name = "Framework Command (Global)"; | ||
| application.not = [ "com.mitchellh.ghostty" ]; | ||
| remap = globalRemap; | ||
| } | ||
| ]; | ||
| }; | ||
| }; | ||
|
|
||
| # Ensure xremap starts after Hyprland and auto-restarts on failure | ||
| systemd.user.services.xremap = { | ||
| after = [ "graphical-session.target" ]; | ||
| partOf = [ "graphical-session.target" ]; | ||
| serviceConfig = { | ||
| Restart = "on-failure"; | ||
| RestartSec = 3; | ||
| }; | ||
| # StartLimitIntervalSec is a [Unit] directive, not [Service]. | ||
| unitConfig.StartLimitIntervalSec = 0; | ||
| }; | ||
|
|
||
| # AMD graphics with hardware acceleration | ||
| hardware.graphics.enable = true; | ||
|
|
||
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 list of letters can be generated more concisely using
lib.stringToCharacters. This improves readability and reduces the line count, making the code easier to maintain.