{ inputs, lib, config, system, pkgs, ... }: with lib; let cfg = config.modules.desktop.hyprland; hyprpkgs = inputs.hyprland.packages.${system}; in { options.modules.desktop.hyprland = { enable = mkEnableOption "Enable hyprland, a dynamic tiling wayland compositor based on wlroots that doesn't sacrifice on its looks"; package = mkOption { type = types.package; default = hyprpkgs.hyprland; example = "pkgs.hyprland"; }; portalPackage = mkOption { type = types.package; default = hyprpkgs.xdg-desktop-portal-hyprland; example = "pkgs.xdg-desktop-portal-hyprland"; }; }; config = mkIf cfg.enable { services.displayManager.sessionPackages = [ cfg.package ]; xdg.portal = { enable = true; extraPortals = [ pkgs.xdg-desktop-portal-gtk cfg.portalPackage ]; config = { common = { default = [ "hyprland" "gtk" ]; }; }; }; # fixes a few things, most notibly, xwayland programs.hyprland = { enable = true; xwayland.enable = true; package = cfg.package; portalPackage = cfg.portalPackage; }; hm.wayland.windowManager.hyprland = { enable = true; xwayland.enable = true; package = cfg.package; systemd.variables = [ "--all" ]; settings = { source = []; "$mod" = "SUPER"; bindm = [ # "bind mouse" # move/resize windows with mod + lmb/rmb and dragging "$mod, mouse:272, movewindow" "$mod, mouse:273, resizewindow" ]; bindel = [ # "bind held & locked" ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+" ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" ", XF86MonBrightnessUp, exec, ${lib.getExe pkgs.brightnessctl} -c backlight s +5%" ", XF86MonBrightnessDown, exec, ${lib.getExe pkgs.brightnessctl} -c backlight s 5%-" ]; bindl = [ # "bind locked" ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" ", XF86AudioPlay, exec, ${lib.getExe pkgs.playerctl} play-pause" ", XF86AudioStop, exec, ${lib.getExe pkgs.playerctl} stop" ", XF86AudioPrev, exec, ${lib.getExe pkgs.playerctl} previous" ", XF86AudioNext, exec, ${lib.getExe pkgs.playerctl} next" ]; bindr = [ # "bind released" "SUPER, Super_L, exec, ${lib.getExe pkgs.nwg-drawer}" ]; bind = let screenshotScript = pkgs.writeScript "screenshot" '' temp_file=$(mktemp) trap 'rm -f "$temp_file"' EXIT ${lib.getExe pkgs.grimblast} --freeze save area - > "$temp_file" || exit 1 cat "$temp_file" | ${lib.getExe pkgs.wl-clipboard-x11} -selection clipboard -t image/png action=$(${pkgs.libnotify}/bin/notify-send "Screenshot Captured" \ --app-name="Screenshot" \ --urgency=normal \ --action="default=Edit Image" \ --icon "$temp_file" \ "Click to annotate image") case "$action" in default) ${lib.getExe pkgs.satty} --filename "$temp_file" ;; esac ''; in [ "$mod, R, exec, ${lib.getExe pkgs.rofi-wayland} -show run" ", print, exec, ${screenshotScript}" "$mod, T, exec, ${lib.getExe pkgs.wezterm}" "$mod, Q, killactive, " "$mod, V, togglefloating, " "$mod, P, pseudo, " # dwindle "$mod, J, togglesplit, " # dwindle # move focus with mod + arrow keys "$mod, left, movefocus, l" "$mod, right, movefocus, r" "$mod, up, movefocus, u" "$mod, down, movefocus, d" # example special workspace (scratchpad) "$mod, S, togglespecialworkspace, magic" "$mod SHIFT, S, movetoworkspace, special:magic" # scroll through workspaces with mod + scroll "$mod, mouse_down, workspace, e+1" "$mod, mouse_up, workspace, e-1" # alternatively, scroll through workspaces with mod + brackets "$mod, bracketleft, workspace, e-1" "$mod, bracketright, workspace, e+1" ", XF86LaunchA, exec, ${screenshotScript}" ", XF86LaunchB, exec, ${lib.getExe pkgs.rofi-rbw-wayland} -a copy -t password --clear-after 20" ] ++ ( # workspaces # binds $mod + [shift +] {1..10} to [move to] workspace {1..10} builtins.concatLists (builtins.genList ( x: let ws = let c = (x + 1) / 10; in builtins.toString (x + 1 - (c * 10)); in [ "$mod, ${ws}, workspace, ${toString (x + 1)}" "$mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}" ] ) 10) ); input = { kb_layout = "us"; touchpad = { disable_while_typing = false; natural_scroll = true; }; follow_mouse = 1; sensitivity = 0; # -1.0 - 1.0, 0 means no modification }; monitor=",highrr,auto,auto"; exec-once = [ "${lib.getExe pkgs.networkmanagerapplet}" ]; env = [ "XCURSOR_THEME,${config.modules.desktop.themes.cursorTheme.name}" "XCURSOR_SIZE,24" ]; general = { gaps_in = 6; gaps_out = 6; border_size = 1; no_border_on_floating = false; layout = "dwindle"; resize_on_border = true; }; windowrulev2 = [ # common popups "float, class:org.gnome.FileRoller" "size 1100 650, class:org.gnome.FileRoller" "float, class:org.gnome.Loupe" "size 1100 650, class:org.gnome.Loupe" "float, class:com.gabm.satty" "size 1100 650, class:com.gabm.satty" "float, initialTitle:^Open Folder$" "size 1100 650, initialTitle:^Open Folder$" "float, initialTitle:^Open File$" "size 1100 650, initialTitle:^Open File$" "float, initialTitle:^Open Files$" "size 1100 650, initialTitle:^Open Files$" "float, initialTitle:^Save As$" "size 1100 650, initialTitle:^Save As$" "float, initialTitle:^Select a file to open$" "size 1100 650, initialTitle:^Select a file to open$" "float, initialTitle:^File Upload$" "size 1100 650, initialTitle:^File Upload$" "float, class:\.exe$" # fix focus "stayfocused, class:^gcr-prompter" "stayfocused, class:^pinentry-" "stayfocused, class:^polkit-" "stayfocused, class:^rofi-" # workspace moving "workspace 1, class:^firefox" "workspace 2, class:code-url-handler" "workspace 4, class:vesktop" ]; blurls = [ "gtk-layer-shell" ]; layerrule = [ "animation slide, notifications" "animation slide, waybar" "blur, notifications" ]; decoration = { rounding = 10; blur = { enabled = true; size = 4; passes = 2; popups = true; }; drop_shadow = false; #shadow_range = 4; #shadow_render_power = 3; }; animations = { enabled = true; bezier = [ "outCubic, 0.33, 1, 0.68, 1" "outExpo, 0.16, 1, 0.3, 1" ]; animation = [ "windows, 1, 5, outExpo, popin" "windowsOut, 1, 5, outCubic, popin 80%" "border, 1, 2, outExpo" "fade, 1, 3, outCubic" "workspaces, 1, 6, outExpo" "specialWorkspace, 1, 2, outCubic, fade" ]; }; dwindle = { pseudotile = "yes"; # master swtich for pseudotiling. enabling is mod + P in the keybinds section preserve_split = "yes"; }; master = { new_status = "master"; }; gestures = { workspace_swipe = true; }; misc = { force_default_wallpaper = 0; disable_splash_rendering = true; disable_hyprland_logo = true; initial_workspace_tracking = 0; }; }; extraConfig = '' general { col.active_border=$pink col.inactive_border=$surface0 } decoration { col.shadow=$surface0 col.shadow_inactive=$surface0 } misc { background_color=$crust } ''; }; }; }