feat: derive desktop input and SDDM scale from host metadata

This commit is contained in:
2026-04-21 22:24:41 +02:00
parent 592e70cf33
commit 4781cc60be
7 changed files with 211 additions and 2 deletions
+69
View File
@@ -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;
};
};
}
+79
View File
@@ -1,5 +1,12 @@
{ lib, ... }: { lib, ... }:
let let
mkNullableOption =
type:
lib.mkOption {
inherit type;
default = null;
};
emailType = lib.types.submodule ( 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 ( hostType = lib.types.submodule (
{ ... }: { ... }:
{ {
@@ -113,6 +187,11 @@ let
default = { }; default = { };
}; };
input = lib.mkOption {
type = inputType;
default = { };
};
users = lib.mkOption { users = lib.mkOption {
type = lib.types.attrsOf userType; type = lib.types.attrsOf userType;
default = { }; default = { };
+29 -1
View File
@@ -23,6 +23,8 @@
... ...
}: }:
let let
hostInput = config.meta.host.input;
outputs = lib.mapAttrs ( outputs = lib.mapAttrs (
_: display: _: display:
{ {
@@ -49,6 +51,27 @@
rawTerminalAttrPath; rawTerminalAttrPath;
terminalPackage = lib.attrByPath terminalAttrPath null pkgs; terminalPackage = lib.attrByPath terminalAttrPath null pkgs;
hasMainProgram = terminalPackage != null && terminalPackage ? meta.mainProgram; 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 in
{ {
assertions = [ assertions = [
@@ -139,7 +162,12 @@
repeat-rate = 50; repeat-rate = 50;
xkb.options = "caps:escape"; xkb.options = "caps:escape";
}; };
mouse.accel-speed = 0.4; }
// lib.optionalAttrs (mouseSettings != { }) {
mouse = mouseSettings;
}
// lib.optionalAttrs (touchpadSettings != { }) {
touchpad = touchpadSettings;
}; };
binds = binds =
+27 -1
View File
@@ -1,14 +1,40 @@
{ {
flake.modules.nixos.sddm = 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 = { services.displayManager.sddm = {
enable = true; enable = true;
enableHidpi = primaryScale == null;
wayland.enable = true; wayland.enable = true;
wayland.compositor = "kwin";
theme = "${pkgs.sddm-astronaut}/share/sddm/themes/sddm-astronaut-theme"; theme = "${pkgs.sddm-astronaut}/share/sddm/themes/sddm-astronaut-theme";
extraPackages = with pkgs; [ extraPackages = with pkgs; [
kdePackages.qtmultimedia kdePackages.qtmultimedia
]; ];
settings = lib.optionalAttrs (greeterEnvironment != [ ]) {
General.GreeterEnvironment = lib.concatStringsSep "," (
[
"QT_WAYLAND_SHELL_INTEGRATION=layer-shell"
]
++ greeterEnvironment
);
};
}; };
}; };
} }
+1
View File
@@ -7,6 +7,7 @@ in
flake.modules.nixos.workstation-base = { flake.modules.nixos.workstation-base = {
imports = [ imports = [
nixosModules.host-base nixosModules.host-base
nixosModules.input
nixosModules.sops-admin-key-file nixosModules.sops-admin-key-file
nixosModules.standard-boot nixosModules.standard-boot
nixosModules.sddm nixosModules.sddm
+4
View File
@@ -26,6 +26,10 @@ in
}; };
}; };
input = {
mouse.accelSpeed = 0.4;
};
users = { users = {
inherit (metaLib.users) inherit (metaLib.users)
ergon ergon
+2
View File
@@ -8,6 +8,7 @@ let
{ {
name, name,
displays ? { }, displays ? { },
input ? { },
users ? { }, users ? { },
imports ? [ ], imports ? [ ],
stateVersion ? "24.05", stateVersion ? "24.05",
@@ -16,6 +17,7 @@ let
meta.host = { meta.host = {
inherit inherit
displays displays
input
name name
users users
; ;