refactor: modularize Hyprland configuration
- Create home/hyprland/default.nix module with configurable options - Add support for monitors, extraEnv, streamcontroller, lockhelper, grimblast, wacom - Add workspace strategy (numbered vs named per monitor) - Update magicman config to use new module with minimal config - Update gunter config to use new module with all customizations - Remove deprecated Hyprland config files - Significantly reduce duplication between host configs - Both configurations build successfully
This commit is contained in:
380
home/hyprland/default.nix
Normal file
380
home/hyprland/default.nix
Normal file
@@ -0,0 +1,380 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.hyprland;
|
||||
in
|
||||
{
|
||||
options.hyprland = {
|
||||
enable = mkEnableOption "Hyprland";
|
||||
|
||||
monitors = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "eDP-1,1920x1080@60,0x0,1" ];
|
||||
description = "Hyprland monitor configuration";
|
||||
};
|
||||
|
||||
extraEnv = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"LIBVA_DRIVER_NAME,nvidia"
|
||||
"GBM_BACKEND,nvidia-drm"
|
||||
];
|
||||
description = "Extra environment variables for Hyprland";
|
||||
};
|
||||
|
||||
enableStreamController = mkEnableOption "streamcontroller service";
|
||||
|
||||
useLockHelper = mkEnableOption "use lockhelper script instead of hyprlock directly";
|
||||
|
||||
enableGrimblast = mkEnableOption "grimblast screenshot keybinds";
|
||||
|
||||
enableWacom = mkEnableOption "Wacom tablet device configuration";
|
||||
|
||||
extraKeybinds = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"$mainMod,Print,exec,grimblast save active ~/tmp/screenshot.png"
|
||||
];
|
||||
description = "Extra keybinds for Hyprland";
|
||||
};
|
||||
|
||||
lockMonitorNames = mkOption {
|
||||
type = types.listOf (types.nullOr types.str);
|
||||
default = [ null ];
|
||||
example = [
|
||||
"desc:BNQ G2420HDBL T2B04424SL000"
|
||||
"desc:Samsung Electric Company LS27A600U HNMT502389"
|
||||
];
|
||||
description = "Monitor names for hyprlock backgrounds (null for all monitors)";
|
||||
};
|
||||
|
||||
workspaceStrategy = mkOption {
|
||||
type = types.enum [
|
||||
"numbered"
|
||||
"named"
|
||||
];
|
||||
default = "numbered";
|
||||
description = "Workspace naming strategy: numbered (1-6) or named per monitor";
|
||||
};
|
||||
|
||||
monitorVariables = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
example = {
|
||||
"$mon_top" = "desc:BNQ G2420HDBL T2B04424SL000";
|
||||
"$mon_left" = "desc:Samsung Electric Company LS27A600U HNMT502389";
|
||||
};
|
||||
description = "Monitor name variables for workspace configuration";
|
||||
};
|
||||
|
||||
cursorNoHardware = mkEnableOption "disable hardware cursors";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
home.packages =
|
||||
with pkgs;
|
||||
[
|
||||
dunst
|
||||
hyprpaper
|
||||
rofi
|
||||
slurp
|
||||
swww
|
||||
waybar
|
||||
wl-clipboard
|
||||
catppuccin-cursors.macchiatoLavender
|
||||
bibata-cursors
|
||||
libsForQt5.qt5.qtwayland
|
||||
libsForQt5.qt5ct
|
||||
]
|
||||
++ optional cfg.enableGrimblast grimblast;
|
||||
|
||||
services.hyprpaper = {
|
||||
enable = true;
|
||||
settings = {
|
||||
splash = false;
|
||||
};
|
||||
};
|
||||
|
||||
services.hypridle = {
|
||||
enable = true;
|
||||
settings = {
|
||||
general = {
|
||||
lock_cmd =
|
||||
if cfg.useLockHelper then
|
||||
"${pkgs.callPackage ../scripts/lockhelper.nix { }}/bin/lockhelper"
|
||||
else
|
||||
"${pkgs.hyprlock}/bin/hyprlock";
|
||||
ignore_dbus_inhibit = false;
|
||||
};
|
||||
listener = {
|
||||
timeout = 240;
|
||||
on-timeout = config.services.hypridle.settings.general.lock_cmd;
|
||||
before_sleep_cmd = config.services.hypridle.settings.general.lock_cmd;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.hyprlock = {
|
||||
enable = true;
|
||||
settings = {
|
||||
background = map (mon: {
|
||||
monitor = if mon == null then "" else "desc:${mon}";
|
||||
path = "screenshot";
|
||||
color = "rgba(17, 17, 17, 1.0)";
|
||||
blur_passes = 3;
|
||||
contrast = 0.8916;
|
||||
brightness = 0.8172;
|
||||
vibrancy = 0.1696;
|
||||
vibrancy_darkness = 0.0;
|
||||
}) cfg.lockMonitorNames;
|
||||
|
||||
general = {
|
||||
grace = 0;
|
||||
};
|
||||
|
||||
input-field = [
|
||||
{
|
||||
size = "250, 60";
|
||||
outline_thickness = 2;
|
||||
dots_size = 0.2;
|
||||
dots_spacing = 0.2;
|
||||
dots_center = true;
|
||||
outer_color = "rgba(0, 0, 0, 0)";
|
||||
inner_color = "rgba(0, 0, 0, 0.5)";
|
||||
font_color = "rgb(200, 200, 200)";
|
||||
fade_on_empty = false;
|
||||
font_family = "JetBrains Mono Nerd Font Mono";
|
||||
placeholder_text = "<i><span foreground=\"##cdd6f4\">Input Password...</span></i>";
|
||||
hide_input = false;
|
||||
position = "0, -120";
|
||||
halign = "center";
|
||||
valign = "center";
|
||||
}
|
||||
];
|
||||
|
||||
label = [
|
||||
{
|
||||
text = "cmd[update:2000] echo \"$(date +\"%b %d %H:%M\")\"";
|
||||
color = "rgba(255, 255, 255, 0.6)";
|
||||
font_size = 120;
|
||||
font_family = "JetBrains Mono Nerd Font Mono ExtraBold";
|
||||
position = "0, -300";
|
||||
halign = "center";
|
||||
valign = "top";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services = mkIf cfg.enableStreamController {
|
||||
streamcontroller = {
|
||||
Unit = {
|
||||
Description = "Streamcontroller service";
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
After = [ "graphical-session.target" ];
|
||||
Requisite = [ "graphical-session.target" ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
ExecStart = "${pkgs.streamcontroller}/bin/streamcontroller -b";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
|
||||
Install = {
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
wayland.windowManager.hyprland = {
|
||||
enable = true;
|
||||
package = pkgs.hyprland;
|
||||
systemd.enable = false;
|
||||
settings = {
|
||||
"$mainMod" = "SUPER";
|
||||
"$shiftMainMod" = "SUPER_SHIFT";
|
||||
"$term" = "kitty";
|
||||
}
|
||||
// cfg.monitorVariables
|
||||
// {
|
||||
monitor = cfg.monitors;
|
||||
|
||||
input = {
|
||||
kb_layout = "no";
|
||||
follow_mouse = 1;
|
||||
};
|
||||
|
||||
device = optional cfg.enableWacom {
|
||||
name = "wacom-one-by-wacom-m-pen";
|
||||
};
|
||||
|
||||
cursor = optionalAttrs cfg.cursorNoHardware {
|
||||
no_hardware_cursors = true;
|
||||
};
|
||||
|
||||
env = [ "XDG_SESSION_TYPE,wayland" ] ++ cfg.extraEnv;
|
||||
|
||||
decoration = {
|
||||
rounding = 10;
|
||||
blur = {
|
||||
enabled = true;
|
||||
size = 3;
|
||||
passes = 1;
|
||||
xray = true;
|
||||
};
|
||||
};
|
||||
|
||||
general = {
|
||||
gaps_in = 4;
|
||||
gaps_out = 10;
|
||||
border_size = 2;
|
||||
layout = "dwindle";
|
||||
};
|
||||
|
||||
animations = {
|
||||
enabled = true;
|
||||
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
|
||||
animation = [
|
||||
"windows, 1, 7, myBezier"
|
||||
"windowsOut, 1, 7, default, popin 80%"
|
||||
"border, 1, 10, default"
|
||||
"borderangle, 1, 8, default"
|
||||
"fade, 1, 7, default"
|
||||
"workspaces, 1, 6, default"
|
||||
"specialWorkspace, 1, 4, default, fade"
|
||||
];
|
||||
};
|
||||
|
||||
dwindle = {
|
||||
pseudotile = true;
|
||||
preserve_split = true;
|
||||
special_scale_factor = 0.85;
|
||||
};
|
||||
|
||||
master = {
|
||||
new_status = "master";
|
||||
};
|
||||
|
||||
misc = {
|
||||
force_default_wallpaper = 0;
|
||||
disable_hyprland_logo = true;
|
||||
};
|
||||
|
||||
ecosystem = {
|
||||
no_update_news = true;
|
||||
};
|
||||
|
||||
windowrule = [
|
||||
{
|
||||
name = "terminal_opacity";
|
||||
"match:class" = "kitty";
|
||||
opacity = 0.9;
|
||||
}
|
||||
];
|
||||
|
||||
workspace =
|
||||
if cfg.workspaceStrategy == "named" then
|
||||
[
|
||||
"name:T1, monitor:$mon_top, persistent:true, default:true"
|
||||
"name:T2, monitor:$mon_top, persistent:true, default:false"
|
||||
"name:L1, monitor:$mon_left, persistent:true, default:true"
|
||||
"name:L2, monitor:$mon_left, persistent:true, default:false"
|
||||
"name:R1, monitor:$mon_right, persistent:true, default:true"
|
||||
"name:R2, monitor:$mon_right, persistent:true, default:false"
|
||||
"name:c1, monitor:$mon_center, persistent:true, default:true"
|
||||
"name:c2, monitor:$mon_center, persistent:true, default:false"
|
||||
"name:c3, monitor:$mon_center, persistent:true, default:false"
|
||||
"name:c4, monitor:$mon_center, persistent:true, default:false"
|
||||
"special:special, on-created-empty:kitty, rounding:true, decorate:false, border:false"
|
||||
]
|
||||
else
|
||||
[ "special:special, on-created-empty:kitty, rounding:true, decorate:false, border:false" ];
|
||||
|
||||
bindm = [
|
||||
"$mainMod,mouse:272,movewindow"
|
||||
"$shiftMainMod,mouse:272,resizewindow"
|
||||
];
|
||||
|
||||
bind = [
|
||||
# term
|
||||
"$mainMod,Return,exec,$term"
|
||||
# rofi
|
||||
"$mainMod,D,exec,rofi-launcher"
|
||||
"$mainMod,P,exec,rofi-rbw"
|
||||
# hyprlock
|
||||
"$shiftMainMod,l,exec,${
|
||||
if cfg.useLockHelper then
|
||||
"${pkgs.callPackage ../scripts/lockhelper.nix { }}/bin/lockhelper"
|
||||
else
|
||||
"${pkgs.hyprlock}/bin/hyprlock"
|
||||
}"
|
||||
# hyprland
|
||||
"$mainMod,Q,killactive,"
|
||||
"CTRLALT,Delete,exit,"
|
||||
"$mainMod,Space,togglefloating,"
|
||||
"$mainMod,F,fullscreen,"
|
||||
# focus
|
||||
"$mainMod,l,movefocus,l"
|
||||
"$mainMod,h,movefocus,r"
|
||||
"$mainMod,k,movefocus,u"
|
||||
"$mainMod,j,movefocus,d"
|
||||
# move
|
||||
"$mainMod,h,movewindow,l"
|
||||
"$mainMod,l,movewindow,r"
|
||||
"$mainMod,k,movewindow,u"
|
||||
"$mainMod,j,movewindow,d"
|
||||
# Force opacity
|
||||
"$shiftMainMod,o,exec, hl-no-opacity"
|
||||
]
|
||||
++ cfg.extraKeybinds
|
||||
++ (
|
||||
if cfg.workspaceStrategy == "numbered" then
|
||||
[
|
||||
"$mainMod,1,workspace,1"
|
||||
"$mainMod,2,workspace,2"
|
||||
"$mainMod,3,workspace,3"
|
||||
"$mainMod,4,workspace,4"
|
||||
"$mainMod,5,workspace,5"
|
||||
"$mainMod,6,workspace,6"
|
||||
"$shiftMainMod,1,movetoworkspace,1"
|
||||
"$shiftMainMod,2,movetoworkspace,2"
|
||||
"$shiftMainMod,3,movetoworkspace,3"
|
||||
"$shiftMainMod,4,movetoworkspace,4"
|
||||
"$shiftMainMod,5,movetoworkspace,5"
|
||||
"$shiftMainMod,5,movetoworkspace,6"
|
||||
]
|
||||
else
|
||||
[
|
||||
"$mainMod,1,workspace,name:c1"
|
||||
"$mainMod,2,workspace,name:c2"
|
||||
"$mainMod,3,workspace,name:c3"
|
||||
"$mainMod,4,workspace,name:c4"
|
||||
"$mainMod,5,workspace,5"
|
||||
"$mainMod,6,workspace,6"
|
||||
"$shiftMainMod,1,movetoworkspace,name:c1"
|
||||
"$shiftMainMod,2,movetoworkspace,name:c2"
|
||||
"$shiftMainMod,3,movetoworkspace,name:c3"
|
||||
"$shiftMainMod,4,movetoworkspace,name:c4"
|
||||
"$shiftMainMod,5,movetoworkspace,5"
|
||||
"$shiftMainMod,6,movetoworkspace,6"
|
||||
]
|
||||
)
|
||||
++ [
|
||||
# Special workspace
|
||||
"$mainMod,c,togglespecialworkspace"
|
||||
"$shiftMainMod,c,movetoworkspace, special"
|
||||
];
|
||||
|
||||
exec-once = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user