From 8166894b78b0ed524dd4b8f37dd378f3f9d9efce Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 7 Jul 2025 21:48:12 +0800 Subject: [PATCH 1/3] feat(nix): add desktop module and refactor machine options --- nix/manifest.nix | 15 +-------------- nix/modules/desktop/default.nix | 7 +++++++ nix/modules/machine/default.nix | 6 ++++-- 3 files changed, 12 insertions(+), 16 deletions(-) create mode 100644 nix/modules/desktop/default.nix diff --git a/nix/manifest.nix b/nix/manifest.nix index eb26d1f..cf8f48e 100644 --- a/nix/manifest.nix +++ b/nix/manifest.nix @@ -1,15 +1,3 @@ -let - testCfg = { - machine = { - bluetooth.enable = true; - usb.automount = true; - virtualisation.podman = { - enable = true; - distrobox.enable = true; - }; - }; - }; -in { flake.manifest = { users.rafiq = { @@ -34,14 +22,13 @@ in } ]; }; - extraCfg = testCfg; + extraCfg.desktop.enable = true; }; apollo = { machine = { platform = "intel"; root.drive = "/dev/disk/by-id/nvme-eui.002538d221b47b01"; }; - extraCfg = testCfg; }; }; }; diff --git a/nix/modules/desktop/default.nix b/nix/modules/desktop/default.nix new file mode 100644 index 0000000..3e2c64b --- /dev/null +++ b/nix/modules/desktop/default.nix @@ -0,0 +1,7 @@ +{ lib, ... }: +let + inherit (lib.options) mkEnableOption; +in +{ + flake.modules.nixos.default.options.desktop.enable = mkEnableOption ""; +} diff --git a/nix/modules/machine/default.nix b/nix/modules/machine/default.nix index e657fa2..8ad3f7a 100644 --- a/nix/modules/machine/default.nix +++ b/nix/modules/machine/default.nix @@ -11,8 +11,10 @@ in in { imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; - options.machine.bluetooth.enable = mkEnableOption ""; - options.machine.usb.automount = mkEnableOption ""; + options.machine = { + bluetooth.enable = mkEnableOption ""; + usb.automount = mkEnableOption ""; + }; config = mkMerge [ (mkIf cfg.usb.automount { services.udisks2.enable = true; From c2bae8cd8560daf33f35cea38b702e18fe3f7cfc Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 7 Jul 2025 22:03:14 +0800 Subject: [PATCH 2/3] feat(homes/rafiq): import desktop configs --- flake.lock | 24 +++ flake.nix | 56 +++--- .../rafiq/desktop/_hyprland/decoration.nix | 14 ++ .../rafiq/desktop/_hyprland/keybinds.nix | 56 ++++++ nix/homes/rafiq/desktop/default.nix | 172 ++++++++++++++++++ 5 files changed, 298 insertions(+), 24 deletions(-) create mode 100644 nix/homes/rafiq/desktop/_hyprland/decoration.nix create mode 100644 nix/homes/rafiq/desktop/_hyprland/keybinds.nix create mode 100644 nix/homes/rafiq/desktop/default.nix diff --git a/flake.lock b/flake.lock index 2436ed5..1276e79 100644 --- a/flake.lock +++ b/flake.lock @@ -257,6 +257,29 @@ "type": "github" } }, + "nur": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751894474, + "narHash": "sha256-0TIIRikLAi042jNgd+gLKYCji1p4uetlmm4gROjrlEw=", + "owner": "nix-community", + "repo": "NUR", + "rev": "85c0c20851e9250e587c33023b788f66b608ca36", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, "nvf": { "inputs": { "flake-parts": [ @@ -305,6 +328,7 @@ "make-shell": "make-shell", "nix-index-database": "nix-index-database", "nixpkgs": "nixpkgs", + "nur": "nur", "nvf": "nvf", "sops-nix": "sops-nix", "systems": "systems", diff --git a/flake.nix b/flake.nix index 19d392c..bdb24b8 100644 --- a/flake.nix +++ b/flake.nix @@ -1,34 +1,40 @@ { + outputs = + inputs: + inputs.flake-parts.lib.mkFlake { inherit inputs; } ( + (inputs.import-tree ./nix) + // { + systems = import inputs.systems; + flake.paths.root = ./.; + } + ); inputs = { - # nixos-unstable provides a binary cache for all packages. - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + ### SYSTEM ### + # systems provides a list of supported nix systems. systems.url = "github:nix-systems/default"; + # nixos-unstable provides a binary cache for all packages. + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + # impermanence provides a nice abstraction over linking files from /persist + impermanence.url = "github:nix-community/impermanence"; # flake-parts lets us define flake modules. flake-parts = { url = "github:hercules-ci/flake-parts"; inputs.nixpkgs-lib.follows = "nixpkgs"; }; - # home-manager manages our user packages and dotfiles - home-manager = { - url = "github:nix-community/home-manager"; - inputs.nixpkgs.follows = "nixpkgs"; - }; # disko provides declarative drive partitioning disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; - # impermanence provides a nice abstraction over linking files from /persist - impermanence.url = "github:nix-community/impermanence"; - - ### FLAKE PARTS MODULES ### - # sops-nix lets us version control secrets like passwords and api keys sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + + ### FLAKE PARTS MODULES ### + # import-tree imports all nix files in a given directory. import-tree.url = "github:vic/import-tree"; # files lets us write text files and automatically add checks for them @@ -50,12 +56,24 @@ }; }; - ### PROGRAMS ### + ### HOME-MANAGER ### + + # home-manager manages our user packages and dotfiles + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; # nix-index-database indexes the nixpkgs binaries for use with comma nix-index-database = { url = "github:nix-community/nix-index-database"; inputs.nixpkgs.follows = "nixpkgs"; }; + # the nix user repository for mainly firefox extensions + nur = { + url = "github:nix-community/NUR"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-parts.follows = "flake-parts"; + }; # nvf provides modules to wrap neovim nvf = { url = "github:notashelf/nvf"; @@ -69,7 +87,7 @@ }; ### DEDUPE ### - # The following are not used in the flake + dedupe_flake-compat.url = "github:edolstra/flake-compat"; dedupe_flake-utils = { url = "github:numtide/flake-utils"; @@ -81,14 +99,4 @@ inputs.nixpkgs.follows = "nixpkgs"; }; }; - - outputs = - inputs: - inputs.flake-parts.lib.mkFlake { inherit inputs; } ( - (inputs.import-tree ./nix) - // { - systems = import inputs.systems; - flake.paths.root = ./.; - } - ); } diff --git a/nix/homes/rafiq/desktop/_hyprland/decoration.nix b/nix/homes/rafiq/desktop/_hyprland/decoration.nix new file mode 100644 index 0000000..ee3d444 --- /dev/null +++ b/nix/homes/rafiq/desktop/_hyprland/decoration.nix @@ -0,0 +1,14 @@ +{ + animation = [ "workspaces, 1, 1, default" ]; + general = { + border_size = 2; + gaps_in = 0; + gaps_out = 0; + resize_on_border = true; + }; + decoration = { + rounding = 10; + rounding_power = 2; + inactive_opacity = 0.9; + }; +} diff --git a/nix/homes/rafiq/desktop/_hyprland/keybinds.nix b/nix/homes/rafiq/desktop/_hyprland/keybinds.nix new file mode 100644 index 0000000..9e75db1 --- /dev/null +++ b/nix/homes/rafiq/desktop/_hyprland/keybinds.nix @@ -0,0 +1,56 @@ +{ pkgs, ... }: +{ + "$hypr" = "CTRL_SUPER_ALT_SHIFT"; + "$meh" = "CONTROL_SHIFT_ALT"; + bind = [ + "$hypr, Q, exec, uwsm stop" + "SUPER, W, killactive" + + "SUPER, return, exec, uwsm app -- $TERMINAL" + "SUPER, O, exec, uwsm app -- $BROWSER" + "SUPER, Escape, exec, uwsm app -- $LOCKSCREEN" + #TODO:add file browser + + #TODO: make it directional + "SUPER, H, cyclenext, visible" + "SUPER, L, cyclenext, visible prev" + "SUPER_ALT, H, movewindow, l" + "SUPER_ALT, J, movewindow, d" + "SUPER_ALT, K, movewindow, u" + "SUPER_ALT, L, movewindow, r" + "ALT_SHIFT, H, resizeactive, -10% 0" + "ALT_SHIFT, J, resizeactive, 0 -10%" + "ALT_SHIFT, K, resizeactive, 0 10%" + "ALT_SHIFT, L, resizeactive, 10% 0" + "SUPER_CTRL, H, workspace, r-1" + "SUPER_CTRL, L, workspace, r+1" + "$hypr, H, movetoworkspace, r-1" + "$hypr, L, movetoworkspace, r+1" + + "$hypr, V, togglefloating" + ]; + + bindr = [ + # Activates on SUPER without any other modifier + "SUPER, Super_L, exec, uwsm app -- $($LAUNCHER --launch-prefix=\"uwsm app -- \")" + ]; + + bindle = [ + "SUPER, 6, exec, ${pkgs.wireplumber}/bin/wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-" + "SUPER, 7, exec, ${pkgs.playerctl}/bin/playerctl previous" + "SUPER, 8, exec, ${pkgs.playerctl}/bin/playerctl -a play-pause" + "SUPER, 9, exec, ${pkgs.playerctl}/bin/playerctl next" + "SUPER, 0, exec, ${pkgs.wireplumber}/bin/wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+" + + "ALT, mouse_up, resizeactive, 10% 10%" + "ALT, mouse_down, resizeactive, -10% -10%" + ]; + + bindm = [ + "ALT, mouse:272, movewindow" + "ALT, mouse:273, resizeactive" + ]; + bindc = [ + "ALT, mouse:272, togglefloating" + ]; +} diff --git a/nix/homes/rafiq/desktop/default.nix b/nix/homes/rafiq/desktop/default.nix new file mode 100644 index 0000000..f28357e --- /dev/null +++ b/nix/homes/rafiq/desktop/default.nix @@ -0,0 +1,172 @@ +{ lib, inputs, ... }: +{ + allowedUnfreePackages = [ + "stremio-shell" + "stremio-server" + ]; + flake.homes.rafiq = + { osConfig, pkgs, ... }: + let + inherit (lib.modules) mkMerge mkIf; + inherit (builtins) map listToAttrs; + inherit (lib.lists) findFirstIndex; + inherit (inputs.nur.legacyPackages.${pkgs.stdenv.hostPlatform.system}.repos.rycee) firefox-addons; + profiles = listToAttrs ( + map (name: { + inherit name; + # If there are duplicate profile names, findFirstIndex will cause issues. + value = profileCfg (findFirstIndex (x: x == name) null syncedProfiles); + }) syncedProfiles + ); + syncedProfiles = [ + "rafiq" + "test" + ]; + profileCfg = id: { + inherit id; + settings."extensions.autoDisableScopes" = 0; # Auto enable extensions + #TODO: add default seach unduck and add rest of extensions + extensions = { + force = true; + packages = with firefox-addons; [ + darkreader + gesturefy + sponsorblock + ublock-origin + ]; + }; + }; + in + mkIf osConfig.desktop.enable { + persistDirs = [ + "docs" + "repos" + "vids" + "tmp" + ".cache/Smart Code ltd/Stremio" + ".local/share/Smart Code ltd/Stremio" + ".mozilla/firefox" + ]; + home = { + packages = with pkgs; [ stremio ]; + sessionVariables = { + BROWSER = "firefox"; + LAUNCHER = "fuzzel"; + LOCKSCREEN = "hyprlock"; + NOTIFICATION_DAEMON = "mako"; + TERMINAL = "ghostty"; + STATUS_BAR = "waybar"; + }; + }; + # TODO: add gamescope here or in nixos desktop module + programs = { + obs-studio.enable = true; + vesktop.enable = true; + thunderbird.enable = true; + thunderbird.profiles.rafiq.isDefault = true; + firefox = { + enable = true; + inherit profiles; + }; + hyprlock.settings = { + general.hide_cursor = true; + general.ignore_empty_input = true; + background.blur_passes = 5; + background.blur_size = 5; + label = { + text = ''hi, $USER.''; + font_size = 32; + position = "0, 0"; + halign = "center"; + valign = "center"; + zindex = 1; + shadow_passes = 5; + shadow_size = 5; + }; + input-field = { + placeholder_text = ""; + fade_on_empty = true; + size = "200, 45"; + position = "0, -5%"; + halign = "center"; + valign = "center"; + zindex = 1; + shadow_passes = 5; + shadow_size = 5; + }; + }; + ghostty = { + enable = true; + settings = { + confirm-close-surface = false; + }; + }; + waybar = { + enable = true; + settings = [ + { + #TODO: review the rest of the modules to see what else can be added + layer = "top"; + modules-left = [ + "pulseaudio" + ]; + modules-right = [ + "battery" + "clock" + ]; + "pulseaudio" = { + format = "{icon} {volume}%"; + format-muted = ""; + format-icons.default = [ + "" + "" + ]; + on-click = "${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; + }; + "clock" = { + interval = 1; + format = "{:%F %T}"; + }; + "battery" = { + interval = 1; + bat-compatibility = true; + }; + } + ]; + style = # css + '' + window#waybar { + background-color: rgba(0, 0, 0, 0); + } + + #pulseaudio, + #battery, + #clock { + padding-top: 5px; + padding-bottom: 5px; + padding-right: 5px; + color: #ffffff; + } + ''; + }; + }; + services = { + mako.enable = true; + mako.settings.default-timeout = 10000; + }; + wayland.windowManager.hyprland.settings = mkMerge [ + (import ./_hyprland/decoration.nix) + (import ./_hyprland/keybinds.nix { inherit pkgs; }) + { + ecosystem.no_update_news = true; + xwayland.force_zero_scaling = true; + monitor = [ ", preferred, auto, 1" ]; + exec-once = [ + "uwsm app -- $LOCKSCREEN" + "uwsm app -- $NOTIFICATION_DAEMON" + "uwsm app -- $STATUS_BAR" + ]; + } + ]; + }; +} From df06e092d6359839c7098942af3ce71e74e649b5 Mon Sep 17 00:00:00 2001 From: Mohammad Rafiq Date: Mon, 7 Jul 2025 22:19:38 +0800 Subject: [PATCH 3/3] feat(nix): add graphical module, pass option to nixosSystem --- nix/configurations.nix | 5 ++- nix/homes/rafiq/desktop/default.nix | 68 ++++++++++++++++++++--------- nix/manifest.nix | 3 +- nix/modules/desktop/default.nix | 7 --- nix/modules/graphical/default.nix | 19 ++++++++ 5 files changed, 73 insertions(+), 29 deletions(-) delete mode 100644 nix/modules/desktop/default.nix create mode 100644 nix/modules/graphical/default.nix diff --git a/nix/configurations.nix b/nix/configurations.nix index 9375b15..aeb2592 100644 --- a/nix/configurations.nix +++ b/nix/configurations.nix @@ -22,7 +22,10 @@ let name: value: if class == "nixos" then nixosSystem { - specialArgs.hostName = name; + specialArgs = { + inherit (value) graphical; + hostName = name; + }; modules = [ cfg.modules.nixos.default inputs.home-manager.nixosModules.home-manager diff --git a/nix/homes/rafiq/desktop/default.nix b/nix/homes/rafiq/desktop/default.nix index f28357e..0e4bf07 100644 --- a/nix/homes/rafiq/desktop/default.nix +++ b/nix/homes/rafiq/desktop/default.nix @@ -5,7 +5,7 @@ "stremio-server" ]; flake.homes.rafiq = - { osConfig, pkgs, ... }: + { pkgs, config, ... }: let inherit (lib.modules) mkMerge mkIf; inherit (builtins) map listToAttrs; @@ -25,7 +25,6 @@ profileCfg = id: { inherit id; settings."extensions.autoDisableScopes" = 0; # Auto enable extensions - #TODO: add default seach unduck and add rest of extensions extensions = { force = true; packages = with firefox-addons; [ @@ -37,7 +36,7 @@ }; }; in - mkIf osConfig.desktop.enable { + mkIf config.graphical { persistDirs = [ "docs" "repos" @@ -46,9 +45,15 @@ ".cache/Smart Code ltd/Stremio" ".local/share/Smart Code ltd/Stremio" ".mozilla/firefox" + ".tor project" ]; home = { - packages = with pkgs; [ stremio ]; + packages = with pkgs; [ + stremio + tor-browser + vlc + wl-clipboard-rs + ]; sessionVariables = { BROWSER = "firefox"; LAUNCHER = "fuzzel"; @@ -58,8 +63,8 @@ STATUS_BAR = "waybar"; }; }; - # TODO: add gamescope here or in nixos desktop module programs = { + fuzzel.enable = true; obs-studio.enable = true; vesktop.enable = true; thunderbird.enable = true; @@ -105,7 +110,6 @@ enable = true; settings = [ { - #TODO: review the rest of the modules to see what else can be added layer = "top"; modules-left = [ "pulseaudio" @@ -149,24 +153,48 @@ } ''; }; + }; services = { mako.enable = true; mako.settings.default-timeout = 10000; }; - wayland.windowManager.hyprland.settings = mkMerge [ - (import ./_hyprland/decoration.nix) - (import ./_hyprland/keybinds.nix { inherit pkgs; }) - { - ecosystem.no_update_news = true; - xwayland.force_zero_scaling = true; - monitor = [ ", preferred, auto, 1" ]; - exec-once = [ - "uwsm app -- $LOCKSCREEN" - "uwsm app -- $NOTIFICATION_DAEMON" - "uwsm app -- $STATUS_BAR" - ]; - } - ]; + wayland.windowManager.hyprland = { + enable = true; + # This is needed for UWSM + systemd.enable = false; + # Null the packages since we use them system wide + package = null; + portalPackage = null; + # settings.monitor = [ + # "${mainMonitor.id}, ${mainMonitor.resolution}@${mainMonitor.refresh-rate}, auto, ${mainMonitor.scale}" + # ]; + + settings = mkMerge [ + (import ./_hyprland/decoration.nix) + (import ./_hyprland/keybinds.nix { inherit pkgs; }) + { + ecosystem.no_update_news = true; + xwayland.force_zero_scaling = true; + monitor = [ ", preferred, auto, 1" ]; + exec-once = [ + "uwsm app -- $LOCKSCREEN" + "uwsm app -- $NOTIFICATION_DAEMON" + "uwsm app -- $STATUS_BAR" + ]; + } + ]; + }; + # xdg.configFile."uwsm/env".text = # sh + # '' + # # Force apps to scale right with Wayland + # export GDK_SCALE=${mainMonitor.scale} + # export STEAM_FORCE_DESKTOPUI_SCALING=${mainMonitor.scale} + # ''; + # xdg.configFile."uwsm/env-hyprland".text = # sh + # '' + # export GDK_SCALE=${mainMonitor.scale} + # export STEAM_FORCE_DESKTOPUI_SCALING=${mainMonitor.scale} + # ''; }; } diff --git a/nix/manifest.nix b/nix/manifest.nix index cf8f48e..3f4af3e 100644 --- a/nix/manifest.nix +++ b/nix/manifest.nix @@ -9,6 +9,7 @@ }; hosts.nixos = { nemesis = { + graphical = true; machine = { platform = "amd"; gpu = "nvidia"; @@ -22,9 +23,9 @@ } ]; }; - extraCfg.desktop.enable = true; }; apollo = { + graphical = false; machine = { platform = "intel"; root.drive = "/dev/disk/by-id/nvme-eui.002538d221b47b01"; diff --git a/nix/modules/desktop/default.nix b/nix/modules/desktop/default.nix deleted file mode 100644 index 3e2c64b..0000000 --- a/nix/modules/desktop/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ lib, ... }: -let - inherit (lib.options) mkEnableOption; -in -{ - flake.modules.nixos.default.options.desktop.enable = mkEnableOption ""; -} diff --git a/nix/modules/graphical/default.nix b/nix/modules/graphical/default.nix new file mode 100644 index 0000000..78874bf --- /dev/null +++ b/nix/modules/graphical/default.nix @@ -0,0 +1,19 @@ +{ lib, ... }: +let + inherit (lib.modules) mkIf; + inherit (lib.options) mkEnableOption; +in +{ + flake.modules.nixos.default = + { graphical, ... }: + { + config = mkIf graphical { + home-manager.sharedModules = [ { graphical = true; } ]; + services.pipewire = { + enable = true; + pulse.enable = true; + }; + }; + }; + flake.modules.homeManager.default.options.graphical = mkEnableOption ""; +}