# Hyprland — fully driven by config.nomarchy.theme (theme-state.json). # Gaps, borders and colors are baked from the JSON at eval time; theme # changes arrive via `home-manager switch`. { config, lib, ... }: let t = config.nomarchy.theme; c = t.colors; inherit (config.nomarchy.lib) rgb rgba; # SUPER+1..9 / SUPER+SHIFT+1..9 workspace binds, generated. workspaceBinds = builtins.concatLists (builtins.genList (i: let ws = toString (i + 1); in [ "$mod, ${ws}, workspace, ${ws}" "$mod SHIFT, ${ws}, movetoworkspace, ${ws}" ]) 9); in { wayland.windowManager.hyprland = lib.mkIf config.nomarchy.hyprland.enable { enable = true; # The binary and portal come from the NixOS module # (programs.hyprland.enable); HM only manages configuration. package = null; portalPackage = null; # HM defaults stateVersion >= 26.05 to the new Lua config and would # render these hyprlang-style settings as broken `hl.$mod(...)` Lua # (Hyprland then boots into emergency mode with no binds). configType = "hyprlang"; settings = { "$mod" = "SUPER"; "$terminal" = config.nomarchy.terminal; monitor = [ ",preferred,auto,1" ]; exec-once = [ # nixpkgs' swww is awww (renamed fork); the binary is awww-daemon. "awww-daemon" # Paint the wallpaper as soon as the session is up (waits for # the daemon internally). "nomarchy-theme-sync wallpaper" ]; # ── Theme-driven look ────────────────────────────────────────── general = { gaps_in = t.ui.gapsIn; gaps_out = t.ui.gapsOut; border_size = t.ui.borderSize; "col.active_border" = "${rgb c.accent} ${rgb c.accentAlt} 45deg"; "col.inactive_border" = rgb c.overlay; layout = "dwindle"; resize_on_border = true; }; decoration = { rounding = t.ui.rounding; active_opacity = t.ui.activeOpacity; inactive_opacity = t.ui.inactiveOpacity; blur = { enabled = t.ui.blur; size = 8; passes = 2; popups = true; }; shadow = { enabled = t.ui.shadow; range = 20; render_power = 3; color = rgba c.mantle "aa"; }; }; animations = { enabled = true; bezier = [ "smooth, 0.25, 0.1, 0.25, 1.0" "snappy, 0.6, 0.0, 0.1, 1.0" ]; animation = [ "windows, 1, 4, snappy, popin 85%" "border, 1, 8, smooth" "fade, 1, 5, smooth" "workspaces, 1, 4, snappy, slidefade 15%" ]; }; # ── Behaviour ────────────────────────────────────────────────── input = { kb_layout = "us"; follow_mouse = 1; touchpad.natural_scroll = true; }; # dwindle:pseudotile was removed in Hyprland 0.55 (the `pseudo` # dispatcher still exists); setting it aborts config parsing. dwindle.preserve_split = true; # Hyprland 0.51+ replaced gestures:workspace_swipe with the # gesture keyword — without this, touchpads have NO gestures. gesture = [ "3, horizontal, workspace" "4, pinch, fullscreen" ]; misc = { disable_hyprland_logo = true; disable_splash_rendering = true; force_default_wallpaper = 0; }; bind = [ "$mod, Return, exec, $terminal" "$mod, D, exec, fuzzel" "$mod, Q, killactive" "$mod, F, fullscreen" "$mod, V, togglefloating" "$mod SHIFT, E, exit" # Theme picker: fuzzel menu over the presets; apply writes the # state and runs home-manager switch (progress via notify-send). "$mod, T, exec, nomarchy-theme-sync apply \"$(nomarchy-theme-sync list | fuzzel --dmenu --prompt 'theme> ')\"" # Cycle the current theme's wallpapers (instant, no rebuild). "$mod SHIFT, T, exec, nomarchy-theme-sync bg next" # Focus "$mod, H, movefocus, l" "$mod, L, movefocus, r" "$mod, K, movefocus, u" "$mod, J, movefocus, d" # Screenshot region to clipboard ", Print, exec, grim -g \"$(slurp)\" - | wl-copy" ] ++ workspaceBinds; # Media keys: wpctl talks to wireplumber directly (no # pipewire-pulse shim like pamixer); e = repeat, l = also on a # locked screen — the standard flags for hardware keys. bindel = [ ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+" ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" ", XF86MonBrightnessUp, exec, brightnessctl set +5%" ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" ]; bindl = [ ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" ", XF86AudioPlay, exec, playerctl play-pause" ", XF86AudioPause, exec, playerctl play-pause" ", XF86AudioNext, exec, playerctl next" ", XF86AudioPrev, exec, playerctl previous" ]; bindm = [ "$mod, mouse:272, movewindow" "$mod, mouse:273, resizewindow" ]; }; }; }