diff options
Diffstat (limited to '.config/niri')
| -rwxr-xr-x | .config/niri/apply-colors.sh | 134 | ||||
| -rw-r--r-- | .config/niri/config.kdl | 24 | ||||
| -rwxr-xr-x | .config/niri/mako-start.sh | 20 | ||||
| -rwxr-xr-x | .config/niri/set-backdrop.sh | 46 | ||||
| -rwxr-xr-x | .config/niri/theme-switcher.sh | 178 |
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 |
