From 9d1ec69a11dbc529fd3fa3b2f915c77c02582eaf Mon Sep 17 00:00:00 2001 From: The_miro Date: Tue, 7 Jul 2026 13:26:48 +0200 Subject: [PATCH] feat: hyprshutdown power binds, 76% scrolling windows, single-sudo sysupdate - hyprshutdown wired into the graceful power flow (Super+Shift+O logout, Super+Ctrl+O power off, Super+Ctrl+Shift+O reboot) so apps close cleanly with a UI before Hyprland exits, instead of a hard systemctl call. Added to the hyprlua package list. - Scrolling layout: default window is now 76% of the monitor along the scroll axis (column_width 0.5 -> 0.76). - sysupdate.sh: primes sudo once at startup and keeps the credential alive for the whole run, so no later step re-prompts. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01SUN7gg6GGfnToghMijLm5Y --- desktopenvs/hyprlua/hypr/layouts/scrolling.lua | 11 +++++++---- desktopenvs/hyprlua/hypr/usr/binds.lua | 8 +++++--- setup/modules/Desktop-Environments/hyprlua.sh | 1 + sysupdate.sh | 13 ++++++++++++- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/desktopenvs/hyprlua/hypr/layouts/scrolling.lua b/desktopenvs/hyprlua/hypr/layouts/scrolling.lua index adfed80..a40cd2e 100644 --- a/desktopenvs/hyprlua/hypr/layouts/scrolling.lua +++ b/desktopenvs/hyprlua/hypr/layouts/scrolling.lua @@ -4,9 +4,12 @@ -- * focus_fit_method 0/1 ("Centered follow") — see M.set_fit(); when centered the -- focused column is centred and the previous/next columns peek in from the sides. -- --- column_width is kept < 1.0 (0.5) so the active column is narrower than the viewport --- and the prev/next columns stay on-screen and clickable. fullscreen_on_one_column --- lets a lone window still fill the screen, so the narrow width costs nothing alone. +-- column_width is the default window size along the scroll axis, as a fraction of the +-- monitor (0.76 = 76% of the monitor's width for a horizontal tape, or its height for a +-- vertical one — the layout applies it to whichever axis `direction` scrolls). Keeping it +-- < 1.0 leaves the prev/next windows peeking in on-screen and clickable; +-- fullscreen_on_one_column lets a lone window still fill the screen, so it costs nothing +-- when a window is alone. return { name = "scrolling", label = "Scrolling", @@ -18,7 +21,7 @@ return { config = { scrolling = { direction = "down", - column_width = 0.5, + column_width = 0.76, -- 76% of the monitor along the scroll axis focus_fit_method = 1, follow_focus = true, fullscreen_on_one_column = true, diff --git a/desktopenvs/hyprlua/hypr/usr/binds.lua b/desktopenvs/hyprlua/hypr/usr/binds.lua index 503afb1..beeac61 100644 --- a/desktopenvs/hyprlua/hypr/usr/binds.lua +++ b/desktopenvs/hyprlua/hypr/usr/binds.lua @@ -88,10 +88,12 @@ hl.bind(mainMod .. " + SHIFT + Q", hl.dsp.exec_cmd("hyprctl kill")) hl.bind(mainMod .. " + CTRL + M", hl.dsp.exec_cmd("~/.config/scripts/toggle-layout.sh")) --- lock/exit +-- lock/exit — hyprshutdown gracefully closes every app (with a UI) before it exits +-- Hyprland and runs its --post-cmd, instead of yanking the session out from under them. hl.bind(mainMod .. " + O", hl.dsp.exec_cmd("hyprlock")) -hl.bind(mainMod .. " + SHIFT + O", hl.dsp.exec_cmd("hyprctl dispatch exit")) -hl.bind(mainMod .. " + CTRL + O", hl.dsp.exec_cmd("systemctl poweroff")) +hl.bind(mainMod .. " + SHIFT + O", hl.dsp.exec_cmd("hyprshutdown")) -- graceful logout +hl.bind(mainMod .. " + CTRL + O", hl.dsp.exec_cmd('hyprshutdown -p "systemctl poweroff"')) -- graceful power off +hl.bind(mainMod .. " + CTRL + SHIFT + O",hl.dsp.exec_cmd('hyprshutdown -p "systemctl reboot"')) -- graceful reboot hl.bind(mainMod .. " + ALT + O", hl.dsp.exec_cmd("~/.config/scripts/pwr-dmenu.sh")) hl.bind(mainMod .. " + ALT + CTRL + SHIFT + END", hl.dsp.exit()) diff --git a/setup/modules/Desktop-Environments/hyprlua.sh b/setup/modules/Desktop-Environments/hyprlua.sh index e1b3389..c2a31fe 100755 --- a/setup/modules/Desktop-Environments/hyprlua.sh +++ b/setup/modules/Desktop-Environments/hyprlua.sh @@ -89,6 +89,7 @@ HYPRLUA_PACKAGES=( hyprsunset # blue-light filter / night-mode daemon hypridle # idle daemon triggering lock/suspend after inactivity + hyprshutdown # hyprtoolkit graphical power/shutdown dialog (Super+Alt+O) ksshaskpass # Qt SSH passphrase dialog registered as ssh-askpass nm-connection-editor # GTK editor for NetworkManager connection profiles diff --git a/sysupdate.sh b/sysupdate.sh index d55abb7..1a266fb 100755 --- a/sysupdate.sh +++ b/sysupdate.sh @@ -96,7 +96,17 @@ spin_stop() { printf '\r%*s\r' "$(_cols)" '' } -trap 'spin_stop; tput cnorm 2>/dev/null || true' EXIT +_SUDO_KEEPALIVE="" +trap 'spin_stop; [[ -n "${_SUDO_KEEPALIVE:-}" ]] && kill "$_SUDO_KEEPALIVE" 2>/dev/null; tput cnorm 2>/dev/null || true' EXIT + +# Prime sudo ONCE at startup and keep the credential fresh for the whole run, so no +# later step (config deploy, pacman -S per package, state-file write) re-prompts. +sudo_prime() { + printf " ${Y}?${RS} ${BO}Elevated access${RS} — enter your password once for this run.\n" + sudo -v || { err "sudo is required."; exit 1; } + ( while true; do sudo -n true 2>/dev/null; sleep 50; kill -0 "$$" 2>/dev/null || exit; done ) & + _SUDO_KEEPALIVE=$! +} # ═══════════════════════════════════════════════════════════════════════════════ # STATE FILE @@ -694,6 +704,7 @@ declare -a FLATPAK_PKGS=() main() { header + sudo_prime # single password prompt up front; kept alive for the whole run # ── Configs-only mode ──────────────────────────────────────────────────── if [[ "$UPDATE_MODE" == "configs" ]]; then