From eda8461304ce5b46b206a1a551a8fd9c420f70c9 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Sat, 13 Jun 2026 07:37:32 +0100 Subject: [PATCH] feat(system): Plymouth splash, distroName, allowUnfree, offline-pin hardening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Plymouth boot splash ported from the legacy branch (modules/nixos/ plymouth/): logo + eased progress + LUKS entry, background tinted from theme-state.json via the new nomarchy.system.stateFile (wired by mkFlake/lib.nix; null → Tokyo Night fallback). Default on; OFF on the live ISO (boot-message visibility on the install medium). Pulls boot.initrd.systemd, which also drives the keyboard-at-LUKS feature. - system.nixos.distroName = "Nomarchy" (os-release PRETTY_NAME, systemd-boot entries, ISO menu label). distroId left "nixos" (feeds DEFAULT_HOSTNAME + upstream isNixos checks — roadmapped). - nixpkgs.config.allowUnfree distro-wide (here + both import-nixpkgs sites) — unblocks claude-code for the menu's ask-Claude module. - systemd-boot.configurationLimit = 10 so entries don't fill the ESP. - Live ISO: nomarchy.idle.enable = false — hypridle was suspending the VM mid-install (the install-hung regression); installed systems keep it. - flake.nix offline pins (verified 0-leak via a foreign-identity gap-analysis probe): the repo's own standalone HM gen + inputDerivations, mustache-go + stdenv (stylix re-renders base16 per switch), microcode-amd/ intel (enableRedistributableFirmware activated updateMicrocode → source-build cascade), buildEnv's builder.pl, findXMLCatalogs, and the representativeInstall mirror (xkb/initrd-systemd/microcode). Co-Authored-By: Claude Fable 5 --- flake.nix | 32 +++ hosts/live.nix | 11 + lib.nix | 3 + modules/home/fuzzel.nix | 82 +++++++ modules/home/idle.nix | 72 ++++++ modules/home/swaync.nix | 92 ++++++++ modules/nixos/default.nix | 39 +++- modules/nixos/options.nix | 16 ++ modules/nixos/plymouth.nix | 87 ++++++++ modules/nixos/plymouth/bullet.png | Bin 0 -> 293 bytes modules/nixos/plymouth/entry.png | Bin 0 -> 694 bytes modules/nixos/plymouth/lock.png | Bin 0 -> 1537 bytes modules/nixos/plymouth/logo.png | Bin 0 -> 23303 bytes modules/nixos/plymouth/nomarchy.plymouth | 11 + modules/nixos/plymouth/nomarchy.script | 271 +++++++++++++++++++++++ modules/nixos/plymouth/progress_bar.png | Bin 0 -> 314 bytes modules/nixos/plymouth/progress_box.png | Bin 0 -> 314 bytes themes/summer-day/waybar.jsonc | 92 ++++++++ themes/summer-night/waybar.jsonc | 99 +++++++++ 19 files changed, 906 insertions(+), 1 deletion(-) create mode 100644 modules/home/fuzzel.nix create mode 100644 modules/home/idle.nix create mode 100644 modules/home/swaync.nix create mode 100644 modules/nixos/plymouth.nix create mode 100644 modules/nixos/plymouth/bullet.png create mode 100644 modules/nixos/plymouth/entry.png create mode 100644 modules/nixos/plymouth/lock.png create mode 100644 modules/nixos/plymouth/logo.png create mode 100644 modules/nixos/plymouth/nomarchy.plymouth create mode 100644 modules/nixos/plymouth/nomarchy.script create mode 100644 modules/nixos/plymouth/progress_bar.png create mode 100644 modules/nixos/plymouth/progress_box.png create mode 100644 themes/summer-day/waybar.jsonc create mode 100644 themes/summer-night/waybar.jsonc diff --git a/flake.nix b/flake.nix index 8df64cd..825a676 100644 --- a/flake.nix +++ b/flake.nix @@ -148,6 +148,7 @@ specialArgs = { inherit username; }; modules = [ self.nixosModules.nomarchy + { nomarchy.system.stateFile = ./theme-state.json; } ./hosts/default/configuration.nix ]; }; @@ -251,6 +252,20 @@ ({ lib, ... }: { nomarchy.system.snapper.enable = true; nomarchy.system.greeter.autoLogin = username; + # The installer writes these (keyboard-everywhere + # incl. the LUKS prompt) — mirror them or the + # initrd/vconsole pins don't match an offline + # install's rebuild set. + console.useXkbConfig = true; + boot.initrd.systemd.enable = true; + # nixos-generate-config keys microcode off + # enableRedistributableFirmware (now on): the + # real machine enables exactly one vendor — + # pin both, or the offline install builds + # amd-ucode/intel-ucode from source (found the + # hard way: the 2700s regression hang). + hardware.cpu.amd.updateMicrocode = true; + hardware.cpu.intel.updateMicrocode = true; swapDevices = [{ device = "/swap/swapfile"; }]; boot.resumeDevice = "/dev/disk/by-uuid/00000000-0000-0000-0000-000000000000"; boot.kernelParams = [ "resume_offset=1" ]; @@ -298,6 +313,11 @@ representativeInstall.config.system.build.etc.inputDerivation representativeInstall.config.system.build.initialRamdisk.inputDerivation template.homeConfigurations.${username}.activationPackage.inputDerivation + # home-files COPIES user-dbus-services instead of + # referencing it (same story as the self pin above) — + # a custom-username install rebuilds home-files and + # needs its direct inputs present. + template.homeConfigurations.${username}.config.home-files.inputDerivation ] ++ [ # A theme switch re-renders stylix's base16 templates # (gtk.css, kvantum, …) on the machine: the renderer and @@ -328,6 +348,18 @@ # tries to BUILD remarshal, whose test closure pulls # matplotlib/ffmpeg/x265 (the ~1900-drv cascade). pkgs.remarshal + # system-path/initrd-bin-env are buildEnvs rebuilt per + # machine; their shared builder.pl is build-time-only + # (never in any runtime closure) — an empty env's + # inputDerivation retains it. + (pkgs.buildEnv { name = "nomarchy-pin-buildenv"; paths = [ ]; }).inputDerivation + # /etc/dbus-1 reassembly wants this setup hook. + pkgs.findXMLCatalogs + # nixos-generate-config keys microcode off + # enableRedistributableFirmware (now on): exactly one + # vendor per real machine, so pin both ucode cpios. + pkgs.microcode-amd + pkgs.microcode-intel # …and one representative disko script: its tool closure # (file, which, wrapper hooks, …) isn't otherwise on the diff --git a/hosts/live.nix b/hosts/live.nix index d3f0c8d..ac769a0 100644 --- a/hosts/live.nix +++ b/hosts/live.nix @@ -16,6 +16,11 @@ # Ghostty silently falls back to the wrong font (seen on the # Latitude 5410). Normal priority (100) beats the override. fonts.fontconfig.enable = true; + + # No boot splash on the install medium: the installer ISO boots its + # own initrd path (squashfs), and visibility of boot messages is + # worth more than polish here. Installed systems get the splash. + nomarchy.system.plymouth.enable = false; xdg.icons.enable = true; xdg.mime.enable = true; xdg.autostart.enable = true; @@ -85,6 +90,12 @@ # ── Live-session desktop tweaks ───────────────────────────────────── home-manager.users.${username} = { + # No idle lock/suspend on the install medium: an offline install + # runs 20-30 min unattended, and hypridle would blank the display + # then SUSPEND the machine mid-install (it did — the install-hung + # regression). Installed systems keep idle management. + nomarchy.idle.enable = false; + wayland.windowManager.hyprland.settings = { # QEMU (and some panels) report a tiny "preferred" mode; ask for # the highest resolution instead. diff --git a/lib.nix b/lib.nix index 07e442d..ff9746c 100644 --- a/lib.nix +++ b/lib.nix @@ -65,6 +65,9 @@ # (`nomarchy-theme-sync apply` → `home-manager switch`) works # out of the box — same pinned input as the desktop modules. { environment.systemPackages = [ home-manager.packages.${system}.home-manager ]; } + # System-side theme consumers (Plymouth splash background) + # read the same JSON the desktop does. + { nomarchy.system.stateFile = src + "/theme-state.json"; } ] ++ hardwareModules ++ [ diff --git a/modules/home/fuzzel.nix b/modules/home/fuzzel.nix new file mode 100644 index 0000000..b0f126b --- /dev/null +++ b/modules/home/fuzzel.nix @@ -0,0 +1,82 @@ +# Fuzzel — launcher, dmenu renderer for the menu system, themed from +# theme-state.json like every other surface. Also home of nomarchy-menu, +# the dispatcher script the menu roadmap grows out of (first module: +# power). +{ config, lib, pkgs, ... }: + +let + cfg = config.nomarchy; + t = cfg.theme; + c = t.colors; + + # fuzzel.ini colors are rrggbbaa, no leading #. + hexa = color: alpha: "${lib.removePrefix "#" color}${alpha}"; + + nomarchy-menu = pkgs.writeShellScriptBin "nomarchy-menu" '' + # Nomarchy menu dispatcher — thin presentation layer over + # `fuzzel --dmenu`; actions delegate to systemctl/hyprctl/ + # nomarchy-theme-sync. The icons are nf-md glyphs (any shipped + # Nerd Font carries them). + case "''${1:-}" in + power) + choice=$(printf '%s\n' \ + "󰍃 Logout" \ + "󰤄 Suspend" \ + "󰒲 Hibernate" \ + "󰜉 Reboot" \ + "󰐥 Shutdown" \ + | fuzzel --dmenu --prompt "power " --lines 5 --width 24) || exit 0 + case "$choice" in + *Logout) hyprctl dispatch exit ;; + *Suspend) systemctl suspend ;; + *Hibernate) systemctl hibernate ;; + *Reboot) systemctl reboot ;; + *Shutdown) systemctl poweroff ;; + esac ;; + *) + echo "usage: nomarchy-menu power" >&2 + exit 64 ;; + esac + ''; +in +{ + config = lib.mkIf cfg.fuzzel.enable { + home.packages = [ nomarchy-menu ]; + + programs.fuzzel = { + enable = true; + settings = { + main = { + # UI font first; the mono Nerd Font follows so menu icons + # (nf-md glyphs) resolve — fcft falls back per glyph. + font = "${t.fonts.ui}:size=${toString (t.fonts.size + 1)}, ${t.fonts.mono}:size=${toString (t.fonts.size + 1)}"; + terminal = cfg.terminal; + layer = "overlay"; + lines = 12; + width = 40; + horizontal-pad = 24; + vertical-pad = 16; + inner-pad = 8; + }; + + colors = { + background = hexa c.base "f2"; + text = hexa c.text "ff"; + prompt = hexa c.subtext "ff"; + placeholder = hexa c.muted "ff"; + input = hexa c.text "ff"; + match = hexa c.accent "ff"; + selection = hexa c.surface "ff"; + selection-text = hexa c.text "ff"; + selection-match = hexa c.accent "ff"; + border = hexa c.accent "ee"; + }; + + border = { + width = t.ui.borderSize; + radius = t.ui.rounding; + }; + }; + }; + }; +} diff --git a/modules/home/idle.nix b/modules/home/idle.nix new file mode 100644 index 0000000..db4b173 --- /dev/null +++ b/modules/home/idle.nix @@ -0,0 +1,72 @@ +# hyprlock + hypridle — screen locking and idle management, themed from +# theme-state.json. One concern, one file: hypridle drives WHEN (idle +# lock, display off, suspend, lock-before-sleep), hyprlock is the +# themed lock screen itself (also behind the power menu's Lock entry). +{ config, lib, ... }: + +let + cfg = config.nomarchy; + t = cfg.theme; + c = t.colors; + inherit (config.nomarchy.lib) rgb; +in +{ + config = lib.mkIf cfg.idle.enable { + programs.hyprlock = { + enable = true; + settings = { + general.hide_cursor = true; + + background = [{ + monitor = ""; + color = rgb c.base; + }]; + + input-field = [{ + monitor = ""; + size = "300, 50"; + outline_thickness = t.ui.borderSize; + dots_size = 0.25; + outer_color = rgb c.accent; + inner_color = rgb c.surface; + font_color = rgb c.text; + check_color = rgb c.warn; + fail_color = rgb c.bad; + rounding = t.ui.rounding; + placeholder_text = "password…"; + }]; + + label = [{ + monitor = ""; + text = "$TIME"; + color = rgb c.text; + font_size = 64; + font_family = t.fonts.ui; + position = "0, 120"; + halign = "center"; + valign = "center"; + }]; + }; + }; + + services.hypridle = { + enable = true; + settings = { + general = { + lock_cmd = "pidof hyprlock || hyprlock"; + before_sleep_cmd = "loginctl lock-session"; + after_sleep_cmd = "hyprctl dispatch dpms on"; + }; + listener = [ + { timeout = 300; on-timeout = "loginctl lock-session"; } + { + timeout = 600; + on-timeout = "hyprctl dispatch dpms off"; + on-resume = "hyprctl dispatch dpms on"; + } + { timeout = 1800; on-timeout = "systemctl suspend"; } + ]; + }; + }; + }; +} diff --git a/modules/home/swaync.nix b/modules/home/swaync.nix new file mode 100644 index 0000000..ed2cba9 --- /dev/null +++ b/modules/home/swaync.nix @@ -0,0 +1,92 @@ +# swaync — notification daemon + control centre, themed from +# theme-state.json. Until this shipped, nothing rendered notify-send at +# all: the theme-switch progress toasts, the CLI's font warnings and the +# live ISO's welcome message were all invisible. +{ config, lib, ... }: + +let + cfg = config.nomarchy; + t = cfg.theme; + c = t.colors; + r = toString t.ui.rounding; +in +{ + config = lib.mkIf cfg.swaync.enable { + services.swaync = { + enable = true; + + settings = { + positionX = "right"; + positionY = "top"; + control-center-margin-top = t.ui.gapsOut; + control-center-margin-right = t.ui.gapsOut; + control-center-width = 420; + notification-window-width = 400; + notification-icon-size = 48; + timeout = 6; + timeout-low = 3; + timeout-critical = 0; # critical stays until dismissed + }; + + style = '' + /* Palette baked from theme-state.json */ + @define-color base ${c.base}; + @define-color surface ${c.surface}; + @define-color text ${c.text}; + @define-color subtext ${c.subtext}; + @define-color accent ${c.accent}; + @define-color bad ${c.bad}; + + .notification { + background: alpha(@base, 0.95); + border: ${toString t.ui.borderSize}px solid alpha(@accent, 0.4); + border-radius: ${r}px; + color: @text; + } + + .notification-content .summary { + color: @text; + font-weight: bold; + } + + .notification-content .body { + color: @subtext; + } + + .notification.critical { + border-color: @bad; + } + + .control-center { + background: alpha(@base, 0.95); + border: ${toString t.ui.borderSize}px solid alpha(@accent, 0.4); + border-radius: ${r}px; + color: @text; + } + + .control-center .notification-row:focus, + .control-center .notification-row:hover { + background: alpha(@surface, 0.6); + border-radius: ${r}px; + } + + .widget-title { + color: @text; + font-weight: bold; + } + + .widget-title > button { + background: @surface; + color: @text; + border: none; + border-radius: ${r}px; + } + + .widget-title > button:hover { + background: @accent; + color: @base; + } + ''; + }; + }; +} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 4ef0cda..4beaa52 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -11,9 +11,15 @@ let cfg = config.nomarchy.system; in { - imports = [ ./options.nix ]; + imports = [ ./options.nix ./plymouth.nix ]; config = { + # The safe half of distro branding: distroName flows into + # /etc/os-release PRETTY_NAME, systemd-boot entry titles and the + # ISO boot-menu label. distroId stays "nixos" on purpose — it feeds + # DEFAULT_HOSTNAME and upstream isNixos checks (see roadmap). + system.nixos.distroName = lib.mkDefault "Nomarchy"; + # Unfree allowed distro-wide: pragmatic-desktop territory (claude-code # for the menu's ask-Claude module, vendor drivers, …). The custom # nixpkgs-config type can't carry a nested mkDefault; disagree with @@ -114,6 +120,9 @@ in inter noto-fonts noto-fonts-color-emoji + # The legacy-ported waybar identities (summer-day/night) use + # FontAwesome codepoints in their layouts and list it in css. + font-awesome ]; fontconfig.defaultFonts = { monospace = lib.mkDefault [ "JetBrainsMono Nerd Font" ]; @@ -125,6 +134,31 @@ in # ── Essential packages ─────────────────────────────────────────── environment.systemPackages = with pkgs; [ nomarchy-theme-sync # provided by overlays.default + + # Friendly wrappers for the two rebuild paths (README §3). Run as + # your user: `nix flake update` must NOT run as root (libgit2 + # refuses the user-owned flake repo) — sudo happens inside, only + # for the system switch. + (pkgs.writeShellScriptBin "sys-update" '' + set -e + if [ "$(id -u)" -eq 0 ]; then + echo "sys-update: run as your normal user (it sudos the rebuild itself)" >&2 + exit 1 + fi + flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" + echo "sys-update: updating flake inputs in $flake" + nix flake update --flake "$flake" + if command -v nixos-rebuild-snap >/dev/null 2>&1; then + sudo nixos-rebuild-snap "$@" # BTRFS snapshot first + else + sudo nixos-rebuild switch --flake "$flake#default" "$@" + fi + '') + (pkgs.writeShellScriptBin "home-update" '' + set -e + exec home-manager switch --flake "''${NOMARCHY_PATH:-$HOME/.nomarchy}" "$@" + '') + git vim wget @@ -152,6 +186,9 @@ in nixos-rebuild switch --flake /etc/nixos#default "$@" ''); + # Don't let boot entries fill the ESP over the years. + boot.loader.systemd-boot.configurationLimit = lib.mkDefault 10; + # ── Nix itself ─────────────────────────────────────────────────── nix = { settings = { diff --git a/modules/nixos/options.nix b/modules/nixos/options.nix index 2b93139..9ed548e 100644 --- a/modules/nixos/options.nix +++ b/modules/nixos/options.nix @@ -21,6 +21,22 @@ ''; }; + plymouth.enable = lib.mkEnableOption '' + the Nomarchy Plymouth boot splash (logo + progress + LUKS prompt), + background-tinted from theme-state.json via nomarchy.system.stateFile. + Recolors on system rebuilds — theme switches don't touch the initrd'' // { default = true; }; + + stateFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = lib.literalExpression "./theme-state.json"; + description = '' + theme-state.json for the system-side consumers (currently the + Plymouth splash background). lib.mkFlake wires it automatically + from your flake; null falls back to the Tokyo Night base color. + ''; + }; + audio.enable = lib.mkEnableOption "the Pipewire audio stack" // { default = true; }; bluetooth.enable = lib.mkEnableOption "Bluetooth support with blueman" // { default = true; }; diff --git a/modules/nixos/plymouth.nix b/modules/nixos/plymouth.nix new file mode 100644 index 0000000..36b9161 --- /dev/null +++ b/modules/nixos/plymouth.nix @@ -0,0 +1,87 @@ +# Plymouth boot splash — Nomarchy-branded (ported from the legacy +# iteration), background tinted from the same theme-state.json that +# drives the desktop (nomarchy.system.stateFile, wired automatically by +# lib.mkFlake). One caveat by design: theme switches are Home +# Manager-only and never touch the initrd, so the splash follows the +# theme as of the last SYSTEM rebuild (`sys-update`), not the last +# `nomarchy-theme-sync apply`. +{ config, lib, pkgs, ... }: + +let + cfg = config.nomarchy.system; + + state = + if cfg.stateFile != null + then builtins.fromJSON (builtins.readFile cfg.stateFile) + else { }; + base = lib.removePrefix "#" ((state.colors or { }).base or "#1a1b26"); + + # Plymouth's Window.SetBackgroundTopColor takes three floats in + # 0.0–1.0; the .plymouth metadata's ConsoleLogBackgroundColor takes a + # 0xRRGGBB hex. Nix has no float math: multiply, integer-divide, pad. + byteToFloat = n: + let + thousandths = (n * 1000) / 255; + s = toString thousandths; + padded = + if lib.stringLength s == 1 then "00${s}" + else if lib.stringLength s == 2 then "0${s}" + else s; + in "0.${padded}"; + channel = off: byteToFloat (lib.fromHexString (lib.substring off 2 base)); + + nomarchy-plymouth = pkgs.stdenv.mkDerivation { + pname = "nomarchy-plymouth"; + version = "1.0"; + + src = ./plymouth; + + installPhase = '' + mkdir -p $out/share/plymouth/themes/nomarchy + cp * $out/share/plymouth/themes/nomarchy/ + + # Point the .plymouth metadata into the store + sed -i "s|/usr/share/plymouth/themes/nomarchy|$out/share/plymouth/themes/nomarchy|g" \ + $out/share/plymouth/themes/nomarchy/nomarchy.plymouth + + # Bake the theme's base color: RGB floats for the script's + # Window.SetBackground* calls, 0xRRGGBB for ConsoleLogBackground. + sed -i \ + -e 's|@BG_R@|${channel 0}|g' \ + -e 's|@BG_G@|${channel 2}|g' \ + -e 's|@BG_B@|${channel 4}|g' \ + $out/share/plymouth/themes/nomarchy/nomarchy.script + sed -i 's|@BG_HEX@|${base}|g' \ + $out/share/plymouth/themes/nomarchy/nomarchy.plymouth + ''; + }; +in +{ + config = lib.mkIf cfg.plymouth.enable { + # Plymouth wants the systemd initrd (also what applies the keyboard + # layout to the LUKS prompt) and a quiet console around it. + boot.initrd.systemd.enable = lib.mkDefault true; + boot.initrd.verbose = lib.mkDefault false; + console.earlySetup = lib.mkDefault true; + boot.consoleLogLevel = lib.mkDefault 0; + + boot.plymouth = { + enable = lib.mkDefault true; + themePackages = lib.mkDefault [ nomarchy-plymouth ]; + theme = lib.mkDefault "nomarchy"; + }; + + # Not mkDefault: kernelParams is a list other modules add to at + # normal priority — a mkDefault def would be dropped entirely, + # losing the quiet/splash boot. These merge with the rest. + boot.kernelParams = [ + "quiet" + "splash" + "loglevel=3" + "rd.systemd.show_status=false" + "rd.udev.log_level=3" + "udev.log_priority=3" + "boot.shell_on_fail" + ]; + }; +} diff --git a/modules/nixos/plymouth/bullet.png b/modules/nixos/plymouth/bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..62249b3bd82b0b670a8a503a3bb69bbfe79cc4f4 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK^6z-MIEH9U zoIA;|uZcmx^}qZQCjEr9ou<6JoZt7m0FRe~3I-q?kdfVZu-@kQlF=GdcP{_{ literal 0 HcmV?d00001 diff --git a/modules/nixos/plymouth/entry.png b/modules/nixos/plymouth/entry.png new file mode 100644 index 0000000000000000000000000000000000000000..5c7891792b8872db933f17a667a449a478c0be53 GIT binary patch literal 694 zcmeAS@N?(olHy`uVBq!ia0y~yV3Y&04FuSLa@a2CEqi4B`cIb_Lo1CD@X@-Ch2J0cXVbJ3tZk5>H=O_LuA|BAOCC zHaNEIWB8gpRxhIrP-q3h6ugFYL#HXzL zs@XQt|A*ck*2`WtwNt_B=Yyw}k1W;qd^{d$X}`l_w|(sWyd1OlR=bb4vobhzyu2J; zZnSHU?(>Dgw^zkpzx{Xds&+;O9q+{%->h5%r*w;NJ|6l0@y}PwUNtf>?BDuhVsPE} zg8wPcOLO0+EPi#6fx-T(fyDNE?akAVe!dFQ`p5hrGs6*K8wLlPp~KkoX?J(~!5v@i zWcGyE3NSoazmLT~cXe58{`dY>a%>D6be?{Bxz<`T_MTZ++WO$HQVb2Mv&zq@Pirx0 z4OBAy4vaL_64!{5l*E!$tK_0oAjM#0U}UOmV6JOm5@KXvWnyS$WTI_gU}a!%k#!|7 zD3LVe=BH$)RpQpLAVSa+oZUJsR-+c`p0rfC=y85}Sb4q9e01cG# AHUIzs literal 0 HcmV?d00001 diff --git a/modules/nixos/plymouth/lock.png b/modules/nixos/plymouth/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..3046de1b6a3f20d194f010fee671c936326beb27 GIT binary patch literal 1537 zcmaKseKgYx7{|AHUkq{cvLRb`y@V2`mnmXdjLEhr)$(pBuF;Fg7MiYcO37PGhEj}Q zjkx2~FG}6iyi`n^Yf__8QcEw2yZ-5)d(J)Q^E}@_p65B=bDrm%=QKHZn*rPs4uL=n zhyi{()JjnYT~}M3b6C_2wdkb;L@*(cWhOrZ3aPkg4uNP1iGDtmqZi-uNcB{I6qr4G z#i8)RDVJ5cL1!Nt{l+uGVeBIuqiPA1leLuzROguk=T?Ra9MON;!yO9zRCRCo6Z~dO zZEkEpocTDP92U}<@#4T*rj2a+(x$Pv@seyCNY93qf#zr(*_!G?;{%hf$7{)0wjI)D_X( zm}u}Ln8`jY-p@J5VO8CjI08(3E0;){?Q-|cD59AsumI2J9^x48{P#=1M@1> z`3H_14&4M@jmRG{e0-T%a$_};xp+UGO5W(w?k>lx9F;;;TAULlesb+OonM22Q!c81az}6c*t>v7~tOVPm zhU!UpisjNWSukBNpiE6b9Q+!olgTZa?zW>>3@H1~d|7^cD&u?XCD2;IcY{V&A|v%} zdgu$wb94J!*DI4eckMCCA2lAHSD>gLRdsonw|WzWbCTnPs>+EhLc?+2mx$6;Pv&90 z`0L*_g4}j}dR=HC;<$8$V8H_R+5)ZzLV8t}3+GKlEaK#JdXNo5RObC<{#qWnTDYlq z)?=4}W)I5KWoU07<8~IqmNFI8_hC%4r#B}#Xw19S$T7|LGujzt$Su_wD^oXACsp6Y z@KIlS8YxqxORtv@zY6`OX~XEy`ZfP$tM|_>py#PwsWV|^yI&|}5<#J-3naFWlPt&0 zMM1pA=0DF$cD`C*@wVbov-TLG5Xo`|Cp3#t1lw$AGfc{*?c{bf87cSbWy55&%tM%p zeXIrPK75<{GLPwF=XCHZ+fTLU^X`|rK`Cd;+jrMtGa(^cXr+} zgVU;=CUsvl!V_DzOK)XsWtP;Abb!{3qlSAP;8kvbDCe<{Y>C!!vz1@u+lCa}en)#) z;t*rZHexumT)tUH-d4SN1?85h(q5JM8U5Fz3%*u)MG1WJ{{KN~pSIm6Hn6(LH){pv ze0V$g{08_ag*>vOzNWv9Sb-lDoN*GiYdmB~>U7k^= z!sR4-SaIB}#^(07LNV=C+^Wxvp#$8peZDi2`#_iZs= zqu`0Tb?EN1+Q1#UGG4l`!VHb{C~R_k3u*CyVN%VraV9KWDT5xw*ws95W?`)tyZ4)2<_Ue8M2_Lb zaSg1=`gadV(~oTBd5ZNyUQ=(QUE*OKK)-|hxBH_7i+@D@94nGF6k#qnb#ZuUGt_nK Vg$$|X5%o`p5dDMwntbUe{{_St%Ul2e literal 0 HcmV?d00001 diff --git a/modules/nixos/plymouth/logo.png b/modules/nixos/plymouth/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..dbcde56164722eaa62573419b6d02943fa32c5e7 GIT binary patch literal 23303 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 literal 0 HcmV?d00001 diff --git a/modules/nixos/plymouth/nomarchy.plymouth b/modules/nixos/plymouth/nomarchy.plymouth new file mode 100644 index 0000000..4ade91c --- /dev/null +++ b/modules/nixos/plymouth/nomarchy.plymouth @@ -0,0 +1,11 @@ +[Plymouth Theme] +Name=Nomarchy +Description=Nomarchy splash screen. +ModuleName=script + +[script] +ImageDir=/usr/share/plymouth/themes/nomarchy +ScriptFile=/usr/share/plymouth/themes/nomarchy/nomarchy.script +ConsoleLogBackgroundColor=0x@BG_HEX@ +MonospaceFont=Cantarell 11 +Font=Cantarell 11 diff --git a/modules/nixos/plymouth/nomarchy.script b/modules/nixos/plymouth/nomarchy.script new file mode 100644 index 0000000..216dac9 --- /dev/null +++ b/modules/nixos/plymouth/nomarchy.script @@ -0,0 +1,271 @@ +# Nomarchy Plymouth Theme Script + +Window.SetBackgroundTopColor(@BG_R@, @BG_G@, @BG_B@); +Window.SetBackgroundBottomColor(@BG_R@, @BG_G@, @BG_B@); + +logo.image = Image("logo.png"); + +# Calculate scale factor to make logo ~15% of screen height +logo_scale_factor = (Window.GetHeight() * 0.15) / logo.image.GetHeight(); +logo_width = logo.image.GetWidth() * logo_scale_factor; +logo_height = logo.image.GetHeight() * logo_scale_factor; +logo.image = logo.image.Scale(logo_width, logo_height); + +logo.sprite = Sprite(logo.image); +logo.sprite.SetX (Window.GetWidth() / 2 - logo.image.GetWidth() / 2); +logo.sprite.SetY (Window.GetHeight() / 2 - logo.image.GetHeight() / 2); +logo.sprite.SetOpacity (1); + +# Use these to adjust the progress bar timing +global.fake_progress_limit = 0.7; # Target percentage for fake progress (0.0 to 1.0) +global.fake_progress_duration = 15.0; # Duration in seconds to reach limit + +# Progress bar animation variables +global.fake_progress = 0.0; +global.real_progress = 0.0; +global.fake_progress_active = 0; # 0 / 1 boolean +global.animation_frame = 0; +global.fake_progress_start_time = 0; # Track when fake progress started +global.password_shown = 0; # Track if password dialog has been shown +global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement + +fun refresh_callback () + { + global.animation_frame++; + + # Animate fake progress to limit over time with easing + if (global.fake_progress_active == 1) + { + # Calculate elapsed time since start + elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS) + + # Calculate linear progress ratio (0 to 1) based on time + time_ratio = elapsed_time / global.fake_progress_duration; + if (time_ratio > 1.0) + time_ratio = 1.0; + + # Apply easing curve: ease-out quadratic + # Formula: 1 - (1 - x)^2 + eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio)); + + # Calculate fake progress based on eased ratio + global.fake_progress = eased_ratio * global.fake_progress_limit; + + # Update progress bar with fake progress + update_progress_bar(global.fake_progress); + } + } + + +Plymouth.SetRefreshFunction (refresh_callback); + +#----------------------------------------- Helper Functions -------------------------------- + +fun update_progress_bar(progress) + { + # Only update if progress is moving forward + if (progress > global.max_progress) + { + global.max_progress = progress; + width = Math.Int(progress_bar.original_image.GetWidth() * progress); + if (width < 1) width = 1; # Ensure minimum width of 1 pixel + + progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight()); + progress_bar.sprite.SetImage(progress_bar.image); + } + } + +fun show_progress_bar() + { + progress_box.sprite.SetOpacity(1); + progress_bar.sprite.SetOpacity(1); + } + +fun hide_progress_bar() + { + progress_box.sprite.SetOpacity(0); + progress_bar.sprite.SetOpacity(0); + } + +fun show_password_dialog() + { + lock.sprite.SetOpacity(1); + entry.sprite.SetOpacity(1); + } + +fun hide_password_dialog() + { + lock.sprite.SetOpacity(0); + entry.sprite.SetOpacity(0); + for (index = 0; bullet.sprites[index]; index++) + bullet.sprites[index].SetOpacity(0); + } + +fun start_fake_progress() + { + # Don't reset if we already have progress + if (global.max_progress == 0.0) + { + global.fake_progress = 0.0; + global.real_progress = 0.0; + update_progress_bar(0.0); + } + global.fake_progress_active = 1; + global.animation_frame = 0; + } + +fun stop_fake_progress() + { + global.fake_progress_active = 0; + } + +#----------------------------------------- Dialogue -------------------------------- + +lock.image = Image("lock.png"); +entry.image = Image("entry.png"); +bullet.image = Image("bullet.png"); + +entry.sprite = Sprite(entry.image); +entry.x = Window.GetWidth()/2 - entry.image.GetWidth() / 2; +entry.y = logo.sprite.GetY() + logo.image.GetHeight() + 40; +entry.sprite.SetPosition(entry.x, entry.y, 10001); +entry.sprite.SetOpacity(0); + +# Scale lock to be slightly shorter than entry field height +# Original lock is 84x96, entry height determines scale +lock_height = entry.image.GetHeight() * 0.8; +lock_scale = lock_height / 96; +lock_width = 84 * lock_scale; + +scaled_lock = lock.image.Scale(lock_width, lock_height); +lock.sprite = Sprite(scaled_lock); +lock.x = entry.x - lock_width - 15; +lock.y = entry.y + entry.image.GetHeight()/2 - lock_height/2; +lock.sprite.SetPosition(lock.x, lock.y, 10001); +lock.sprite.SetOpacity(0); + +# Bullet array +bullet.sprites = []; + +fun display_normal_callback () + { + hide_password_dialog(); + + # Get current mode + mode = Plymouth.GetMode(); + + # Only show progress bar for boot and resume modes + if (mode == "boot" || mode == "resume") + { + show_progress_bar(); + start_fake_progress(); + } + } + +fun display_password_callback (prompt, bullets) + { + global.password_shown = 1; # Mark that password dialog has been shown + + # Reset progress when password dialog appears + stop_fake_progress(); + hide_progress_bar(); + global.max_progress = 0.0; + global.fake_progress = 0.0; + global.real_progress = 0.0; + show_password_dialog(); + + # Clear all bullets first + for (index = 0; bullet.sprites[index]; index++) + bullet.sprites[index].SetOpacity(0); + + # Create and show bullets for current password (max 21) + max_bullets = 21; + bullets_to_show = bullets; + if (bullets_to_show > max_bullets) + bullets_to_show = max_bullets; + + for (index = 0; index < bullets_to_show; index++) + { + if (!bullet.sprites[index]) + { + # Scale bullet image to 7x7 pixels + scaled_bullet = bullet.image.Scale(7, 7); + bullet.sprites[index] = Sprite(scaled_bullet); + bullet.x = entry.x + 20 + index * (7 + 5); + bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5; + bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002); + } + bullet.sprites[index].SetOpacity(1); + } + } + +Plymouth.SetDisplayNormalFunction(display_normal_callback); +Plymouth.SetDisplayPasswordFunction(display_password_callback); + +#----------------------------------------- Progress Bar -------------------------------- + +progress_box.image = Image("progress_box.png"); +progress_box.sprite = Sprite(progress_box.image); + +progress_box.x = Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2; +progress_box.y = entry.y + entry.image.GetHeight() / 2 - progress_box.image.GetHeight() / 2; +progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0); +progress_box.sprite.SetOpacity(0); + +progress_bar.original_image = Image("progress_bar.png"); +progress_bar.sprite = Sprite(); +progress_bar.image = progress_bar.original_image.Scale(1, progress_bar.original_image.GetHeight()); + +progress_bar.x = Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2; +progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2; +progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1); +progress_bar.sprite.SetOpacity(0); + +fun progress_callback (duration, progress) + { + global.real_progress = progress; + + # If real progress is above limit, stop fake progress and use real progress + if (progress > global.fake_progress_limit) + { + stop_fake_progress(); + update_progress_bar(progress); + } + } + +Plymouth.SetBootProgressFunction(progress_callback); + +#----------------------------------------- Quit -------------------------------- + +fun quit_callback () +{ + logo.sprite.SetOpacity (1); +} + +Plymouth.SetQuitFunction(quit_callback); + +#----------------------------------------- Message -------------------------------- + +message_sprite = Sprite(); +message_sprite.SetPosition(10, 10, 10000); + +fun display_message_callback (text) +{ + my_image = Image.Text(text, 1, 1, 1); + message_sprite.SetImage(my_image); +} + +fun hide_message_callback (text) +{ + message_sprite.SetOpacity(0); +} + +Plymouth.SetDisplayMessageFunction (display_message_callback); +Plymouth.SetHideMessageFunction (hide_message_callback); + +# Initialize progress bar immediately for normal boots +if (Plymouth.GetMode() == "boot" || Plymouth.GetMode() == "resume") + { + show_progress_bar(); + start_fake_progress(); + } diff --git a/modules/nixos/plymouth/progress_bar.png b/modules/nixos/plymouth/progress_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..dbb9fd74fc853d8a79ff072f5070cc660ea11897 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!xfq#&q>16jl|V`%*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1CD;OdLR?pFy!QY9|E)n1Qa};LByV>Y#{W#Z z_kbMs5>H=O_LuA|;<}1kzlXd83h{cnIEF}EPEL?uW#(sKY-3>5a*dk16jl|V`%*(1o8fuTx`fuW&=f#DZW zsNn?zL#Y7+!>a@a2CEqi4B`cIb_Lo1CD;OdLR>ZVoc{m+e`?yP4?q#dByV>Y#{W#Z z_kbMs5>H=O_LuA|;=1xB(>$GkLcE?Xjv*44lM^IZnfVzQ+ZY(NT;t{dB~(jXBT7;d zOH!?pi&B9UgOP!esjh*!u7OF2k+GGDsg<#zwt<0_fx+)>UOXroa`RI%(<*Um=z9HW l15kqo+=i0O+|=Td#M}bhdhY(aoDbB);OXk;vd$@?2>|VqQP%(f literal 0 HcmV?d00001 diff --git a/themes/summer-day/waybar.jsonc b/themes/summer-day/waybar.jsonc new file mode 100644 index 0000000..a45b8f5 --- /dev/null +++ b/themes/summer-day/waybar.jsonc @@ -0,0 +1,92 @@ +{ + "margin-top": 0, + "margin-left": 120, + "margin-bottom": 0, + "margin-right": 120, + "height": 60, + "layer": "top", + "position": "top", + "spacing": 15, + "reload_style_on_change": true, + + "modules-left": ["custom/launcher", "clock", "clock#date"], + "modules-center": ["hyprland/workspaces"], + "modules-right": ["pulseaudio", "network", "battery", "tray", "custom/powermenu"], + + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": true, + "on-click": "activate", + "on-scroll-up": "hyprctl dispatch workspace e+1", + "on-scroll-down": "hyprctl dispatch workspace e-1", + "persistent-workspaces": { + "1": [], "2": [], "3": [], "4": [], "5": [], + "6": [], "7": [], "8": [], "9": [], "10": [] + } + }, + + "custom/launcher": { + "interval": "once", + "format": "󰣇", + "on-click": "nomarchy-menu", + "tooltip-format": "Nomarchy menu" + }, + + "pulseaudio": { + "format": "{icon} {volume}%", + "format-bluetooth": "{icon}  {volume}%", + "format-bluetooth-muted": "  muted", + "format-muted": " muted", + "format-icons": { + "headphone": "", + "hands-free": "", + "headset": "", + "phone": "", + "portable": "", + "car": "", + "default": ["", "", ""] + }, + "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", + "tooltip-format": "Playing at {volume}%" + }, + + "network": { + "format-wifi": " {signalStrength}%", + "format-ethernet": "", + "format-disconnected": "󰤭", + "on-click": "sh -c '$TERMINAL -e nmtui'", + "tooltip-format": "{ipaddr} via {gwaddr}" + }, + + "battery": { + "interval": 60, + "states": { "warning": 30, "critical": 15 }, + "max-length": 10, + "format": "{icon} {capacity}%", + "format-charging": " {capacity}%", + "format-plugged": " {capacity}%", + "format-full": " 100%", + "format-icons": ["", "", "", "", ""], + "on-click": "nomarchy-menu power", + "tooltip-format": "Battery status" + }, + + "clock": { + "format": " {:%H:%M}", + "tooltip": true, + "tooltip-format": "{calendar}" + }, + + "clock#date": { + "format": " {:%A, %B %d, %Y}", + "tooltip": false + }, + + "tray": { "spacing": 8 }, + + "custom/powermenu": { + "format": "", + "on-click": "nomarchy-menu power", + "tooltip": false + } +} diff --git a/themes/summer-night/waybar.jsonc b/themes/summer-night/waybar.jsonc new file mode 100644 index 0000000..e5a1430 --- /dev/null +++ b/themes/summer-night/waybar.jsonc @@ -0,0 +1,99 @@ +{ + "margin-top": 0, + "margin-left": 120, + "margin-bottom": 0, + "margin-right": 120, + "height": 61, + "layer": "top", + "position": "top", + "spacing": 15, + "reload_style_on_change": true, + + "modules-left": ["custom/nomarchy", "clock", "clock#date"], + "modules-center": ["hyprland/workspaces"], + "modules-right": ["idle_inhibitor", "pulseaudio", "network", "battery", "tray", "custom/powermenu"], + + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": true, + "on-click": "activate", + "on-scroll-up": "hyprctl dispatch workspace r+1", + "on-scroll-down": "hyprctl dispatch workspace r-1", + "persistent-workspaces": { + "1": [], "2": [], "3": [], "4": [], "5": [], + "6": [], "7": [], "8": [], "9": [], "10": [] + } + }, + + "custom/nomarchy": { + "interval": "once", + "format": "󱄅", + "on-click": "nomarchy-menu", + "tooltip-format": "Nomarchy menu" + }, + + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": " 󰅶 ", + "deactivated": " 󰾪 " + } + }, + + "pulseaudio": { + "scroll-step": 5, + "format": "{icon} {volume}%", + "format-bluetooth": "{icon} {volume}%", + "format-bluetooth-muted": " {icon}", + "format-muted": " muted", + "format-icons": { + "headphone": "", + "hands-free": "", + "headset": "", + "phone": "", + "portable": "", + "car": "", + "default": ["", "", ""] + }, + "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", + "tooltip-format": "{desc} | {volume}%" + }, + + "network": { + "format-wifi": " {essid}", + "format-ethernet": "", + "format-disconnected": "󰤭", + "on-click": "sh -c '$TERMINAL -e nmtui'", + "tooltip-format": "{ipaddr} via {gwaddr}" + }, + + "battery": { + "interval": 30, + "states": { "warning": 25, "critical": 10 }, + "format": "{icon} {capacity}%", + "format-charging": " {capacity}%", + "format-plugged": " {capacity}%", + "format-icons": ["", "", "", "", ""], + "on-click": "nomarchy-menu power", + "tooltip-format": "Battery status" + }, + + "clock": { + "format": " {:%H:%M}", + "tooltip": true, + "tooltip-format": "{calendar}" + }, + + "clock#date": { + "format": " {:%A, %B %d, %Y}", + "tooltip": false + }, + + "tray": { "spacing": 8 }, + + "custom/powermenu": { + "format": "", + "on-click": "nomarchy-menu power", + "tooltip": false + } +}