{ user }: { lib, pkgs, config, ... }: with lib; let cfg = config.displays; renderDisplaysForHyprland = displays: "# === DISPLAY MODULE ===\n" + concatStringsSep "\n" (map displayHyprlandSetting displays); displayHyprlandSetting = display: "monitor = " + specificDisplay display + ", " + resToString display.resolution + ", " + positionToHyprlandString display.position + ", " + toString display.scaling; swaybgJob = displays: { Unit = { Description = "SwayBG"; }; Service = { ExecStart = "${pkgs.swaybg}/bin/swaybg " + concatStringsSep " " (map swaybgCmd displays); }; Install = { WantedBy = ["graphical-session.target"]; }; }; swaybgCmd = display: if (display.wallpaper != "") then "-o ${display.name} -i ${display.wallpaper}" else ""; specificDisplay = display: if display.description == "" then display.name else "desc:" + display.description; positionToHyprlandString = { x, y }: if (x == "" || y == "") then "auto" else x + "x" + y; renderDisplaysForSway = displays: listToAttrs (map displaySwaySetting displays); displaySwaySetting = display: { name = display.name; value = let res = display.resolution; in { mode = mkIf (resIsSet res) "${toString res.x}x${toString res.y}@${toString res.freq}Hz"; bg = display.wallpaper + " fill"; scale = toString display.scaling; }; }; resolutionType = types.submodule ({ x, y, freq, ... }: { options = { x = mkOption { description = "x"; type = types.int; default = 0; }; y = mkOption { description = "y"; type = types.int; default = 0; }; freq = mkOption { description = "frequency"; type = types.int; default = 0; }; }; }); displayType = types.submodule ({ ... }: { options = { name = mkOption { description = "name of the display"; }; description = mkOption { description = "description of display from hyprctl monitors"; default = ""; }; scaling = mkOption { type = types.float; default = 1.0; }; resolution = mkOption { description = "res"; type = resolutionType; default = { }; }; position.x = mkOption { default = ""; }; position.y = mkOption { default = ""; }; wallpaper = mkOption { description = "path to wallpaper"; default = ""; }; }; }); resIsSet = res: !(res.x == 0 || res.y == 0 || res.freq == 0); resToString = res: if resIsSet res then "preferred" else "${toString res.x}x${toString res.y}@${toString res.freq}"; in { options.displays = { enable = mkEnableOption "manage displays"; displays = mkOption { type = types.listOf displayType; default = [ ]; }; }; config = mkIf cfg.enable { home-manager.users.${user}.imports = [ { wayland.windowManager.hyprland.extraConfig = mkIf (cfg.displays != [ ]) (renderDisplaysForHyprland cfg.displays); systemd.user.services.swaybg = swaybgJob cfg.displays; wayland.windowManager.sway.config.output = mkIf (cfg.displays != [ ]) (renderDisplaysForSway cfg.displays); } ]; }; }