{ pkgs, lib, ... }: let mkLua = lib.generators.mkLuaInline; in { wayland.windowManager.hyprland = { enable = true; configType = "lua"; package = null; # Hyprland package is managed system-wide via NixOS programs.hyprland settings = { # ----------------------------------------------------------------------- # 1. Variables & Modifiers (Rendered as Lua local variables) # ----------------------------------------------------------------------- mainMod = { _var = "SUPER"; }; terminal = { _var = "foot"; }; browser = { _var = "brave"; }; # ----------------------------------------------------------------------- # 2. Monitors (hl.monitor) # ----------------------------------------------------------------------- monitor = [ { output = "eDP-2"; mode = "3840x2160@144"; position = "0x0"; scale = 2; } { output = "desc:Dell Inc. DELL U3419W 28DQ5T2"; mode = "3440x1440@60"; position = "0x-1440"; scale = 1; } { output = "desc:Samsung Electric Company Odyssey Ark H1AK500000"; mode = "3840x2160@144"; position = "3840x0"; scale = 1; } { output = ""; mode = "preferred"; position = "auto"; scale = "auto"; } ]; # ----------------------------------------------------------------------- # 3. Environment Variables (hl.env) # ----------------------------------------------------------------------- env = [ { _args = [ "XCURSOR_SIZE" "24" ]; } { _args = [ "LIBVA_DRIVE_NAME" "nvidia" ]; } { _args = [ "XDG_SESSION_TYPE" "wayland" ]; } { _args = [ "GBM_BACKEND" "nvidia-drm" ]; } { _args = [ "WLR_NO_HARDWARE_CURSORS" "1" ]; } { _args = [ "WLR_DRM_DEVICES" "/dev/dri/card1:/dev/dri/card0" ]; } ]; # ----------------------------------------------------------------------- # 4. Main Configuration (hl.config) - Strictly validates against Hyprland 0.55+ schema # ----------------------------------------------------------------------- config = { input = { kb_layout = "us"; repeat_delay = 300; repeat_rate = 50; follow_mouse = 1; sensitivity = 0; touchpad = { natural_scroll = false; }; }; cursor = { inactive_timeout = 3; }; general = { gaps_in = 5; gaps_out = 10; border_size = 2; col = { active_border = { colors = [ "rgba(33ccffee)" "rgba(00ff99ee)" ]; angle = 45; }; inactive_border = "rgba(595959aa)"; }; layout = "dwindle"; }; group = { groupbar = { font_size = 14; font_family = "SF Pro Display"; col = { active = "rgba(33ccff00)"; inactive = "rgba(59595900)"; }; }; col = { border_active = { colors = [ "rgba(33ccffee)" "rgba(00ff99ee)" ]; angle = 45; }; border_inactive = "rgba(595959aa)"; }; }; misc = { disable_hyprland_logo = true; disable_splash_rendering = true; }; decoration = { rounding = 10; blur = { enabled = false; size = 3; passes = 1; }; shadow = { enabled = false; range = 4; render_power = 3; color = "rgba(1a1a1aee)"; }; }; animations = { enabled = true; }; dwindle = { preserve_split = true; }; master = { new_status = "master"; }; }; # ----------------------------------------------------------------------- # 5. Curves & Animations (hl.curve & hl.animation) # ----------------------------------------------------------------------- curve = [ { _args = [ "myBezier" { type = "bezier"; points = [ [ 0.05 0.9 ] [ 0.1 1.05 ] ]; } ]; } ]; animation = [ { leaf = "windows"; enabled = true; speed = 7; bezier = "myBezier"; } { leaf = "windowsOut"; enabled = true; speed = 7; bezier = "default"; style = "popin 80%"; } { leaf = "border"; enabled = true; speed = 10; bezier = "default"; } { leaf = "borderangle"; enabled = true; speed = 8; bezier = "default"; } { leaf = "fade"; enabled = true; speed = 7; bezier = "default"; } { leaf = "workspaces"; enabled = true; speed = 6; bezier = "default"; } ]; # ----------------------------------------------------------------------- # 6. Autostart Daemons & Apps (hl.on) # ----------------------------------------------------------------------- on = [ { _args = [ "hyprland.start" (mkLua ''function() hl.exec_cmd("waybar") hl.exec_cmd("hyprpaper") hl.exec_cmd("swayidle -w") hl.exec_cmd("swaync") hl.exec_cmd("/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1") hl.exec_cmd("hyprlock") end'') ]; } ]; # ----------------------------------------------------------------------- # 7. Keybindings (hl.bind) # ----------------------------------------------------------------------- bind = [ # Launchers & Window Controls { _args = [ (mkLua "mainMod .. \" + Q\"") (mkLua "hl.dsp.exec_cmd(terminal)") ]; } { _args = [ (mkLua "mainMod .. \" + C\"") (mkLua "hl.dsp.window.close()") ]; } { _args = [ (mkLua "mainMod .. \" + N\"") (mkLua "hl.dsp.exec_cmd(\"swaync-client -t -sw\")") ]; } { _args = [ (mkLua "mainMod .. \" + V\"") (mkLua "hl.dsp.window.float({ action = \"toggle\" })") ]; } { _args = [ (mkLua "mainMod .. \" + R\"") (mkLua "hl.dsp.exec_cmd(\"rofi -show combi -show-icons\")") ]; } { _args = [ (mkLua "mainMod .. \" + G\"") (mkLua "hl.dsp.group.toggle()") ]; } { _args = [ (mkLua "mainMod .. \" + F\"") (mkLua "hl.dsp.window.fullscreen({ fullscreen = 0 })") ]; } # Move focus with mainMod + vim { _args = [ (mkLua "mainMod .. \" + h\"") (mkLua "hl.dsp.focus({ direction = \"left\" })") ]; } { _args = [ (mkLua "mainMod .. \" + l\"") (mkLua "hl.dsp.focus({ direction = \"right\" })") ]; } { _args = [ (mkLua "mainMod .. \" + k\"") (mkLua "hl.dsp.focus({ direction = \"up\" })") ]; } { _args = [ (mkLua "mainMod .. \" + j\"") (mkLua "hl.dsp.focus({ direction = \"down\" })") ]; } # Move focus within a grouped page { _args = [ (mkLua "mainMod .. \" + e\"") (mkLua "hl.dsp.group.next()") ]; } { _args = [ (mkLua "mainMod .. \" + d\"") (mkLua "hl.dsp.group.prev()") ]; } # Move window or group with vim keys { _args = [ (mkLua "mainMod .. \" + SHIFT + h\"") (mkLua "hl.dsp.window.move({ direction = \"left\" })") ]; } { _args = [ (mkLua "mainMod .. \" + SHIFT + l\"") (mkLua "hl.dsp.window.move({ direction = \"right\" })") ]; } { _args = [ (mkLua "mainMod .. \" + SHIFT + k\"") (mkLua "hl.dsp.window.move({ direction = \"up\" })") ]; } { _args = [ (mkLua "mainMod .. \" + SHIFT + j\"") (mkLua "hl.dsp.window.move({ direction = \"down\" })") ]; } # Scroll through existing workspaces with mainMod + scroll { _args = [ (mkLua "mainMod .. \" + mouse_down\"") (mkLua "hl.dsp.focus({ workspace = \"e+1\" })") ]; } { _args = [ (mkLua "mainMod .. \" + mouse_up\"") (mkLua "hl.dsp.focus({ workspace = \"e-1\" })") ]; } # Lock shortcut { _args = [ (mkLua "mainMod .. \" + S\"") (mkLua "hl.dsp.exec_cmd(\"wlogout\")") ]; } # Quick access applications { _args = [ (mkLua "mainMod .. \" + b\"") (mkLua "hl.dsp.exec_cmd(browser)") ]; } { _args = [ (mkLua "mainMod .. \" + t\"") (mkLua "hl.dsp.exec_cmd(\"thunderbird\")") ]; } # Scratch workspace { _args = [ (mkLua "mainMod .. \" + RETURN\"") (mkLua "hl.dsp.workspace.toggle_special(\"scratch\")") ]; } { _args = [ (mkLua "mainMod .. \" + SHIFT + RETURN\"") (mkLua "hl.dsp.window.move({ workspace = \"special:scratch\" })") ]; } # Messaging workspace { _args = [ (mkLua "mainMod .. \" + M\"") (mkLua "hl.dsp.workspace.toggle_special(\"messaging\")") ]; } # Move/resize windows with mouse and dragging { _args = [ (mkLua "mainMod .. \" + mouse:272\"") (mkLua "hl.dsp.window.drag()") { mouse = true; } ]; } { _args = [ (mkLua "mainMod .. \" + mouse:273\"") (mkLua "hl.dsp.window.resize()") { mouse = true; } ]; } # Function Row Keys { _args = [ "XF86AudioRaiseVolume" (mkLua "hl.dsp.exec_cmd(\"pactl -- set-sink-volume @DEFAULT_SINK@ +5%\")") { repeating = true; } ]; } { _args = [ "XF86AudioLowerVolume" (mkLua "hl.dsp.exec_cmd(\"pactl -- set-sink-volume @DEFAULT_SINK@ -5%\")") { repeating = true; locked = true; } ]; } { _args = [ "XF86AudioMute" (mkLua "hl.dsp.exec_cmd(\"pactl -- set-sink-mute @DEFAULT_SINK@ toggle\")") { repeating = true; locked = true; } ]; } { _args = [ "XF86MonBrightnessUp" (mkLua "hl.dsp.exec_cmd(\"brightnessctl -d acpi_video0 set 5%+\")") { repeating = true; locked = true; } ]; } { _args = [ "XF86MonBrightnessDown" (mkLua "hl.dsp.exec_cmd(\"brightnessctl -d acpi_video0 set 5%-\")") { repeating = true; locked = true; } ]; } # Lid switch { _args = [ "switch:off:Lid Switch" (mkLua "hl.dsp.exec_cmd(\"hyprctl keyword monitor \\\"eDP-2,3840x2160@144,0x0,2\\\"\")") { locked = true; } ]; } { _args = [ "switch:on:Lid Switch" (mkLua "hl.dsp.exec_cmd(\"hyprctl keyword monitor \\\"eDP-2, disable\\\"\")") { locked = true; } ]; } ] # Workspace 1-9 switching and moving ++ (lib.concatMap (i: [ { _args = [ (mkLua "mainMod .. \" + ${toString i}\"") (mkLua "hl.dsp.focus({ workspace = ${toString i} })") ]; } { _args = [ (mkLua "mainMod .. \" + SHIFT + ${toString i}\"") (mkLua "hl.dsp.window.move({ workspace = ${toString i} })") ]; } ]) (lib.range 1 9)) # Workspace 10 switching and moving (mapped to key 0) ++ [ { _args = [ (mkLua "mainMod .. \" + 0\"") (mkLua "hl.dsp.focus({ workspace = 10 })") ]; } { _args = [ (mkLua "mainMod .. \" + SHIFT + 0\"") (mkLua "hl.dsp.window.move({ workspace = 10 })") ]; } ]; # ----------------------------------------------------------------------- # 8. Workspace Rules (hl.workspace_rule) # ----------------------------------------------------------------------- workspace_rule = [ { workspace = "name:messaging"; on_created_empty = "[] togglegroup"; } ]; # ----------------------------------------------------------------------- # 9. Window Rules (hl.window_rule) # ----------------------------------------------------------------------- window_rule = [ { name = "signal-messaging"; match = { class = "Signal"; }; workspace = "special:messaging"; } { name = "webcord-messaging"; match = { class = "WebCord"; }; workspace = "special:messaging"; } { name = "ghidra-tile"; match = { class = "ghidra-Ghidra"; }; float = false; } ]; }; }; }