# Omarchy-style Hyprland desktop (classic dotfiles Omarchy, ported to a # no-home-manager NixOS system module). Imported ONLY by hw/straylight, so # the other desktop hosts (imladris, ono-sendai) keep i3. # # Layout mirrors Omarchy v3: # ~/.config/{hypr,waybar,rofi,wlogout,swayosd,alacritty} -> read-only store links # ~/.local/share/omarchy -> store payload (themes/, bin/) # ~/.config/omarchy/current/ -> mutable state # (theme + background) # # Theme colours are generated at build time from each theme's palette # (Omarchy themes//colors.toml) into themes//{hyprland.conf, # hyprlock.conf,waybar.css,rofi.rasi,swayosd.css,wlogout.css,alacritty.toml, # mako.ini}. Wallpapers are fetched from the Omarchy v3.8.4 tag. { config, lib, pkgs, ... }: let inherit (lib) mkForce mapAttrsToList concatMapStrings; user = "kyle"; home = "/home/${user}"; omarchyPath = "${home}/.local/share/omarchy"; current = "${home}/.config/omarchy/current"; defaultTheme = "tokyo-night"; # ---- Omarchy themes/*/colors.toml ---- themes = { tokyo-night = { accent = "#7aa2f7"; cursor = "#c0caf5"; foreground = "#a9b1d6"; background = "#1a1b26"; selection_foreground = "#c0caf5"; selection_background = "#7aa2f7"; color0 = "#32344a"; color1 = "#f7768e"; color2 = "#9ece6a"; color3 = "#e0af68"; color4 = "#7aa2f7"; color5 = "#ad8ee6"; color6 = "#449dab"; color7 = "#787c99"; color8 = "#444b6a"; color9 = "#ff7a93"; color10 = "#b9f27c"; color11 = "#ff9e64"; color12 = "#7da6ff"; color13 = "#bb9af7"; color14 = "#0db9d7"; color15 = "#acb0d0"; }; catppuccin = { accent = "#89b4fa"; cursor = "#f5e0dc"; foreground = "#cdd6f4"; background = "#1e1e2e"; selection_foreground = "#1e1e2e"; selection_background = "#f5e0dc"; color0 = "#45475a"; color1 = "#f38ba8"; color2 = "#a6e3a1"; color3 = "#f9e2af"; color4 = "#89b4fa"; color5 = "#f5c2e7"; color6 = "#94e2d5"; color7 = "#bac2de"; color8 = "#585b70"; color9 = "#f38ba8"; color10 = "#a6e3a1"; color11 = "#f9e2af"; color12 = "#89b4fa"; color13 = "#f5c2e7"; color14 = "#94e2d5"; color15 = "#a6adc8"; }; gruvbox = { accent = "#7daea3"; cursor = "#bdae93"; foreground = "#d4be98"; background = "#282828"; selection_foreground = "#ebdbb2"; selection_background = "#d65d0e"; color0 = "#3c3836"; color1 = "#ea6962"; color2 = "#a9b665"; color3 = "#d8a657"; color4 = "#7daea3"; color5 = "#d3869b"; color6 = "#89b482"; color7 = "#d4be98"; color8 = "#3c3836"; color9 = "#ea6962"; color10 = "#a9b665"; color11 = "#d8a657"; color12 = "#7daea3"; color13 = "#d3869b"; color14 = "#89b482"; color15 = "#d4be98"; }; kanagawa = { accent = "#7e9cd8"; cursor = "#c8c093"; foreground = "#dcd7ba"; background = "#1f1f28"; selection_foreground = "#c8c093"; selection_background = "#2d4f67"; color0 = "#090618"; color1 = "#c34043"; color2 = "#76946a"; color3 = "#c0a36e"; color4 = "#7e9cd8"; color5 = "#957fb8"; color6 = "#6a9589"; color7 = "#c8c093"; color8 = "#727169"; color9 = "#e82424"; color10 = "#98bb6c"; color11 = "#e6c384"; color12 = "#7fb4ca"; color13 = "#938aa9"; color14 = "#7aa89f"; color15 = "#dcd7ba"; }; everforest = { accent = "#7fbbb3"; cursor = "#d3c6aa"; foreground = "#d3c6aa"; background = "#2d353b"; selection_foreground = "#2d353b"; selection_background = "#d3c6aa"; color0 = "#475258"; color1 = "#e67e80"; color2 = "#a7c080"; color3 = "#dbbc7f"; color4 = "#7fbbb3"; color5 = "#d699b6"; color6 = "#83c092"; color7 = "#d3c6aa"; color8 = "#475258"; color9 = "#e67e80"; color10 = "#a7c080"; color11 = "#dbbc7f"; color12 = "#7fbbb3"; color13 = "#d699b6"; color14 = "#83c092"; color15 = "#d3c6aa"; }; nord = { accent = "#81a1c1"; cursor = "#d8dee9"; foreground = "#d8dee9"; background = "#2e3440"; selection_foreground = "#d8dee9"; selection_background = "#4c566a"; color0 = "#3b4252"; color1 = "#bf616a"; color2 = "#a3be8c"; color3 = "#ebcb8b"; color4 = "#81a1c1"; color5 = "#b48ead"; color6 = "#88c0d0"; color7 = "#e5e9f0"; color8 = "#4c566a"; color9 = "#bf616a"; color10 = "#a3be8c"; color11 = "#ebcb8b"; color12 = "#81a1c1"; color13 = "#b48ead"; color14 = "#8fbcbb"; color15 = "#eceff4"; }; rose-pine = { accent = "#56949f"; cursor = "#cecacd"; foreground = "#575279"; background = "#faf4ed"; selection_foreground = "#575279"; selection_background = "#dfdad9"; color0 = "#f2e9e1"; color1 = "#b4637a"; color2 = "#286983"; color3 = "#ea9d34"; color4 = "#56949f"; color5 = "#907aa9"; color6 = "#d7827e"; color7 = "#575279"; color8 = "#9893a5"; color9 = "#b4637a"; color10 = "#286983"; color11 = "#ea9d34"; color12 = "#56949f"; color13 = "#907aa9"; color14 = "#d7827e"; color15 = "#575279"; }; hackerman = { accent = "#82FB9C"; cursor = "#ddf7ff"; foreground = "#ddf7ff"; background = "#0B0C16"; selection_foreground = "#0B0C16"; selection_background = "#ddf7ff"; color0 = "#3E4058"; color1 = "#50f872"; color2 = "#4fe88f"; color3 = "#50f7d4"; color4 = "#829dd4"; color5 = "#86a7df"; color6 = "#7cf8f7"; color7 = "#85E1FB"; color8 = "#6a6e95"; color9 = "#85ff9d"; color10 = "#9cf7c2"; color11 = "#a4ffec"; color12 = "#c4d2ed"; color13 = "#cddbf4"; color14 = "#d1fffe"; color15 = "#ddf7ff"; }; }; # ---- Omarchy themes//backgrounds/ (v3.8.4) ---- wallpapers = { tokyo-night = [ { file = "1-sunset-lake.png"; hash = "sha256-Bt+5/OAp7DWttA6jk5KWd3wrFA0SMrWhaXsVBS1XU2I="; } { file = "2-pawel-czerwinski.jpg"; hash = "sha256-acxN1KQHwH9VRgD549BP7AKTuMiF3dhR/lg+/C6ty1I="; } { file = "4-oma-cityscape.jpg"; hash = "sha256-IuHWOXIrM/pvDTrCczRQtLrpYbSB9WZcsWOXvF9xTlw="; } ]; catppuccin = [ { file = "1-totoro.png"; hash = "sha256-O8+rFOjnsEEwfLd9cAxpWRYP5/bV3mMbFb0C3gz42f8="; } { file = "2-waves.png"; hash = "sha256-VjGQ35WJvrLVEX1A2wLGSSMqtrw8Py622Xqfs1haDP0="; } ]; gruvbox = [ { file = "1-the-backwater.jpg"; hash = "sha256-E8/GrjcK+YTAioIP+BtWoP67D7/pcSptsSi5TRTsqsY="; } { file = "4-idyllic-procession.jpg"; hash = "sha256-vgrnMmOl62lBb7E1R4JqYIBoWaoxuwMQU6/HPeYKVcU="; } { file = "5-leaves.jpg"; hash = "sha256-zb0817NKLI5+dIGK9RAahTF4aHiwo6/Lj2mFsnOU9m0="; } ]; kanagawa = [ { file = "1-kanagawa.jpg"; hash = "sha256-m4F9cXaIU58NuHYDtmGZKDnDy7XUkYoCpO/AXJ+Isn0="; } ]; everforest = [ { file = "1-tree-tops.jpg"; hash = "sha256-DwCl4tD3jV51x6L0gQH23uaRecbZTp9OvG+3wPOUYr8="; } ]; nord = [ { file = "1-city-view.png"; hash = "sha256-sRhvp+5OnZAIe4aTTE3jGoZ9qkojxAGIUYGwe6Ev/3U="; } { file = "2-night-hawks.png"; hash = "sha256-YaS8ScE3ERId6H9ffyQH/4I1BRzRf5ze1+IOFbGdVpI="; } ]; rose-pine = [ { file = "1-funky-shapes.jpg"; hash = "sha256-b1qeo9wiP76RBGfMc5Z7pt2ffoCn2Aa8FemFVj0V/gM="; } ]; hackerman = [ { file = "1-synth-scape.jpg"; hash = "sha256-x9JZSTXyBODfG0Pf56EjieocHT/Y5XqSqfCEl/J6N34="; } ]; }; # ---- helpers ---- hexDigits = { "0" = 0; "1" = 1; "2" = 2; "3" = 3; "4" = 4; "5" = 5; "6" = 6; "7" = 7; "8" = 8; "9" = 9; "a" = 10; "b" = 11; "c" = 12; "d" = 13; "e" = 14; "f" = 15; }; hexToRgb = hex: let s = lib.toLower (lib.removePrefix "#" hex); dig = i: hexDigits.${builtins.substring i 1 s}; byte = i: (dig (i * 2)) * 16 + (dig (i * 2 + 1)); in "${toString (byte 0)},${toString (byte 1)},${toString (byte 2)}"; strip = hex: lib.removePrefix "#" hex; mkFile = name: text: pkgs.writeText name text; themeDir = name: t: let bgs = wallpapers.${name} or [ ]; hyprlandConf = mkFile "hyprland.conf" '' $activeBorderColor = rgb(${strip t.accent}) general { col.active_border = $activeBorderColor } group { col.border_active = $activeBorderColor } ''; hyprlockConf = mkFile "hyprlock.conf" '' $color = rgba(${hexToRgb t.background}, 1.0) $inner_color = rgba(${hexToRgb t.background}, 0.8) $outer_color = rgba(${hexToRgb t.foreground}, 1.0) $font_color = rgba(${hexToRgb t.foreground}, 1.0) $check_color = rgba(${hexToRgb t.accent}, 1.0) ''; waybarCss = mkFile "waybar.css" '' @define-color foreground ${t.foreground}; @define-color background ${t.background}; ''; swayosdCss = mkFile "swayosd.css" '' @define-color background ${t.background}; @define-color border-color ${t.foreground}; @define-color label ${t.foreground}; @define-color image ${t.foreground}; @define-color progress ${t.accent}; ''; wlogoutCss = mkFile "wlogout.css" '' @define-color background ${t.background}; @define-color foreground ${t.foreground}; @define-color accent ${t.accent}; ''; rofiRasi = mkFile "rofi.rasi" '' * { bg: ${t.background}; fg: ${t.foreground}; accent: ${t.accent}; background-color: @bg; text-color: @fg; border: 2px; border-color: @accent; border-radius: 0; padding: 8px; spacing: 6px; font: "JetBrainsMono Nerd Font 12"; } window { width: 40%; background-color: @bg; border: 2px; border-color: @accent; } inputbar { background-color: @bg; text-color: @fg; } listview { lines: 10; background-color: @bg; } element { padding: 4px; } element selected { background-color: @accent; text-color: @bg; } ''; alacrittyToml = mkFile "alacritty.toml" '' [colors.primary] background = "${t.background}" foreground = "${t.foreground}" [colors.cursor] text = "${t.background}" cursor = "${t.cursor}" [colors.vi_mode_cursor] text = "${t.background}" cursor = "${t.cursor}" [colors.selection] text = "${t.selection_foreground}" background = "${t.selection_background}" [colors.normal] black = "${t.color0}" red = "${t.color1}" green = "${t.color2}" yellow = "${t.color3}" blue = "${t.color4}" magenta = "${t.color5}" cyan = "${t.color6}" white = "${t.color7}" [colors.bright] black = "${t.color8}" red = "${t.color9}" green = "${t.color10}" yellow = "${t.color11}" blue = "${t.color12}" magenta = "${t.color13}" cyan = "${t.color14}" white = "${t.color15}" ''; makoIni = mkFile "mako.ini" '' text-color=${t.foreground} border-color=${t.accent} background-color=${t.background} width=420 height=110 padding=10 margin=10 border-size=2 border-radius=0 anchor=top-right layer=overlay default-timeout=5000 max-visible=5 font=JetBrainsMono Nerd Font 10 ''; in pkgs.runCommand "omarchy-theme-${name}" { } '' mkdir -p $out/backgrounds cp ${hyprlandConf} $out/hyprland.conf cp ${hyprlockConf} $out/hyprlock.conf cp ${waybarCss} $out/waybar.css cp ${swayosdCss} $out/swayosd.css cp ${wlogoutCss} $out/wlogout.css cp ${rofiRasi} $out/rofi.rasi cp ${alacrittyToml} $out/alacritty.toml cp ${makoIni} $out/mako.ini ${concatMapStrings (b: '' cp ${pkgs.fetchurl { url = "https://raw.githubusercontent.com/omacom/omarchy/v3.8.4/themes/${name}/backgrounds/${b.file}"; hash = b.hash; }} $out/backgrounds/${b.file} '') bgs} ''; themesTree = pkgs.linkFarm "omarchy-themes" (mapAttrsToList (n: t: { name = n; path = themeDir n t; }) themes); omarchyDots = pkgs.runCommand "omarchy-dots" { } '' mkdir -p $out cp -r ${./omarchy/hypr} $out/hypr cp -r ${./omarchy/waybar} $out/waybar cp -r ${./omarchy/rofi} $out/rofi cp -r ${./omarchy/wlogout} $out/wlogout cp -r ${./omarchy/swayosd} $out/swayosd cp -r ${./omarchy/alacritty} $out/alacritty cp -r ${themesTree} $out/themes ''; omarchyBin = pkgs.runCommand "omarchy-bin" { } '' mkdir -p $out/bin cp ${./omarchy/bin}/* $out/bin/ chmod +x $out/bin/* ''; polkitAgent = pkgs.writeShellScriptBin "omarchy-polkit-agent" '' exec ${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1 ''; in { programs.hyprland = { enable = true; systemd.setPath.enable = true; }; # Hyprland is the default login session. i3 stays enabled (configs/desktop-light.nix) # and remains selectable in lightdm as a fallback. services.displayManager.defaultSession = "hyprland"; # Hyprland's own portal should be the default (desktop-light.nix sets gtk). xdg.portal = { config.common.default = mkForce "hyprland"; extraPortals = [ pkgs.xdg-desktop-portal-hyprland ]; }; environment.systemPackages = with pkgs; [ omarchyBin polkitAgent waybar rofi wlogout hyprlock hypridle swayosd mako clipse wl-clipboard wl-clip-persist grim slurp hyprpicker brightnessctl pamixer playerctl alacritty swaybg jq gnome-calculator pavucontrol nautilus nerd-fonts.jetbrains-mono ]; # Link the read-only config into ~/.config, seed the mutable theme state, and # resolve the active theme/background symlinks. Runs on every switch/boot. system.activationScripts.omarchy-dots = { deps = [ "users" ]; text = '' set -eu export PATH=${lib.makeBinPath [ pkgs.coreutils pkgs.findutils pkgs.bash ]}:$PATH install -d -m0755 -o ${user} -g users ${home}/.config ${home}/.local/share ${current} ln -sfnT ${omarchyDots}/hypr ${home}/.config/hypr ln -sfnT ${omarchyDots}/waybar ${home}/.config/waybar ln -sfnT ${omarchyDots}/rofi ${home}/.config/rofi ln -sfnT ${omarchyDots}/wlogout ${home}/.config/wlogout ln -sfnT ${omarchyDots}/swayosd ${home}/.config/swayosd ln -sfnT ${omarchyDots}/alacritty ${home}/.config/alacritty ln -sfnT ${omarchyDots} ${omarchyPath} [ -f ${current}/theme.name ] || printf '%s\n' ${defaultTheme} > ${current}/theme.name chown -R ${user}:users ${home}/.config/omarchy HOME=${home} OMARCHY_PATH=${omarchyPath} ${omarchyBin}/bin/omarchy-theme-apply chown -h ${user}:users ${current}/theme ${current}/background 2>/dev/null || true ''; }; }