summaryrefslogtreecommitdiff
path: root/.config/niri
diff options
context:
space:
mode:
Diffstat (limited to '.config/niri')
-rwxr-xr-x.config/niri/apply-colors.sh134
-rw-r--r--.config/niri/config.kdl24
-rwxr-xr-x.config/niri/mako-start.sh20
-rwxr-xr-x.config/niri/set-backdrop.sh46
-rwxr-xr-x.config/niri/theme-switcher.sh178
5 files changed, 134 insertions, 268 deletions
diff --git a/.config/niri/apply-colors.sh b/.config/niri/apply-colors.sh
index aebf509..3d3b433 100755
--- a/.config/niri/apply-colors.sh
+++ b/.config/niri/apply-colors.sh
@@ -1,85 +1,71 @@
-#!/bin/bash
-# Apply a wallpaper and generate colors with wallust (16-color palette) + matugen (Material You / M3).
-# Usage: apply-colors.sh <image> [light|dark]
-# Called by theme-switcher.sh and the waybar random-wallpaper click.
+#!/bin/sh
+# Regenerate wallust colors from the current wallpaper and reload running apps.
+# Also keeps the niri backdrop in sync with the wallpaper.
+#
+# This is the single startup entry point: it derives the last used wallpaper
+# from awww's own cache (so "main = last used wallpaper"), reads the saved
+# palette/threshold from the runtime state file, runs `wallust run` (which
+# regenerates EVERY template -> adding a new app only needs a wallust.toml
+# template, never a new autostart line), and reloads live apps.
-set -euo pipefail
+CACHE="${XDG_CACHE_HOME:-$HOME/.cache}"
+STATE="$CACHE/wallust_runtime"
+WP_DIR="$HOME/Pictures/wallpapers"
-SCRIPT_DIR="$(cd "$(dirname "$(realpath "$0")")" && pwd)"
-IMG="${1:-}"
-MODE="${2:-auto}"
-LOG="${THEME_LOG:-/tmp/theme-switcher.log}"
-
-log() {
- printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG"
+# Determine the current wallpaper.
+# Primary: the marker file written by theme-switcher.sh (last used wallpaper).
+# Fallback: parse awww's cache (the last image set via `awww img`), excluding
+# the blurred backdrop layer. awww stores the cache as one concatenated line,
+# so we grep for the first absolute image path that is not a backdrop blur.
+get_wp() {
+ marker="$CACHE/current_wallpaper"
+ if [ -f "$marker" ]; then
+ wp="$(cat "$marker" 2>/dev/null)"
+ [ -n "$wp" ] && [ -f "$wp" ] && { echo "$wp"; return 0; }
+ fi
+ for f in "$CACHE"/awww/*/*; do
+ [ -f "$f" ] || continue
+ # awww stores the cache as one concatenated line; the main-namespace
+ # image is everything before the first "backdrop" delimiter. Cut there
+ # so the greedy path match can't swallow the (blurred) backdrop path.
+ wp=$(sed 's/backdrop.*//' "$f" \
+ | tr '\0' '\n' \
+ | grep -oE '/[^[:space:]]+\.(png|jpg|jpeg|webp|gif)' \
+ | head -1)
+ [ -n "$wp" ] && [ -f "$wp" ] && { echo "$wp"; return 0; }
+ done
+ return 1
}
-# Record the exact failing command + line on any error.
-trap 'log "apply-colors FAILED (exit $?) in ${BASH_SOURCE[0]}:$LINENO: $BASH_COMMAND"' ERR
-
-if [ -z "$IMG" ] || [ ! -f "$IMG" ]; then
- echo "usage: $0 <image> [light|dark]" >&2
- exit 1
+# Read saved palette/threshold/saturation/colorspace from the runtime state.
+palette=""; threshold=""; sat=""; cs=""
+if [ -f "$STATE" ]; then
+ while IFS='=' read -r k v; do
+ case "$k" in
+ palette) palette="$v" ;;
+ threshold) threshold="$v" ;;
+ saturation) sat="$v" ;;
+ colorspace) cs="$v" ;;
+ esac
+ done < "$STATE"
fi
-# wait for the awww daemon to be ready (it is spawned next to this script at login)
-log "awww img $IMG"
-for _ in $(seq 1 10); do
- if awww query >/dev/null 2>&1; then
- break
- fi
- sleep 1
-done
-
-# set the wallpaper FIRST and unconditionally — this is the critical, must-work
-# step. Color generation below is best-effort: a failure there must never block
-# the wallpaper from changing (that coupling is what froze the wallpaper before).
-awww img "$IMG" || { log "awww img FAILED ($IMG)"; exit 1; }
+WP="$(get_wp)" || WP="$(ls -1 "$WP_DIR"/*.* 2>/dev/null | head -1)" || true
-# blurred copy for the Overview backdrop (sibling or on-the-fly generation)
-"$SCRIPT_DIR/set-backdrop.sh" "$IMG" || log "set-backdrop FAILED ($IMG)"
-
-# wallust: classic 16-color palette (foot, btop, ...)
-# fastresize (the config default) is flaky on some images — always use resized.
-# Best-effort: a wallust failure must not prevent the wallpaper from sticking.
-log "wallust palette=$MODE $IMG"
-case "$MODE" in
-light|dark) WALLUST_PALETTE=("--palette" "$MODE") ;;
-*) WALLUST_PALETTE=() ;;
-esac
-# wallust's `resized` backend is intermittently flaky on some images; retry a
-# few times, but ultimately tolerate failure.
-ok=0
-for attempt in 1 2 3; do
- if wallust run -b resized "${WALLUST_PALETTE[@]}" "$IMG"; then
- ok=1
- break
- fi
- log "wallust attempt $attempt FAILED ($IMG, mode=$MODE)"
- [ "$attempt" -lt 3 ] && sleep 2
-done
-if [ "$ok" -ne 1 ]; then
- log "wallust FAILED after 3 attempts ($IMG, mode=$MODE) — continuing without wallust colors"
-else
- # foot needs bare RRGGBB, not #RRGGBB — strip the leading '#'
- sed -i 's/#\([0-9a-fA-F]\)/\1/g' ~/.cache/wallust/foot-theme.ini 2>/dev/null || true
+if [ -n "$WP" ] && [ -f "$WP" ]; then
+ args=""
+ [ -n "$palette" ] && args="$args -p $palette"
+ [ -n "$threshold" ] && args="$args -t $threshold"
+ [ -n "$sat" ] && args="$args --saturation $sat"
+ [ -n "$cs" ] && args="$args -c $cs"
+ # shellcheck disable=SC2086
+ wallust run $args "$WP" || true
+ "$HOME/.config/niri/set-backdrop.sh" "$WP" || true
fi
-# matugen: Material You / M3 colors (niri focus ring, ...)
-# --prefer is required for non-interactive runs (multiple source colors).
-# Best-effort: a matugen failure (e.g. bad config after an upgrade) must not
-# block the wallpaper.
-log "matugen mode=$MODE $IMG"
-case "$MODE" in
-light) matugen image "$IMG" -m "light" --prefer saturation ;;
-dark) matugen image "$IMG" -m "dark" --prefer saturation ;;
-*) matugen image "$IMG" --prefer saturation ;;
-esac || log "matugen FAILED ($IMG, mode=$MODE) — continuing without matugen colors"
-
-# reload consumers
-killall -SIGUSR2 waybar 2>/dev/null || true
-killall -USR1 foot 2>/dev/null || true
-niri msg action load-config-file 2>/dev/null || true
+# Reload apps that support live reload.
makoctl reload 2>/dev/null || true
-log "apply-colors OK ($IMG, $MODE)"
+# Refresh niri's own theme (focus ring, etc.) from the freshly generated
+# wallust niri template. Optional because niri may still be starting up.
+niri msg action reload-config 2>/dev/null || true
diff --git a/.config/niri/config.kdl b/.config/niri/config.kdl
index b71b8ed..72b0fbb 100644
--- a/.config/niri/config.kdl
+++ b/.config/niri/config.kdl
@@ -1,19 +1,22 @@
-include optional=true "/home/seraphim/.cache/matugen/theme.kdl"
-spawn-at-startup "/home/seraphim/dotfiles-gentoo/niri/.config/niri/mako-start.sh"
+//-- Theme importing & X server config
+include optional=true "/home/seraphim/.cache/wallust/niri-theme.kdl"
spawn-at-startup "xrdb" "-merge" "/home/seraphim/.Xresources"
+//--- Apps startup
+spawn-at-startup "/usr/libexec/hyprpolkitagent"
spawn-at-startup "vicinae" "server"
spawn-at-startup "gentoo-pipewire-launcher"
spawn-at-startup "telegram-desktop" "-autostart" "--minimized"
spawn-at-startup "keepassxc" "--minimized"
+spawn-at-startup "/usr/bin/Throne"
+//--- Wallpapers
spawn-at-startup "awww-daemon"
spawn-at-startup "awww-daemon" "--namespace" "backdrop"
-spawn-at-startup "/usr/libexec/hyprpolkitagent"
+spawn-at-startup "sh" "-c" "$HOME/.config/niri/apply-colors.sh"
+//--- Dbus & darkman
spawn-at-startup "dbus-update-activation-environment" "WAYLAND_DISPLAY" "DISPLAY" "XDG_CURRENT_DESKTOP"
spawn-at-startup "darkman" "run"
-spawn-at-startup "/home/seraphim/dotfiles-gentoo/.config/niri/theme-switcher.sh" "--last"
spawn-at-startup "sh" "-c" "NO_AT_BRIDGE=1 waybar"
-spawn-at-startup "/usr/bin/Throne"
-spawn-at-startup "mpd"
+
prefer-no-csd
screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
@@ -29,14 +32,12 @@ blur {
saturation 1.1
}
-// awww-daemon --namespace backdrop: pre-blurred wallpaper shown in the
-// Overview backdrop. niri cannot blur a backdrop surface itself.
layer-rule {
match namespace="^awww-daemonbackdrop$"
place-within-backdrop true
}
input {
- focus-follows-mouse max-scroll-amount="100%"
+// focus-follows-mouse max-scroll-amount="100%"
keyboard {
xkb {
@@ -160,8 +161,9 @@ gestures {
}
cursor {
- xcursor-theme "Bibata-Modern-Classic"
- xcursor-size 15
+ xcursor-theme "Notwaita-Black"
+ //xcursor-theme "macOS"
+ xcursor-size 16
}
overview {
diff --git a/.config/niri/mako-start.sh b/.config/niri/mako-start.sh
deleted file mode 100755
index aceaa3b..0000000
--- a/.config/niri/mako-start.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-# Start mako after making sure the wallust-generated color file exists.
-# mako's config uses `include=~/.cache/wallust/mako`; if that file is missing
-# (e.g. on first login before wallust has run) mako would fail to start, so we
-# seed a neutral default here. apply-colors.sh regenerates it and runs
-# `makoctl reload` once the real palette is ready.
-set -e
-
-CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/wallust/mako"
-if [ ! -f "$CACHE" ]; then
- mkdir -p "$(dirname "$CACHE")"
- cat > "$CACHE" <<'EOF'
-background-color=#1e1e1e
-text-color=#e0e0e0
-border-color=#3a3a3a
-progress-color=over #4f4f4f
-EOF
-fi
-
-exec mako "$@"
diff --git a/.config/niri/set-backdrop.sh b/.config/niri/set-backdrop.sh
index efd02b3..32e4144 100755
--- a/.config/niri/set-backdrop.sh
+++ b/.config/niri/set-backdrop.sh
@@ -1,29 +1,19 @@
-#!/bin/bash
-# Push a blurred copy of a wallpaper to the awww-daemon backdrop namespace.
-# Prefers a pre-made <name>-blur.<ext> sibling; otherwise generates one into the cache.
-# Used by theme-switcher.sh and apply-colors.sh for the niri Overview backdrop.
-
-set -euo pipefail
-
-IMG="${1:-}"
-if [ -z "$IMG" ] || [ ! -f "$IMG" ]; then
- echo "usage: $0 <image>" >&2
- exit 1
-fi
-
-EXT="${IMG##*.}"
-SIBLING="${IMG%.*}-blur.${EXT}"
-if [ -f "$SIBLING" ]; then
- BLURRED="$SIBLING"
-else
- CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/niri-backdrop"
- mkdir -p "$CACHE_DIR"
- BASE=$(basename "${IMG%.*}")
- BLURRED="$CACHE_DIR/${BASE}-blur.jpg"
- if [ ! -f "$BLURRED" ] || [ "$IMG" -nt "$BLURRED" ]; then
- magick "$IMG" -blur 0x16 -quality 90 "$BLURRED"
+#!/bin/sh
+# Generate a blurred copy of WALLPAPER and set it as the awww backdrop layer.
+set -eu
+WP="${1:?usage: set-backdrop.sh <wallpaper>}"
+CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/niri-backdrop"
+mkdir -p "$CACHE_DIR"
+name="$(basename "${WP%.*}")"
+blur="$CACHE_DIR/${name}-blur.jpg"
+# (re)generate the blur only if it is missing
+[ -f "$blur" ] || magick "$WP" -blur 0x40 -quality 85 "$blur"
+# wait for the backdrop daemon socket, then set the image
+for _ in 1 2 3 4 5 6 7 8; do
+ if awww img --namespace backdrop "$blur" 2>/dev/null; then
+ exit 0
fi
-fi
-
-awww img "$BLURRED" -n backdrop
-echo "$BLURRED" >/tmp/current_backdrop_state \ No newline at end of file
+ sleep 0.5
+done
+echo "set-backdrop: awww backdrop daemon not reachable" >&2
+exit 1
diff --git a/.config/niri/theme-switcher.sh b/.config/niri/theme-switcher.sh
index 01786d8..af9035f 100755
--- a/.config/niri/theme-switcher.sh
+++ b/.config/niri/theme-switcher.sh
@@ -1,143 +1,51 @@
-#!/bin/bash
-
-# Manual theme switcher + wallpaper/color applier.
-# No time-based switching: you pick the wallpaper and mode explicitly.
+#!/bin/sh
+# Set a new wallpaper everywhere: main layer, blurred backdrop, wallust colors.
#
-# Usage:
-# ./theme-switcher.sh <image> <day|night> apply <image> in light/dark mode, remember it
-# ./theme-switcher.sh --last apply the last manually-set wallpaper+mode
-# ./theme-switcher.sh -h | --help show this help
-
-WALLPAPERS="$HOME/Pictures/wallpapers"
-STATE_FILE="/tmp/current_theme_state"
-WALLPAPER_STATE_FILE="/tmp/current_wallpaper_state"
-BACKDROP_STATE_FILE="/tmp/current_backdrop_state"
-LAST_FILE="${XDG_STATE_HOME:-$HOME/.local/state}/theme-switcher/last"
-LOG="/tmp/theme-switcher.log"
-SCRIPT_DIR="$(cd "$(dirname "$(realpath "$0")")" && pwd)"
-SET_BACKDROP="$SCRIPT_DIR/set-backdrop.sh"
-
-log() {
- printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG"
-}
-
-# Persist the last manually-chosen wallpaper + mode so --last survives reboots.
-save_last() {
- mkdir -p "$(dirname "$LAST_FILE")"
- printf '%s\n%s\n' "$WALLPAPER" "$MODE" >"$LAST_FILE"
-}
-
-# Load the last chosen wallpaper + mode. Falls back to the old default so a
-# fresh boot (nothing saved yet) never lands on a blank wallpaper.
-load_last() {
- if [ -f "$LAST_FILE" ]; then
- WALLPAPER=$(sed -n '1p' "$LAST_FILE")
- MODE=$(sed -n '2p' "$LAST_FILE")
- case "$MODE" in
- light) TARGET_STATE="light" ;;
- *) TARGET_STATE="dark"; MODE="dark" ;;
+# Usage: theme-switcher.sh <wallpaper|path> [--palette P] [--threshold T]
+# [--saturation S] [--colorspace C]
+#
+# The chosen palette/threshold are persisted to ~/.cache/wallust_runtime so
+# that apply-colors.sh reproduces them after a reboot. The main wallpaper is
+# cached by awww itself, so it is also restored on the next boot.
+
+set -eu
+CACHE="${XDG_CACHE_HOME:-$HOME/.cache}"
+STATE="$CACHE/wallust_runtime"
+WP=""; palette=""; threshold=""; sat=""; cs=""
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --palette|-p) palette="$2"; shift 2 ;;
+ --threshold|-t) threshold="$2"; shift 2 ;;
+ --saturation) sat="$2"; shift 2 ;;
+ --colorspace|-c) cs="$2"; shift 2 ;;
+ *) WP="${WP:-$1}"; shift ;;
esac
- else
- WALLPAPER="$WALLPAPERS/night.jpg"
- TARGET_STATE="dark"
- MODE="dark"
- fi
-}
-
-# Resolve TARGET_STATE / MODE from an explicit mode argument.
-resolve_explicit() {
- local mode="$1"
- case "$mode" in
- day | light) TARGET_STATE="light"; MODE="light" ;;
- night | dark) TARGET_STATE="dark"; MODE="dark" ;;
- *)
- echo "mode must be day|night (got: $mode)" >&2
- exit 1
- ;;
- esac
-}
+done
-# Apply the resolved target once. Returns 0 on success.
-apply_target() {
- if [ ! -f "$WALLPAPER" ]; then
- log "wallpaper missing: $WALLPAPER"
- return 1
- fi
-
- local CURRENT_THEME CURRENT_WALLPAPER EXPECTED_BACKDROP ACTUAL_BACKDROP
-
- CURRENT_THEME=$(cat "$STATE_FILE" 2>/dev/null || true)
- CURRENT_WALLPAPER=$(cat "$WALLPAPER_STATE_FILE" 2>/dev/null || true)
-
- # Self-heal the Overview backdrop if it drifted from the expected image.
- EXPECTED_BACKDROP=$(cat "$BACKDROP_STATE_FILE" 2>/dev/null || true)
- ACTUAL_BACKDROP=$(awww query -n backdrop -j 2>/dev/null | jq -r '.["backdrop"][0].displaying.image // empty')
- if [ -n "$EXPECTED_BACKDROP" ] && [ "$ACTUAL_BACKDROP" != "$EXPECTED_BACKDROP" ]; then
- "$SET_BACKDROP" "$WALLPAPER"
- fi
-
- # Already in this exact theme AND wallpaper: skip the heavy color work.
- if [ "$CURRENT_THEME" = "$TARGET_STATE" ] && [ "$CURRENT_WALLPAPER" = "$WALLPAPER" ]; then
- return 0
- fi
-
- log "switching to $TARGET_STATE ($WALLPAPER)"
- if sh "$SCRIPT_DIR/apply-colors.sh" "$WALLPAPER" "$MODE"; then
- if [ "$CURRENT_THEME" != "$TARGET_STATE" ]; then
- darkman set "$TARGET_STATE"
- fi
+[ -n "$WP" ] || { echo "usage: $0 <wallpaper> [--palette P] [--threshold T]" >&2; exit 1; }
+case "$WP" in
+ /*) ;;
+ *) WP="$HOME/Pictures/wallpapers/$WP" ;;
+esac
+[ -f "$WP" ] || { echo "no such wallpaper: $WP" >&2; exit 1; }
- ln -sf \
- "theme-${TARGET_STATE}.css" \
- "$HOME/dotfiles-gentoo/.config/waybar/theme.css"
+# Remember the last used wallpaper so apply-colors.sh reproduces it on reboot.
+echo "$WP" > "$CACHE/current_wallpaper"
- ln -sf \
- "settings-${TARGET_STATE}.ini" \
- "$HOME/dotfiles-gentoo/.config/gtk-3.0/settings.ini"
+# Persist palette/threshold for the next boot.
+: > "$STATE"
+[ -n "$palette" ] && echo "palette=$palette" >> "$STATE"
+[ -n "$threshold" ] && echo "threshold=$threshold" >> "$STATE"
+[ -n "$sat" ] && echo "saturation=$sat" >> "$STATE"
+[ -n "$cs" ] && echo "colorspace=$cs" >> "$STATE"
- echo "$TARGET_STATE" >"$STATE_FILE"
- echo "$WALLPAPER" >"$WALLPAPER_STATE_FILE"
- save_last
- log "switched to $TARGET_STATE ($WALLPAPER)"
- return 0
- else
- log "FAILED to apply $TARGET_STATE ($WALLPAPER)"
- return 1
- fi
-}
+# Main wallpaper (awww caches it -> restored automatically on next boot).
+awww img "$WP"
-usage() {
- cat >&2 <<EOF
-usage: $0 <image> <day|night> | --last
- <image> <day|night> apply <image> in light/dark mode and remember it
- --last apply the last manually-set wallpaper + mode
-EOF
-}
+# Regenerate colors, sync backdrop, reload live apps.
+"$HOME/.config/niri/apply-colors.sh"
-case "${1:-}" in
- --last)
- load_last
- apply_target
- exit $?
- ;;
- -h | --help)
- usage
- exit 0
- ;;
- "")
- usage
- exit 1
- ;;
- *)
- WALLPAPER="${1:-}"
- MODEARG="${2:-}"
- if [ -z "$MODEARG" ]; then
- echo "missing mode (day|night)" >&2
- usage
- exit 1
- fi
- resolve_explicit "$MODEARG"
- apply_target
- exit $?
- ;;
-esac
+# Refresh niri's own theme (focus ring, etc.) live.
+matugen image "$WP" 2>/dev/null || true
+niri msg action reload-config 2>/dev/null || true