implementing home.file instead of xdg.config

This commit is contained in:
2026-03-01 18:32:41 +01:00
parent 15607aca9b
commit 0906a319c1
3 changed files with 395 additions and 330 deletions
+334 -312
View File
File diff suppressed because it is too large Load Diff
+31 -9
View File
@@ -1770,6 +1770,7 @@ in
** Workspace Wallpaper ** Workspace Wallpaper
#+begin_src nix :tangle home/desktop/workspace_wallpaper.nix :noweb tangle :mkdirp yes #+begin_src nix :tangle home/desktop/workspace_wallpaper.nix :noweb tangle :mkdirp yes
{ config, lib, pkgs, flakeRoot, ... }: { config, lib, pkgs, flakeRoot, ... }:
let let
userRelRoot = "nixos_conf/wallpaperstuff"; userRelRoot = "nixos_conf/wallpaperstuff";
userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}"; userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}";
@@ -1792,11 +1793,13 @@ in
pkgs.gnused pkgs.gnused
pkgs.gawk pkgs.gawk
]; ];
# Sync wallpapers into a writable directory # Sync wallpapers into a writable directory
home.file."${userRelRoot}" = { home.file."${userRelRoot}" = {
source = repoWallpapersOnly; source = repoWallpapersOnly;
recursive = true; recursive = true;
}; };
# Hyprpaper config # Hyprpaper config
home.file.".config/hypr/hyprpaper.conf" = { home.file.".config/hypr/hyprpaper.conf" = {
text = '' text = ''
@@ -1804,34 +1807,39 @@ in
splash = false splash = false
''; '';
}; };
# Workspace wallpaper daemon # Workspace wallpaper daemon
home.file."${daemonRel}" = { home.file."${daemonRel}" = {
executable = true; executable = true;
text = '' text = ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
: "${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" : "${XDG_RUNTIME_DIR?"XDG_RUNTIME_DIR not set"}"
: "${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" : "${HYPRLAND_INSTANCE_SIGNATURE?"HYPRLAND_INSTANCE_SIGNATURE not set"}"
SOCK="${XDG_RUNTIME_DIR}/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" SOCK="${XDG_RUNTIME_DIR}/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
[[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; }
PICTURES_DIR="${1:-${picturesDir}}" PICTURES_DIR="${1:-${picturesDir}}"
FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill FIT_MODE="fill"
HYPR_DIR="${config.xdg.configHome}/hypr" HYPR_DIR="${config.xdg.configHome}/hypr"
MAP_ROOT="${HYPR_DIR}/hyprpaper/config" MAP_ROOT="${HYPR_DIR}/hyprpaper/config"
focused_monitor() { focused_monitor() {
hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1
} }
map_file_for_monitor() { map_file_for_monitor() {
local mon="$1" local mon="$1"
echo "${MAP_ROOT}/${mon}/defaults.conf" echo "${MAP_ROOT}/${mon}/defaults.conf"
} }
ensure_map_file() { ensure_map_file() {
local mon="$1" local mon="$1"
local f local f
f="$(map_file_for_monitor "$mon")" f="$(map_file_for_monitor "$mon")"
mkdir -p "$(dirname "$f")" mkdir -p "$(dirname "$f")"
if [[ ! -f "$f" ]]; then if [[ ! -f "$f" ]]; then
# Seed with 1..9 from picturesDir if present, else empty entries
{ {
for i in 1 2 3 4 5 6 7 8 9; do for i in 1 2 3 4 5 6 7 8 9; do
seed="$(ls -1 "${PICTURES_DIR}/${i}."* 2>/dev/null | head -n 1 || true)" seed="$(ls -1 "${PICTURES_DIR}/${i}."* 2>/dev/null | head -n 1 || true)"
@@ -1841,6 +1849,7 @@ in
fi fi
echo "$f" echo "$f"
} }
get_wall_for_ws() { get_wall_for_ws() {
local mon="$1" local mon="$1"
local wsid="$2" local wsid="$2"
@@ -1850,6 +1859,7 @@ in
val="$(awk -F= -v k="$key" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "$f" || true)" val="$(awk -F= -v k="$key" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "$f" || true)"
echo "$val" echo "$val"
} }
apply_wallpaper() { apply_wallpaper() {
local mon="$1" local mon="$1"
local wsid="$2" local wsid="$2"
@@ -1859,68 +1869,78 @@ in
[[ -f "$file" ]] || return 0 [[ -f "$file" ]] || return 0
hyprctl hyprpaper wallpaper "$mon, $file, $FIT_MODE" >/dev/null hyprctl hyprpaper wallpaper "$mon, $file, $FIT_MODE" >/dev/null
} }
# Initial apply on startup
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
[[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid" [[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid"
handle() { handle() {
local line="$1" local line="$1"
case "$line" in case "$line" in
workspacev2* ) workspacev2* )
# workspacev2>>ID,NAME
local payload wsid
payload="${line#*>>}" payload="${line#*>>}"
wsid="${payload%%,*}" wsid="${payload%%,*}"
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
[[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid" [[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid"
;; ;;
focusedmon* ) focusedmon* )
# focusedmon>>MON,WORKSPACENAME
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
[[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid" [[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid"
;; ;;
esac esac
} }
socat -U - UNIX-CONNECT:"$SOCK" | while read -r line; do socat -U - UNIX-CONNECT:"$SOCK" | while read -r line; do
handle "$line" || true handle "$line" || true
done done
''; '';
}; };
# CLI setter # CLI setter
home.file."${setRel}" = { home.file."${setRel}" = {
executable = true; executable = true;
text = '' text = ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
HYPR_DIR="${config.xdg.configHome}/hypr" HYPR_DIR="${config.xdg.configHome}/hypr"
MAP_ROOT="${HYPR_DIR}/hyprpaper/config" MAP_ROOT="${HYPR_DIR}/hyprpaper/config"
usage() { usage() {
echo "Usage: $0 <workspace_id> <monitor> [wallpaper_path]" echo "Usage: $0 <workspace_id> <monitor> [wallpaper_path]"
} }
wsid="${1:-}" wsid="${1:-}"
mon="${2:-}" mon="${2:-}"
wp="${3:-}" wp="${3:-}"
[[ -n "$wsid" ]] || { usage; exit 1; } [[ -n "$wsid" ]] || { usage; exit 1; }
[[ -n "$mon" ]] || { usage; exit 1; } [[ -n "$mon" ]] || { usage; exit 1; }
cfg="${MAP_ROOT}/${mon}/defaults.conf" cfg="${MAP_ROOT}/${mon}/defaults.conf"
mkdir -p "$(dirname "$cfg")" mkdir -p "$(dirname "$cfg")"
[[ -f "$cfg" ]] || touch "$cfg" [[ -f "$cfg" ]] || touch "$cfg"
if [[ -z "$wp" ]]; then if [[ -z "$wp" ]]; then
wp="$(find "${config.home.homeDirectory}/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)" wp="$(find "${config.home.homeDirectory}/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)"
[[ -n "$wp" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } [[ -n "$wp" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; }
fi fi
key="w-${wsid}" key="w-${wsid}"
if ! grep -q "^${key}=" "$cfg"; then if ! grep -q "^${key}=" "$cfg"; then
echo "${key}=" >> "$cfg" echo "${key}=" >> "$cfg"
fi fi
${pkgs.gnused}/bin/sed -i "s|^${key}=.*|${key}= ${wp}|g" "$cfg" ${pkgs.gnused}/bin/sed -i "s|^${key}=.*|${key}= ${wp}|g" "$cfg"
curws="$(hyprctl -j monitors | jq -r --arg m "$mon" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)" curws="$(hyprctl -j monitors | jq -r --arg m "$mon" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)"
if [[ "$curws" == "$wsid" ]]; then if [[ "$curws" == "$wsid" ]]; then
hyprctl hyprpaper wallpaper "$mon, $wp, fill" >/dev/null hyprctl hyprpaper wallpaper "$mon, $wp, fill" >/dev/null
fi fi
''; '';
}; };
# Services # Services
systemd.user.services.hyprpaper = { systemd.user.services.hyprpaper = {
Unit = { Unit = {
@@ -1935,6 +1955,7 @@ in
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; };
}; };
systemd.user.services.hyprpaper-ws-daemon = { systemd.user.services.hyprpaper-ws-daemon = {
Unit = { Unit = {
Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)";
@@ -1942,13 +1963,14 @@ in
After = [ "graphical-session.target" "hyprpaper.service" ]; After = [ "graphical-session.target" "hyprpaper.service" ];
}; };
Service = { Service = {
ExecStart = "${pkgs.bash}/bin/bash ${daemonRel} ${picturesDir}"; ExecStart = "${pkgs.bash}/bin/bash ${config.home.homeDirectory}/${daemonRel} ${picturesDir}";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; };
}; };
} }
#+end_src #+end_src
** Waybar ** Waybar
@@ -1,4 +1,5 @@
{ config, lib, pkgs, flakeRoot, ... }: { config, lib, pkgs, flakeRoot, ... }:
let let
userRelRoot = "nixos_conf/wallpaperstuff"; userRelRoot = "nixos_conf/wallpaperstuff";
userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}"; userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}";
@@ -21,11 +22,13 @@ in
pkgs.gnused pkgs.gnused
pkgs.gawk pkgs.gawk
]; ];
# Sync wallpapers into a writable directory # Sync wallpapers into a writable directory
home.file."${userRelRoot}" = { home.file."${userRelRoot}" = {
source = repoWallpapersOnly; source = repoWallpapersOnly;
recursive = true; recursive = true;
}; };
# Hyprpaper config # Hyprpaper config
home.file.".config/hypr/hyprpaper.conf" = { home.file.".config/hypr/hyprpaper.conf" = {
text = '' text = ''
@@ -33,34 +36,39 @@ in
splash = false splash = false
''; '';
}; };
# Workspace wallpaper daemon # Workspace wallpaper daemon
home.file."${daemonRel}" = { home.file."${daemonRel}" = {
executable = true; executable = true;
text = '' text = ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
: "${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" : "${XDG_RUNTIME_DIR?"XDG_RUNTIME_DIR not set"}"
: "${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" : "${HYPRLAND_INSTANCE_SIGNATURE?"HYPRLAND_INSTANCE_SIGNATURE not set"}"
SOCK="${XDG_RUNTIME_DIR}/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" SOCK="${XDG_RUNTIME_DIR}/hypr/${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock"
[[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; }
PICTURES_DIR="${1:-${picturesDir}}" PICTURES_DIR="${1:-${picturesDir}}"
FIT_MODE="fill" # hyprpaper fit_mode: contain|cover|tile|fill FIT_MODE="fill"
HYPR_DIR="${config.xdg.configHome}/hypr" HYPR_DIR="${config.xdg.configHome}/hypr"
MAP_ROOT="${HYPR_DIR}/hyprpaper/config" MAP_ROOT="${HYPR_DIR}/hyprpaper/config"
focused_monitor() { focused_monitor() {
hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1 hyprctl -j monitors | jq -r '.[] | select(.focused==true) | .name' | head -n 1
} }
map_file_for_monitor() { map_file_for_monitor() {
local mon="$1" local mon="$1"
echo "${MAP_ROOT}/${mon}/defaults.conf" echo "${MAP_ROOT}/${mon}/defaults.conf"
} }
ensure_map_file() { ensure_map_file() {
local mon="$1" local mon="$1"
local f local f
f="$(map_file_for_monitor "$mon")" f="$(map_file_for_monitor "$mon")"
mkdir -p "$(dirname "$f")" mkdir -p "$(dirname "$f")"
if [[ ! -f "$f" ]]; then if [[ ! -f "$f" ]]; then
# Seed with 1..9 from picturesDir if present, else empty entries
{ {
for i in 1 2 3 4 5 6 7 8 9; do for i in 1 2 3 4 5 6 7 8 9; do
seed="$(ls -1 "${PICTURES_DIR}/${i}."* 2>/dev/null | head -n 1 || true)" seed="$(ls -1 "${PICTURES_DIR}/${i}."* 2>/dev/null | head -n 1 || true)"
@@ -70,6 +78,7 @@ in
fi fi
echo "$f" echo "$f"
} }
get_wall_for_ws() { get_wall_for_ws() {
local mon="$1" local mon="$1"
local wsid="$2" local wsid="$2"
@@ -79,6 +88,7 @@ in
val="$(awk -F= -v k="$key" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "$f" || true)" val="$(awk -F= -v k="$key" '$1==k {sub(/^[[:space:]]+/, "", $2); print $2; exit}' "$f" || true)"
echo "$val" echo "$val"
} }
apply_wallpaper() { apply_wallpaper() {
local mon="$1" local mon="$1"
local wsid="$2" local wsid="$2"
@@ -88,68 +98,78 @@ in
[[ -f "$file" ]] || return 0 [[ -f "$file" ]] || return 0
hyprctl hyprpaper wallpaper "$mon, $file, $FIT_MODE" >/dev/null hyprctl hyprpaper wallpaper "$mon, $file, $FIT_MODE" >/dev/null
} }
# Initial apply on startup
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
[[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid" [[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid"
handle() { handle() {
local line="$1" local line="$1"
case "$line" in case "$line" in
workspacev2* ) workspacev2* )
# workspacev2>>ID,NAME
local payload wsid
payload="${line#*>>}" payload="${line#*>>}"
wsid="${payload%%,*}" wsid="${payload%%,*}"
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
[[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid" [[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid"
;; ;;
focusedmon* ) focusedmon* )
# focusedmon>>MON,WORKSPACENAME
mon="$(focused_monitor || true)" mon="$(focused_monitor || true)"
wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)" wsid="$(hyprctl -j activeworkspace | jq -r '.id' | head -n 1 || true)"
[[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid" [[ -n "$mon" && -n "$wsid" ]] && apply_wallpaper "$mon" "$wsid"
;; ;;
esac esac
} }
socat -U - UNIX-CONNECT:"$SOCK" | while read -r line; do socat -U - UNIX-CONNECT:"$SOCK" | while read -r line; do
handle "$line" || true handle "$line" || true
done done
''; '';
}; };
# CLI setter # CLI setter
home.file."${setRel}" = { home.file."${setRel}" = {
executable = true; executable = true;
text = '' text = ''
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
HYPR_DIR="${config.xdg.configHome}/hypr" HYPR_DIR="${config.xdg.configHome}/hypr"
MAP_ROOT="${HYPR_DIR}/hyprpaper/config" MAP_ROOT="${HYPR_DIR}/hyprpaper/config"
usage() { usage() {
echo "Usage: $0 <workspace_id> <monitor> [wallpaper_path]" echo "Usage: $0 <workspace_id> <monitor> [wallpaper_path]"
} }
wsid="${1:-}" wsid="${1:-}"
mon="${2:-}" mon="${2:-}"
wp="${3:-}" wp="${3:-}"
[[ -n "$wsid" ]] || { usage; exit 1; } [[ -n "$wsid" ]] || { usage; exit 1; }
[[ -n "$mon" ]] || { usage; exit 1; } [[ -n "$mon" ]] || { usage; exit 1; }
cfg="${MAP_ROOT}/${mon}/defaults.conf" cfg="${MAP_ROOT}/${mon}/defaults.conf"
mkdir -p "$(dirname "$cfg")" mkdir -p "$(dirname "$cfg")"
[[ -f "$cfg" ]] || touch "$cfg" [[ -f "$cfg" ]] || touch "$cfg"
if [[ -z "$wp" ]]; then if [[ -z "$wp" ]]; then
wp="$(find "${config.home.homeDirectory}/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)" wp="$(find "${config.home.homeDirectory}/.config/wallpapers/defaults" -type f 2>/dev/null | shuf -n 1 || true)"
[[ -n "$wp" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; } [[ -n "$wp" ]] || { echo "No wallpaper found (random). Provide a path as arg 3."; exit 1; }
fi fi
key="w-${wsid}" key="w-${wsid}"
if ! grep -q "^${key}=" "$cfg"; then if ! grep -q "^${key}=" "$cfg"; then
echo "${key}=" >> "$cfg" echo "${key}=" >> "$cfg"
fi fi
${pkgs.gnused}/bin/sed -i "s|^${key}=.*|${key}= ${wp}|g" "$cfg" ${pkgs.gnused}/bin/sed -i "s|^${key}=.*|${key}= ${wp}|g" "$cfg"
curws="$(hyprctl -j monitors | jq -r --arg m "$mon" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)" curws="$(hyprctl -j monitors | jq -r --arg m "$mon" '.[] | select(.name==$m) | .activeWorkspace.id' | head -n 1 || true)"
if [[ "$curws" == "$wsid" ]]; then if [[ "$curws" == "$wsid" ]]; then
hyprctl hyprpaper wallpaper "$mon, $wp, fill" >/dev/null hyprctl hyprpaper wallpaper "$mon, $wp, fill" >/dev/null
fi fi
''; '';
}; };
# Services # Services
systemd.user.services.hyprpaper = { systemd.user.services.hyprpaper = {
Unit = { Unit = {
@@ -164,6 +184,7 @@ in
}; };
Install = { WantedBy = [ "graphical-session.target" ]; }; Install = { WantedBy = [ "graphical-session.target" ]; };
}; };
systemd.user.services.hyprpaper-ws-daemon = { systemd.user.services.hyprpaper-ws-daemon = {
Unit = { Unit = {
Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)"; Description = "Workspace->wallpaper mapping daemon (hyprpaper + socket2)";
@@ -171,7 +192,7 @@ in
After = [ "graphical-session.target" "hyprpaper.service" ]; After = [ "graphical-session.target" "hyprpaper.service" ];
}; };
Service = { Service = {
ExecStart = "${pkgs.bash}/bin/bash ${daemonRel} ${picturesDir}"; ExecStart = "${pkgs.bash}/bin/bash ${config.home.homeDirectory}/${daemonRel} ${picturesDir}";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 1; RestartSec = 1;
}; };