remove custom screensavers (let shells handle it)
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
# hypridle.conf — screensaver only.
|
||||
# Managed by dotfiles (stow hypr).
|
||||
#
|
||||
# IDLE OWNERSHIP: Noctalia owns dim / lock / screen-off / suspend via its own
|
||||
# [idle] block in ~/.config/noctalia/config.toml. hypridle is started only for
|
||||
# the Noctalia shell (see hyprland.lua) and contributes just the tte
|
||||
# screensaver. Do not re-add lock/DPMS listeners here — that duplication is
|
||||
# what made two idle managers fight over the same transitions.
|
||||
#
|
||||
# lock_cmd goes through scripts/lock.sh, which resolves the active shell from
|
||||
# env.lua. That keeps a manually started hypridle under Caelestia from calling
|
||||
# `noctalia ...` (which would silently do nothing).
|
||||
#
|
||||
# WARNING — do not add DPMS dispatchers back to this file. This Hyprland
|
||||
# (hyprmod Lua runtime, 0.56.x) evaluates `hyprctl dispatch` args as Lua, and
|
||||
# the dpms dispatcher takes a TABLE, not a boolean:
|
||||
# WRONG (silently becomes a TOGGLE, ignoring the argument):
|
||||
# hyprctl dispatch 'hl.dsp.dpms(true)'
|
||||
# RIGHT:
|
||||
# hyprctl dispatch 'hl.dsp.dpms({action="enable"})'
|
||||
# A toggle in after_sleep_cmd turns the display OFF on resume, and with
|
||||
# misc:key_press_enables_dpms = false nothing could wake it again.
|
||||
|
||||
general {
|
||||
lock_cmd = ~/.config/hypr/scripts/lock.sh
|
||||
}
|
||||
|
||||
# Screensaver via backend wrappers (switch backend in modules/screensaver.lua).
|
||||
listener {
|
||||
timeout = 300
|
||||
on-timeout = ~/.config/hypr/scripts/screensaver-start.sh
|
||||
on-resume = ~/.config/hypr/scripts/screensaver-stop.sh
|
||||
}
|
||||
@@ -40,11 +40,6 @@ hl.on("hyprland.start", function()
|
||||
else -- default: "noctalia"
|
||||
hl.exec_cmd("noctalia &")
|
||||
end
|
||||
-- activate hypridle when not using Caelestia (has its own idle-ing mechnism)
|
||||
if env.shell ~= "caelestia" then
|
||||
hl.exec_cmd("hypridle &")
|
||||
end
|
||||
|
||||
hl.exec_cmd("sh ~/.config/hypr/scripts/portal-host-override.sh")
|
||||
hl.exec_cmd("sh ~/.config/hypr/scripts/ensure-mime-defaults.sh")
|
||||
end)
|
||||
@@ -74,4 +69,3 @@ if fid_gui2 then
|
||||
fid_gui2:close()
|
||||
require("hyprland-gui")
|
||||
end
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# hyprsaver.toml — chill playlist: calm shaders + cool palettes, cycling.
|
||||
# Location: ~/.config/hypr/hyprsaver.toml (stowed from dotfiles).
|
||||
# Names verified against `hyprsaver --list-shaders` / `--list-palettes`.
|
||||
# Everything else uses hyprsaver's built-in defaults (see
|
||||
# /usr/share/hyprsaver/examples/config.toml for the full reference).
|
||||
|
||||
[general]
|
||||
fps = 30
|
||||
shader = "cycle"
|
||||
palette = "cycle"
|
||||
shader_cycle_interval = 300
|
||||
palette_cycle_interval = 60
|
||||
cycle_order = "random"
|
||||
synced = true
|
||||
shader_playlist = "chill"
|
||||
palette_playlist = "chill"
|
||||
|
||||
[playlists.chill]
|
||||
shaders = [
|
||||
"plasma",
|
||||
"marble",
|
||||
"snowfall",
|
||||
"aurora",
|
||||
"clouds",
|
||||
"planet",
|
||||
"starfield",
|
||||
"fireflies",
|
||||
]
|
||||
palettes = [
|
||||
"vaporwave",
|
||||
"frost",
|
||||
"ocean",
|
||||
"aurora",
|
||||
]
|
||||
|
||||
[behavior]
|
||||
fade_in_ms = 800
|
||||
fade_out_ms = 400
|
||||
dismiss_on = ["key", "mouse_move", "mouse_click", "touch"]
|
||||
exclusive_keyboard = true
|
||||
@@ -233,7 +233,6 @@ bind("SHIFT + PRINT", exec("hyprshot -m active --output-folder " .. var.screensh
|
||||
})
|
||||
|
||||
bind(var.mainMod .. " + L", exec(command.lock), { locked = true, description = "Lock screen" })
|
||||
bind(var.mainMod .. " + SHIFT + L", exec(command.screensaver), { description = "Start screensaver (any key quits)" })
|
||||
bind(var.mainMod .. " + K", exec(command.keybinds_show), { description = "Show keybind overview" })
|
||||
bind(var.mainMod .. " + W", exec(command.wallpaper_select), { description = "Wallpaper select" })
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
-- Single source of truth for "how do I lock this session", keyed on the
|
||||
-- active shell in env.lua. Consumed by two callers:
|
||||
-- * scripts/lock.sh (hypridle's lock_cmd) - loaded via plain dofile
|
||||
-- * modules/shell_commands.lua (SUPER+L) - loaded via require
|
||||
--
|
||||
-- Both contexts load this file, so it must NOT use require("env"): Lua's
|
||||
-- default package.path is cwd-relative, and that only resolves inside
|
||||
-- ~/.config/hypr. hypridle's cwd is not guaranteed. Resolve by path instead.
|
||||
local config_home = os.getenv("XDG_CONFIG_HOME") or os.getenv("HOME") .. "/.config"
|
||||
local prefix = config_home .. "/hypr/"
|
||||
|
||||
local function load_env()
|
||||
local fid = io.open(prefix .. "env.lua")
|
||||
if fid then
|
||||
fid:close()
|
||||
return dofile(prefix .. "env.lua")
|
||||
end
|
||||
return dofile(prefix .. "env_example.lua")
|
||||
end
|
||||
|
||||
local LOCK = {
|
||||
noctalia = "noctalia msg session lock",
|
||||
caelestia = "caelestia shell lock lock",
|
||||
}
|
||||
|
||||
local env = load_env()
|
||||
|
||||
return {
|
||||
shell = env.shell,
|
||||
-- nil for an unknown shell; scripts/lock.sh treats that as a hard error
|
||||
-- rather than reporting success while nothing is actually locked.
|
||||
cmd = LOCK[env.shell],
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
-- Screensaver commands for idle (hypridle on-timeout/on-resume) and manual
|
||||
-- (SUPER+SHIFT+L) use. scripts/screensaver-start.sh and
|
||||
-- scripts/screensaver-stop.sh exec the .start / .stop command below.
|
||||
--
|
||||
-- Active backend: tte (fullscreen kitty + terminal-text-effects).
|
||||
return {
|
||||
start = "~/.config/hypr/scripts/launch-screensaver.sh",
|
||||
stop = "~/.config/hypr/scripts/screensaver-stop.sh",
|
||||
-- Alternative backend: hyprsaver (GPU fractal shaders, wlr-layer-shell).
|
||||
-- Swap the commented pair in to switch (no other file changes needed).
|
||||
-- start = "hyprsaver",
|
||||
-- stop = "hyprsaver --quit",
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
|
||||
local env = require("env")
|
||||
|
||||
-- Shell-agnostic on purpose: the active shell is resolved inside lock.sh from
|
||||
-- env.lua, so hypridle's lock_cmd and this bind cannot drift apart.
|
||||
local LOCK = "~/.config/hypr/scripts/lock.sh"
|
||||
|
||||
local commands = {
|
||||
session = "",
|
||||
logout = "",
|
||||
@@ -13,8 +9,7 @@ local commands = {
|
||||
menu = "",
|
||||
settings = "",
|
||||
control_center = "",
|
||||
lock = LOCK,
|
||||
screensaver = "sh ~/.config/hypr/scripts/screensaver-start.sh force",
|
||||
lock = "",
|
||||
wallpaper_select = "",
|
||||
keybinds_show = "sh ~/.config/hypr/scripts/show-keybinds.sh",
|
||||
clipboard = "",
|
||||
@@ -33,6 +28,7 @@ if env.shell == "noctalia" then
|
||||
commands.settings = "noctalia msg settings-toggle"
|
||||
commands.control_center = "noctalia msg panel-toggle control-center"
|
||||
commands.wallpaper_select = "noctalia msg panel-toggle wallpaper"
|
||||
commands.lock = "noctalia msg session lock"
|
||||
elseif env.shell == "caelestia" then
|
||||
commands.session = "caelestia shell drawers toggle session"
|
||||
commands.logout = "hyprctl dispatch exit"
|
||||
@@ -47,6 +43,7 @@ elseif env.shell == "caelestia" then
|
||||
commands.emoji = "caelestia emoji -p"
|
||||
commands.show_all = "caelestia shell drawers toggle utilities"
|
||||
commands.clear_notifications = "caelestia shell notifs clear"
|
||||
commands.lock = "caelestia shell lock lock"
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -101,16 +101,6 @@ hl.window_rule({
|
||||
border_size = 0,
|
||||
})
|
||||
|
||||
-- Manual tte screensaver preview (SUPER+SHIFT+L): fullscreen kitty.
|
||||
hl.window_rule({
|
||||
name = "screensaver-fullscreen",
|
||||
match = {
|
||||
class = "org.screensaver",
|
||||
},
|
||||
fullscreen = true,
|
||||
float = true,
|
||||
})
|
||||
|
||||
hl.window_rule({
|
||||
name = "floating-windows",
|
||||
match = { class = "(imv|.*hyprmod)" },
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
hyprland
|
||||
// idle looks good on you
|
||||
|
||||
ArchTop is relaxing 🧘
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# launch-screensaver.sh — idle-triggered tte screensaver (hypridle on-timeout).
|
||||
# Spawns one fullscreen kitty running screensaver-tte.sh per monitor.
|
||||
# Usage: launch-screensaver.sh [force]
|
||||
# force ignore the screensaver-off toggle file.
|
||||
# Toggle off: touch ~/.local/state/hypr/screensaver-off
|
||||
#
|
||||
# Lessons baked in: no focus-restore after spawn (it raced the new window and
|
||||
# caused flash-then-nothing), no pkill -f patterns anywhere (teardown is done
|
||||
# by screensaver-stop.sh via exact client PIDs).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCREENSAVER_CLASS="org.screensaver"
|
||||
TOGGLE_FILE="$HOME/.local/state/hypr/screensaver-off"
|
||||
|
||||
command -v tte >/dev/null 2>&1 || exit 1
|
||||
command -v kitty >/dev/null 2>&1 || exit 1
|
||||
|
||||
# Already running (precise client check).
|
||||
if hyprctl clients -j 2>/dev/null | jq -e '.[] | select(.class=="org.screensaver")' >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Opt-out toggle (unless forced, e.g. manual invocation).
|
||||
if [[ -f "$TOGGLE_FILE" ]] && [[ "${1:-}" != "force" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# hyprctl prints plain-text errors (not JSON) when HYPRLAND_INSTANCE_SIGNATURE
|
||||
# is stale (e.g. shell/tmux predates the current compositor). Fail clearly
|
||||
# instead of dumping a jq parse error.
|
||||
monitors_json="$(hyprctl monitors -j 2>/dev/null)" || {
|
||||
echo "launch-screensaver: hyprctl failed - is HYPRLAND_INSTANCE_SIGNATURE stale? (try a fresh terminal)" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "$monitors_json" | jq -e . >/dev/null 2>&1 || {
|
||||
echo "launch-screensaver: hyprctl did not return JSON - stale HYPRLAND_INSTANCE_SIGNATURE?" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# NOTE: hyprmod Lua runtime (Hyprland 0.56.x) evaluates `hyprctl dispatch` args
|
||||
# as Lua — classic `dispatch focusmonitor eDP-1` fails. Dispatchers must be
|
||||
# hl.dsp.* expressions. Focus each monitor before exec so the saver kitty
|
||||
# spawns there; deliberately no focus-restore afterwards (spawn race).
|
||||
for m in $(echo "$monitors_json" | jq -r '.[] | .name'); do
|
||||
hyprctl dispatch "hl.dsp.focus({monitor=\"$m\"})" >/dev/null 2>&1
|
||||
hyprctl dispatch "hl.dsp.exec_cmd('kitty --class=\"$SCREENSAVER_CLASS\" --override font_size=18 --override window_padding_width=0 --override background_opacity=1 --override mouse_hide_wait=1.0 -e \"$SCRIPT_DIR/screensaver-tte.sh\"')" >/dev/null 2>&1
|
||||
done
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# lock.sh — lock the session with the active shell's own lock command.
|
||||
# The mapping lives in modules/lock.lua (reads env.lua), so neither hypridle's
|
||||
# lock_cmd nor the SUPER+L bind hardcodes a shell. This is what keeps a
|
||||
# manually started hypridle under Caelestia from failing on `noctalia ...`.
|
||||
#
|
||||
# Usage: lock.sh (no args; safe to call while locked)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Resolve from this script's own location so it works through the
|
||||
# ~/.config/hypr symlink and does not depend on XDG_CONFIG_HOME.
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOCK_LUA="$(cd "$SCRIPT_DIR/.." && pwd)/modules/lock.lua"
|
||||
|
||||
CMD="$(LOCK_LUA="$LOCK_LUA" lua -e 'print(dofile(os.getenv("LOCK_LUA")).cmd)' 2>/dev/null)" || {
|
||||
echo "lock: cannot read modules/lock.lua" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Empty here means env.lua named a shell with no known lock command. Fail loudly
|
||||
# instead of exiting 0, or a caller would think the session got locked.
|
||||
[[ -n "$CMD" ]] || {
|
||||
echo "lock: no lock command for the active shell (check env.lua)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Word-split on purpose: CMD is a command line, not a single path.
|
||||
# shellcheck disable=SC2086
|
||||
exec $CMD
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# screensaver-start.sh — exec the start command from modules/screensaver.lua.
|
||||
# Usage: screensaver-start.sh [force] (forwarded to .sh targets, e.g. the tte
|
||||
# launcher's toggle bypass; dropped for bare commands like `hyprsaver`).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
CMD="$(lua -e 'print(dofile(os.getenv("HOME").."/.config/hypr/modules/screensaver.lua").start)' 2>/dev/null)" || {
|
||||
echo "screensaver-start: cannot read modules/screensaver.lua" >&2
|
||||
exit 1
|
||||
}
|
||||
CMD="${CMD/#\~/$HOME}"
|
||||
[[ -n "$CMD" ]] || {
|
||||
echo "screensaver-start: empty start command" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ "$CMD" == *.sh ]]; then
|
||||
exec "$CMD" "$@"
|
||||
else
|
||||
# Bare command, may carry flags (e.g. "hyprsaver --quit").
|
||||
# shellcheck disable=SC2086
|
||||
exec $CMD
|
||||
fi
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# screensaver-stop.sh — exec the stop command from modules/screensaver.lua.
|
||||
# When it points back here (tte backend), run the built-in teardown below:
|
||||
# kill saver windows by Hyprland client PID (class org.screensaver) plus
|
||||
# stray tte processes (exact comm match). Never `pkill -f <pattern>`: a
|
||||
# full-cmdline pattern also matches bystander shells merely mentioning it.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ME="$(realpath "$SCRIPT_DIR/screensaver-stop.sh")"
|
||||
|
||||
WANT="$(lua -e 'print(dofile(os.getenv("HOME").."/.config/hypr/modules/screensaver.lua").stop)' 2>/dev/null)" || {
|
||||
echo "screensaver-stop: cannot read modules/screensaver.lua" >&2
|
||||
exit 1
|
||||
}
|
||||
WANT="${WANT/#\~/$HOME}"
|
||||
|
||||
# Alternative backend configured (e.g. "hyprsaver --quit"): run it instead.
|
||||
if [[ "$(realpath -m "$WANT")" != "$ME" ]]; then
|
||||
# shellcheck disable=SC2086
|
||||
exec $WANT
|
||||
fi
|
||||
|
||||
# --- tte teardown ---
|
||||
pids="$(hyprctl clients -j 2>/dev/null | jq -r '.[] | select(.class=="org.screensaver") | .pid' 2>/dev/null)" || pids=""
|
||||
if [[ -n "${pids:-}" ]]; then
|
||||
# shellcheck disable=SC2086
|
||||
kill $pids 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# tte runs under comm "tte" (verified); -x matches the comm only, so this
|
||||
# cannot hit bystander shells.
|
||||
pkill -x tte 2>/dev/null || true
|
||||
|
||||
exit 0
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# screensaver-tte.sh — runs inside each fullscreen tte kitty.
|
||||
# Loops random tte effects until any keypress, then exits (kitty closes).
|
||||
# Child teardown uses the exact PID ($!) — never pkill -f patterns, which
|
||||
# would also match bystander shells mentioning the class name.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCREENSAVER_TEXT="$HOME/.config/hypr/screensaver.txt"
|
||||
|
||||
trap 'exit 0' SIGINT SIGTERM SIGHUP SIGQUIT
|
||||
|
||||
printf '\033]11;rgb:00/00/00\007' # black background
|
||||
|
||||
input="$SCREENSAVER_TEXT"
|
||||
[[ -f "$input" ]] || input="/etc/hostname"
|
||||
|
||||
while true; do
|
||||
tte -i <(fastfetch --pipe) \
|
||||
--frame-rate 60 --canvas-width 0 --canvas-height 0 \
|
||||
--anchor-canvas c --anchor-text c \
|
||||
--random-effect --exclude-effects dev_worm \
|
||||
--no-eol --no-restore-cursor &
|
||||
TPID=$!
|
||||
# Wait for tte to appear (Python startup) before polling it.
|
||||
for _ in $(seq 1 10); do
|
||||
kill -0 "$TPID" 2>/dev/null || break
|
||||
pgrep -x tte >/dev/null 2>&1 && break
|
||||
sleep 0.1
|
||||
done
|
||||
while kill -0 "$TPID" 2>/dev/null; do
|
||||
if read -r -n1 -t 1; then
|
||||
kill "$TPID" 2>/dev/null || true
|
||||
wait "$TPID" 2>/dev/null || true
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
wait "$TPID" 2>/dev/null || true
|
||||
# Throttle respawn if tte exits instantly (e.g. a sub-second effect).
|
||||
sleep 0.2
|
||||
done
|
||||
+3
-1
@@ -31,7 +31,9 @@ say_pass() { printf 'ok: %s\n' "$*"; PASS=$((PASS+1)); }
|
||||
# Exclusions: never lint tpm or general vendored plugin trees, whose third-party
|
||||
# scripts may legitimately fail `bash -n` and are not written/maintained here.
|
||||
EXCLUDE_VENDOR='(/tpm/|/plugins/|/plugins$)'
|
||||
mapfile -t SCRIPTS < <(git ls-files '*.sh' 2>/dev/null | grep -vE "$EXCLUDE_VENDOR")
|
||||
mapfile -t SCRIPTS < <(git ls-files '*.sh' 2>/dev/null | grep -vE "$EXCLUDE_VENDOR" | while IFS= read -r script; do
|
||||
[[ -f "$script" ]] && printf '%s\n' "$script"
|
||||
done)
|
||||
if [[ ${#SCRIPTS[@]} -eq 0 ]]; then
|
||||
mapfile -t SCRIPTS < <(find . -name '*.sh' \
|
||||
-not -path './.git/*' -not -path '*/.git/*' \
|
||||
|
||||
Reference in New Issue
Block a user