diff --git a/modules/home/programs/graphical/wms/hyprland/config/hyprland.conf b/modules/home/programs/graphical/wms/hyprland/config/hyprland.conf deleted file mode 100755 index 8ddf764..0000000 --- a/modules/home/programs/graphical/wms/hyprland/config/hyprland.conf +++ /dev/null @@ -1,153 +0,0 @@ -exec-once = uwsm app -- waybar -exec-once = uwsm app -- $terminal -exec-once = uwsm app -- firefox - -general { - gaps_in = 5 - gaps_out = 12 - - border_size = 2 - - # https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors - col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg - col.inactive_border = rgba(595959aa) - - # Set to true enable resizing windows by clicking and dragging on borders and gaps - resize_on_border = false - - # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on - allow_tearing = false - - layout = dwindle -} - -# https://wiki.hyprland.org/Configuring/Variables/#decoration -decoration { - rounding = 10 - - active_opacity = 1.0 - inactive_opacity = 1.0 - - shadow { - enabled = true - range = 4 - render_power = 3 - color = rgba(1a1a1aee) - } - - blur { - enabled = true - size = 3 - passes = 1 - vibrancy = 0.1696 - } -} - -# https://wiki.hyprland.org/Configuring/Variables/#animations -animations { - enabled = yes, please :) - - - bezier = easeOutQuint,0.23,1,0.32,1 - bezier = easeInOutCubic,0.65,0.05,0.36,1 - bezier = linear,0,0,1,1 - bezier = almostLinear,0.5,0.5,0.75,1.0 - bezier = quick,0.15,0,0.1,1 - - animation = global, 1, 10, default - animation = border, 1, 5.39, easeOutQuint - animation = windows, 1, 4.79, easeOutQuint - animation = windowsIn, 1, 4.1, easeOutQuint, popin 87% - animation = windowsOut, 1, 1.49, linear, popin 87% - animation = fadeIn, 1, 1.73, almostLinear - animation = fadeOut, 1, 1.46, almostLinear - animation = fade, 1, 3.03, quick - animation = layers, 1, 3.81, easeOutQuint - animation = layersIn, 1, 4, easeOutQuint, fade - animation = layersOut, 1, 1.5, linear, fade - animation = fadeLayersIn, 1, 1.79, almostLinear - animation = fadeLayersOut, 1, 1.39, almostLinear - animation = workspaces, 1, 1.94, almostLinear, fade - animation = workspacesIn, 1, 1.21, almostLinear, fade - animation = workspacesOut, 1, 1.94, almostLinear, fade -} - -# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/ -# "Smart gaps" / "No gaps when only" -# uncomment all if you wish to use that. -# workspace = w[tv1], gapsout:0, gapsin:0 -# workspace = f[1], gapsout:0, gapsin:0 -# windowrulev2 = bordersize 0, floating:0, onworkspace:w[tv1] -# windowrulev2 = rounding 0, floating:0, onworkspace:w[tv1] -# windowrulev2 = bordersize 0, floating:0, onworkspace:f[1] -# windowrulev2 = rounding 0, floating:0, onworkspace:f[1] - -# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more -dwindle { - preserve_split = true # You probably want this -} - -# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more -master { - new_status = master -} - -# https://wiki.hyprland.org/Configuring/Variables/#misc -misc { - force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers - disable_hyprland_logo = false # If true disables the random hyprland logo / anime girl background. :( -} - - -############# -### INPUT ### -############# - -# https://wiki.hyprland.org/Configuring/Variables/#input -input { - kb_layout = us - kb_variant = - kb_model = - kb_options = - kb_rules = - - follow_mouse = 1 - - sensitivity = 0.0 # -1.0 - 1.0, 0 means no modification. - - touchpad { - scroll_factor = 0.5 - disable_while_typing = true - natural_scroll = true - clickfinger_behavior = true - tap-to-click = false - } -} - -# https://wiki.hyprland.org/Configuring/Variables/#gestures -gesture = 4, horizontal, workspace, invert - -# Thinkpad Trackpoint -device { - name = tpps/2-elan-trackpoint - sensitivity = -0.3 -} - -############################## -### WINDOWS AND WORKSPACES ### -############################## - -# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more -# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules - -# Example windowrule v1 -# windowrule = float, ^(kitty)$ - -# Example windowrule v2 -# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$ - -# Ignore maximize requests from apps. You'll probably like this. -windowrule = suppressevent maximize, class:.* - -# Fix some dragging issues with XWayland -windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0 diff --git a/modules/home/programs/graphical/wms/hyprland/config/hyprland.lua b/modules/home/programs/graphical/wms/hyprland/config/hyprland.lua new file mode 100644 index 0000000..288fbbd --- /dev/null +++ b/modules/home/programs/graphical/wms/hyprland/config/hyprland.lua @@ -0,0 +1,217 @@ +-- Hyprland config (lua backend, Hyprland 0.55+). +-- `mainMod`, `menuMod`, and the monitor(s) are injected by Nix above this file. +-- See https://wiki.hypr.land/Configuring/Start/ + +local terminal = "ghostty" +local menu = "wofi --show drun" + +------------------- +---- AUTOSTART ---- +------------------- + +hl.on("hyprland.start", function() + hl.exec_cmd("uwsm app -- waybar") + hl.exec_cmd("uwsm app -- " .. terminal) + hl.exec_cmd("uwsm app -- firefox") +end) + +----------------------- +---- LOOK AND FEEL ---- +----------------------- + +hl.config({ + general = { + gaps_in = 5, + gaps_out = 12, + + border_size = 2, + + col = { + active_border = { colors = { "rgba(33ccffee)", "rgba(00ff99ee)" }, angle = 45 }, + inactive_border = "rgba(595959aa)", + }, + + resize_on_border = false, + allow_tearing = false, + + layout = "dwindle", + }, + + decoration = { + rounding = 10, + + active_opacity = 1.0, + inactive_opacity = 1.0, + + shadow = { + enabled = true, + range = 4, + render_power = 3, + color = 0xee1a1a1a, + }, + + blur = { + enabled = true, + size = 3, + passes = 1, + vibrancy = 0.1696, + }, + }, + + animations = { + enabled = true, + }, + + dwindle = { + preserve_split = true, + }, + + master = { + new_status = "master", + }, + + misc = { + force_default_wallpaper = -1, + disable_hyprland_logo = false, + }, +}) + +---------------------- +---- ANIMATIONS ------ +---------------------- + +hl.curve("easeOutQuint", { type = "bezier", points = { { 0.23, 1 }, { 0.32, 1 } } }) +hl.curve("easeInOutCubic", { type = "bezier", points = { { 0.65, 0.05 }, { 0.36, 1 } } }) +hl.curve("linear", { type = "bezier", points = { { 0, 0 }, { 1, 1 } } }) +hl.curve("almostLinear", { type = "bezier", points = { { 0.5, 0.5 }, { 0.75, 1 } } }) +hl.curve("quick", { type = "bezier", points = { { 0.15, 0 }, { 0.1, 1 } } }) + +hl.animation({ leaf = "global", enabled = true, speed = 10, bezier = "default" }) +hl.animation({ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" }) +hl.animation({ leaf = "windows", enabled = true, speed = 4.79, bezier = "easeOutQuint" }) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 4.1, bezier = "easeOutQuint", style = "popin 87%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 1.49, bezier = "linear", style = "popin 87%" }) +hl.animation({ leaf = "fadeIn", enabled = true, speed = 1.73, bezier = "almostLinear" }) +hl.animation({ leaf = "fadeOut", enabled = true, speed = 1.46, bezier = "almostLinear" }) +hl.animation({ leaf = "fade", enabled = true, speed = 3.03, bezier = "quick" }) +hl.animation({ leaf = "layers", enabled = true, speed = 3.81, bezier = "easeOutQuint" }) +hl.animation({ leaf = "layersIn", enabled = true, speed = 4, bezier = "easeOutQuint", style = "fade" }) +hl.animation({ leaf = "layersOut", enabled = true, speed = 1.5, bezier = "linear", style = "fade" }) +hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 1.79, bezier = "almostLinear" }) +hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 1.39, bezier = "almostLinear" }) +hl.animation({ leaf = "workspaces", enabled = true, speed = 1.94, bezier = "almostLinear", style = "fade" }) +hl.animation({ leaf = "workspacesIn", enabled = true, speed = 1.21, bezier = "almostLinear", style = "fade" }) +hl.animation({ leaf = "workspacesOut", enabled = true, speed = 1.94, bezier = "almostLinear", style = "fade" }) + +--------------- +---- INPUT ---- +--------------- + +hl.config({ + input = { + kb_layout = "us", + kb_variant = "", + kb_model = "", + kb_options = "", + kb_rules = "", + + follow_mouse = 1, + sensitivity = 0.0, + + touchpad = { + scroll_factor = 0.5, + disable_while_typing = true, + natural_scroll = true, + clickfinger_behavior = true, + tap_to_click = false, + }, + }, +}) + +-- 4-finger horizontal swipe to switch workspaces. The old `invert` modifier was +-- removed in the 0.51 gesture rework; flip the physical swipe direction if needed. +hl.gesture({ fingers = 4, direction = "horizontal", action = "workspace" }) + +-- Thinkpad Trackpoint +hl.device({ name = "tpps/2-elan-trackpoint", sensitivity = -0.3 }) + +--------------------- +---- KEYBINDINGS ---- +--------------------- + +-- Menu Mod Bindings (macOS Transition - Spotlight & Screenshots) +hl.bind(menuMod .. " + SPACE", hl.dsp.exec_cmd(menu)) +hl.bind(menuMod .. " + SHIFT + 1", hl.dsp.exec_cmd("hyprshot -m output")) +hl.bind(menuMod .. " + SHIFT + 2", hl.dsp.exec_cmd("hyprshot -m window")) +hl.bind(menuMod .. " + SHIFT + 3", hl.dsp.exec_cmd("hyprshot -m region")) +hl.bind(menuMod .. " + Q", hl.dsp.window.close()) + +-- Primary Bindings +hl.bind(mainMod .. " + RETURN", hl.dsp.exec_cmd(terminal)) +hl.bind(mainMod .. " + M", hl.dsp.exec_cmd("uwsm stop")) +hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" })) +hl.bind(mainMod .. " + P", hl.dsp.window.pin()) +hl.bind(mainMod .. " + J", hl.dsp.layout("togglesplit")) +hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic")) +hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" })) + +-- Window Focus +hl.bind(mainMod .. " + left", hl.dsp.focus({ direction = "left" })) +hl.bind(mainMod .. " + right", hl.dsp.focus({ direction = "right" })) +hl.bind(mainMod .. " + up", hl.dsp.focus({ direction = "up" })) +hl.bind(mainMod .. " + down", hl.dsp.focus({ direction = "down" })) + +-- Workspace switch + move active window to workspace (1-9, 0 -> 10) +for i = 1, 10 do + local key = i % 10 + hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i })) + hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i })) +end + +hl.bind(mainMod .. " + SHIFT + right", hl.dsp.focus({ workspace = "+1" })) +hl.bind(mainMod .. " + SHIFT + left", hl.dsp.focus({ workspace = "-1" })) + +-- Window move/resize with mouse +hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) +hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) + +-- Multimedia & Brightness Keys +hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true }) +hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true }) +hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, repeating = true }) +hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true }) +hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 4%+"), { locked = true, repeating = true }) +hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 5%-"), { locked = true, repeating = true }) + +-- macOS Keyboard Brightness +hl.bind(menuMod .. " + XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl -d kbd_backlight s 10%+"), { locked = true, repeating = true }) +hl.bind(menuMod .. " + XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl -d kbd_backlight s 10%-"), { locked = true, repeating = true }) + +-- Player Controls +hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true }) +hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) +hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) +hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) + +-------------------------------- +---- WINDOWS AND WORKSPACES ---- +-------------------------------- + +hl.window_rule({ + name = "suppress-maximize-events", + match = { class = ".*" }, + suppress_event = "maximize", +}) + +hl.window_rule({ + name = "fix-xwayland-drags", + match = { + class = "^$", + title = "^$", + xwayland = true, + float = true, + fullscreen = false, + pin = false, + }, + no_focus = true, +}) diff --git a/modules/home/programs/graphical/wms/hyprland/default.nix b/modules/home/programs/graphical/wms/hyprland/default.nix index 88fcb54..e357c5a 100755 --- a/modules/home/programs/graphical/wms/hyprland/default.nix +++ b/modules/home/programs/graphical/wms/hyprland/default.nix @@ -24,92 +24,27 @@ in wayland.windowManager.hyprland = { enable = true; - # Pin Renderer - stateVersion 26.05 flips configType default to "lua"; our settings/extraConfig are hyprlang. - configType = "hyprlang"; - extraConfig = builtins.readFile ./config/hyprland.conf; - settings = { - "$mainMod" = cfg.mainMod; - "$menuMod" = cfg.menuMod; - "$terminal" = "ghostty"; - "$menu" = "wofi --show drun"; + # Lua Backend - Hyprland 0.55 deprecated hyprlang and home-manager 26.05 defaults configType to "lua". + configType = "lua"; + extraConfig = + let + # Quote unless the value is numeric, so scale can be `2` or `"auto"`. + luaScalar = v: if builtins.match "[0-9]+(\\.[0-9]+)?" v != null then v else ''"${v}"''; + mkMonitor = + s: + let + parts = map lib.trim (lib.splitString "," s); + field = i: if builtins.length parts > i then builtins.elemAt parts i else ""; + in + ''hl.monitor({ output = "${field 0}", mode = "${field 1}", position = "${field 2}", scale = ${luaScalar (field 3)} })''; + in + '' + local mainMod = "${cfg.mainMod}" + local menuMod = "${cfg.menuMod}" - monitor = cfg.monitors; - - bind = [ - # Menu Mod Bindings (macOS Transition - Spotlight & Screenshots) - "$menuMod, SPACE, exec, $menu" - "$menuMod SHIFT, 1, exec, hyprshot -m output" - "$menuMod SHIFT, 2, exec, hyprshot -m window" - "$menuMod SHIFT, 3, exec, hyprshot -m region" - "$menuMod, Q, killactive" - - # Primary Bindings - "$mainMod, RETURN, exec, $terminal" - "$mainMod, M, exit" - "$mainMod, V, togglefloating" - "$mainMod, P, pin" - "$mainMod, J, layoutmsg, togglesplit" - "$mainMod, S, togglespecialworkspace, magic" - "$mainMod SHIFT, S, movetoworkspace, special:magic" - - # Window Focus - "$mainMod, left, movefocus, l" - "$mainMod, right, movefocus, r" - "$mainMod, up, movefocus, u" - "$mainMod, down, movefocus, d" - - # Workspace Switch - "$mainMod, 1, workspace, 1" - "$mainMod, 2, workspace, 2" - "$mainMod, 3, workspace, 3" - "$mainMod, 4, workspace, 4" - "$mainMod, 5, workspace, 5" - "$mainMod, 6, workspace, 6" - "$mainMod, 7, workspace, 7" - "$mainMod, 8, workspace, 8" - "$mainMod, 9, workspace, 9" - "$mainMod, 0, workspace, 10" - - # Window Workspace Move - "$mainMod SHIFT, 1, movetoworkspace, 1" - "$mainMod SHIFT, 2, movetoworkspace, 2" - "$mainMod SHIFT, 3, movetoworkspace, 3" - "$mainMod SHIFT, 4, movetoworkspace, 4" - "$mainMod SHIFT, 5, movetoworkspace, 5" - "$mainMod SHIFT, 6, movetoworkspace, 6" - "$mainMod SHIFT, 7, movetoworkspace, 7" - "$mainMod SHIFT, 8, movetoworkspace, 8" - "$mainMod SHIFT, 9, movetoworkspace, 9" - "$mainMod SHIFT, 0, movetoworkspace, 10" - "$mainMod SHIFT, right, workspace, +1" - "$mainMod SHIFT, left, workspace, -1" - ]; - bindm = [ - # Window Resizing - "$mainMod, mouse:272, movewindow" - "$mainMod, mouse:273, resizewindow" - ]; - bindel = [ - # Multimedia & Brightness Keys - ",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 4%+" - ",XF86MonBrightnessDown, exec, brightnessctl s 5%-" - - # macOS Keyboard Brightness - "$menuMod, XF86MonBrightnessUp, exec, brightnessctl -d kbd_backlight s 10%+" - "$menuMod, XF86MonBrightnessDown, exec, brightnessctl -d kbd_backlight s 10%-" - ]; - bindl = [ - # Player Controls - ", XF86AudioNext, exec, playerctl next" - ", XF86AudioPause, exec, playerctl play-pause" - ", XF86AudioPlay, exec, playerctl play-pause" - ", XF86AudioPrev, exec, playerctl previous" - ]; - }; + ${lib.concatMapStringsSep "\n" mkMonitor cfg.monitors} + '' + + builtins.readFile ./config/hyprland.lua; }; programs.waybar = {