dotfiles

My PC Dotfiles & Website
commit 533a133b2e3f2c8ebb7cc4d47ea46fea8948d1d7
parent a94c801d13ce511cea01e7f9f4101469f7164ef0
Author: maydayv7 <maydayv7@gmail.com>
Date:   Mon,  2 Dec 2024 15:14:18 +0530

feat(Hyprland): Transition to UWSM

Also add `lib.build.until`

Diffstat:

Mlib/README.md | 1+
Mlib/build.nix | 30++++++++++++++++++++++++++++--
Mmodules/gui/desktop/hyprland/apps/bar.nix | 17+++++++++++------
Mmodules/gui/desktop/hyprland/apps/default.nix | 73++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mmodules/gui/desktop/hyprland/apps/rules.nix | 14+++++---------
Mmodules/gui/desktop/hyprland/apps/security.nix | 28++++------------------------
Mmodules/gui/desktop/hyprland/default.nix | 47++++++++++++++++++-----------------------------
Mmodules/gui/desktop/hyprland/settings/keybindings.nix | 2+-
Mmodules/gui/desktop/hyprland/settings/plugins.nix | 35-----------------------------------
Mmodules/gui/launcher.nix | 6+++++-
Mscripts/hyprutils.nix | 34++++++++++++++--------------------
11 files changed, 129 insertions(+), 158 deletions(-)

diff --git a/lib/README.md b/lib/README.md @@ -10,6 +10,7 @@ The `lib` directory contains custom-made utility functions (exposed as `util`), - `mime`: Builds and sets `mimetype` values according to specified application and types - `script`: Builds script from specified file by removing `shebangs` and exporting as a _string_ - `theme`: Builds specified file by replacing placeholders with provided theming elements + - `until`: Returns part of _string_ before specified character, or entire _string_ if character is not present - [`map`](./map.nix): Mapping functions primarily aimed at shortening code complexity - diff --git a/lib/build.nix b/lib/build.nix @@ -1,6 +1,24 @@ lib: let - inherit (lib) flatten hasPrefix mapAttrsToList nameValuePair replaceStrings splitString; - inherit (builtins) concatStringsSep filter hasAttr listToAttrs map readFile; + inherit + (builtins) + concatStringsSep + filter + hasAttr + listToAttrs + map + match + readFile + ; + + inherit + (lib) + flatten + hasPrefix + mapAttrsToList + nameValuePair + replaceStrings + splitString + ; in { ## Builder Functions ## # Mime Types Handler @@ -36,4 +54,12 @@ in { else if (fonts != null) then replaceStrings font font' file else throw "One of 'colors' or 'fonts' must be declared"; + + # String Extractor + until = check: string: let + value = match "([^ ]+)${check}.*" string; + in + if (value == null) + then string + else concatStringsSep "" value; } diff --git a/modules/gui/desktop/hyprland/apps/bar.nix b/modules/gui/desktop/hyprland/apps/bar.nix @@ -18,17 +18,22 @@ in rec { # Environment Setup home.packages = [pkgs.wttrbar]; systemd.user = { - # nix-community/home-manager/4099 - services.waybar.Service.ExecStart = lib.mkForce (pkgs.writeShellScript "waybar-wrapper.sh" '' - ${files.path.systemd} - ${lib.getExe programs.waybar.package} - ''); + services.waybar = { + # nix-community/home-manager/pull/5785 + Unit.After = lib.mkForce ["graphical-session.target"]; + + # nix-community/home-manager/4099 + Service.ExecStart = lib.mkForce (pkgs.writeShellScript "waybar-wrapper.sh" '' + ${files.path.systemd} + ${lib.getExe programs.waybar.package} + ''); + }; # nix-community/home-manager/2064 targets.tray = { Unit = { Description = "Home Manager System Tray"; - Requires = ["graphical-session-pre.target"]; + Requires = ["graphical-session.target"]; }; }; }; diff --git a/modules/gui/desktop/hyprland/apps/default.nix b/modules/gui/desktop/hyprland/apps/default.nix @@ -7,7 +7,6 @@ ... }: with files; let - inherit (lib) getExe mkIf; inherit (config.lib.stylix) colors; exists = app: builtins.elem app config.apps.list; theme = import ../theme.nix pkgs; @@ -57,7 +56,9 @@ in { grim grimblast hyprkeys + hyprshade pavucontrol + pyprland slurp wev wl-clipboard @@ -129,45 +130,56 @@ in { }; # Shortcuts - wayland.windowManager.hyprland.settings.bind = [ - "$mod SHIFT, slash, exec, pkill kebihelp || kebihelp show -a" + wayland.windowManager.hyprland.settings.bind = let + toggle = app: "pkill ${app} || uwsm app -u ${app}.scope -- ${app}"; + runOnce = app: "pgrep ${app} || uwsm app -u ${app}.scope -- ${app}"; + in [ + "$mod SHIFT, slash, exec, ${toggle "kebihelp"} show -a" "$mod, slash, exec, ulauncher-toggle" "$mod, A, exec, nwg-drawer" "$mod SHIFT, A, exec, hyprutils toggle panel" - "$mod SHIFT, C, exec, hyprpicker -arf hex" + "$mod SHIFT, C, exec, ${runOnce "hyprpicker"} -arf hex" "$mod, D, exec, pypr toggle displays" "$mod, F, exec, thunar" "$mod, N, exec, dunstctl history-pop" "$mod, T, exec, kitty" "$mod SHIFT, T, exec, pypr toggle term" - ''$mod, V, exec, sh -c "if ! hyprctl clients | grep 'class: clipse'; then pypr show clip; fi"'' + ''$mod, V, exec, sh -c "hyprctl clients | grep 'class: clipse' || pypr show clip"'' "$mod, W, exec, firefox" - "$mod, Return, exec, missioncenter" + "$mod, Return, exec, ${runOnce "missioncenter"}" ", XF86Calculator, exec, qalculate-gtk" - "$mod, Escape, exec, sh -c 'if ! pgrep -x wlogout; then wlogout -p layer-shell; fi'" + "$mod, Escape, exec, ${toggle "wlogout"} -p layer-shell" ]; # Autostart - wayland.windowManager.hyprland.settings.exec-once = [ - "dbus-update-activation-environment --systemd --all" + wayland.windowManager.hyprland.settings.exec-once = + ["uwsm finalize"] + ++ (builtins.map (app: "uwsm app -t service -u ${util.build.until " " app}.service -- " + app) [ + "hyprutils daemon" - # Application Drawer - "nwg-drawer -r" + # Application Drawer + "nwg-drawer -r" - # Clipboard Manager - "clipse -listen" + # Clipboard Manager + "clipse -listen" - # Desktop Icons - "dicons" + # Desktop Icons + "dicons" - # Minimized Windows - "hyprutils minimize" - ]; + # Pyprland + "pypr" + ]); # Utilities services.playerctld.enable = true; services.poweralertd.enable = true; + # nix-community/home-manager/pull/5785 + systemd.user.services = { + poweralertd.Unit.After = lib.mkForce ["graphical-session.target"]; + dunst.Unit.After = lib.mkForce ["graphical-session.target"]; + }; + # Wallpaper Daemon services.hyprpaper = { enable = true; @@ -274,22 +286,21 @@ in { tray = true; }; - # Screen Share - systemd.user.services.xwaylandvideobridge = { - Unit.Description = "Stream Wayland windows to apps running under XWayland"; - Install.wantedBy = ["graphical-session.target"]; - Service = { - ExecStart = getExe pkgs.xwaylandvideobridge; - Restart = "on-failure"; - }; - }; - # Configuration Files home.file = { # Application Drawer ".config/nwg-drawer/drawer.css".text = hyprland.drawer; + # Pyprland + ".config/hypr/pyprland.toml".text = hyprland.pypr; + + # Shaders + ".config/hypr/shaders" = { + source = "${pkgs.custom.hyprshaders}/share/hypr/shaders"; + recursive = true; + }; + # Keybinds Viewer ".config/kebihelp.json".text = util.build.theme { inherit colors; @@ -333,15 +344,15 @@ in { // { # Discord Chat ".config/vesktop/settings/quickCss.css" = with theme; - mkIf (exists "discord") {text = ''@import url("https://${name}.github.io/discord/dist/${name}-${variant}-${accent}.theme.css");'';}; + lib.mkIf (exists "discord") {text = ''@import url("https://${name}.github.io/discord/dist/${name}-${variant}-${accent}.theme.css");'';}; # Logseq Notes ".logseq/config.edn" = with theme; - mkIf (exists "notes") {text = ''{:custom-css-url "@import url('https://logseq.${name}.com/ctp-${variant}.css');"}'';}; + lib.mkIf (exists "notes") {text = ''{:custom-css-url "@import url('https://logseq.${name}.com/ctp-${variant}.css');"}'';}; }; # Code Editor - programs.vscode = mkIf (exists "vscode") { + programs.vscode = lib.mkIf (exists "vscode") { extensions = with pkgs; [ vscode-extensions.catppuccin.catppuccin-vsc-icons (catppuccin-vsc.override { diff --git a/modules/gui/desktop/hyprland/apps/rules.nix b/modules/gui/desktop/hyprland/apps/rules.nix @@ -46,16 +46,12 @@ _: { # Prompt Windows "dimaround, class:^(gcr-prompter)$" "dimaround, class:^(xdg-desktop-portal-gtk)$" - "dimaround, class:^(polkit-gnome-authentication-agent-1)$" - "stayfocused, class:^(polkit-gnome-authentication-agent-1)" + "pin, class:^(pinentry-)" + "dimaround, class:^(pinentry-)" "stayfocused, class:^(pinentry-)" - - # Screen Share - "maxsize 1 1, class:^(xwaylandvideobridge)$" - "noanim, class:^(xwaylandvideobridge)$" - "noblur, class:^(xwaylandvideobridge)$" - "noinitialfocus, class:^(xwaylandvideobridge)$" - "opacity 0.0 override 0.0 override, class:^(xwaylandvideobridge)$" + "pin, class:^(gay.vaskel.Soteria)$" + "dimaround, class:^(gay.vaskel.Soteria)$" + "stayfocused, class:^(gay.vaskel.Soteria)" ]; }; } diff --git a/modules/gui/desktop/hyprland/apps/security.nix b/modules/gui/desktop/hyprland/apps/security.nix @@ -27,20 +27,19 @@ in { # Idle Daemon services.swayidle = let - lock = pre: post: "sh -c 'if ! ${getExe' pkgs.procps "pgrep"} -x swaylock; then ${pre}; ${getExe locker} -f ${post}; fi'"; + pause = "${getExe pkgs.playerctl} pause -a"; + lock = pre: flag: "sh -c 'if ! ${getExe' pkgs.procps "pgrep"} -x swaylock; then ${pre}; ${getExe locker} -f ${flag}; fi'"; in { enable = true; extraArgs = ["-w"]; - systemdTarget = "hyprland-session.target"; - events = [ { event = "before-sleep"; - command = lock "" ""; + command = lock pause ""; } { event = "lock"; - command = lock "${getExe pkgs.playerctl} pause -a" "--fade-in 0.2 --grace 15 --grace-no-mouse"; + command = lock pause "--fade-in 0.2 --grace 15 --grace-no-mouse"; } ]; @@ -91,23 +90,4 @@ in { ]} ''; }; - - # Authorization Agent - systemd.user.services.polkit = { - Unit.Description = "Polkit Authentication"; - - Install = { - WantedBy = ["graphical-session.target"]; - Wants = ["graphical-session.target"]; - After = ["graphical-session.target"]; - }; - - Service = { - Type = "simple"; - ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; - Restart = "on-failure"; - RestartSec = 1; - TimeoutStopSec = 10; - }; - }; } diff --git a/modules/gui/desktop/hyprland/default.nix b/modules/gui/desktop/hyprland/default.nix @@ -23,20 +23,11 @@ in { }; }; - # Session - services.displayManager.defaultSession = "Desktop"; - services.xserver.displayManager.session = [ - { - name = "Desktop"; - manage = "desktop"; - start = "Hyprland &> /dev/null"; - } - ]; - programs = { # WM hyprland = { enable = true; + withUWSM = true; xwayland.enable = true; package = pkgs.hyprworld.hyprland; }; @@ -52,16 +43,21 @@ in { }; }; - # Greeter - services.greetd.settings.default_session.command = with programs; - mkForce "${getExe hyprland.package} --config ${ - pkgs.writeText "greeter.conf" - (replaceStrings ["@greeter"] [(getExe regreet.package)] - (util.build.theme { - inherit (config.lib.stylix) colors; - file = files.hyprland.greeter; - })) - } &> /dev/null"; + services = { + # Auostart + xserver.desktopManager.runXdgAutostartIfNone = true; + + # Greeter + greetd.settings.default_session.command = with programs; + mkForce "${getExe hyprland.package} --config ${ + pkgs.writeText "greeter.conf" + (replaceStrings ["@greeter"] [(getExe regreet.package)] + (util.build.theme { + inherit (config.lib.stylix) colors; + file = files.hyprland.greeter; + })) + } &> /dev/null"; + }; } { @@ -124,17 +120,10 @@ in { hardware.brillo.enable = true; # Security + security.soteria.enable = true; security.pam.services = { + greetd.enableGnomeKeyring = true; swaylock.text = "auth include login"; - greetd = { - enableGnomeKeyring = true; - text = '' - auth substack login - account include login - password substack login - session include login - ''; - }; }; } diff --git a/modules/gui/desktop/hyprland/settings/keybindings.nix b/modules/gui/desktop/hyprland/settings/keybindings.nix @@ -41,7 +41,7 @@ # Window Minimization "ALT, Q, movetoworkspacesilent, special:minimized" - "ALT SHIFT, Q, exec, hyprutils minimize show" + "ALT SHIFT, Q, exec, hyprutils toggle minimized" # Cycle Workspaces "$mod, comma, split:workspace, m-1" diff --git a/modules/gui/desktop/hyprland/settings/plugins.nix b/modules/gui/desktop/hyprland/settings/plugins.nix @@ -1,23 +1,10 @@ { sys, config, - lib, pkgs, - files, ... }: { ## Plugin Settings - home = { - packages = with pkgs; [hyprshade pyprland]; - file = { - ".config/hypr/pyprland.toml".text = files.hyprland.pypr; - ".config/hypr/shaders" = { - source = "${pkgs.custom.hyprshaders}/share/hypr/shaders"; - recursive = true; - }; - }; - }; - wayland.windowManager.hyprland = { plugins = with pkgs.hyprworld; [hycov hyprexpo Hypr-DarkWindow Hyprspace hyprsplit]; settings = { @@ -95,26 +82,4 @@ ]; }; }; - - # Pyprland - systemd.user.services.pyprland = { - Install.WantedBy = ["graphical-session.target"]; - Unit = { - Description = "Hyprland Goodies"; - PartOf = ["graphical-session.target"]; - }; - - Service = let - pypr = lib.getExe pkgs.pyprland; - in { - Restart = "on-failure"; - ExecStop = "${pypr} exit"; - ExecStart = pkgs.writeShellScript "pypr-wrapper.sh" '' - ${files.path.systemd} - ${pypr} exit || true - rm "$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.pyprland.sock" || true - ${pypr} - ''; - }; - }; } diff --git a/modules/gui/launcher.nix b/modules/gui/launcher.nix @@ -70,7 +70,11 @@ in { # Autostart systemd.user.services.ulauncher = { - Unit.Description = "Start ULauncher"; + Unit = { + Description = "Start ULauncher"; + After = ["graphical-session.target"]; + }; + Install.WantedBy = ["graphical-session.target"]; Service = { Type = "Simple"; diff --git a/scripts/hyprutils.nix b/scripts/hyprutils.nix @@ -16,19 +16,19 @@ backlight [up,down] - Keyboard Backlight Controls volume [up,down,mute] - Volume Controls media [next,previous,toggle] - Media Controls - minimize [show] - Show Minimized windows zoom [in,out] - Screen Zoom toggle  fancy - Toggle Compositor Effects float - Toggle window floating in current workspace idle - Toggle Idle Daemon service + minimized - Show minimized windows monitor - Toggle specified Monitor panel - Toggle top Panel shader - Toggle Compositor Shader touchpad - Toggle touchpad ''; - minimize = builtins.toFile "minimize.sh" '' + daemon = builtins.toFile "daemon.sh" '' event_activespecial() { case "$WORKSPACENAME" in special:minimized*) @@ -101,6 +101,10 @@ in case "$1" in "") error "Expected an Option" "${help}";; "help") echo -e "## Hyprland Utility Script ##\n${help}";; + "daemon") + info "Monitoring Hyprland Socket..." + socat -u UNIX-CONNECT:"$XDG_RUNTIME_DIR"/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock EXEC:"shellevents ${daemon}",nofork + ;; "brightness") brightness_notification() { brightness=$(brillo | grep -Po '[0-9]{1,3}' | head -n 1) @@ -220,24 +224,6 @@ in *) error "Unexpected Option 'media $2'" "Try 'hyprutils help' for more information" ;; esac ;; - "minimize") - case "$2" in - "show") - if hyprctl workspaces | grep "special:minimized" - then - hyprctl dispatch workspace special:minimized - else - hyprctl notify 1 2000 0 "No minimized windows present" - fi - ;; - "") - info "Monitoring workspace 'special:minimized' activation..." - socat -u UNIX-CONNECT:"$XDG_RUNTIME_DIR"/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock \ - EXEC:"shellevents ${minimize}",nofork - ;; - *) error "Unexpected Option 'minimize $2'" "Try 'hyprutils help' for more information" ;; - esac - ;; "zoom") ZOOM=$(hyprctl getoption cursor:zoom_factor | grep float | awk '{print $2}') case "$2" in @@ -295,6 +281,14 @@ in notify idle -i "system-lock-screen" "Started Idle Daemon" fi ;; + "minimized") + if hyprctl workspaces | grep "special:minimized" + then + hyprctl dispatch workspace special:minimized + else + hyprctl notify 1 2000 0 "No minimized windows present" + fi + ;; "monitor") if hyprctl monitors | grep "$3" then