From 428c2eb64f329f35b3cdcbf798a731dd5b61cb62 Mon Sep 17 00:00:00 2001 From: _cry64 Date: Sun, 22 Mar 2026 13:54:14 +1000 Subject: [PATCH] finally manage hyprland declaratively!! --- homes/modules/wm/hyprland/default.nix | 360 +++++++++++++++++++++++++- 1 file changed, 355 insertions(+), 5 deletions(-) diff --git a/homes/modules/wm/hyprland/default.nix b/homes/modules/wm/hyprland/default.nix index ee7ff2d..e82b8ee 100755 --- a/homes/modules/wm/hyprland/default.nix +++ b/homes/modules/wm/hyprland/default.nix @@ -1,10 +1,18 @@ # NOTE: hyprland must be enabled in BOTH your host config (for running hyprland) # NOTE: and your home-manager config (for managing hyprland's config files) -{...}: { +{ + hostname, + pkgs, + ... +}: { imports = [ ./kanshi.nix ]; + home.packages = with pkgs; [ + playerctl + ]; + wayland.windowManager.hyprland = { enable = true; package = null; @@ -12,15 +20,357 @@ xwayland.enable = true; - # systemd = { + # systemd= { # enable = true; # # enable autostart of applications # # REF: `man 8 systemd-xdg-autostart-generator` # enableXdgAutostart = true; # }; - # plugins = with inputs; [ - # split-monitor-workspaces.packages.${pkgs.system}.split - # ]; + settings = { + "$MOD" = "ALT"; + + # applications + "$editor" = "hx"; + "$terminal" = "foot"; + "$menu" = "fuzzel"; + "$colorpicker" = "hyprpicker | head -c 7 | wl-copy"; + "$screenshot_region" = "hyprshot -m region --clipboard-only"; + "$screenshot_window" = "hyprshot -m window --clipboard-only"; + "$cursorLock" = "~/scripts/bin/hyprland-cursor-lock"; + + # startup programs + exec-once = [ + "mako &" + "awww-daemon &" + + # "wl-paste --type text --watch cliphist store" + # "wl-paste --type image --watch cliphist store" + # "wl-clip-persist --clipboard regular" + # "playerctld daemon" + + "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP" + ]; + + # monitor configuration + monitor = + if hostname == "lolcathost" + then [ + "eDP-1, highres@highrr, 0x0, 1.0" # Programming + # "eDP-1, highres@highrr, 0x0, 1.5" # Comfy + ] + else if hostname == "myputer" + then [ + "DP-2, 3840x2160@59.99700, 0x0, 1.5" + "HDMI-A-1, 1920x1080@119.98Hz, 2560x0, 1.0" + ] + else []; + + # .__. .___ __..___. . . .___ .___. ._. __ __. + # [__] [__ (__ | |__| [__ | | / ` (__ + # | | [___ .__) | | | [___ | _|_ \__. .__) + general = { + gaps_in = 12; # margin between windows + gaps_out = 25; # margin from windows to monitor edge + gaps_workspaces = 0; # margin between workspaces (stacks with gaps_out) + # float_gaps = 0; # gaps_out but for floating windows + + border_size = 4; + + "col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg"; + "col.inactive_border" = "rgba(00000000)"; + + # Enable resizing windows by clicking and dragging the border + resize_on_border = true; + + # REF: https://wiki.hyprland.org/Configuring/Tearing/ + allow_tearing = false; + + layout = "dwindle"; + + snap = { + enabled = false; + window_gap = 10; + monitor_gap = 10; + border_overlap = false; + # respect_gaps = false; + }; + }; + + decoration = { + rounding = 20; + rounding_power = 4.0; # Lp norm + border_part_of_window = true; # consider border as part of its window + # screen_shader = ...; # path to custom GLSL fragment shader + + # window Transparency + active_opacity = 1.0; + inactive_opacity = 0.95; + fullscreen_opacity = 1.0; # fullscreened windows + # inactive Window Dimming + dim_inactive = false; + dim_strength = 0.5; + dim_special = 0.2; + dim_around = 0.4; + + blur = { + enabled = true; + new_optimizations = true; + xray = false; # floating windows xray through tiling windows + ignore_opacity = true; + + # blur Parameters + size = 8; + passes = 1; + noise = 0.0117; # default + contrast = 0.8916; # default + brightness = 0.8172; # default + vibrancy = 0.1696; # default + vibrancy_darkness = 0.0; # default + + # blurring For Specific Window Types + special = false; # blur special windows + popups = false; # blur popups + popups_ignorealpha = 0.2; + input_methods = false; + input_methods_ignorealpha = 0.2; + }; + + shadow = { + enabled = true; + ignore_window = true; # only render at edges (not behind) + + range = 3; + render_power = 1; # falloff rate + sharp = false; # aka infinite shadow.render_power + offset = "0 0"; # vec2 + scale = 1.0; + + color = "rgba(00000000)"; + color_inactive = "rgba(000000ff)"; # defaults to shadow.color if unset + }; + }; + + # REF: https://cubic-bezier.com + bezier = [ + "easeOutQuint,0.23,1,0.32,1" + "easeInOutCubic,0.65,0.05,0.36,1" + "linear,0,0,1,1" + "almostLinear,0.5,0.5,0.75,1.0" + "quick,0.15,0,0.1,1" + ]; + + # REF: https://wiki.hyprland.org/Configuring/Animations + # Animation Declaration Format: + # "animation = NAME, ENABLE, SPEED, BEZIER [,STYLE]" + # NOTE: SPEED is in ds (where 1ds = 100ms) + animations = [ + "global, 1, 10, default" + "border, 1, 5.39, easeOutQuint" + + "windowsIn, 1, 4, linear, slide bottom" + "windowsOut, 1, 10, linear, popin" + + "fadeIn, 1, 1.73, almostLinear" + "fadeOut, 1, 1.46, almostLinear" + "fade, 1, 3.03, quick" + + "layers, 1, 3.81, easeOutQuint" + "layersIn, 1, 4, easeOutQuint, fade" + "layersOut, 1, 1.5, linear, fade" + + "fadeLayersIn, 1, 1.79, almostLinear" + "fadeLayersOut, 1, 1.39, almostLinear" + + "workspaces, 1, 1.94, almostLinear, fade" + "workspacesIn, 1, 1.21, almostLinear, fade" + "workspacesOut, 1, 1.94, almostLinear, fade" + ]; + + # REF: https://wiki.hyprland.org/Configuring/Dwindle-Layout + dwindle = { + # master switch for pseudotiling. enabling is bound to MOD + P in the keybinds section below + pseudotile = true; + preserve_split = true; # You probably want this + }; + + # REF: https://wiki.hyprland.org/Configuring/Master-Layout + master = { + new_status = "master"; + }; + + misc = { + #force_default_wallpaper = -1; # Set to 0 or 1 to disable the anime mascot wallpapers + disable_hyprland_logo = true; + disable_splash_rendering = true; + + enable_anr_dialog = false; + font_family = "Geist Mono"; + }; + + input = { + # kb_layout = "us"; + # kb_variant = + # kb_model = + # kb_options = + # kb_rules = + + follow_mouse = 1; + + sensitivity = 0; # -1.0 - 1.0, 0 means no modification + accel_profile = "flat"; + force_no_accel = false; # not recommended to turn on + + repeat_rate = 50; + repeat_delay = 300; + + touchpad = { + natural_scroll = hostname == "lolcathost"; + }; + }; + + cursor.no_hardware_cursors = true; + + # standard keypress bindings + bind = [ + # terminal commands + "$MOD, RETURN, exec, $terminal" + "$MOD SHIFT, RETURN, exec, $terminal -D `[ -f ~/cry/.projdir ] && cat ~/cry/.projdir || echo ~`" + + # btop + "$MOD, P, exec, bash -c \"{ hyprctl clients | rg '^\w*title: btop' &>/dev/null; } && hyprctl dispatch closewindow title:btop || $terminal -T btop btop & disown\"" + + "$MOD, R, exec, $menu" + + # lock mouse to window (mostly, for gaming) + "$MOD, F1, exec, pkill hyprland-cursor || $cursorLock" + "$MOD, F2, exec, $colorpicker" + + # screenshots + "$MOD, S, exec, $screenshot_region" + "$MOD SHIFT, S, exec, $screenshot_window" + + "$MOD, F, fullscreen" + "$MOD SHIFT, F, fullscreenstate, 0 3" # fakefullscreen + "$MOD, C, killactive" + "$MOD SHIFT, Delete, exit" + + # switch window + "$MOD, left, movefocus, l" + "$MOD, right, movefocus, r" + "$MOD, up, movefocus, u" + "$MOD, down, movefocus, d" + "$MOD, H, movefocus, l" + "$MOD, J, movefocus, d" + "$MOD, K, movefocus, u" + "$MOD, L, movefocus, r" + + # switch workspaces + "$MOD, 1, workspace, 1" + "$MOD, 2, workspace, 2" + "$MOD, 3, workspace, 3" + "$MOD, 4, workspace, 4" + "$MOD, 5, workspace, 5" + "$MOD, 6, workspace, 6" + "$MOD, 7, workspace, 7" + "$MOD, 8, workspace, 8" + "$MOD, 9, workspace, 9" + "$MOD, 0, workspace, 10" + "$MOD SHIFT, left, workspace, e-1" + "$MOD SHIFT, right, workspace, e+1" + + # move window to workspace + "$MOD SHIFT, 1, movetoworkspace, 1" + "$MOD SHIFT, 2, movetoworkspace, 2" + "$MOD SHIFT, 3, movetoworkspace, 3" + "$MOD SHIFT, 4, movetoworkspace, 4" + "$MOD SHIFT, 5, movetoworkspace, 5" + "$MOD SHIFT, 6, movetoworkspace, 6" + "$MOD SHIFT, 7, movetoworkspace, 7" + "$MOD SHIFT, 8, movetoworkspace, 8" + "$MOD SHIFT, 9, movetoworkspace, 9" + "$MOD SHIFT, 0, movetoworkspace, 10" + + # move workspace to monitor + "$MOD TAB, 1, movecurrentworkspacetomonitor, DP-2" + "$MOD TAB, 2, movecurrentworkspacetomonitor, HDMA-A-1" + ]; + + # bindings for mouse + bindm = [ + "$MOD, mouse:272, movewindow" + "$MOD, mouse:273, resizewindow" + ]; + + # bindings that work even while screen is locked + bindl = [ + # WARNING: requires `pkgs.playerctl` + ", XF86AudioNext, exec, playerctl next" + ", XF86AudioPause, exec, playerctl play-pause" + ", XF86AudioPlay, exec, playerctl play-pause" + ", XF86AudioPrev, exec, playerctl previous" + ]; + + # bindings that work even while screen is locked + # and also repeat when the key is held + bindel = [ + ",XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+" + ",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" + ",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" + ",XF86MonBrightnessUp, exec, brightnessctl s 10%+" + ",XF86MonBrightnessDown, exec, brightnessctl s 10%-" + ]; + + windowrule = [ + # btop process manager + { + name = "terminal-manager"; + "match:class" = "^(foot)$"; + "match:title" = "^(btop)$"; + float = true; + center = true; + size = "(monitor_w*0.65) (monitor_h*0.65)"; + } + + # ignore maximize requests from apps + { + name = "suppress-maximize"; + suppress_event = "maximize"; + "match:class" = ".*"; + } + + # fix some dragging issues with XWayland + { + name = "no-focus"; + no_focus = "on"; + "match:class" = "^$"; + "match:title" = "^$"; + "match:xwayland" = true; + "match:float" = true; + "match:fullscreen" = false; + "match:pin" = false; + } + + # TODO: style fakefullscreen windows to clearly indicate their difference + # { + # name = "fake-fullscreen"; + # } + ]; + + # █▀▀ █▄░█ █░█   █░█ ▄▀█ █▀█ + # ██▄ █░▀█ ▀▄▀   ▀▄▀ █▀█ █▀▄ + env = [ + "XCURSOR_THEME,Bibata-Modern-Ice" + "XCURSOR_SIZE,16" + "HYPRCURSOR_THEME,Bibata-Modern-Ice" + "HYPRCURSOR_SIZE,16" + + "QT_QPA_PLATFORM,wayland" + "QT_QPA_PLATFORMTHEME,xdgdesktopportal" # makes portals work correctly + "XDG_MENU_PREFIX,arch-" + "XDG_CURRENT_DESKTOP,Hyprland" + ]; + }; }; }