139 lines
3.5 KiB
Nix
139 lines
3.5 KiB
Nix
{ 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);
|
|
}
|
|
];
|
|
};
|
|
}
|
|
|