From 43aad292d8a91da9ff39a9a1da56039cd21e8788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kier=C3=A1n=20Meinhardt?= Date: Tue, 17 Mar 2026 23:06:15 +0100 Subject: [PATCH] niri: finally, real keyboards --- flake.nix | 24 ++- packages/keyboardScripts.nix | 38 +++++ packages/niri.nix | 277 +++++++++++++++++------------------ 3 files changed, 196 insertions(+), 143 deletions(-) create mode 100644 packages/keyboardScripts.nix diff --git a/flake.nix b/flake.nix index 080d373..f5311d1 100644 --- a/flake.nix +++ b/flake.nix @@ -51,10 +51,20 @@ inherit (inputs) wrappers; pkgs = prev; }; - niphas-niri = import packages/niri.nix { - inherit (inputs) wrappers; - pkgs = final; - }; + + niphas-niri-config-with = + overwriteSettings: + (import packages/niri.nix { + inherit (inputs) wrappers; + inherit overwriteSettings; + pkgs = final; + })."config.kdl".path; + + niphas-niri = + (import packages/niri.nix { + inherit (inputs) wrappers; + pkgs = final; + }).wrapper; niphas-kanshi = import packages/kanshi.nix { inherit (inputs) wrappers; pkgs = final; @@ -95,6 +105,11 @@ ''; vimv = prev.callPackage packages/vimv.nix { }; + + keyboardScripts = prev.callPackage packages/keyboardScripts.nix { + pkgs = final; + inherit (final) lib; + }; }; packages = eachSupportedSystem ( @@ -120,6 +135,7 @@ vimv ; } + // pkgs.keyboardScripts ); formatter = eachSupportedSystem (system: treefmtEval.${system}.config.build.wrapper); diff --git a/packages/keyboardScripts.nix b/packages/keyboardScripts.nix new file mode 100644 index 0000000..a0c55a3 --- /dev/null +++ b/packages/keyboardScripts.nix @@ -0,0 +1,38 @@ +{ pkgs, lib }: +let + keyboards = { + german = { + code = "de"; + variant = "T3"; + }; + russian = { + code = "ru"; + variant = "phonetic_winkeys"; + }; + greek = { + code = "gr"; + variant = "polytonic"; + }; + }; + + keyboardScripts = lib.mapAttrs' ( + name: keyboard: + lib.nameValuePair "kb-${name}" ( + pkgs.writers.writeDashBin "kb-${name}" '' + exec ${lib.getExe pkgs.niphas-niri} msg action load-config-file --path ${ + pkgs.niphas-niri-config-with { + input = { + keyboard = { + xkb.layout = "de,${keyboard.code}"; + xkb.variant = "T3,${keyboard.variant}"; + xkb.options = "compose:caps,grp:ctrls_toggle"; + numlock = null; + }; + }; + } + } + '' + ) + ) keyboards; +in +keyboardScripts diff --git a/packages/niri.nix b/packages/niri.nix index 6750d6b..0934d89 100644 --- a/packages/niri.nix +++ b/packages/niri.nix @@ -1,6 +1,7 @@ { wrappers, pkgs, + overwriteSettings ? { }, }: let lib = pkgs.lib; @@ -10,157 +11,155 @@ let shadow-color = "#0007"; }; - niri = wrappers.wrapperModules.niri.apply { + niriWrapper = wrappers.wrapperModules.niri.apply { inherit pkgs; - settings = builtins.foldl' lib.recursiveUpdate { } ([ - { - input = { - keyboard = { - xkb.layout = "de"; - xkb.variant = "T3"; - xkb.options = "compose:caps"; - numlock = null; - }; - touchpad = { - tap = null; - drag = true; - }; - mouse = null; - trackpoint = null; - warp-mouse-to-focus = null; - focus-follows-mouse = null; + settings = lib.recursiveUpdate { + input = { + keyboard = { + xkb.layout = "de"; + xkb.variant = "T3"; + xkb.options = "compose:caps"; + numlock = null; }; - layout = { - gaps = 8; - center-focused-column = "never"; - preset-column-widths = [ - { proportion = 1. / 3.; } - { proportion = 1. / 2.; } - { proportion = 2. / 3.; } - ]; - default-column-width = { - proportion = 1. / 2.; - }; - focus-ring = { - width = 2; - active-color = colors.active-color; - inactive-color = colors.inactive-color; - }; - shadow = { - on = null; - draw-behind-window = true; - softness = 30; - spread = 5; - color = colors.shadow-color; - }; + touchpad = { + tap = null; + drag = true; }; - spawn-at-startup = [ - (lib.getExe pkgs.niphas-bar) - (lib.getExe pkgs.niphas-set-wallpaper) - (lib.getExe pkgs.niphas-clipboard-watcher) - (lib.getExe pkgs.niphas-redshift) - (lib.getExe pkgs.niphas-kanshi) + mouse = null; + trackpoint = null; + warp-mouse-to-focus = null; + focus-follows-mouse = null; + }; + layout = { + gaps = 8; + center-focused-column = "never"; + preset-column-widths = [ + { proportion = 1. / 3.; } + { proportion = 1. / 2.; } + { proportion = 2. / 3.; } ]; - hotkey-overlay.skip-at-startup = null; - prefer-no-csd = null; - animations.slowdown = 0.5; # twice as fast - binds = - let - wpctl = lib.getExe' pkgs.wireplumber "wpctl"; - in - { - "Mod+Shift+Slash".show-hotkey-overlay = null; - "Mod+Y".spawn = lib.getExe pkgs.niphas-web-browser; - "Mod+T".spawn = lib.getExe pkgs.niphas-file-browser; - "Mod+Return".spawn = lib.getExe pkgs.niphas-terminal; - "Mod+D".spawn = lib.getExe pkgs.niphas-runner; - "Mod+Shift+W".spawn = lib.getExe pkgs.niphas-locker; - "Print".spawn = lib.getExe pkgs.niphas-screenshot; - "Mod+Q".spawn = lib.getExe pkgs.niphas-clipman; + default-column-width = { + proportion = 1. / 2.; + }; + focus-ring = { + width = 2; + active-color = colors.active-color; + inactive-color = colors.inactive-color; + }; + shadow = { + on = null; + draw-behind-window = true; + softness = 30; + spread = 5; + color = colors.shadow-color; + }; + }; + spawn-at-startup = [ + (lib.getExe pkgs.niphas-bar) + (lib.getExe pkgs.niphas-set-wallpaper) + (lib.getExe pkgs.niphas-clipboard-watcher) + (lib.getExe pkgs.niphas-redshift) + (lib.getExe pkgs.niphas-kanshi) + ]; + hotkey-overlay.skip-at-startup = null; + prefer-no-csd = null; + animations.slowdown = 0.5; # twice as fast + binds = + let + wpctl = lib.getExe' pkgs.wireplumber "wpctl"; + in + { + "Mod+Shift+Slash".show-hotkey-overlay = null; + "Mod+Y".spawn = lib.getExe pkgs.niphas-web-browser; + "Mod+T".spawn = lib.getExe pkgs.niphas-file-browser; + "Mod+Return".spawn = lib.getExe pkgs.niphas-terminal; + "Mod+D".spawn = lib.getExe pkgs.niphas-runner; + "Mod+Shift+W".spawn = lib.getExe pkgs.niphas-locker; + "Print".spawn = lib.getExe pkgs.niphas-screenshot; + "Mod+Q".spawn = lib.getExe pkgs.niphas-clipman; - # TODO allow-when-locked - "XF86AudioRaiseVolume".spawn-sh = "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 0.1+ -l 1.0"; - "XF86AudioLowerVolume".spawn-sh = "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 0.1-"; - "XF86AudioMute".spawn-sh = "${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle"; - "XF86AudioMicMute".spawn-sh = "${wpctl} set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; - "XF86AudioPlay".spawn-sh = "${lib.getExe pkgs.playerctl} play-pause"; - "XF86AudioStop".spawn-sh = "${lib.getExe pkgs.playerctl} stop"; - "XF86AudioPrev".spawn-sh = "${lib.getExe pkgs.playerctl} previous"; - "XF86AudioNext".spawn-sh = "${lib.getExe pkgs.playerctl} next"; - "XF86MonBrightnessUp".spawn-sh = "${lib.getExe pkgs.brightnessctl} --class=backlight set +25%"; - "XF86MonBrightnessDown".spawn-sh = "${lib.getExe pkgs.brightnessctl} --class=backlight set 25%-"; + # TODO allow-when-locked + "XF86AudioRaiseVolume".spawn-sh = "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 0.1+ -l 1.0"; + "XF86AudioLowerVolume".spawn-sh = "${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 0.1-"; + "XF86AudioMute".spawn-sh = "${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle"; + "XF86AudioMicMute".spawn-sh = "${wpctl} set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; + "XF86AudioPlay".spawn-sh = "${lib.getExe pkgs.playerctl} play-pause"; + "XF86AudioStop".spawn-sh = "${lib.getExe pkgs.playerctl} stop"; + "XF86AudioPrev".spawn-sh = "${lib.getExe pkgs.playerctl} previous"; + "XF86AudioNext".spawn-sh = "${lib.getExe pkgs.playerctl} next"; + "XF86MonBrightnessUp".spawn-sh = "${lib.getExe pkgs.brightnessctl} --class=backlight set +25%"; + "XF86MonBrightnessDown".spawn-sh = "${lib.getExe pkgs.brightnessctl} --class=backlight set 25%-"; - # TODO repeat=false - "Mod+O".toggle-overview = null; - "Mod+Shift+Q".close-window = null; + # TODO repeat=false + "Mod+O".toggle-overview = null; + "Mod+Shift+Q".close-window = null; - "Mod+H".focus-column-left = null; - "Mod+J".focus-window-or-workspace-down = null; - "Mod+K".focus-window-or-workspace-up = null; - "Mod+L".focus-column-right = null; - "Mod+Shift+H".move-column-left = null; - "Mod+Shift+J".move-window-down-or-to-workspace-down = null; - "Mod+Shift+K".move-window-up-or-to-workspace-up = null; - "Mod+Shift+L".move-column-right = null; - "Mod+Shift+Ctrl+H".move-column-to-monitor-left = null; - "Mod+Shift+Ctrl+J".move-column-to-monitor-down = null; - "Mod+Shift+Ctrl+K".move-column-to-monitor-up = null; - "Mod+Shift+Ctrl+L".move-column-to-monitor-right = null; - "Mod+Home".focus-column-first = null; - "Mod+End".focus-column-last = null; - "Mod+Shift+Home".move-column-to-first = null; - "Mod+Shift+End".move-column-to-last = null; + "Mod+H".focus-column-left = null; + "Mod+J".focus-window-or-workspace-down = null; + "Mod+K".focus-window-or-workspace-up = null; + "Mod+L".focus-column-right = null; + "Mod+Shift+H".move-column-left = null; + "Mod+Shift+J".move-window-down-or-to-workspace-down = null; + "Mod+Shift+K".move-window-up-or-to-workspace-up = null; + "Mod+Shift+L".move-column-right = null; + "Mod+Shift+Ctrl+H".move-column-to-monitor-left = null; + "Mod+Shift+Ctrl+J".move-column-to-monitor-down = null; + "Mod+Shift+Ctrl+K".move-column-to-monitor-up = null; + "Mod+Shift+Ctrl+L".move-column-to-monitor-right = null; + "Mod+Home".focus-column-first = null; + "Mod+End".focus-column-last = null; + "Mod+Shift+Home".move-column-to-first = null; + "Mod+Shift+End".move-column-to-last = null; - # TODO cooldown-ms=150 - "Mod+WheelScrollDown".focus-workspace-down = null; - "Mod+WheelScrollUp".focus-workspace-up = null; - "Mod+Shift+WheelScrollDown".move-column-to-workspace-down = null; - "Mod+Shift+WheelScrollUp".move-column-to-workspace-up = null; + # TODO cooldown-ms=150 + "Mod+WheelScrollDown".focus-workspace-down = null; + "Mod+WheelScrollUp".focus-workspace-up = null; + "Mod+Shift+WheelScrollDown".move-column-to-workspace-down = null; + "Mod+Shift+WheelScrollUp".move-column-to-workspace-up = null; - "Mod+WheelScrollRight".focus-column-right = null; - "Mod+WheelScrollLeft".focus-column-left = null; - "Mod+Shift+WheelScrollRight".move-column-right = null; - "Mod+Shift+WheelScrollLeft".move-column-left = null; + "Mod+WheelScrollRight".focus-column-right = null; + "Mod+WheelScrollLeft".focus-column-left = null; + "Mod+Shift+WheelScrollRight".move-column-right = null; + "Mod+Shift+WheelScrollLeft".move-column-left = null; - "Mod+1".focus-workspace = 1; - "Mod+2".focus-workspace = 2; - "Mod+3".focus-workspace = 3; - "Mod+4".focus-workspace = 4; - "Mod+5".focus-workspace = 5; - "Mod+6".focus-workspace = 6; - "Mod+7".focus-workspace = 7; - "Mod+8".focus-workspace = 8; - "Mod+9".focus-workspace = 9; - "Mod+Shift+1".move-window-to-workspace = 1; - "Mod+Shift+2".move-window-to-workspace = 2; - "Mod+Shift+3".move-window-to-workspace = 3; - "Mod+Shift+4".move-window-to-workspace = 4; - "Mod+Shift+5".move-window-to-workspace = 5; - "Mod+Shift+6".move-window-to-workspace = 6; - "Mod+Shift+7".move-window-to-workspace = 7; - "Mod+Shift+8".move-window-to-workspace = 8; - "Mod+Shift+9".move-window-to-workspace = 9; - "Mod+Tab".focus-workspace-previous = null; - "Mod+Comma".consume-window-into-column = null; - "Mod+Period".expel-window-from-column = null; - "Mod+R".switch-preset-column-width = null; - "Mod+F".maximize-column = null; - "Mod+Shift+F".fullscreen-window = null; - "Mod+Ctrl+F".expand-column-to-available-width = null; - "Mod+Minus".set-column-width = "-10%"; - "Mod+Plus".set-column-width = "+10%"; + "Mod+1".focus-workspace = 1; + "Mod+2".focus-workspace = 2; + "Mod+3".focus-workspace = 3; + "Mod+4".focus-workspace = 4; + "Mod+5".focus-workspace = 5; + "Mod+6".focus-workspace = 6; + "Mod+7".focus-workspace = 7; + "Mod+8".focus-workspace = 8; + "Mod+9".focus-workspace = 9; + "Mod+Shift+1".move-window-to-workspace = 1; + "Mod+Shift+2".move-window-to-workspace = 2; + "Mod+Shift+3".move-window-to-workspace = 3; + "Mod+Shift+4".move-window-to-workspace = 4; + "Mod+Shift+5".move-window-to-workspace = 5; + "Mod+Shift+6".move-window-to-workspace = 6; + "Mod+Shift+7".move-window-to-workspace = 7; + "Mod+Shift+8".move-window-to-workspace = 8; + "Mod+Shift+9".move-window-to-workspace = 9; + "Mod+Tab".focus-workspace-previous = null; + "Mod+Comma".consume-window-into-column = null; + "Mod+Period".expel-window-from-column = null; + "Mod+R".switch-preset-column-width = null; + "Mod+F".maximize-column = null; + "Mod+Shift+F".fullscreen-window = null; + "Mod+Ctrl+F".expand-column-to-available-width = null; + "Mod+Minus".set-column-width = "-10%"; + "Mod+Plus".set-column-width = "+10%"; - "Mod+V".toggle-window-floating = null; - "Mod+Shift+V".switch-focus-between-floating-and-tiling = null; + "Mod+V".toggle-window-floating = null; + "Mod+Shift+V".switch-focus-between-floating-and-tiling = null; - # allow-inhibiting=false - "Mod+Escape".toggle-keyboard-shortcuts-inhibit = null; + # allow-inhibiting=false + "Mod+Escape".toggle-keyboard-shortcuts-inhibit = null; - "Mod+Shift+E".quit = null; - "Ctrl+Alt+Delete".quit = null; - }; - } - ]); + "Mod+Shift+E".quit = null; + "Ctrl+Alt+Delete".quit = null; + }; + } overwriteSettings; }; in -niri.wrapper +niriWrapper