diff --git a/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix b/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix index 1f88f00..e9e0071 100755 --- a/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix +++ b/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix @@ -31,14 +31,24 @@ in programs.hyprland = { enable = true; primaryDisplay = "eDP-1"; - display1 = display; - wallpaper = [ - "${display.input}, /run/wallpaper.jpg" - ]; - - monitor = [ - "${display.input},${display.resolution}@${display.refreshRate},0x0,1.25,bitdepth,10,cm,hdr,sdrbrightness,1.2,sdrsaturation,0.98" + monitorv2 = [ + { + name = display.input; + mode = "${display.resolution}@${display.refreshRate}"; + position = "0x0"; + scale = 1.25; + extra = [ + "bitdepth" + "10" + "cm" + "hdr" + "sdrbrightness" + "1.2" + "sdrsaturation" + "0.98" + ]; + } ]; workspace = [ @@ -50,6 +60,17 @@ in windowRule = [ "size 2160 3356, tag:horizonrdp" ]; + + hyprpaper = { + wallpaperPath = "/run/wallpaper.jpg"; + }; + + keybinds = { + bind = [ + "$mod, A, exec, chromium --app=\"https://music.apple.com\"" + ]; + }; + defaultApps = { browser = pkgs.firefox; }; diff --git a/homes/x86_64-linux/matt@matt-nixos/default.nix b/homes/x86_64-linux/matt@matt-nixos/default.nix index d9900c7..2160828 100755 --- a/homes/x86_64-linux/matt@matt-nixos/default.nix +++ b/homes/x86_64-linux/matt@matt-nixos/default.nix @@ -33,14 +33,39 @@ in enable = true; primaryDisplay = "DP-1"; - wallpaper = [ - "${displayLeft.input}, /run/wallpaper.jpg" - "${displayRight.input}, /run/wallpaper.jpg" - ]; - - monitor = [ - "${displayLeft.input},${displayLeft.resolution}@${displayLeft.refreshRate},0x0,1,bitdepth,10,cm,hdr,sdrbrightness,1.2,sdrsaturation,0.98" - "${displayRight.input},${displayRight.resolution}@${displayRight.refreshRate},3840x0,1,bitdepth,10,cm,hdr,sdrbrightness,1.5,sdrsaturation,0.98" + monitorv2 = [ + { + name = displayLeft.input; + mode = "${displayLeft.resolution}@${displayLeft.refreshRate}"; + position = "0x0"; + scale = 1.0; + extra = [ + "bitdepth" + "10" + "cm" + "hdr" + "sdrbrightness" + "1.2" + "sdrsaturation" + "0.98" + ]; + } + { + name = displayRight.input; + mode = "${displayRight.resolution}@${displayRight.refreshRate}"; + position = "3840x0"; + scale = 1.0; + extra = [ + "bitdepth" + "10" + "cm" + "hdr" + "sdrbrightness" + "1.5" + "sdrsaturation" + "0.98" + ]; + } ]; workspace = [ @@ -53,12 +78,24 @@ in "size 2160 7680, tag:horizonrdp" ]; - extraConfig = '' - exec-once = [silent] firefox - exec-once = [silent] vesktop - exec-once = [silent] chromium --app="https://music.apple.com" - exec-once = [silent] steam - ''; + autostartCommands = [ + "[silent] firefox" + "[silent] vesktop" + "[silent] chromium --app=\"https://music.apple.com\"" + "[silent] steam" + ]; + + hyprpaper = { + wallpaperPath = "/run/wallpaper.jpg"; + }; + + keybinds = { + bind = [ + "$mod, A, exec, chromium --app=\"https://music.apple.com\"" + "$mod, C, exec, vesktop" + "$mod, G, exec, steam" + ]; + }; defaultApps = { browser = pkgs.firefox; diff --git a/modules/home/programs/hyprland/default.nix b/modules/home/programs/hyprland/default.nix index a5335b5..a9bd83d 100644 --- a/modules/home/programs/hyprland/default.nix +++ b/modules/home/programs/hyprland/default.nix @@ -17,64 +17,62 @@ in config = mkIf cfg.enable { # Home packages - home.packages = with pkgs; [ - box64 - brightnessctl - ddcutil - dunst - egl-wayland - file-roller - glib - gnome-calculator - gnome-calendar - gnome-disk-utility - gnome-firmware - gnome-firmware-updater - gnome-font-viewer - gnome-logs - gnome-photos - gnome-tweaks - gnome-weather - gsettings-desktop-schemas - hyprcursor - hyprland - hyprpaper - hyprshot - hyprsysteminfo - kdePackages.qtmultimedia - libnotify - libz - mako - meson - nautilus - nomacs - nwg-look - overskride - pamixer - pavucontrol - playerctl - polkit - polkit_gnome - qt5.qtwayland - qt6.qtwayland - rofi - waybar - wayland-protocols - wayland-utils - waypaper - wev - wl-clipboard - wlogout - wlroots - xdg-desktop-portal-hyprland - xdg-desktop-portal-gtk - xdg-desktop-portal-wlr - xorg.xhost - xsettingsd - xwayland + home.packages = + with pkgs; + ( + [ + box64 + brightnessctl + ddcutil + egl-wayland + file-roller + glib + gnome-calculator + gnome-calendar + gnome-disk-utility + gnome-firmware + gnome-firmware-updater + gnome-font-viewer + gnome-logs + gnome-photos + gnome-tweaks + gnome-weather + gsettings-desktop-schemas + hyprcursor + hyprland + hyprpaper + hyprshot + hyprsysteminfo + kdePackages.qtmultimedia + libnotify + libz + meson + nautilus + nomacs + nwg-look + overskride + pamixer + pavucontrol + playerctl + qt5.qtwayland + qt6.qtwayland + waybar + wayland-protocols + wayland-utils + waypaper + wev + wl-clipboard + wlogout + wlroots + xorg.xhost + xsettingsd + xwayland - pkgs.mjallen.pipewire-python - ]; + pkgs.mjallen.pipewire-python + ] + ++ (if cfg.notificationDaemon == "mako" then [ mako ] else [ dunst ]) + ++ (if cfg.launcher == "wofi" then [ wofi ] else [ rofi ]) + ); # Session variables home.sessionVariables = { @@ -114,11 +112,23 @@ in hyprpaper = { enable = true; settings = { - preload = [ "/run/wallpaper.jpg" ]; - wallpaper = [ - "${cfg.display1.input}, /run/wallpaper.jpg" - "${cfg.display2.input}, /run/wallpaper.jpg" - ]; + preload = [ cfg.hyprpaper.wallpaperPath ]; + wallpaper = + let + useMonitorV2 = (lib.versionAtLeast pkgs.hyprland.version "0.40.0") && (cfg.monitorv2 != [ ]); + names = + if useMonitorV2 then + map (m: m.name) cfg.monitorv2 + else + [ + cfg.display1.input + cfg.display2.input + ]; + in + if cfg.hyprpaper.usePerMonitor then + map (n: "${n}, ${cfg.hyprpaper.wallpaperPath}") names + else + [ ", ${cfg.hyprpaper.wallpaperPath}" ]; splash = false; }; }; @@ -139,16 +149,16 @@ in # on-resume = "brightnessctl -r"; # monitor backlight restore. # } { - timeout = 900; # 15 min + timeout = cfg.hyprIdle.lockScreenTimer; on-timeout = "loginctl lock-session"; # lock screen when timeout has passed } { - timeout = 930; # 15.5 min + timeout = cfg.hyprIdle.screenOffTimer; on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired. } { - timeout = 3600; # 1hr + timeout = cfg.hyprIdle.suspendTimer; on-timeout = "systemctl suspend"; # suspend pc } ]; @@ -212,367 +222,410 @@ in # hyprgrass ]; - settings = { - "$mod" = "SUPER"; + settings = + let + useMonitorV2 = (lib.versionAtLeast pkgs.hyprland.version "0.40.0") && (cfg.monitorv2 != [ ]); + names = + if useMonitorV2 then + map (m: m.name) cfg.monitorv2 + else + [ + cfg.display1.input + cfg.display2.input + ]; + firstMonitor = builtins.elemAt names 0; + secondMonitor = if builtins.length names > 1 then builtins.elemAt names 1 else firstMonitor; + in + { + "$mod" = cfg.modKey; - # Mouse - # mouse_[up|down] - scroll wheel - # middle_mouse - 274 - # thumb_up - 276 - # thumb_down - 275 + # Mouse + # mouse_[up|down] - scroll wheel + # middle_mouse - 274 + # thumb_up - 276 + # thumb_down - 275 - # l -> locked, will also work when an input inhibitor (e.g. a lockscreen) is active. - # r -> release, will trigger on release of a key. - # e -> repeat, will repeat when held. - # n -> non-consuming, key/mouse events will be passed to the active window in addition to triggering the dispatcher. - # m -> mouse, see below. - # t -> transparent, cannot be shadowed by other binds. - # i -> ignore mods, will ignore modifiers. - # s -> separate, will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos) above. - # d -> has description, will allow you to write a description for your bind. - # p -> bypasses the app's requests to inhibit keybinds. + # l -> locked, will also work when an input inhibitor (e.g. a lockscreen) is active. + # r -> release, will trigger on release of a key. + # e -> repeat, will repeat when held. + # n -> non-consuming, key/mouse events will be passed to the active window in addition to triggering the dispatcher. + # m -> mouse, see below. + # t -> transparent, cannot be shadowed by other binds. + # i -> ignore mods, will ignore modifiers. + # s -> separate, will arbitrarily combine keys between each mod/key, see [Keysym combos](#keysym-combos) above. + # d -> has description, will allow you to write a description for your bind. + # p -> bypasses the app's requests to inhibit keybinds. - # https://wiki.hyprland.org/Configuring/Binds/ - # https://wiki.hyprland.org/Configuring/Binds/#mouse-buttons + # https://wiki.hyprland.org/Configuring/Binds/ + # https://wiki.hyprland.org/Configuring/Binds/#mouse-buttons - bind = [ - "$mod, Return, exec, ${cfg.defaultApps.terminal.pname}" - "$mod, SPACE, exec, wofi --show drun" - ", xf86Search, exec, wofi --show drun" - "$mod, Q, killactive, " - "$mod, M, exec, wlogout --protocol layer-shell" - "$mod, E, exec, ${cfg.defaultApps.fileExplorer.pname}" - "$mod, V, togglefloating, " - "$mod, D, exec, ${drawer}" - "$mod, P, pseudo, " # dwindle - "$mod, S, togglesplit, " # dwindle - "$mod SHIFT, Q, exec, hyprlock" - "$mod SHIFT, 4, exec, hyprshot -m region --clipboard-only" - "$mod, F, fullscreen, 1" - "$mod SHIFT, F, fullscreen, 0" - "$mod SHIFT, E, exec, smile" + bind = [ + "$mod, Return, exec, ${cfg.defaultApps.terminal.pname}" + "$mod, SPACE, exec, ${if cfg.launcher == "wofi" then "wofi --show drun" else "rofi -show drun"}" + ", xf86Search, exec, ${if cfg.launcher == "wofi" then "wofi --show drun" else "rofi -show drun"}" + "$mod, Q, killactive, " + "$mod, M, exec, wlogout --protocol layer-shell" + "$mod, E, exec, ${cfg.defaultApps.fileExplorer.pname}" + "$mod, V, togglefloating, " + "$mod, D, exec, ${drawer}" + "$mod, P, pseudo, " # dwindle + "$mod, S, togglesplit, " # dwindle + "$mod SHIFT, Q, exec, hyprlock" + "$mod SHIFT, 4, exec, hyprshot -m region --clipboard-only" + "$mod, F, fullscreen, 1" + "$mod SHIFT, F, fullscreen, 0" + "$mod SHIFT, E, exec, smile" - "$mod, mouse:276, movecurrentworkspacetomonitor, ${cfg.display1.input}" - "$mod, mouse:275, movecurrentworkspacetomonitor, ${cfg.display2.input}" + "$mod, mouse:276, movecurrentworkspacetomonitor, ${firstMonitor}" + "$mod, mouse:275, movecurrentworkspacetomonitor, ${secondMonitor}" - # alt-tab between workspaces on active monitor - "$mod, Tab, workspace, m+1" - "$mod SHIFT, Tab, workspace, m-1" + # alt-tab between workspaces on active monitor + "$mod, Tab, workspace, m+1" + "$mod SHIFT, Tab, workspace, m-1" - "$mod, h, movefocus, l" - "$mod, l, movefocus, r" - "$mod, k, movefocus, u" - "$mod, j, movefocus, d" + "$mod, h, movefocus, l" + "$mod, l, movefocus, r" + "$mod, k, movefocus, u" + "$mod, j, movefocus, d" - "$mod, 1, workspace, 1" - "$mod, 2, workspace, 2" - "$mod, 3, workspace, 3" - "$mod, 4, workspace, 4" - "$mod, 5, workspace, 5" - "$mod, 6, workspace, 6" - "$mod, 7, workspace, 7" - "$mod, 8, workspace, 8" - "$mod, 9, workspace, 9" - "$mod, 0, workspace, 10" + "$mod, 1, workspace, 1" + "$mod, 2, workspace, 2" + "$mod, 3, workspace, 3" + "$mod, 4, workspace, 4" + "$mod, 5, workspace, 5" + "$mod, 6, workspace, 6" + "$mod, 7, workspace, 7" + "$mod, 8, workspace, 8" + "$mod, 9, workspace, 9" + "$mod, 0, workspace, 10" - "$mod ALT, 1, movetoworkspace, 1" - "$mod ALT, 2, movetoworkspace, 2" - "$mod ALT, 3, movetoworkspace, 3" - "$mod ALT, 4, movetoworkspace, 4" - "$mod ALT, 5, movetoworkspace, 5" - "$mod ALT, 6, movetoworkspace, 6" - "$mod ALT, 7, movetoworkspace, 7" - "$mod ALT, 8, movetoworkspace, 8" - "$mod ALT, 9, movetoworkspace, 9" - "$mod ALT, 0, movetoworkspace, discord" + "$mod ALT, 1, movetoworkspace, 1" + "$mod ALT, 2, movetoworkspace, 2" + "$mod ALT, 3, movetoworkspace, 3" + "$mod ALT, 4, movetoworkspace, 4" + "$mod ALT, 5, movetoworkspace, 5" + "$mod ALT, 6, movetoworkspace, 6" + "$mod ALT, 7, movetoworkspace, 7" + "$mod ALT, 8, movetoworkspace, 8" + "$mod ALT, 9, movetoworkspace, 9" + "$mod ALT, 0, movetoworkspace, discord" - "$mod CTRL, l, resizeactive, 10 0" - "$mod CTRL, h, resizeactive, -10 0" - "$mod CTRL, k, resizeactive, 0 -10" - "$mod CTRL, j, resizeactive, 0 10" + "$mod CTRL, l, resizeactive, 10 0" + "$mod CTRL, h, resizeactive, -10 0" + "$mod CTRL, k, resizeactive, 0 -10" + "$mod CTRL, j, resizeactive, 0 10" - "$mod SHIFT, l, movewindow, r" - "$mod SHIFT, h, movewindow, l" - "$mod SHIFT, k, movewindow, u" - "$mod SHIFT, j, movewindow, d" + "$mod SHIFT, l, movewindow, r" + "$mod SHIFT, h, movewindow, l" + "$mod SHIFT, k, movewindow, u" + "$mod SHIFT, j, movewindow, d" - "$mod, b, exec, ${cfg.defaultApps.browser.pname}" - ]; + "$mod, b, exec, ${cfg.defaultApps.browser.pname}" + ] + ++ cfg.keybinds.bind; - bindm = [ - # Move/resize windows with mod + LMB/RMB and dragging - "$mod, mouse:272, movewindow" - "$mod, mouse:273, resizewindow" - # middle mouse will grab a window, mod + middle mouse will close it - "$mod SHIFT, mouse:274, movewindow" - ]; + bindm = [ + # Move/resize windows with mod + LMB/RMB and dragging + "$mod, mouse:272, movewindow" + "$mod, mouse:273, resizewindow" + # middle mouse will grab a window, mod + middle mouse will close it + "$mod SHIFT, mouse:274, movewindow" + ] + ++ cfg.keybinds.bindm; - bindel = [ - ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+" - ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" - ]; + bindel = [ + ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+" + ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" + ] + ++ cfg.keybinds.bindel; - bindl = [ - ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" - ", XF86AudioPlay, exec, playerctl play-pause" - ", XF86AudioPrev, exec, playerctl previous" - ", XF86AudioNext, exec, playerctl next" - ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" + bindl = [ + ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ", XF86AudioPlay, exec, playerctl play-pause" + ", XF86AudioPrev, exec, playerctl previous" + ", XF86AudioNext, exec, playerctl next" + ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" - ", XF86MonBrightnessUp, exec, brightnessctl set +5%" - ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" + ", XF86MonBrightnessUp, exec, brightnessctl set +5%" + ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" - "$mod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight set +10%" - "$mod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight set 10%-" - ]; + "$mod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight set +10%" + "$mod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight set 10%-" + ] + ++ cfg.keybinds.bindl; - monitor = cfg.monitor; - monitorv2 = cfg.monitorv2 or { }; + monitor = cfg.monitor; + monitorv2 = map ( + m: + if m.disabled then + "${m.name}, disable" + else if m.mirrorOf != null then + "${m.name}, mirror, ${m.mirrorOf}" + else + let + mode = if m.mode == null then "preferred" else m.mode; + position = if m.position == null then "auto" else m.position; + scale = if m.scale == null then "1" else (toString m.scale); + transform = if m.transform == null then "auto" else m.transform; + base = [ + m.name + mode + position + scale + transform + ]; + line = builtins.concatStringsSep ", " (base ++ m.extra); + in + line + ) cfg.monitorv2; - render = { - cm_fs_passthrough = 1; - }; + render = { + cm_fs_passthrough = 1; + }; - misc = { - vrr = 1; - force_default_wallpaper = 0; - }; + misc = { + vrr = if cfg.enableVRR then 1 else 0; + force_default_wallpaper = 0; + }; - general = { - gaps_in = 5; - gaps_out = 10; - border_size = 1; - "col.active_border" = "rgb(8aadf4) rgb(24273A) rgb(24273A) rgb(8aadf4) 45deg"; - "col.inactive_border" = "rgb(24273A) rgb(24273A) rgb(24273A) rgb(24273A) 45deg"; - layout = "dwindle"; - allow_tearing = true; - }; + general = { + gaps_in = 5; + gaps_out = 10; + border_size = 1; + "col.active_border" = "rgb(8aadf4) rgb(24273A) rgb(24273A) rgb(8aadf4) 45deg"; + "col.inactive_border" = "rgb(24273A) rgb(24273A) rgb(24273A) rgb(24273A) 45deg"; + layout = "dwindle"; + allow_tearing = cfg.allowTearing; + }; - decoration = { - rounding = 10; - blur = { - enabled = true; - size = 2; - passes = 2; - new_optimizations = true; - xray = false; + decoration = { + rounding = 10; + blur = { + enabled = true; + size = 2; + passes = 2; + new_optimizations = true; + xray = false; + }; + }; + + animations = { + enabled = "yes"; + bezier = [ + "overshot, 0.05, 0.9, 0.1, 1.05" + "smoothOut, 0.36, 0, 0.66, -0.56" + "smoothIn, 0.25, 1, 0.5, 1" + ]; + animation = [ + "windows, 1, 5, overshot, slide" + "windowsOut, 1, 4, smoothOut, slide" + "windowsMove, 1, 4, default" + "border, 1, 10, default" + "fade, 1, 10, smoothIn" + "fadeDim, 1, 10, smoothIn" + "workspaces, 1, 6, default" + ]; + }; + + dwindle = { + pseudotile = "yes"; + preserve_split = "yes"; + }; + + workspace = cfg.workspace; + + windowrule = [ + "float, title:(file_progress)" + "float, title:(.*[Cc]onfirm.*)" + "float, title:(.*[Dd]ialog.*)" + "float, title:(.*[Dd]ownload.*)" + "float, title:(.*[Nn]otification.*)" + "float, title:(.*[Ee]rror.*)" + "float, title:(.*[Ss]plash.*)" + "float, title:(.*[Cc]onfirmreset.*)" + "float, title:(.*[Ss]ign [Ii]n - .*)" + "float, title:(.*[Oo]pen [Ff]ile.*)" + "float, title:(.*branchdialog.*)" + "float, class:(.*pavucontrol.*)" + "move onscreen cursor 0% 0%, class:(.*pavucontrol.*)" + "float, class:(.*[Oo]verskride.*)" + "float, class:(.*FileRoller.*)" + "float, class:(.*wlogout.*)" + "idleinhibit stayfocused, title:(.*mpv.*)" + + "float, class:(.*nm-connection-editor.*)" + "move onscreen cursor 0% 0%, class:(.*nm-connection-editor.*)" + + "float, title:(Media viewer)" + "float, class:(it.mijorus.smile),title:(Smile)" + "float, class:(.blueman-manager-wrapped)$,title:(Bluetooth Devices)" + # Picture in picture windows + "float, title:(.*Picture-in-Picture.*)" + "pin, title::(.*Picture-in-Picture.*)" + + # discord/vesktop + "workspace: name:discord, class:(.*vesktop)" + "float, class:(.*vesktop),title:(.*Discord Popout.*)" + "pin, class:(.*vesktop),title:(.*Discord Popout.*)" + + # Music + "workspace: name:discord, class:(Apple Music.*)" + + # Steam + "float, class:(.*[Ss]team), title:(.*[Ss]team.*)$" + "workspace name:steam silent, class:(.*[Ss]team), title:(.*[Ss]team.*)$" + "tile, class:(.*[Ss]team), title:(.*[Ss]team.*)$" + "float, class:(.*steam),title:(.*Friends List.*)" + + # Code + "pin, class:(.*codium.*),title:(Save As)" + "float, class:(.*codium.*),title:(Save As)" + "float, class:(xdg-desktop-portal-gtk),title:(Open Workspace from File)" + + # Game Tearing??? https://wiki.hypr.land/Configuring/Tearing/ + "immediate, class:(.*gamescope)" + + # vmware + # this tag will set the below options to the vdi window + # this will have it auto open as a 2160x7680 window + # and makes multi-monitor work + "tag +horizonrdp, class:(.*[Hh]orizon-client),title:(USPS Next VDI)" + + "noanim, tag:horizonrdp" + "noblur, tag:horizonrdp" + "norounding, tag:horizonrdp" + "noshadow, tag:horizonrdp" + "immediate, tag:horizonrdp" + "allowsinput, tag:horizonrdp" + "noborder, tag:horizonrdp" + "nodim, tag:horizonrdp" + "nomaxsize, tag:horizonrdp" + "renderunfocused, tag:horizonrdp" + "idleinhibit, tag:horizonrdp" + "float, tag:horizonrdp" + # float the vmware window cause its annoying to use in fullscreen + "float, class:(.*[Hh]orizon-client),title:([Oo]mnissa [Hh]orizon [Cc]lient)" + + "tag +waydroid, class:([Ww]aydroid.*)" + "float, tag:waydroid" + "pin, tag:waydroid" + ] + ++ cfg.windowRule; + + plugin = { + # touch_gestures = { + # # The default sensitivity is probably too low on tablet screens, + # # I recommend turning it up to 4.0 + # sensitivity = "4.0"; + + # # must be >= 3 + # workspace_swipe_fingers = "3"; + + # # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers + # # and can be used at the same time + # # possible values: l, r, u, or d + # # to disable it set it to anything else + # workspace_swipe_edge = "d"; + + # # in milliseconds + # long_press_delay = "400"; + + # # resize windows by long-pressing on window borders and gaps. + # # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating + # # windows + # resize_on_border_long_press = true; + + # # in pixels, the distance from the edge that is considered an edge + # edge_margin = "10"; + + # # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe. + # # ONLY triggers when finger count is equal to workspace_swipe_fingers + # # + # # might be removed in the future in favor of event hooks + # emulate_touchpad_swipe = false; + + # experimental = { + # # send proper cancel events to windows instead of hacky touch_up events, + # # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default + # send_cancel = "0"; + # }; + + # hyprgrass-bind = [ + # # swipe left from right edge + # ", edge:r:l, workspace, +1" + + # # swipe up from bottom edge + # ", edge:d:u, exec, ${cfg.defaultApps.browser.pname}" + + # # swipe down from left edge + # ", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%" + + # # swipe down with 4 fingers + # ", swipe:4:d, killactive" + + # # swipe diagonally left and down with 3 fingers + # # l (or r) must come before d and u + # ", swipe:3:ld, exec, foot" + + # # tap with 3 fingers + # ", tap:3, exec, foot" + + # # longpress can trigger mouse binds: + # ", longpress:2, movewindow" + # ", longpress:3, resizewindow" + # ]; + # }; + }; + + gesture = [ + "3, horizontal, scale: 0.75, workspace" # swipe 3 fingers to change workspace + "3, pinch, mod: SUPER, resize" + "4, pinch, fullscreen" + ]; + + input = { + kb_layout = "us"; + + kb_variant = ""; + kb_model = ""; + kb_options = ""; + kb_rules = ""; + + numlock_by_default = true; + + follow_mouse = 1; + + touchpad = { + clickfinger_behavior = 1; + natural_scroll = "yes"; + }; + + sensitivity = 0; # -1.0 - 1.0, 0 means no modification. + }; + + experimental = { + xx_color_management_v4 = true; + }; + + debug = { + full_cm_proto = cfg.debug.fullCmProto; + disable_logs = cfg.debug.disableLogs; + disable_scale_checks = cfg.debug.disableScaleChecks; }; }; - animations = { - enabled = "yes"; - bezier = [ - "overshot, 0.05, 0.9, 0.1, 1.05" - "smoothOut, 0.36, 0, 0.66, -0.56" - "smoothIn, 0.25, 1, 0.5, 1" - ]; - animation = [ - "windows, 1, 5, overshot, slide" - "windowsOut, 1, 4, smoothOut, slide" - "windowsMove, 1, 4, default" - "border, 1, 10, default" - "fade, 1, 10, smoothIn" - "fadeDim, 1, 10, smoothIn" - "workspaces, 1, 6, default" - ]; - }; - - dwindle = { - pseudotile = "yes"; - preserve_split = "yes"; - }; - - workspace = cfg.workspace; - - windowrule = [ - "float, title:(file_progress)" - "float, title:(.*[Cc]onfirm.*)" - "float, title:(.*[Dd]ialog.*)" - "float, title:(.*[Dd]ownload.*)" - "float, title:(.*[Nn]otification.*)" - "float, title:(.*[Ee]rror.*)" - "float, title:(.*[Ss]plash.*)" - "float, title:(.*[Cc]onfirmreset.*)" - "float, title:(.*[Ss]ign [Ii]n - .*)" - "float, title:(.*[Oo]pen [Ff]ile.*)" - "float, title:(.*branchdialog.*)" - "float, class:(.*pavucontrol.*)" - "move onscreen cursor 0% 0%, class:(.*pavucontrol.*)" - "float, class:(.*[Oo]verskride.*)" - "float, class:(.*FileRoller.*)" - "float, class:(.*wlogout.*)" - "idleinhibit stayfocused, title:(.*mpv.*)" - - "float, class:(.*nm-connection-editor.*)" - "move onscreen cursor 0% 0%, class:(.*nm-connection-editor.*)" - - "float, title:(Media viewer)" - "float, class:(it.mijorus.smile),title:(Smile)" - "float, class:(.blueman-manager-wrapped)$,title:(Bluetooth Devices)" - # Picture in picture windows - "float, title:(.*Picture-in-Picture.*)" - "pin, title::(.*Picture-in-Picture.*)" - - # discord/vesktop - "workspace: name:discord, class:(.*vesktop)" - "float, class:(.*vesktop),title:(.*Discord Popout.*)" - "pin, class:(.*vesktop),title:(.*Discord Popout.*)" - - # Music - "workspace: name:discord, class:(Apple Music.*)" - - # Steam - "float, class:(.*[Ss]team), title:(.*[Ss]team.*)$" - "workspace name:steam silent, class:(.*[Ss]team), title:(.*[Ss]team.*)$" - "tile, class:(.*[Ss]team), title:(.*[Ss]team.*)$" - "float, class:(.*steam),title:(.*Friends List.*)" - - # Code - "pin, class:(.*codium.*),title:(Save As)" - "float, class:(.*codium.*),title:(Save As)" - "float, class:(xdg-desktop-portal-gtk),title:(Open Workspace from File)" - - # Game Tearing??? https://wiki.hypr.land/Configuring/Tearing/ - "immediate, class:(.*gamescope)" - - # vmware - # this tag will set the below options to the vdi window - # this will have it auto open as a 2160x7680 window - # and makes multi-monitor work - "tag +horizonrdp, class:(.*[Hh]orizon-client),title:(USPS Next VDI)" - - "noanim, tag:horizonrdp" - "noblur, tag:horizonrdp" - "norounding, tag:horizonrdp" - "noshadow, tag:horizonrdp" - "immediate, tag:horizonrdp" - "allowsinput, tag:horizonrdp" - "noborder, tag:horizonrdp" - "nodim, tag:horizonrdp" - "nomaxsize, tag:horizonrdp" - "renderunfocused, tag:horizonrdp" - "idleinhibit, tag:horizonrdp" - "float, tag:horizonrdp" - # float the vmware window cause its annoying to use in fullscreen - "float, class:(.*[Hh]orizon-client),title:([Oo]mnissa [Hh]orizon [Cc]lient)" - - "tag +waydroid, class:([Ww]aydroid.*)" - "float, tag:waydroid" - "pin, tag:waydroid" - ] - ++ cfg.windowRule; - - plugin = { - # touch_gestures = { - # # The default sensitivity is probably too low on tablet screens, - # # I recommend turning it up to 4.0 - # sensitivity = "4.0"; - - # # must be >= 3 - # workspace_swipe_fingers = "3"; - - # # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers - # # and can be used at the same time - # # possible values: l, r, u, or d - # # to disable it set it to anything else - # workspace_swipe_edge = "d"; - - # # in milliseconds - # long_press_delay = "400"; - - # # resize windows by long-pressing on window borders and gaps. - # # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating - # # windows - # resize_on_border_long_press = true; - - # # in pixels, the distance from the edge that is considered an edge - # edge_margin = "10"; - - # # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe. - # # ONLY triggers when finger count is equal to workspace_swipe_fingers - # # - # # might be removed in the future in favor of event hooks - # emulate_touchpad_swipe = false; - - # experimental = { - # # send proper cancel events to windows instead of hacky touch_up events, - # # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default - # send_cancel = "0"; - # }; - - # hyprgrass-bind = [ - # # swipe left from right edge - # ", edge:r:l, workspace, +1" - - # # swipe up from bottom edge - # ", edge:d:u, exec, ${cfg.defaultApps.browser.pname}" - - # # swipe down from left edge - # ", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%" - - # # swipe down with 4 fingers - # ", swipe:4:d, killactive" - - # # swipe diagonally left and down with 3 fingers - # # l (or r) must come before d and u - # ", swipe:3:ld, exec, foot" - - # # tap with 3 fingers - # ", tap:3, exec, foot" - - # # longpress can trigger mouse binds: - # ", longpress:2, movewindow" - # ", longpress:3, resizewindow" - # ]; - # }; - }; - - gesture = [ - "3, horizontal, scale: 0.75, workspace" # swipe 3 fingers to change workspace - "3, pinch, mod: SUPER, resize" - "4, pinch, fullscreen" - ]; - - input = { - kb_layout = "us"; - - kb_variant = ""; - kb_model = ""; - kb_options = ""; - kb_rules = ""; - - numlock_by_default = true; - - follow_mouse = 1; - - touchpad = { - clickfinger_behavior = 1; - natural_scroll = "yes"; - }; - - sensitivity = 0; # -1.0 - 1.0, 0 means no modification. - }; - - experimental = { - xx_color_management_v4 = true; - }; - - debug = { - full_cm_proto = true; - disable_logs = true; - disable_scale_checks = true; - }; - }; - - extraConfig = '' - exec-once = dbus-update-activation-environment --systemd --all - exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP - exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 - exec-once = xhost +SI:localuser:root - exec-once = nwg-look -a - exec-once = nwg-dock-hyprland -d - '' - + cfg.extraConfig or ''''; + extraConfig = + let + autostarts = builtins.concatStringsSep "\n" (map (cmd: "exec-once = ${cmd}") cfg.autostartCommands); + in + '' + exec-once = dbus-update-activation-environment --systemd --all + exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP + exec-once = xhost +SI:localuser:root + '' + + autostarts + + "\n" + + (cfg.extraConfig or ""); }; }; } diff --git a/modules/home/programs/hyprland/options.nix b/modules/home/programs/hyprland/options.nix index d7e219d..a2c9c8d 100644 --- a/modules/home/programs/hyprland/options.nix +++ b/modules/home/programs/hyprland/options.nix @@ -14,19 +14,19 @@ with lib; input = mkOption { type = types.str; default = "DP-1"; - description = "First display identifier"; + description = "First display identifier (Deprecated: prefer monitorv2)"; }; resolution = mkOption { type = types.str; default = "3840x2160"; - description = "First display resolution"; + description = "First display resolution (Deprecated: prefer monitorv2)"; }; refreshRate = mkOption { type = types.str; default = "240.00000"; - description = "First display refresh rate"; + description = "First display refresh rate (Deprecated: prefer monitorv2)"; }; }; @@ -34,38 +34,104 @@ with lib; input = mkOption { type = types.str; default = "DP-1"; - description = "Second display identifier"; + description = "Second display identifier (Deprecated: prefer monitorv2)"; }; resolution = mkOption { type = types.str; default = "3840x2160"; - description = "Second display resolution"; + description = "Second display resolution (Deprecated: prefer monitorv2)"; }; refreshRate = mkOption { type = types.str; default = "240.00000"; - description = "Second display refresh rate"; + description = "Second display refresh rate (Deprecated: prefer monitorv2)"; }; }; + # Deprecated: prefer hyprpaper.* options wallpaper = mkOption { type = with types; listOf str; default = [ ]; - description = "List of hyprland wallpaper configs"; + description = "Deprecated: no longer used; prefer hyprpaper.wallpaperPath and hyprpaper.usePerMonitor."; + }; + + hyprpaper = mkOption { + type = types.submodule { + options = { + wallpaperPath = mkOption { + type = types.str; + default = "/run/wallpaper.jpg"; + description = "Path to the wallpaper used by hyprpaper."; + }; + usePerMonitor = mkOption { + type = types.bool; + default = true; + description = "If true, generate one wallpaper entry per monitor (monitorv2 preferred, falls back to display1/display2)."; + }; + }; + }; + default = { }; + description = "Hyprpaper configuration."; }; monitor = mkOption { type = with types; listOf str; default = [ ]; - description = "List of hyprland monitor configs"; + description = "List of Hyprland monitor configs (legacy). Example: [ \"eDP-1, 1920x1080@60, 0x0, 1\" ]"; }; monitorv2 = mkOption { - type = with types; listOf str; + type = + with types; + listOf ( + types.submodule { + options = { + name = mkOption { + type = types.str; + description = "Monitor name (e.g., DP-1, eDP-1)."; + }; + mode = mkOption { + type = types.nullOr types.str; + default = null; + description = "Resolution@Hz or keyword (e.g., \"3840x2160@144\" or \"preferred\")."; + }; + position = mkOption { + type = types.nullOr types.str; + default = null; + description = "Position like \"0x0\" or \"auto\"."; + }; + scale = mkOption { + type = types.nullOr types.float; + default = null; + description = "Scale factor (e.g., 1.0)."; + }; + transform = mkOption { + type = types.nullOr types.str; + default = null; + description = "Rotation/transform (e.g., \"normal\", \"90\", \"180\", \"270\", \"flipped\")."; + }; + disabled = mkOption { + type = types.bool; + default = false; + description = "Disable this monitor."; + }; + mirrorOf = mkOption { + type = types.nullOr types.str; + default = null; + description = "Mirror another monitor by name."; + }; + extra = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Additional monitorv2 flags appended as-is."; + }; + }; + } + ); default = [ ]; - description = "List of hyprland monitorv2 configs"; + description = "Hyprland monitorv2 entries as structured options; rendered to lines like \"name, mode, position, scale, transform, ...\"."; }; workspace = mkOption { @@ -146,6 +212,110 @@ with lib; description = "Default applications used across the system"; }; + autostartCommands = mkOption { + type = with types; listOf str; + default = [ + "nwg-look -a" + "nwg-dock-hyprland -d" + ]; + description = "Commands to run via Hyprland exec-once"; + }; + + launcher = mkOption { + type = types.enum [ + "wofi" + "rofi" + ]; + default = "wofi"; + description = "Application launcher to use in keybinds and packages."; + }; + + notificationDaemon = mkOption { + type = types.enum [ + "mako" + "dunst" + ]; + default = "mako"; + description = "Notification daemon to install."; + }; + + modKey = mkOption { + type = types.str; + default = "SUPER"; + description = "Modifier key used for Hyprland binds (e.g., SUPER, ALT)."; + }; + + enableVRR = mkOption { + type = types.bool; + default = true; + description = "Enable variable refresh rate (maps to Hyprland misc.vrr)."; + }; + + allowTearing = mkOption { + type = types.bool; + default = true; + description = "Allow tearing (maps to Hyprland general.allow_tearing)."; + }; + + debug = mkOption { + type = types.submodule { + options = { + disableLogs = mkOption { + type = types.bool; + default = false; + description = "Set Hyprland debug.disable_logs."; + }; + fullCmProto = mkOption { + type = types.bool; + default = false; + description = "Set Hyprland debug.full_cm_proto."; + }; + disableScaleChecks = mkOption { + type = types.bool; + default = false; + description = "Set Hyprland debug.disable_scale_checks."; + }; + }; + }; + default = { }; + description = "Hyprland debug flags."; + }; + + keybinds = mkOption { + type = types.submodule { + options = { + bind = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Hyprland bind entries."; + }; + bindm = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Hyprland bindm entries."; + }; + bindel = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Hyprland bindel entries."; + }; + bindl = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Hyprland bindl entries."; + }; + }; + }; + default = { }; + description = "Keybinding lists for Hyprland; useful for host-level overrides."; + }; + + gestures = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Hyprland gesture entries."; + }; + hyprIdle = { lockScreenTimer = mkOption { type = with types; int; diff --git a/modules/nixos/desktop/hyprland/wallpapers/default.nix b/modules/nixos/desktop/hyprland/wallpapers/default.nix index 7810b99..2d2ac7a 100644 --- a/modules/nixos/desktop/hyprland/wallpapers/default.nix +++ b/modules/nixos/desktop/hyprland/wallpapers/default.nix @@ -119,12 +119,12 @@ in enable = true; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; -# before = [ "display-manager.service" ]; -# requiredBy = [ -# "plymouth-quit-wait.service" -# "display-manager.service" -# ]; -# wantedBy = [ "display-manager.service" ]; + # before = [ "display-manager.service" ]; + # requiredBy = [ + # "plymouth-quit-wait.service" + # "display-manager.service" + # ]; + # wantedBy = [ "display-manager.service" ]; path = [ pkgs.bash pkgs.jq diff --git a/modules/nixos/development/default.nix b/modules/nixos/development/default.nix index dbd418b..3dd5110 100644 --- a/modules/nixos/development/default.nix +++ b/modules/nixos/development/default.nix @@ -83,10 +83,5 @@ in dns_enabled = true; }; }; - - # Common development programs - programs = { - nix-ld.enable = lib.mkDefault true; - }; }; } diff --git a/modules/nixos/home/default.nix b/modules/nixos/home/default.nix index 82bd827..f89ed4b 100644 --- a/modules/nixos/home/default.nix +++ b/modules/nixos/home/default.nix @@ -9,7 +9,10 @@ }: let isArm = ("aarch64-linux" == system) || ("aarch64-darwin" == system); - hasDestopEnvironment = config.${namespace}.desktop.cosmic.enable || config.${namespace}.desktop.gnome.enable || config.${namespace}.desktop.hyprland.enable; + hasDestopEnvironment = + config.${namespace}.desktop.cosmic.enable + || config.${namespace}.desktop.gnome.enable + || config.${namespace}.desktop.hyprland.enable; in { diff --git a/modules/nixos/impermanence/default.nix b/modules/nixos/impermanence/default.nix index b4f86ba..0bb0fe9 100755 --- a/modules/nixos/impermanence/default.nix +++ b/modules/nixos/impermanence/default.nix @@ -61,6 +61,12 @@ in "/var/lib/systemd/coredump" "/etc/NetworkManager/system-connections" "/var/lib/tailscale" + { + directory = "/var/lib/wallpapers"; + user = "nobody"; + group = "nobody"; + mode = "u=rwx,g=rwx,o=rx"; + } { directory = "/etc/nix"; user = "root"; diff --git a/modules/nixos/programs/default.nix b/modules/nixos/programs/default.nix index 5223435..7d3a124 100644 --- a/modules/nixos/programs/default.nix +++ b/modules/nixos/programs/default.nix @@ -1,6 +1,15 @@ -{ config, pkgs, lib, namespace, ... }: +{ + config, + pkgs, + lib, + namespace, + ... +}: let - hasDestopEnvironment = config.${namespace}.desktop.cosmic.enable || config.${namespace}.desktop.gnome.enable || config.${namespace}.desktop.hyprland.enable; + hasDestopEnvironment = + config.${namespace}.desktop.cosmic.enable + || config.${namespace}.desktop.gnome.enable + || config.${namespace}.desktop.hyprland.enable; in { programs = { diff --git a/modules/nixos/services/actual/default.nix b/modules/nixos/services/actual/default.nix index 2e4b553..c201b1f 100644 --- a/modules/nixos/services/actual/default.nix +++ b/modules/nixos/services/actual/default.nix @@ -40,7 +40,7 @@ let group = "actual"; home = cfg.dataDir; }; - users.groups.actual = {}; + users.groups.actual = { }; }; # Create reverse proxy configuration using mkReverseProxy diff --git a/modules/nixos/services/headscale/default.nix b/modules/nixos/services/headscale/default.nix index b881655..b8df9d4 100644 --- a/modules/nixos/services/headscale/default.nix +++ b/modules/nixos/services/headscale/default.nix @@ -1,6 +1,5 @@ { config, - pkgs, lib, namespace, ... @@ -18,7 +17,7 @@ let settings = { server_url = "https://headscale.mjallen.dev:443"; database.sqlite.path = "${cfg.dataDir}/db.sqlite"; - dns ={ + dns = { nameservers.global = [ "1.1.1.1" "8.8.8.8" diff --git a/modules/nixos/services/jellyseerr/default.nix b/modules/nixos/services/jellyseerr/default.nix index 95c2f3c..828e66b 100644 --- a/modules/nixos/services/jellyseerr/default.nix +++ b/modules/nixos/services/jellyseerr/default.nix @@ -6,10 +6,8 @@ }: with lib; let - inherit (lib.${namespace}) mkOpt mkReverseProxyOpt; + inherit (lib.${namespace}) mkOpt; cfg = config.${namespace}.services.jellyseerr; - - jellyseerrPort = 5055; in { options.${namespace}.services.jellyseerr = { @@ -46,6 +44,6 @@ in group = "jellyseerr"; home = cfg.dataDir; }; - users.groups.jellyseerr = {}; + users.groups.jellyseerr = { }; }; } diff --git a/modules/nixos/services/ntfy/default.nix b/modules/nixos/services/ntfy/default.nix index 70a690a..e3df875 100644 --- a/modules/nixos/services/ntfy/default.nix +++ b/modules/nixos/services/ntfy/default.nix @@ -8,8 +8,6 @@ let inherit (lib.${namespace}) mkOpt mkReverseProxyOpt; cfg = config.${namespace}.services.ntfy; - ntfyEnvFile = config.sops.secrets."jallen-nas/ntfy/auth-users".path; - ntfyConfig = { services = { ntfy-sh = { @@ -48,7 +46,7 @@ let group = "ntfy-sh"; home = cfg.dataDir; }; - users.groups.ntfy-sh = {}; + users.groups.ntfy-sh = { }; }; # Create reverse proxy configuration using mkReverseProxy diff --git a/modules/nixos/services/uptimekuma/default.nix b/modules/nixos/services/uptimekuma/default.nix index 3e5052e..7ddbf35 100644 --- a/modules/nixos/services/uptimekuma/default.nix +++ b/modules/nixos/services/uptimekuma/default.nix @@ -1,6 +1,5 @@ { config, - pkgs, lib, namespace, ... diff --git a/overlays/rcon/default.nix b/overlays/rcon/default.nix index 6c0b2a9..23e380a 100644 --- a/overlays/rcon/default.nix +++ b/overlays/rcon/default.nix @@ -1,5 +1,5 @@ { inputs, ... }: -final: prev: { +_final: prev: { rcon = inputs.nixpkgs-stable.legacyPackages.${prev.system}.rcon; open-webui = inputs.nixpkgs-stable.legacyPackages.${prev.system}.open-webui; nextcloud-client = inputs.nixpkgs-stable.legacyPackages.${prev.system}.nextcloud-client; diff --git a/packages/homeassistant/ha-local-llm/default.nix b/packages/homeassistant/ha-local-llm/default.nix index 4822f9f..bf92517 100644 --- a/packages/homeassistant/ha-local-llm/default.nix +++ b/packages/homeassistant/ha-local-llm/default.nix @@ -2,7 +2,6 @@ buildHomeAssistantComponent, python3Packages, fetchFromGitHub, - lib, ... }: buildHomeAssistantComponent rec { diff --git a/systems/x86_64-linux/jallen-nas/services.nix b/systems/x86_64-linux/jallen-nas/services.nix index fca1ec0..485adb7 100755 --- a/systems/x86_64-linux/jallen-nas/services.nix +++ b/systems/x86_64-linux/jallen-nas/services.nix @@ -25,7 +25,10 @@ package = pkgs.postgresql_16; enableTCPIP = true; dataDir = "/media/nas/main/nix-app-data/postgresql"; - ensureDatabases = [ "authentik" "homeassistant" ]; + ensureDatabases = [ + "authentik" + "homeassistant" + ]; ensureUsers = [ { name = "authentik";