From 2d186cb603d86126033470bb257e66858df88b25 Mon Sep 17 00:00:00 2001 From: isabel Date: Fri, 19 Dec 2025 15:27:44 +0000 Subject: [PATCH] nixos/hardware: cleanup monitors --- home/isabel/gui/hyprland.nix | 145 +++++++++++++++++------------ modules/flake/lib/default.nix | 2 +- modules/flake/lib/hardware.nix | 25 +---- modules/nixos/hardware/options.nix | 51 +++++++++- systems/amaterasu/default.nix | 8 +- systems/athena/default.nix | 3 +- systems/valkyrie/default.nix | 1 - 7 files changed, 138 insertions(+), 97 deletions(-) diff --git a/home/isabel/gui/hyprland.nix b/home/isabel/gui/hyprland.nix index f4bcff75..af93c7b8 100644 --- a/home/isabel/gui/hyprland.nix +++ b/home/isabel/gui/hyprland.nix @@ -14,10 +14,56 @@ let concatLists imap0 concatLines + mod + attrNames + foldl' + min + id ; inherit (config.garden.programs) defaults; inherit (osConfig.garden.device) monitors keyboard; + + mapMonitors = concatLines ( + imap0 ( + i: m: + "monitor=${m.name},${toString m.width}x${toString m.height}@${toString m.refresh-rate},${toString (i * 1920)}x0,${toString m.scale}" + ) monitors + ); + + mapMonitorsToWs = + let + names = attrNames monitors; + count = length names; + splitBy = builtins.div 10 count; + remainder = mod 10 count; + firstSplitBy = splitBy + remainder; + in + concatLines + (foldl' + ( + acc: i: + let + currentSplitBy = if acc.elem == 0 then firstSplitBy else splitBy; + shouldIncrement = acc.usedFor >= currentSplitBy; + newElem = min (if shouldIncrement then acc.elem + 1 else acc.elem) (count - 1); + asStr = "workspace=${toString (i + 1)}, monitor:${elemAt names newElem}${ + if i == 0 then ", default:true" else "" + }"; + in + { + usedFor = if shouldIncrement then 1 else acc.usedFor + 1; + elem = newElem; + out = acc.out ++ [ asStr ]; + } + ) + { + usedFor = 0; + elem = 0; + out = [ ]; + } + (genList id 10) + ).out; in { options.programs.hyprland.enable = lib.mkEnableOption "Enable Hyprland as the Wayland window manager"; @@ -281,67 +327,44 @@ in ]; }; - extraConfig = - let - mapMonitors = concatLines ( - imap0 ( - i: monitor: - ''monitor=${monitor},${ - if monitor == "eDP-1" then "1920x1080@60" else "preferred" - },${toString (i * 1920)}x0,1'' - ) monitors - ); - - mapMonitorsToWs = concatLines ( - genList (x: '' - workspace = ${toString (x + 1)}, monitor:${ - if (x + 1) <= 5 then - "${elemAt monitors 0} ${if (x + 1) == 1 then ", default:true" else ""}" - else - "${elemAt monitors 1}" - } - '') 10 - ); - - in - '' - ${mapMonitors} - ${optionalString (length monitors != 1) "${mapMonitorsToWs}"} - - # █▀▄▀█ █▀█ █░█ █▀▀ - # █░▀░█ █▄█ ▀▄▀ ██▄ - bind=SUPER, M, submap, move - submap=move - - binde = , left, movewindow, l - binde = , right, movewindow, r - binde = , up, movewindow, u - binde = , down, movewindow, d - binde = , j, movewindow, l - binde = , l, movewindow, r - binde = , i, movewindow, u - binde = , k, movewindow, d - - bind=,escape,submap,reset - submap=reset - - # █▀█ █▀▀ █▀ █ ▀█ █▀▀ - # █▀▄ ██▄ ▄█ █ █▄ ██▄ - bind=SUPER, R, submap, resize - submap=resize - - binde = , left, resizeactive, -20 0 - binde = , right, resizeactive, 20 0 - binde = , up, resizeactive, 0 -20 - binde = , down, resizeactive, 0 20 - binde = , h, resizeactive, -20 0 - binde = , j, resizeactive, 20 0 - binde = , i, resizeactive, 0 -20 - binde = , k, resizeactive, 0 20 - - bind=,escape,submap,reset - submap=reset - ''; + extraConfig = '' + ${mapMonitors} + ${optionalString (length (attrNames monitors) != 1) "${mapMonitorsToWs}"} + + # █▀▄▀█ █▀█ █░█ █▀▀ + # █░▀░█ █▄█ ▀▄▀ ██▄ + bind=SUPER, M, submap, move + submap=move + + binde = , left, movewindow, l + binde = , right, movewindow, r + binde = , up, movewindow, u + binde = , down, movewindow, d + binde = , j, movewindow, l + binde = , l, movewindow, r + binde = , i, movewindow, u + binde = , k, movewindow, d + + bind=,escape,submap,reset + submap=reset + + # █▀█ █▀▀ █▀ █ ▀█ █▀▀ + # █▀▄ ██▄ ▄█ █ █▄ ██▄ + bind=SUPER, R, submap, resize + submap=resize + + binde = , left, resizeactive, -20 0 + binde = , right, resizeactive, 20 0 + binde = , up, resizeactive, 0 -20 + binde = , down, resizeactive, 0 20 + binde = , h, resizeactive, -20 0 + binde = , j, resizeactive, 20 0 + binde = , i, resizeactive, 0 -20 + binde = , k, resizeactive, 0 20 + + bind=,escape,submap,reset + submap=reset + ''; }; }; } diff --git a/modules/flake/lib/default.nix b/modules/flake/lib/default.nix index 4e44af84..7f6f8924 100644 --- a/modules/flake/lib/default.nix +++ b/modules/flake/lib/default.nix @@ -16,7 +16,7 @@ let # we have to rexport the functions we want to use, but don't want to refer to the whole lib # "path". e.g. gardenLib.hardware.isx86Linux can be shortened to gardenLib.isx86Linux # NOTE: never rexport templates - inherit (final.hardware) isx86Linux primaryMonitor ldTernary; + inherit (final.hardware) isx86Linux ldTernary; inherit (final.helpers) mkPubs giturl diff --git a/modules/flake/lib/hardware.nix b/modules/flake/lib/hardware.nix index aee4bbc0..a58fa4f9 100644 --- a/modules/flake/lib/hardware.nix +++ b/modules/flake/lib/hardware.nix @@ -51,30 +51,7 @@ let d else throw "Unsupported system: ${pkgs.stdenv.system}"; - - /** - assume the first monitor in the list of monitors is primary - get its name from the list of monitors - - # Arguments - - - [config] the configuration that nixosConfigurations provides - - # Type - - ``` - primaryMonitor :: AttrSet -> String - ``` - - # Example - - ```nix - primaryMonitor osConfig - => "DP-1" - ``` - */ - primaryMonitor = config: builtins.elemAt config.garden.device.monitors 0; in { - inherit isx86Linux primaryMonitor ldTernary; + inherit isx86Linux ldTernary; } diff --git a/modules/nixos/hardware/options.nix b/modules/nixos/hardware/options.nix index 87971372..8bb9e6e5 100644 --- a/modules/nixos/hardware/options.nix +++ b/modules/nixos/hardware/options.nix @@ -1,13 +1,54 @@ { lib, ... }: let - inherit (lib.options) mkOption; - inherit (lib.types) listOf str enum; + inherit (lib) mkOption types; in { options.garden.device = { monitors = mkOption { - type = listOf str; - default = [ ]; + type = types.attrsOf ( + types.submodule ( + { name, ... }: + { + options = { + name = mkOption { + type = types.str; + default = name; + description = "the name of the monitor"; + example = "HDMI-1"; + }; + + width = mkOption { + type = types.int; + default = 1920; + example = 1080; + description = "the width of the monitor in pixels"; + }; + + height = mkOption { + type = types.int; + default = 1080; + example = 1024; + description = "the height of the monitor in pixels"; + }; + + refresh-rate = mkOption { + type = types.int; + default = 60; + example = 120; + description = "the refresh rate of the monitor in Hz"; + }; + + scale = mkOption { + type = types.float; + default = 1.0; + example = 1.5; + description = "the scale factor for the monitor"; + }; + }; + } + ) + ); + description = '' this does not affect any drivers and such, it is only necessary for declaring things like monitors in window manager configurations @@ -16,7 +57,7 @@ in }; keyboard = mkOption { - type = enum [ + type = types.enum [ "us" "gb" ]; diff --git a/systems/amaterasu/default.nix b/systems/amaterasu/default.nix index 93b81b8f..6fd5f934 100644 --- a/systems/amaterasu/default.nix +++ b/systems/amaterasu/default.nix @@ -13,10 +13,10 @@ device = { cpu = "intel"; gpu = "nvidia"; - monitors = [ - "DP-1" - "DP-2" - ]; + monitors = { + DP-1.refresh-rate = 144; + DP-2 = { }; + }; capabilities = { tpm = true; bluetooth = true; diff --git a/systems/athena/default.nix b/systems/athena/default.nix index f6861647..a3a4c9e6 100644 --- a/systems/athena/default.nix +++ b/systems/athena/default.nix @@ -11,7 +11,8 @@ device = { cpu = "intel"; gpu = "intel"; - monitors = [ "eDP-1" ]; + monitors.eDP-1 = { }; + keyboard = "us"; capabilities = { tpm = true; bluetooth = true; diff --git a/systems/valkyrie/default.nix b/systems/valkyrie/default.nix index fa964c63..dfa04e3e 100644 --- a/systems/valkyrie/default.nix +++ b/systems/valkyrie/default.nix @@ -10,7 +10,6 @@ device = { cpu = null; gpu = null; - monitors = [ ]; capabilities = { tpm = true; bluetooth = false; -- 2.51.2