diff --git a/modules/features/input.nix b/modules/features/input.nix new file mode 100644 index 0000000..0eae387 --- /dev/null +++ b/modules/features/input.nix @@ -0,0 +1,69 @@ +{ + flake.modules.nixos.input = + { + lib, + config, + ... + }: + let + hostInput = config.meta.host.input; + + hasAnyConfiguredValue = attrs: lib.any (value: value != null) (lib.attrValues attrs); + libinputScrollMethodMap = { + edge = "edge"; + "no-scroll" = "none"; + "on-button-down" = "button"; + "two-finger" = "twofinger"; + }; + libinputClickMethodMap = { + "button-areas" = "buttonareas"; + clickfinger = "clickfinger"; + }; + + hasMouseConfig = hasAnyConfiguredValue hostInput.mouse; + hasTouchpadConfig = hasAnyConfiguredValue hostInput.touchpad; + hasPointerConfig = hasMouseConfig || hasTouchpadConfig; + + mouseConfig = lib.filterAttrs (_: value: value != null) { + accelProfile = hostInput.mouse.accelProfile; + accelSpeed = + if hostInput.mouse.accelSpeed == null then null else toString hostInput.mouse.accelSpeed; + leftHanded = hostInput.mouse.leftHanded; + middleEmulation = hostInput.mouse.middleEmulation; + naturalScrolling = hostInput.mouse.naturalScrolling; + scrollMethod = + if hostInput.mouse.scrollMethod == null then + null + else + libinputScrollMethodMap.${hostInput.mouse.scrollMethod}; + }; + + touchpadConfig = lib.filterAttrs (_: value: value != null) { + accelProfile = hostInput.touchpad.accelProfile; + accelSpeed = + if hostInput.touchpad.accelSpeed == null then null else toString hostInput.touchpad.accelSpeed; + clickMethod = + if hostInput.touchpad.clickMethod == null then + null + else + libinputClickMethodMap.${hostInput.touchpad.clickMethod}; + disableWhileTyping = hostInput.touchpad.disableWhileTyping; + leftHanded = hostInput.touchpad.leftHanded; + middleEmulation = hostInput.touchpad.middleEmulation; + naturalScrolling = hostInput.touchpad.naturalScrolling; + scrollMethod = + if hostInput.touchpad.scrollMethod == null then + null + else + libinputScrollMethodMap.${hostInput.touchpad.scrollMethod}; + tapping = hostInput.touchpad.tapping; + }; + in + { + services.libinput = lib.mkIf hasPointerConfig { + enable = true; + mouse = mouseConfig; + touchpad = touchpadConfig; + }; + }; +} diff --git a/modules/features/meta.nix b/modules/features/meta.nix index 16d4458..5debee7 100644 --- a/modules/features/meta.nix +++ b/modules/features/meta.nix @@ -1,5 +1,12 @@ { lib, ... }: let + mkNullableOption = + type: + lib.mkOption { + inherit type; + default = null; + }; + emailType = lib.types.submodule ( { ... }: { @@ -100,6 +107,73 @@ let } ); + mouseInputType = lib.types.submodule ( + { ... }: + { + options = { + accelProfile = mkNullableOption (lib.types.nullOr (lib.types.enum [ + "adaptive" + "flat" + ])); + accelSpeed = mkNullableOption (lib.types.nullOr lib.types.float); + leftHanded = mkNullableOption (lib.types.nullOr lib.types.bool); + middleEmulation = mkNullableOption (lib.types.nullOr lib.types.bool); + naturalScrolling = mkNullableOption (lib.types.nullOr lib.types.bool); + scrollMethod = mkNullableOption (lib.types.nullOr (lib.types.enum [ + "no-scroll" + "two-finger" + "edge" + "on-button-down" + ])); + }; + } + ); + + touchpadInputType = lib.types.submodule ( + { ... }: + { + options = { + accelProfile = mkNullableOption (lib.types.nullOr (lib.types.enum [ + "adaptive" + "flat" + ])); + accelSpeed = mkNullableOption (lib.types.nullOr lib.types.float); + clickMethod = mkNullableOption (lib.types.nullOr (lib.types.enum [ + "button-areas" + "clickfinger" + ])); + disableWhileTyping = mkNullableOption (lib.types.nullOr lib.types.bool); + leftHanded = mkNullableOption (lib.types.nullOr lib.types.bool); + middleEmulation = mkNullableOption (lib.types.nullOr lib.types.bool); + naturalScrolling = mkNullableOption (lib.types.nullOr lib.types.bool); + scrollMethod = mkNullableOption (lib.types.nullOr (lib.types.enum [ + "no-scroll" + "two-finger" + "edge" + "on-button-down" + ])); + tapping = mkNullableOption (lib.types.nullOr lib.types.bool); + }; + } + ); + + inputType = lib.types.submodule ( + { ... }: + { + options = { + mouse = lib.mkOption { + type = mouseInputType; + default = { }; + }; + + touchpad = lib.mkOption { + type = touchpadInputType; + default = { }; + }; + }; + } + ); + hostType = lib.types.submodule ( { ... }: { @@ -113,6 +187,11 @@ let default = { }; }; + input = lib.mkOption { + type = inputType; + default = { }; + }; + users = lib.mkOption { type = lib.types.attrsOf userType; default = { }; diff --git a/modules/features/niri/default.nix b/modules/features/niri/default.nix index 87468e8..2f2f222 100644 --- a/modules/features/niri/default.nix +++ b/modules/features/niri/default.nix @@ -23,6 +23,8 @@ ... }: let + hostInput = config.meta.host.input; + outputs = lib.mapAttrs ( _: display: { @@ -49,6 +51,27 @@ rawTerminalAttrPath; terminalPackage = lib.attrByPath terminalAttrPath null pkgs; hasMainProgram = terminalPackage != null && terminalPackage ? meta.mainProgram; + + mouseSettings = lib.filterAttrs (_: value: value != null) { + accel-profile = hostInput.mouse.accelProfile; + accel-speed = hostInput.mouse.accelSpeed; + left-handed = hostInput.mouse.leftHanded; + middle-emulation = hostInput.mouse.middleEmulation; + natural-scroll = hostInput.mouse.naturalScrolling; + scroll-method = hostInput.mouse.scrollMethod; + }; + + touchpadSettings = lib.filterAttrs (_: value: value != null) { + accel-profile = hostInput.touchpad.accelProfile; + accel-speed = hostInput.touchpad.accelSpeed; + click-method = hostInput.touchpad.clickMethod; + dwt = hostInput.touchpad.disableWhileTyping; + left-handed = hostInput.touchpad.leftHanded; + middle-emulation = hostInput.touchpad.middleEmulation; + natural-scroll = hostInput.touchpad.naturalScrolling; + scroll-method = hostInput.touchpad.scrollMethod; + tap = hostInput.touchpad.tapping; + }; in { assertions = [ @@ -139,7 +162,12 @@ repeat-rate = 50; xkb.options = "caps:escape"; }; - mouse.accel-speed = 0.4; + } + // lib.optionalAttrs (mouseSettings != { }) { + mouse = mouseSettings; + } + // lib.optionalAttrs (touchpadSettings != { }) { + touchpad = touchpadSettings; }; binds = diff --git a/modules/features/sddm.nix b/modules/features/sddm.nix index b625fce..95a777f 100644 --- a/modules/features/sddm.nix +++ b/modules/features/sddm.nix @@ -1,14 +1,40 @@ { flake.modules.nixos.sddm = - { pkgs, ... }: + { + config, + lib, + pkgs, + ... + }: + let + primaryDisplays = builtins.filter (display: display.primary or false) (builtins.attrValues config.meta.host.displays); + primaryDisplay = if primaryDisplays == [ ] then null else builtins.head primaryDisplays; + primaryScale = + if primaryDisplay == null then + null + else + primaryDisplay.scale; + greeterEnvironment = + lib.optional (primaryScale != null) "QT_SCALE_FACTOR=${toString primaryScale}"; + in { services.displayManager.sddm = { enable = true; + enableHidpi = primaryScale == null; wayland.enable = true; + wayland.compositor = "kwin"; theme = "${pkgs.sddm-astronaut}/share/sddm/themes/sddm-astronaut-theme"; extraPackages = with pkgs; [ kdePackages.qtmultimedia ]; + settings = lib.optionalAttrs (greeterEnvironment != [ ]) { + General.GreeterEnvironment = lib.concatStringsSep "," ( + [ + "QT_WAYLAND_SHELL_INTEGRATION=layer-shell" + ] + ++ greeterEnvironment + ); + }; }; }; } diff --git a/modules/features/workstation-base.nix b/modules/features/workstation-base.nix index c1d249e..accd586 100644 --- a/modules/features/workstation-base.nix +++ b/modules/features/workstation-base.nix @@ -7,6 +7,7 @@ in flake.modules.nixos.workstation-base = { imports = [ nixosModules.host-base + nixosModules.input nixosModules.sops-admin-key-file nixosModules.standard-boot nixosModules.sddm diff --git a/modules/hosts/zenith/default.nix b/modules/hosts/zenith/default.nix index 642dbed..06e2cd5 100644 --- a/modules/hosts/zenith/default.nix +++ b/modules/hosts/zenith/default.nix @@ -26,6 +26,10 @@ in }; }; + input = { + mouse.accelSpeed = 0.4; + }; + users = { inherit (metaLib.users) ergon diff --git a/modules/lib.nix b/modules/lib.nix index 7ae48f2..c5488b3 100644 --- a/modules/lib.nix +++ b/modules/lib.nix @@ -8,6 +8,7 @@ let { name, displays ? { }, + input ? { }, users ? { }, imports ? [ ], stateVersion ? "24.05", @@ -16,6 +17,7 @@ let meta.host = { inherit displays + input name users ;