diff --git a/home/toph/common/optional/hyprland/binds.nix b/home/toph/common/optional/hyprland/binds.nix new file mode 100644 index 0000000..26e5ee9 --- /dev/null +++ b/home/toph/common/optional/hyprland/binds.nix @@ -0,0 +1,119 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + #INFO: Reference bind flags: https://wiki.hyprland.org/Configuring/Binds/#bind-flags + wayland.windowManager.hyprland.settings = + let + # -- Functions -- + defaultApp = + type: "${pkgs.gtk3}/bin/gtk-launch $(${pkgs.xdg-utils}/bin/xdg-mime query default ${type})"; + exec = script: "${pkgs.fish}/bin/fish ${script}"; + xdg-open = command: "${pkgs.xdg-utils}/bin/xdg-open ${command}"; + + # -- Script Launchers -- + # colorpicker = exec ./scripts/colorpicker.fish; + # lockscreen = exec ./scripts/lockscreen.fish; + # notify = exec ./scripts/notify.fish; + terminal = exec ./scripts/terminal.fish; + # wlogout = exec ./scripts/wlogout.fish; + + # -- Commands or Binaries -- + browser = defaultApp "x-scheme-handler/https"; + editor = "code"; + menu = "${pkgs.walker}/bin/walker --modules applications,ssh"; + files = xdg-open "$HOME"; + pactl = lib.getExe' pkgs.pulseaudio "pactl"; + + #playerctl = lib.getExe pkgs.playerctl; # installed via /home/common/optional/desktops/playerctl.nix + #swaylock = "lib.getExe pkgs.swaylock; + #makoctl = "${config.services.mako.package}/bin/makoctl"; + #gtk-play = "${pkgs.libcanberra-gtk3}/bin/canberra-gtk-play"; + #notify-send = "${pkgs.libnotify}/bin/notify-send"; + + # This shits too long + lowerVol = "XF86AudioLowerVolume"; + raiseVol = "XF86AudioRaiseVolume"; + in + { + ## Mouse Binds ## + bindm = [ + ", mouse:275, movewindow" + ", mouse:276, resizewindow" + ]; + + ## Non-consuming Binds ## + bindn = [ + ]; + + ## Repeat Binds ## + binde = [ + # Resize active window 5 pixels in direction + "SUPER_ALT, left, resizeactive, -20 0" + "SUPER_ALT, right, resizeactive, 20 0" + "SUPER_ALT, up, resizeactive, 0 -20" + "SUPER_ALT, down, resizeactive, 0 20" + + # -- Volume -- + ", ${raiseVol}, exec, ${pactl} set-sink-volume @DEFAULT_SINK@ +5%" + ", ${lowerVol}, exec, ${pactl} set-sink-volume @DEFAULT_SINK@ -5%" + ", ${raiseVol}, exec, ${pactl} set-source-volume @DEFAULT_SOURCE@ +5%" + ", ${lowerVol}, exec, ${pactl} set-source-volume @DEFAULT_SOURCE@ -5%" + ]; + + ## One-shot Binds ## + bind = [ + # -- Terminal -- + "SUPER, T, exec, ${terminal}" + "SUPER_SHIFT, T, exec, ${terminal}" # floating + "SUPER_ALT, T, exec, ${terminal}" # select size? + + # -- Apps -- + "SUPER, F, exec, ${files}" + "SUPER, E, exec, ${editor}" + "SUPER, W, exec, ${browser}" + "SUPER, N, exec, nm-connection-editor" + # "SUPER, P, exec, ${colorpicker}" + + # -- Menu -- + "SUPER, SUPER_L, exec, ${menu}" + # "SUPER, V, exec, ${menu}" + + # -- System -- + # "SUPER, X, exec, ${wlogout}" + # "SUPER, L, exec, ${lockscreen}" + "SUPER, L, exec, hyprlock" + "SUPER, Q, killactive," + "CTRL_ALT, Delete, exit," + + # -- Window Management -- + "SUPER_SHIFT, F, fullscreen, 0" + # "SUPER, F, exec, ${notify} 'Fullscreen Mode'" + "SUPER, Backspace, togglefloating," + "SUPER, Backspace, centerwindow," + "SUPER, left, movefocus, l" + "SUPER, right, movefocus, r" + "SUPER, up, movefocus, u" + "SUPER, down, movefocus, d" + "SUPER_SHIFT, left, movewindow, l" + "SUPER_SHIFT, right, movewindow, r" + "SUPER_SHIFT, up, movewindow, u" + "SUPER_SHIFT, down, movewindow, d" + "SUPER_SHIFT, P, pin," + # "SUPER_SHIFT, P, exec, ${notify} 'Toggled Pin'" + "SUPER_SHIFT, S, swapnext" + # "SUPER_SHIFT, O, toggleopaque" + + # -- Workspaces -- + ", Home, overview:toggle" + # "SUPER, A, " + # TODO: use hycov for alt tab, https://github.com/bighu630/hycov + "ALT, Tab, cyclenext," + "ALT, Tab, bringactivetotop," + ]; + + }; +} diff --git a/home/toph/common/optional/hyprland/default.nix b/home/toph/common/optional/hyprland/default.nix index e69de29..bb8b998 100644 --- a/home/toph/common/optional/hyprland/default.nix +++ b/home/toph/common/optional/hyprland/default.nix @@ -0,0 +1,240 @@ +{ + config, + inputs, + lib, + pkgs, + ... +}: + +{ + imports = lib.custom.scanPaths ./.; + + wayland.windowManager.hyprland = { + enable = true; + # withUWSM = true; # One day, but not today + package = inputs.hyprland.packages."${pkgs.system}".hyprland; + + systemd = { + enable = true; + variables = [ "--all" ]; + extraCommands = lib.mkBefore [ + "systemctl --user stop graphical-session.target" + "systemctl --user start hyprland-session.target" + ]; + }; + + plugins = [ + # inputs.hycov.packages.${pkgs.system}.hycov + (inputs.hyprspace.packages.${pkgs.system}.Hyprspace.overrideAttrs { + dontUseCmakeConfigure = true; + }) + ]; + + settings = { + # + # ========== Environment Vars ========== + # + env = [ + "NIXOS_OZONE_WL, 1" # for ozone-based and electron apps to run on wayland + "MOZ_ENABLE_WAYLAND, 1" # for firefox to run on wayland + "MOZ_WEBRENDER, 1" # for firefox to run on wayland + "XDG_SESSION_TYPE,wayland" + "WLR_NO_HARDWARE_CURSORS,1" + "WLR_RENDERER_ALLOW_SOFTWARE,1" + "QT_QPA_PLATFORM,wayland" + "HYPRCURSOR_THEME,rose-pine-hyprcursor" # this will be better than default for now + ]; + + ## Monitor ## + # parse the monitor spec defined in home///default.nix + monitor = ( + map ( + m: + "${m.name},${ + if m.enabled then + "${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},1,transform,${toString m.transform},vrr,${toString m.vrr}" + else + "disable" + }" + ) (config.monitors) + ); + + #FIXME(hyprland): adapt this to work with new monitor module + #FIXME(hyprland): ws1 still appears on both DP-1 and DP-3 on reboot + # workspace = [ + # "1, monitor:DP-1, default:true, persistent:true" + # "2, monitor:DP-1, default:true" + # "3, monitor:DP-1, default:true" + # "4, monitor:DP-1, default:true" + # "5, monitor:DP-1, default:true" + # "6, monitor:DP-1, default:true" + # "7, monitor:DP-1, default:true" + # "8, monitor:DP-2, default:true, persistent:true" + # "9, monitor:HDMI-A-1, default:true, persistent:true" + # "0, monitor:DP-3, default:true, persistent:true" + # ]; + + # + # ========== Behavior ========== + # + binds = { + workspace_center_on = 1; # Whether switching workspaces should center the cursor on the workspace (0) or on the last active window for that workspace (1) + movefocus_cycles_fullscreen = false; # If enabled, when on a fullscreen window, movefocus will cycle fullscreen, if not, it will move the focus in a direction. + }; + input = { + follow_mouse = 2; + # follow_mouse options: + # 0 - Cursor movement will not change focus. + # 1 - Cursor movement will always change focus to the window under the cursor. + # 2 - Cursor focus will be detached from keyboard focus. Clicking on a window will move keyboard focus to that window. + # 3 - Cursor focus will be completely separate from keyboard focus. Clicking on a window will not change keyboard focus. + mouse_refocus = false; + kb_options = "fkeys:basic_13-24"; + }; + cursor.inactive_timeout = 10; + misc = { + disable_hyprland_logo = true; + animate_manual_resizes = true; + animate_mouse_windowdragging = true; + #disable_autoreload = true; + new_window_takes_over_fullscreen = 2; # 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize + middle_click_paste = false; + }; + + # + # ========== Appearance ========== + # + #FIXME-rice colors conflict with stylix + general = { + gaps_in = 6; + gaps_out = 6; + border_size = 0; + #col.inactive-border = "0x00000000"; + #col.active-border = "0x0000000"; + resize_on_border = true; + hover_icon_on_border = true; + allow_tearing = true; # used to reduce latency and/or jitter in games + }; + decoration = { + active_opacity = 1.0; + inactive_opacity = 0.85; + fullscreen_opacity = 1.0; + rounding = 10; + blur = { + enabled = true; + size = 4; + passes = 2; + new_optimizations = true; + popups = true; + }; + shadow = { + enabled = true; + range = 12; + offset = "3 3"; + #color = "0x88ff9400"; + #color_inactive = "0x8818141d"; + }; + }; + # group = { + #groupbar = { + # }; + #}; + + # + # ========== Auto Launch ========== + # + # exec-once = ''${startupScript}/path''; + # To determine path, run `which foo` + exec-once = [ + ''${pkgs.waypaper}/bin/waypaper --restore'' + ]; + # + # ========== Layer Rules ========== + # + layer = [ + #"blur, rofi" + #"ignorezero, rofi" + #"ignorezero, logout_dialog" + + ]; + # + # ========== Window Rules ========== + # + windowrule = [ + # Dialogs + "float, title:^(Open File)(.*)$" + "float, title:^(Select a File)(.*)$" + "float, title:^(Choose wallpaper)(.*)$" + "float, title:^(Open Folder)(.*)$" + "float, title:^(Save As)(.*)$" + "float, title:^(Library)(.*)$" + "float, title:^(Accounts)(.*)$" + ]; + windowrulev2 = [ + "float, class:^(galculator)$" + "float, class:^(waypaper)$" + "float, class:^(keymapp)$" + + # + # ========== Always opaque ========== + # + "opaque, class:^([Gg]imp)$" + "opaque, class:^([Ff]lameshot)$" + "opaque, class:^([Ii]nkscape)$" + "opaque, class:^([Bb]lender)$" + "opaque, class:^([Oo][Bb][Ss])$" + "opaque, class:^([Ss]team)$" + "opaque, class:^([Ss]team_app_*)$" + "opaque, class:^([Vv]lc)$" + + # Remove transparency from video + "opaque, title:^(Netflix)(.*)$" + "opaque, title:^(.*YouTube.*)$" + "opaque, title:^(Picture-in-Picture)$" + # + # ========== Scratch rules ========== + # + #"size 80% 85%, workspace:^(special:special)$" + #"center, workspace:^(special:special)$" + + # + # ========== Steam rules ========== + # + "stayfocused, title:^()$,class:^([Ss]team)$" + "minsize 1 1, title:^()$,class:^([Ss]team)$" + "immediate, class:^([Ss]team_app_*)$" + "workspace 7, class:^([Ss]team_app_*)$" + "monitor 0, class:^([Ss]team_app_*)$" + + # + # ========== Fameshot rules ========== + # + # flameshot currently doesn't have great wayland support so needs some tweaks + #"rounding 0, class:^([Ff]lameshot)$" + #"noborder, class:^([Ff]lameshot)$" + #"float, class:^([Ff]lameshot)$" + #"move 0 0, class:^([Ff]lameshot)$" + #"suppressevent fullscreen, class:^([Ff]lameshot)$" + # "monitor:DP-1, ${flameshot}" + + # + # ========== Workspace Assignments ========== + # + "workspace 8, class:^(virt-manager)$" + "workspace 8, class:^(obsidian)$" + "workspace 9, class:^(brave-browser)$" + "workspace 9, class:^(signal)$" + "workspace 9, class:^(org.telegram.desktop)$" + "workspace 9, class:^(discord)$" + "workspace 0, title:^([Ss]potify*)$" + "workspace special, class:^(yubioath-flutter)$" + ]; + + # load at the end of the hyperland set + # extraConfig = ''''; + + plugin = { + }; + }; + }; +} diff --git a/home/toph/common/optional/hyprland/dunst.nix b/home/toph/common/optional/hyprland/dunst.nix new file mode 100644 index 0000000..f89960b --- /dev/null +++ b/home/toph/common/optional/hyprland/dunst.nix @@ -0,0 +1,200 @@ +# +# Dunst +# Notification Daemon +# +{ pkgs, ... }: +{ + home.packages = builtins.attrValues { + inherit (pkgs) libnotify; # required by dunst + }; + + services.dunst = { + enable = true; + # waylandDisplay = ""; # set the service's WAYLAND_DISPLAY environment variable + # configFile = ""; + iconTheme = { + name = "Adwaita"; + package = pkgs.adwaita-icon-theme; + size = "16x16"; + }; + settings = { + global = { + # Allow a small subset of html markup:, , , and . + # For a complete reference see + # . + # If markup is not allowed, those tags will be stripped out of the message. + allow_markup = "yes"; + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # Markup is allowed + format = "%I %s %p\\n%b"; + + #TODO dynamic fonts + #font = "Droid Sans 12"; + alignment = "left"; # Options are "left", "center", and "right". + + sort = "yes"; # Sort messages by urgency. + indicate_hidden = "yes"; # Show how many messages are currently hidden (because of geometry). + + # The frequency with which text that is longer than the notification + # window allows bounces back and forth. + # This option conflicts with "word_wrap". + # Set to 0 to disable. + bounce_freq = 5; + + # Show age of message if message is older than show_age_threshold + # seconds. + # Set to -1 to disable. + show_age_threshold = 60; + + # Split notifications into multiple lines if they don't fit into + # geometry. + word_wrap = "no"; + + # Ignore newlines '\n' in notifications. + ignore_newline = "no"; + + # The geometry of the window: + # [{width}]x{height}[+/-{x}+/-{y}] + # The geometry of the message window. + # The height is measured in number of notifications everything else + # in pixels. If the width is omitted but the height is given + # ("-geometry x2"), the message window expands over the whole screen + # (dmenu-like). If width is 0, the window expands to the longest + # message displayed. A positive x is measured from the left, a + # negative from the right side of the screen. Y is measured from + # the top and down respectevly. + # The width can be negative. In this case the actual width is the + # screen width minus the width defined in within the geometry option. + geometry = "0x4-25+25"; + + # Shrink window if it's smaller than the width. Will be ignored if + # width is 0. + shrink = "yes"; + + # Display notification on focused monitor. Possible modes are: + # mouse: follow mouse pointer + # keyboard: follow window with keyboard focus + # none: don't follow anything + # + # "keyboard" needs a windowmanager that exports the _NET_ACTIVE_WINDOW property. + # This should be the case for almost all modern windowmanagers. + # + # If this option is set to mouse or keyboard, the monitor option will be ignored. + follow = "mouse"; + + # Should a notification popped up from history be sticky or timeout + # as if it would normally do. + sticky_history = "yes"; + + # Maximum amount of notifications kept in history + history_length = 20; + + # Display indicators for URLs (U) and actions (A). + show_indicators = "yes"; + + # The height of a single line. If the height is smaller than the + # font height, it will get raised to the font height. + # This adds empty space above and under the text. + line_height = 0; + + # Draw a line of "separator_height" pixel height between two + # notifications. Set to 0 to disable. + separator_height = 1; + + # Padding between text and separator. + padding = 8; + + # Horizontal padding. + horizontal_padding = 10; + + # The transparency of the window. Range: [0; 100]. + # This option will only work if a compositing windowmanager is + # present (e.g. xcompmgr, compiz, etc.). + transparency = 15; + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + # separator_color = "#454947"; + + # Print a notification on startup. + # This is mainly for error detection, since dbus (re-)starts dunst + # automatically after a crash. + + #set to true for debugging + startup_notification = false; + + # Align icons left/right/off + icon_position = "left"; + + width = 300; + height = 300; + offset = "30x50"; + #origin = "top-right"; + origin = "top-center"; + + #TODO dynamic theme colours + # frame_color = "#dc7f41"; + + # Browser for opening urls in context menu. + browser = "firefox"; + }; + + frame = { + width = 2; + #TODO dynamic colours + # color = "#dc7f41"; + }; + + shortcuts = { + # Shortcuts are specified as [modifier+][modifier+]...key + # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2", + # "mod3" and "mod4" (windows-key). + # Xev might be helpful to find names for keys. + + # Close notification. + close = "mod1+space"; + + # Close all notifications. + close_all = "ctrl+mod1+space"; + + # Redisplay last message(s). + history = "ctrl+mod4+h"; + + # Context menu. + context = "ctrl+mod1+c"; + }; + + urgency_low = { + #TODO dynamic colours + # background = "#1e1e20"; + # foreground = "#c5c8c6"; + timeout = 10; + }; + + urgency_normal = { + #TODO dynamic colours + # background = "#1e1e20"; + # foreground = "#c5c8c6"; + timeout = 10; + }; + + urgency_critical = { + #TODO dynamic colours + # background = "#1e1e20"; + # foreground = "#c5c8c6"; + timeout = 0; + }; + }; + }; +} diff --git a/home/toph/common/optional/hyprland/gtk.nix b/home/toph/common/optional/hyprland/gtk.nix new file mode 100644 index 0000000..ab274f0 --- /dev/null +++ b/home/toph/common/optional/hyprland/gtk.nix @@ -0,0 +1,33 @@ +{ + pkgs, + ... +}: + +{ + home.pointerCursor = { + gtk.enable = true; + # x11.enable = true; + package = pkgs.bibata-cursors; + name = "Bibata-Modern-Classic"; + size = 16; + }; + + gtk = { + enable = true; + + theme = { + package = pkgs.flat-remix-gtk; + name = "Flat-Remix-GTK-Grey-Darkest"; + }; + + iconTheme = { + package = pkgs.adwaita-icon-theme; + name = "Adwaita"; + }; + + font = { + name = "Sans"; + size = 14; + }; + }; +} diff --git a/home/toph/common/optional/hyprland/hyprlock.nix b/home/toph/common/optional/hyprland/hyprlock.nix new file mode 100644 index 0000000..808866c --- /dev/null +++ b/home/toph/common/optional/hyprland/hyprlock.nix @@ -0,0 +1,38 @@ +{ lib, ... }: +{ + programs.hyprlock = { + enable = true; + + settings = { + general = { + disable_loading_bar = true; + immediate_render = true; + hide_cursor = false; + no_fade_in = true; + }; + + background = lib.mkDefault [ + { + path = "screenshot"; + blur_passes = 3; + blur_size = 8; + } + ]; + + input-field = lib.mkDefault [ + { + size = "200, 50"; + position = "0, -80"; + monitor = ""; + dots_center = true; + fade_on_empty = false; + font_color = "rgb(202, 211, 245)"; + inner_color = "rgb(91, 96, 120)"; + outer_color = "rgb(24, 25, 38)"; + outline_thickness = 5; + shadow_passes = 2; + } + ]; + }; + }; +} diff --git a/home/toph/common/optional/hyprland/playerctl.nix b/home/toph/common/optional/hyprland/playerctl.nix new file mode 100644 index 0000000..944b52b --- /dev/null +++ b/home/toph/common/optional/hyprland/playerctl.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: +{ + home.packages = [ pkgs.playerctl ]; + services.playerctld = { + enable = true; + }; +} diff --git a/home/toph/common/optional/hyprland/scripts/default.nix b/home/toph/common/optional/hyprland/scripts/default.nix new file mode 100644 index 0000000..ffcd441 --- /dev/null +++ b/home/toph/common/optional/hyprland/scripts/default.nix @@ -0,0 +1 @@ +{ } diff --git a/home/toph/common/optional/hyprland/scripts/terminal.fish b/home/toph/common/optional/hyprland/scripts/terminal.fish new file mode 100644 index 0000000..17c3fb8 --- /dev/null +++ b/home/toph/common/optional/hyprland/scripts/terminal.fish @@ -0,0 +1,3 @@ +#!/usr/bin/env fish + +foot \ No newline at end of file diff --git a/home/toph/vm/default.nix b/home/toph/vm/default.nix index c460343..ac8308e 100644 --- a/home/toph/vm/default.nix +++ b/home/toph/vm/default.nix @@ -9,9 +9,11 @@ ## Host-specific Optional Configs ## ../common/optional/browsers - ../common/optional/gnome - # ../common/optional/development + # ../common/optional/gnome + ../common/optional/hyprland + ../common/optional/development # ../common/optional/gaming + ../common/optional/vscode-server.nix ../common/optional/xdg.nix # file associations ]; @@ -20,7 +22,17 @@ inherit (pkgs) ## Tools ## inspector - wezterm + foot ; }; + + monitors = [ + { + name = "Virtual-1"; + width = 2560; + height = 1440; + refreshRate = 60; + primary = true; + } + ]; } diff --git a/hosts/common/optional/hyprland/default.nix b/hosts/common/optional/hyprland/default.nix new file mode 100644 index 0000000..9c8b88d --- /dev/null +++ b/hosts/common/optional/hyprland/default.nix @@ -0,0 +1,21 @@ +{ + inputs, + pkgs, + lib, + ... +}: +{ + + imports = lib.custom.scanPaths ./.; + + programs.hyprland = { + enable = true; + # withUWSM = true; # One day, but not today + package = inputs.hyprland.packages."${pkgs.system}".hyprland; + portalPackage = inputs.hyprland.packages.${pkgs.system}.xdg-desktop-portal-hyprland; + }; + + environment.systemPackages = [ + inputs.rose-pine-hyprcursor.packages.${pkgs.system}.default + ]; +} diff --git a/hosts/common/optional/hyprland/greetd.nix b/hosts/common/optional/hyprland/greetd.nix new file mode 100644 index 0000000..9da1b4f --- /dev/null +++ b/hosts/common/optional/hyprland/greetd.nix @@ -0,0 +1,35 @@ +# +# greeter -> tuigreet https://github.com/apognu/tuigreet?tab=readme-ov-file +# display manager -> greetd https://man.sr.ht/~kennylevinsen/greetd/ +# + +{ + config, + pkgs, + lib, + ... +}: + +let + hostSpec = config.hostSpec.username; + default = { + command = "${pkgs.greetd.tuigreet}/bin/tuigreet --asterisks --time --time-format '%I:%M %p | %a • %h | %F' --cmd Hyprland"; + user = "toph"; + }; + initial = { + command = "${pkgs.hyprland}/bin/Hyprland"; + user = "toph"; + }; +in +{ + # environment.systemPackages = [ pkgs.greetd.tuigreet ]; + services.greetd = { + enable = true; + + restart = true; + settings = rec { + default_session = default; + initial_session = initial; + }; + }; +} diff --git a/hosts/common/optional/hyprland/wayland.nix b/hosts/common/optional/hyprland/wayland.nix new file mode 100644 index 0000000..e65e74a --- /dev/null +++ b/hosts/common/optional/hyprland/wayland.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + # general packages related to wayland + environment.systemPackages = with pkgs; [ + grim # screen capture component, required by flameshot + waypaper # wayland packages(nitrogen analog for wayland) + swww # backend wallpaper daemon required by waypaper + wl-clipboard-rs + wlr-randr + ]; +} diff --git a/hosts/nixos/vm/default.nix b/hosts/nixos/vm/default.nix index 2f99439..93440ca 100644 --- a/hosts/nixos/vm/default.nix +++ b/hosts/nixos/vm/default.nix @@ -28,7 +28,8 @@ in ## Optional Configs ## "hosts/common/optional/audio.nix" # pipewire and cli controls # "hosts/common/optional/gaming.nix" # steam, gamescope, gamemode, and related hardware - "hosts/common/optional/gnome.nix" # desktop + # "hosts/common/optional/gnome.nix" # desktop + "hosts/common/optional/hyprland" # desktop # "hosts/common/optional/nvtop.nix" # GPU monitor (not available in home-manager) # "hosts/common/optional/plymouth.nix" # fancy boot screen