197 lines
4.7 KiB
Nix
197 lines
4.7 KiB
Nix
{
|
|
lib,
|
|
pkgs,
|
|
config,
|
|
...
|
|
}:
|
|
with lib; let
|
|
user = config.user;
|
|
|
|
cfg = config.displays;
|
|
|
|
renderDisplaysForHyprland = displays: (map displayHyprlandSetting (builtins.filter (d: d.enable) displays));
|
|
|
|
swaybgJob = displays: {
|
|
Unit = {
|
|
Description = "SwayBG";
|
|
};
|
|
Service = {
|
|
ExecStart =
|
|
"${pkgs.swaybg}/bin/swaybg "
|
|
+ builtins.concatStringsSep " " (map swaybgCmd displays);
|
|
};
|
|
Install = {
|
|
WantedBy = ["graphical-session.target"];
|
|
};
|
|
};
|
|
|
|
swaybgCmd = display:
|
|
if (display.enable && display ? wallpaper && display.wallpaper != null)
|
|
then "-o ${display.name} -i ${display.wallpaper} -m fill"
|
|
else "";
|
|
|
|
displayHyprlandSetting = display:
|
|
specificDisplay display
|
|
+ ", "
|
|
+ resToString display.resolution
|
|
+ ", "
|
|
+ positionToHyprlandString display.position
|
|
+ ", "
|
|
+ toString display.scaling
|
|
+ ", "
|
|
+ "transform,"
|
|
+ toString display.rotation;
|
|
|
|
specificDisplay = display:
|
|
if display.description == ""
|
|
then display.name
|
|
else "desc:" + display.description;
|
|
|
|
positionToHyprlandString = {
|
|
x,
|
|
y,
|
|
}:
|
|
if (x == -1 || y == -1)
|
|
then "auto"
|
|
else toString x + "x" + toString y;
|
|
|
|
renderDisplaysForSway = displays:
|
|
listToAttrs (map displaySwaySetting (builtins.filter (d: d.enable) displays));
|
|
|
|
displaySwaySetting = display: {
|
|
name = display.name;
|
|
value = let
|
|
res = display.resolution;
|
|
in
|
|
{
|
|
mode =
|
|
mkIf (!resUnset res)
|
|
"${toString res.x}x${toString res.y}@${toString res.freq}Hz";
|
|
scale = toString display.scaling;
|
|
}
|
|
// lib.mkIf (display ? wallpaper && display.wallpaper != null) {
|
|
bg = "${display.wallpaper} fill";
|
|
};
|
|
};
|
|
|
|
resolutionType = types.submodule {
|
|
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 = {
|
|
enable = mkEnableOption "enable this display";
|
|
name = mkOption {
|
|
description = "name of the display";
|
|
default = "";
|
|
};
|
|
description = mkOption {
|
|
description = "description of display from hyprctl monitors";
|
|
default = "";
|
|
};
|
|
scaling = mkOption {
|
|
type = types.float;
|
|
default = 1.0;
|
|
};
|
|
rotation = mkOption {
|
|
type = types.int;
|
|
default = 0;
|
|
};
|
|
resolution = mkOption {
|
|
description = "res";
|
|
type = resolutionType;
|
|
default = {};
|
|
};
|
|
position.x = mkOption {
|
|
default = -1;
|
|
type = types.int;
|
|
};
|
|
position.y = mkOption {
|
|
default = -1;
|
|
type = types.int;
|
|
};
|
|
wallpaper = mkOption {
|
|
description = "path to wallpaper";
|
|
default = null;
|
|
};
|
|
workspaces = mkOption {
|
|
default = {};
|
|
type = types.submodule {
|
|
options = {
|
|
start = mkOption {
|
|
type = types.int;
|
|
default = 1;
|
|
};
|
|
end = mkOption {
|
|
type = types.int;
|
|
default = 1;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
resUnset = res: (res.x == 0 || res.y == 0 || res.freq == 0);
|
|
|
|
resToString = res:
|
|
if resUnset res
|
|
then "preferred"
|
|
else "${toString res.x}x${toString res.y}@${toString res.freq}";
|
|
|
|
waybarWorkspaceConf = monitors: (map (display: {
|
|
${display.name} = display.workspaces.start;
|
|
})
|
|
monitors);
|
|
|
|
renderWorkspacesForHyprland = displays: (map hyprWorkspaceSetting displays);
|
|
|
|
hyprWorkspaceSetting = display:
|
|
specificDisplay display
|
|
+ ", "
|
|
+ toString display.workspaces.start;
|
|
in {
|
|
options.displays = {
|
|
enable = mkEnableOption "manage displays";
|
|
displays = mkOption {
|
|
type = types.attrsOf displayType;
|
|
default = {};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
home-manager.users.${user}.imports = [
|
|
{
|
|
programs.waybar.settings.mainBar."hyprland/workspaces".persistent_workspaces = waybarWorkspaceConf (attrValues cfg.displays);
|
|
|
|
systemd.user.services.swaybg = swaybgJob (builtins.attrValues cfg.displays);
|
|
|
|
wayland.windowManager = mkIf (cfg.displays != {}) {
|
|
hyprland.settings = {
|
|
monitor = renderDisplaysForHyprland (attrValues cfg.displays);
|
|
workspace = renderWorkspacesForHyprland (attrValues cfg.displays);
|
|
};
|
|
|
|
sway.config.output =
|
|
renderDisplaysForSway (attrValues cfg.displays);
|
|
};
|
|
}
|
|
];
|
|
};
|
|
}
|