From 18cc25b3b87627699b861e7587240d948362daa7 Mon Sep 17 00:00:00 2001 From: Pedro Rey Anca Date: Fri, 5 Dec 2025 17:56:38 +0100 Subject: [PATCH] Update hyprland config (gestures and other stuff) --- modules/desktop/hyprland.nix | 23 +- .../home-configuration/hyprland/hyprland.nix | 557 +++++++++--------- .../home-configuration/hyprland/variables.nix | 18 +- 3 files changed, 298 insertions(+), 300 deletions(-) diff --git a/modules/desktop/hyprland.nix b/modules/desktop/hyprland.nix index d29e3d3..ec31e9e 100644 --- a/modules/desktop/hyprland.nix +++ b/modules/desktop/hyprland.nix @@ -1,10 +1,10 @@ { - pkgs, lib, config, ... -}: { - imports = [./regreet.nix]; +}: +{ + imports = [ ./regreet.nix ]; options = { programs.hyprland.autoLogin.username = lib.mkOption { @@ -21,19 +21,10 @@ withUWSM = true; }; - xdg.portal = { - enable = true; - wlr.enable = true; - xdgOpenUsePortal = true; - extraPortals = [ - pkgs.xdg-desktop-portal-hyprland - pkgs.xdg-desktop-portal-gtk - ]; - }; - - services.greetd.settings.initial_session = let - username = config.programs.hyprland.autoLogin.username; - in + services.greetd.settings.initial_session = + let + username = config.programs.hyprland.autoLogin.username; + in lib.mkIf (!isNull username) { command = "uwsm start hyprland-uwsm.desktop"; user = username; diff --git a/users/pedro/home-configuration/hyprland/hyprland.nix b/users/pedro/home-configuration/hyprland/hyprland.nix index 6c54725..480876f 100644 --- a/users/pedro/home-configuration/hyprland/hyprland.nix +++ b/users/pedro/home-configuration/hyprland/hyprland.nix @@ -1,4 +1,5 @@ -{pkgs, ...}: { +{ pkgs, ... }: +{ wayland.windowManager.hyprland = { enable = true; xwayland = { @@ -10,119 +11,120 @@ pkgs.hyprlandPlugins.hyprgrass ]; - settings = let - app_menu = "${pkgs.fuzzel}/bin/fuzzel"; - in { - # Autostart - exec-once = [ - "uwsm app -- nm-applet" - "uwsm app -- ${pkgs.wl-clip-persist}/bin/persist --clipboard regular" - "uwsm app -- bash -c 'if [ ! -f ~/.config/hypr/wallpaper.png ]; then wall-change ~/.config/hypr/default_wallpaper.png; fi'" - "uwsm app -- ${pkgs.swaybg}/bin/swaybg -m fill -i ~/.config/hypr/wallpaper.png &" - "uwsm app -- ${pkgs.poweralertd}/bin/poweralertd" - "uwsm app -- waybar" - "uwsm app -- element-desktop --hidden" - ]; - - input = { - kb_layout = "es,us"; - kb_options = "grp:alt_caps_toggle"; - numlock_by_default = true; - follow_mouse = 1; - sensitivity = 0; - touchpad = { - natural_scroll = true; - }; - }; - - general = { - "$mainMod" = "SUPER"; - layout = "dwindle"; - gaps_in = 0; - gaps_out = 0; - border_size = 2; - no_border_on_floating = false; - }; - - misc = { - disable_autoreload = true; - disable_hyprland_logo = true; - always_follow_on_dnd = true; - layers_hog_keyboard_focus = true; - animate_manual_resizes = false; - enable_swallow = true; - focus_on_activate = true; - }; - - dwindle = { - force_split = 0; - special_scale_factor = 1.0; - split_width_multiplier = 1.0; - use_active_for_splits = true; - pseudotile = true; - preserve_split = true; - }; - - master = { - new_status = "master"; - special_scale_factor = 1; - }; - - decoration = { - rounding = 0; - - blur = { - enabled = true; - size = 1; - passes = 1; - brightness = 1; - contrast = 1.400; - ignore_opacity = true; - noise = 0; - new_optimizations = true; - xray = false; - }; - - shadow = { - enabled = true; - - ignore_window = true; - offset = "0 2"; - range = 20; - render_power = 3; - }; - }; - - animations = { - enabled = true; - - bezier = [ - "fluent_decel, 0, 0.2, 0.4, 1" - "easeOutCirc, 0, 0.55, 0.45, 1" - "easeOutCubic, 0.33, 1, 0.68, 1" - "easeinoutsine, 0.37, 0, 0.63, 1" + settings = + let + app_menu = "${pkgs.fuzzel}/bin/fuzzel"; + in + { + # Autostart + exec-once = [ + "uwsm app -- nm-applet" + "uwsm app -- ${pkgs.wl-clip-persist}/bin/persist --clipboard regular" + "uwsm app -- bash -c 'if [ ! -f ~/.config/hypr/wallpaper.png ]; then wall-change ~/.config/hypr/default_wallpaper.png; fi'" + "uwsm app -- ${pkgs.swaybg}/bin/swaybg -m fill -i ~/.config/hypr/wallpaper.png &" + "uwsm app -- ${pkgs.poweralertd}/bin/poweralertd" + "uwsm app -- waybar" + "uwsm app -- element-desktop --hidden" ]; - animation = [ - # Windows - "windowsIn, 1, 3, easeOutCubic, popin 30%" # window open - "windowsOut, 1, 3, fluent_decel, popin 70%" # window close. - "windowsMove, 1, 2, easeinoutsine, slide" # everything in between, moving, dragging, resizing. + input = { + kb_layout = "es,us"; + kb_options = "grp:alt_caps_toggle"; + numlock_by_default = true; + follow_mouse = 1; + sensitivity = 0; + touchpad = { + natural_scroll = true; + }; + }; - # Fade - "fadeIn, 1, 3, easeOutCubic" # fade in (open) -> layers and windows - "fadeOut, 1, 2, easeOutCubic" # fade out (close) -> layers and windows - "fadeSwitch, 0, 1, easeOutCirc" # fade on changing activewindow and its opacity - "fadeShadow, 1, 10, easeOutCirc" # fade on changing activewindow for shadows - "fadeDim, 1, 4, fluent_decel" # the easing of the dimming of inactive windows - "border, 1, 2.7, easeOutCirc" # for animating the border's color switch speed - "borderangle, 1, 30, fluent_decel, once" # for animating the border's gradient angle - styles: once (default), loop - "workspaces, 1, 4, easeOutCubic, fade" # styles: slide, slidevert, fade, slidefade, slidefadevert - ]; - }; + general = { + "$mainMod" = "SUPER"; + layout = "dwindle"; + gaps_in = 0; + gaps_out = 0; + border_size = 2; + no_border_on_floating = false; + }; - bind = - [ + misc = { + disable_autoreload = true; + disable_hyprland_logo = true; + always_follow_on_dnd = true; + layers_hog_keyboard_focus = true; + animate_manual_resizes = false; + enable_swallow = true; + focus_on_activate = true; + }; + + dwindle = { + force_split = 0; + special_scale_factor = 1.0; + split_width_multiplier = 1.0; + use_active_for_splits = true; + pseudotile = true; + preserve_split = true; + }; + + master = { + new_status = "master"; + special_scale_factor = 1; + }; + + decoration = { + rounding = 0; + + blur = { + enabled = true; + size = 1; + passes = 1; + brightness = 1; + contrast = 1.400; + ignore_opacity = true; + noise = 0; + new_optimizations = true; + xray = false; + }; + + shadow = { + enabled = true; + + ignore_window = true; + offset = "0 2"; + range = 20; + render_power = 3; + }; + }; + + animations = { + enabled = true; + + bezier = [ + "fluent_decel, 0, 0.2, 0.4, 1" + "easeOutCirc, 0, 0.55, 0.45, 1" + "easeOutCubic, 0.33, 1, 0.68, 1" + "easeinoutsine, 0.37, 0, 0.63, 1" + ]; + + animation = [ + # Windows + "windowsIn, 1, 3, easeOutCubic, popin 30%" # window open + "windowsOut, 1, 3, fluent_decel, popin 70%" # window close. + "windowsMove, 1, 2, easeinoutsine, slide" # everything in between, moving, dragging, resizing. + + # Fade + "fadeIn, 1, 3, easeOutCubic" # fade in (open) -> layers and windows + "fadeOut, 1, 2, easeOutCubic" # fade out (close) -> layers and windows + "fadeSwitch, 0, 1, easeOutCirc" # fade on changing activewindow and its opacity + "fadeShadow, 1, 10, easeOutCirc" # fade on changing activewindow for shadows + "fadeDim, 1, 4, fluent_decel" # the easing of the dimming of inactive windows + "border, 1, 2.7, easeOutCirc" # for animating the border's color switch speed + "borderangle, 1, 30, fluent_decel, once" # for animating the border's gradient angle - styles: once (default), loop + "workspaces, 1, 4, easeOutCubic, fade" # styles: slide, slidevert, fade, slidefade, slidefadevert + ]; + }; + + bind = [ # show keybinds list "$mainMod, F1, exec, show-keybinds" @@ -160,17 +162,19 @@ # binds $mod + [shift +] {1..10} to [move to] workspace {1..10} builtins.concatLists ( builtins.genList ( - x: let - ws = let - c = (x + 1) / 10; - in + x: + let + ws = + let + c = (x + 1) / 10; + in builtins.toString (x + 1 - (c * 10)); - in [ + in + [ "$mainMod, ${ws}, workspace, ${toString (x + 1)}" "$mainMod SHIFT, ${ws}, movetoworkspacesilent, ${toString (x + 1)}" ] - ) - 10 + ) 10 ) ) ++ [ @@ -184,24 +188,40 @@ # Window focus, movement and control builtins.concatLists ( let - keys = ["H" "L" "K" "J"]; - directions = ["l" "r" "u" "d"]; + keys = [ + "H" + "L" + "K" + "J" + ]; + directions = [ + "l" + "r" + "u" + "d" + ]; resize = toString 80; # Change this to change how much a window resizes each keypress - resize_list = ["-${resize} 0" "${resize} 0" "0 -${resize}" "0 ${resize}"]; + resize_list = [ + "-${resize} 0" + "${resize} 0" + "0 -${resize}" + "0 ${resize}" + ]; in - builtins.genList ( - x: let - k = builtins.elemAt keys x; - d = builtins.elemAt directions x; - r = builtins.elemAt resize_list x; - in [ - "$mainMod, ${k}, movefocus, ${d}" - "$mainMod SHIFT, ${k}, movewindow, ${d}" - "$mainMod CTRL, ${k}, resizeactive, ${r}" - "$mainMod ALT, ${k}, moveactive, ${r}" - ] - ) - 4 + builtins.genList ( + x: + let + k = builtins.elemAt keys x; + d = builtins.elemAt directions x; + r = builtins.elemAt resize_list x; + in + [ + "$mainMod, ${k}, movefocus, ${d}" + "$mainMod SHIFT, ${k}, movewindow, ${d}" + "$mainMod CTRL, ${k}, resizeactive, ${r}" + "$mainMod ALT, ${k}, moveactive, ${r}" + ] + ) 4 ) ) ++ [ @@ -218,172 +238,167 @@ "$mainMod, V, exec, cliphist list | fuzzel --dmenu --prompt '📋 ' | cliphist decode | wl-copy" ]; - # Bindings that work when locked - bindl = [ - # media and volume controls - ",XF86AudioRaiseVolume,exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+ && wp-vol" - ",XF86AudioLowerVolume,exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- && wp-vol" - ",XF86AudioMute,exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" - ",XF86AudioPlay,exec, playerctl play-pause" - ",XF86AudioNext,exec, playerctl next" - ",XF86AudioPrev,exec, playerctl previous" - ",XF86AudioStop, exec, playerctl stop" - ]; + # Bindings that work when locked + bindl = [ + # media and volume controls + ",XF86AudioRaiseVolume,exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+ && wp-vol" + ",XF86AudioLowerVolume,exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- && wp-vol" + ",XF86AudioMute,exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ",XF86AudioPlay,exec, playerctl play-pause" + ",XF86AudioNext,exec, playerctl next" + ",XF86AudioPrev,exec, playerctl previous" + ",XF86AudioStop, exec, playerctl stop" + ]; - # mouse binding - bindm = [ - "$mainMod, mouse:272, movewindow" - "$mainMod, mouse:273, resizewindow" - ]; + # mouse binding + bindm = [ + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; - # windowrule - windowrule = [ - "float,class:vimiv" - "center,class:vimiv" - "float,class:mpv" - "center,class:mpv" - "size 1200 725,class:mpv" - "float,title:^(float_kitty)$" - "center,title:^(float_kitty)$" - "size 950 600,title:^(float_kitty)$" - "tile, class:neovide" - "idleinhibit focus,class:mpv" - "float,class:udiskie" - "float,title:^(Volume Control)$" - "float,title:^(Firefox — Sharing Indicator)$" - "move 0 0,title:^(Firefox — Sharing Indicator)$" - "size 700 450,title:^(Volume Control)$" - "move 40 55%,title:^(Volume Control)$" - "float, title:^(Picture-in-Picture)$" - "opacity 1.0 override 1.0 override, title:^(Picture-in-Picture)$" - "pin, title:^(Picture-in-Picture)$" - "opacity 1.0 override 1.0 override, class:(Aseprite)" - "opacity 1.0 override 1.0 override, class:(Unity)" - "idleinhibit focus, class:^(mpv)$" - "idleinhibit fullscreen, class:^(firefox)$" - "float,class:^(zenity)$" - "center,class:^(zenity)$" - "size 850 500,class:^(zenity)$" - "float,class:^(pavucontrol)$" - "float,class:^(.sameboy-wrapped)$" - "float,class:^(file_progress)$" - "float,class:^(confirm)$" - "float,class:^(dialog)$" - "float,class:^(download)$" - "float,class:^(notification)$" - "float,class:^(error)$" - "float,class:^(confirmreset)$" - "float,title:^(Open File)$" - "float,title:^(branchdialog)$" - "float,title:^(Confirm to replace files)$" - "float,title:^(File Operation Progress)$" + gesture = [ + "3, horizontal, workspace" + ]; - "opacity 0.0 override,class:^(xwaylandvideobridge)$" - "noanim,class:^(xwaylandvideobridge)$" - "noinitialfocus,class:^(xwaylandvideobridge)$" - "maxsize 1 1,class:^(xwaylandvideobridge)$" - "noblur,class:^(xwaylandvideobridge)$" - ]; + # windowrule + windowrule = [ + "float,class:vimiv" + "center,class:vimiv" + "float,class:mpv" + "center,class:mpv" + "size 1200 725,class:mpv" + "float,title:^(float_kitty)$" + "center,title:^(float_kitty)$" + "size 950 600,title:^(float_kitty)$" + "tile, class:neovide" + "idleinhibit focus,class:mpv" + "float,class:udiskie" + "float,title:^(Volume Control)$" + "float,title:^(Firefox — Sharing Indicator)$" + "move 0 0,title:^(Firefox — Sharing Indicator)$" + "size 700 450,title:^(Volume Control)$" + "move 40 55%,title:^(Volume Control)$" + "float, title:^(Picture-in-Picture)$" + "opacity 1.0 override 1.0 override, title:^(Picture-in-Picture)$" + "pin, title:^(Picture-in-Picture)$" + "opacity 1.0 override 1.0 override, class:(Aseprite)" + "opacity 1.0 override 1.0 override, class:(Unity)" + "idleinhibit focus, class:^(mpv)$" + "idleinhibit fullscreen, class:^(firefox)$" + "float,class:^(zenity)$" + "center,class:^(zenity)$" + "size 850 500,class:^(zenity)$" + "float,class:^(pavucontrol)$" + "float,class:^(.sameboy-wrapped)$" + "float,class:^(file_progress)$" + "float,class:^(confirm)$" + "float,class:^(dialog)$" + "float,class:^(download)$" + "float,class:^(notification)$" + "float,class:^(error)$" + "float,class:^(confirmreset)$" + "float,title:^(Open File)$" + "float,title:^(branchdialog)$" + "float,title:^(Confirm to replace files)$" + "float,title:^(File Operation Progress)$" - monitor = [ - ",preferred,auto,1" - ]; + "opacity 0.0 override,class:^(xwaylandvideobridge)$" + "noanim,class:^(xwaylandvideobridge)$" + "noinitialfocus,class:^(xwaylandvideobridge)$" + "maxsize 1 1,class:^(xwaylandvideobridge)$" + "noblur,class:^(xwaylandvideobridge)$" + ]; - xwayland = { - force_zero_scaling = true; - }; + monitor = [ + ",preferred,auto,1" + ]; - gestures = { - workspace_swipe = true; - workspace_swipe_direction_lock = false; - }; - ecosystem = { - no_update_news = true; - no_donation_nag = true; - }; - plugin = { - touch_gestures = { - # The default sensitivity is probably too low on tablet screens, - # I recommend turning it up to 4.0 - sensitivity = 5.0; + xwayland = { + force_zero_scaling = true; + }; - # must be >= 3 - workspace_swipe_fingers = 3; + ecosystem = { + no_update_news = true; + no_donation_nag = true; + }; - # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers - # and can be used at the same time - # possible values: l, r, u, or d - # to disable it set it to anything else - workspace_swipe_edge = "no"; + plugin = { + touch_gestures = { + # The default sensitivity is probably too low on tablet screens, + # I recommend turning it up to 4.0 + sensitivity = 5.0; - # in milliseconds - long_press_delay = 400; + # must be >= 3 + workspace_swipe_fingers = 3; - # resize windows by long-pressing on window borders and gaps. - # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating - # windows - resize_on_border_long_press = true; + # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers + # and can be used at the same time + # possible values: l, r, u, or d + # to disable it set it to anything else + workspace_swipe_edge = "no"; - # in pixels, the distance from the edge that is considered an edge - edge_margin = 20; + # in milliseconds + long_press_delay = 400; - # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe. - # ONLY triggers when finger count is equal to workspace_swipe_fingers - # - # might be removed in the future in favor of event hooks - emulate_touchpad_swipe = false; + # resize windows by long-pressing on window borders and gaps. + # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating + # windows + resize_on_border_long_press = true; - hyprgrass-bind = [ - # swipe left from right edge - ", edge:r:l, exec, playerctl next" + # in pixels, the distance from the edge that is considered an edge + edge_margin = 20; - # swipe right from left edge - ", edge:l:r, exec, playerctl previous" + # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe. + # ONLY triggers when finger count is equal to workspace_swipe_fingers + # + # might be removed in the future in favor of event hooks + emulate_touchpad_swipe = false; - # swipe up from bottom edge - ", edge:d:u, exec, pkill -SIGUSR2 wvkbd" # Show wvkbd + hyprgrass-bind = [ + # swipe left from right edge + ", edge:r:l, exec, playerctl next" - # swipe down to bottom edge - ", edge:u:d, exec, pkill -SIGUSR1 wvkbd" # Hide wvkbd + # swipe right from left edge + ", edge:l:r, exec, playerctl previous" - # tap with 3 fingers - ", tap:4, exec, pkill -SIGRTMIN wvkbd" # Toggles wvkbd + # swipe up from bottom edge + ", edge:d:u, exec, pkill -SIGUSR2 wvkbd" # Show wvkbd - # swipe up from left edge - ", edge:l:u, exec, pamixer -i 4" + # swipe down to bottom edge + ", edge:u:d, exec, pkill -SIGUSR1 wvkbd" # Hide wvkbd - # swipe down from left edge - ", edge:l:d, exec, pamixer -d 4" + # tap with 3 fingers + ", tap:4, exec, pkill -SIGRTMIN wvkbd" # Toggles wvkbd - # swipe up with 3 fingers - ", swipe:3:u, exec, ${pkgs.nwg-drawer}/bin/nwg-drawer" + # swipe up from left edge + ", edge:l:u, exec, pamixer -i 4" - # swipe down with 3 fingers - ", swipe:3:d, killactive" + # swipe down from left edge + ", edge:l:d, exec, pamixer -d 4" - # swipe diagonally left and down with 3 fingers - ", swipe:3:ld, exec, uwsm app -- librewolf" + # swipe up with 3 fingers + ", swipe:3:u, exec, ${pkgs.nwg-drawer}/bin/nwg-drawer" - # swipe diagonally right and down with 3 fingers - ", swipe:3:rd, exec, uwsm app -- xournalpp" + # swipe down with 3 fingers + ", swipe:3:d, killactive" - # tap with 3 fingers - ", tap:3, exec, playerctl play-pause" - ]; + # swipe diagonally left and down with 3 fingers + ", swipe:3:ld, exec, uwsm app -- librewolf" - # longpress can trigger mouse binds: - hyprgrass-bindm = [ - ", longpress:2, movewindow" - ", longpress:3, resizewindow" - ]; + # swipe diagonally right and down with 3 fingers + ", swipe:3:rd, exec, uwsm app -- xournalpp" - experimental = { - # send proper cancel events to windows instead of hacky touch_up events, - # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default - send_cancel = 0; + # tap with 3 fingers + ", tap:3, exec, playerctl play-pause" + ]; + + # longpress can trigger mouse binds: + hyprgrass-bindm = [ + ", longpress:2, movewindow" + ", longpress:3, resizewindow" + ]; }; }; }; - }; }; } diff --git a/users/pedro/home-configuration/hyprland/variables.nix b/users/pedro/home-configuration/hyprland/variables.nix index bb68b39..138683b 100644 --- a/users/pedro/home-configuration/hyprland/variables.nix +++ b/users/pedro/home-configuration/hyprland/variables.nix @@ -1,15 +1,9 @@ -{lib, ...}: let +{ lib, ... }: +let variables = { NIXOS_OZONE_WL = 1; ELECTRON_OZONE_PLATFORM_HINT = "auto"; - __GL_GSYNC_ALLOWED = 0; - __GL_VRR_ALLOWED = 0; - _JAVA_AWT_WM_NONEREPARENTING = 1; - DISABLE_QT5_COMPAT = 0; GDK_BACKEND = "wayland,x11,*"; - ANKI_WAYLAND = 1; - DIRENV_LOG_FORMAT = ""; - WLR_DRM_NO_ATOMIC = 1; QT_AUTO_SCREEN_SCALE_FACTOR = 1; QT_WAYLAND_DISABLE_WINDOWDECORATION = 1; QT_QPA_PLATFORM = "wayland;xcb"; @@ -19,13 +13,11 @@ SDL_VIDEODRIVER = "wayland"; CLUTTER_BACKEND = "wayland"; }; -in { +in +{ home.sessionVariables = variables; xdg.configFile."uwsm/env".text = builtins.concatStringsSep "\n" ( - lib.attrsets.mapAttrsToList ( - name: value: "export ${name}=\"${builtins.toString value}\"" - ) - variables + lib.attrsets.mapAttrsToList (name: value: "export ${name}=\"${builtins.toString value}\"") variables ); }