From bdfe9882c256fa811fd729f6acc034de3d62cb64 Mon Sep 17 00:00:00 2001 From: punkfairie Date: Thu, 9 Jan 2025 19:39:14 -0800 Subject: [PATCH] feat(home): Assign workspaces to monitors --- homes/x86_64-linux/marley@nyx/default.nix | 9 +- modules/home/wayland/hyprland/default.nix | 106 ++++++++++++++++++++-- 2 files changed, 105 insertions(+), 10 deletions(-) diff --git a/homes/x86_64-linux/marley@nyx/default.nix b/homes/x86_64-linux/marley@nyx/default.nix index 3416da1..1fa4501 100644 --- a/homes/x86_64-linux/marley@nyx/default.nix +++ b/homes/x86_64-linux/marley@nyx/default.nix @@ -55,10 +55,11 @@ in { }; wayland.hyprland = { enable = true; - monitors = [ - "desc:Apple Computer Inc LED Cinema 2A91946Z0K0, 1920x1200, 0x0, 1" - "desc:Lenovo Group Limited LT2252p Wide 6V8ACF74, 1680x1050, 1920x0, 1" - ]; + monitors = { + "DP-1" = "desc:Apple Computer Inc LED Cinema 2A91946Z0K0, 1920x1200, 0x0, 1"; + "HDMI-A-1" = "desc:Lenovo Group Limited LT2252p Wide 6V8ACF74, 1680x1050, 1920x0, 1"; + }; + mainMonitor = "DP-1"; }; }; diff --git a/modules/home/wayland/hyprland/default.nix b/modules/home/wayland/hyprland/default.nix index 1f310d6..0820427 100644 --- a/modules/home/wayland/hyprland/default.nix +++ b/modules/home/wayland/hyprland/default.nix @@ -3,9 +3,28 @@ config, inputs, system, + pkgs, ... }: let - inherit (lib) mkEnableOption mkOption mkIf getExe; + inherit + (lib) + mkEnableOption + mkOption + mkIf + length + attrNames + range + zipListsWith + subtractLists + sublist + mapAttrs + replicate + last + getExe + concatLists + attrValues + listToAttrs + ; cfg = config.marleyos.wayland.hyprland; in { @@ -14,12 +33,28 @@ in { monitors = mkOption { description = "Monitor configuration."; - type = with lib.types; listOf str; - default = []; + type = with lib.types; attrsOf str; + }; + + mainMonitor = mkOption { + description = "Which monitor to treat as the main for workspace assignment"; + type = with lib.types; str; }; }; config = mkIf cfg.enable { + assertions = [ + { + assertion = + if cfg ? monitors + then cfg ? mainMonitor + else true; + message = '' + You have defined monitors but not selected the main monitor. Please + define marleyos.wayland.hyprland.mainMonitor. + ''; + } + ]; marleyos.programs.wofi.enable = true; wayland.windowManager.hyprland = { @@ -28,12 +63,71 @@ in { systemd.enable = true; xwayland.enable = true; - settings = { - monitor = cfg.monitors; + settings = let + numMonitors = length (attrNames (cfg.monitors or {})); + workspaces = range 1 10; + wsPerMonitor = 10 / numMonitors; + + mainMonWs = range 1 wsPerMonitor; + secondaryWs = subtractLists mainMonWs workspaces; + + monitors = mapAttrs (mon: _: + if (mon == (cfg.mainMonitor or "")) + then "" + else replicate wsPerMonitor "${mon}") + (cfg.monitors or {}); + + secondaryMons = removeAttrs monitors [(cfg.mainMonitor or "")]; + monList = concatLists (attrValues secondaryMons); + + firstWsToMons = + zipListsWith (mon: ws: { + name = toString ws; + value = mon; + }) + monList + secondaryWs; + + leftover = + sublist (length monList) (10 - (wsPerMonitor * numMonitors)) secondaryWs; + + wsToMons = + firstWsToMons + ++ (map (ws: { + name = toString ws; + value = last monList; + }) + leftover) + ++ (map (ws: { + name = toString ws; + value = cfg.mainMonitor or ""; + }) + mainMonWs); + + wsMons = listToAttrs wsToMons; + in { + monitor = attrValues cfg.monitors; # TODO: Use overlay once it's made. "$terminal" = getExe inputs.wezterm.packages."${system}".default; - "$launcher" = "wofi --show drun"; + "$launcher" = "${getExe pkgs.wofi} --show drun"; + + exec-once = let + browserWs = + if (cfg ? monitors) + then wsPerMonitor + 1 + else 2; + in [ + "[workspace 1 silent] $terminal" + # TODO: Change once waterfox is set up + "[workspace ${toString browserWs} silent] firefox" + ]; + + workspace = + mkIf (cfg ? monitors) + (map + (ws: "${toString ws}, monitor:${wsMons."${toString ws}"}") + workspaces); "$mod" = "SUPER";