niri-autoblur -> wallpaper-daemon

This commit is contained in:
2025-10-08 16:12:58 +02:00
parent 12ca32e0d4
commit d0c00410ae
6 changed files with 107 additions and 44 deletions

View File

@@ -10,8 +10,9 @@ fi
[ ! -f "$image" ] && exit 1
ext=${image##*.}
random_name=$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 16)
current_dir="$HOME/.local/share/wallpaper/current"
image_copied="$current_dir/wallpaper.$ext"
image_copied="$current_dir/wallpaper-${random_name}.${ext}"
mkdir -p "$current_dir" || (
echo "Could not create directory $current_dir"
@@ -21,7 +22,7 @@ mkdir -p "$current_dir" || (
temp_img=$(mktemp --suffix=."$ext") || exit 1
trap 'rm -f "$temp_img"' EXIT
cp "$image" "$temp_img" || exit 1
rm -f "$current_dir"/wallpaper.*
rm -f "${current_dir:?}"/wallpaper-*
cp -f "$temp_img" "$image_copied" || (
echo "Could not copy image to $current_dir"
exit 1
@@ -42,8 +43,8 @@ elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
echo "Could not create cache directory"
exit 1
)
rm -rf "${blur_dir:?}"/*
blurred_image="$blur_dir/blurred.$ext"
rm -f "${blur_dir:?}"/blurred-*
blurred_image="$blur_dir/blurred-${random_name}.$ext"
# blur
(
@@ -57,15 +58,21 @@ elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
printf "%.2f", s
}')
magick "$image_copied" -blur 0x"$sigma" "$blurred_image" || (
temp_blurred=$(mktemp --suffix=."$ext") || exit 1
trap 'rm -f "${temp_blurred}"' EXIT
magick "$image_copied" -blur 0x"$sigma" "$temp_blurred" || (
echo "Could not create blurred image"
exit 1
)
mv -f "$temp_blurred" "$blurred_image" || (
echo "Could not move blurred image to cache directory"
exit 1
)
# nohup swaybg -i "$blurred_image" -m fill > /dev/null 2> /dev/null &
swww img -n backdrop "$blurred_image" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null
notify-send "Blurred Wallpaper set" "Selected wallpaper has been successfully applied for overview"
notify-send "Blurred Wallpaper Generated" "$blurred_image"
) &
swww img -n background "$image_copied" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null

View File

@@ -13,8 +13,8 @@ NORMAL_WALLPAPER_DIR = Path("/home/kolkas/.local/share/wallpaper/current")
BLURRED_WALLPAPER_DIR = Path("/home/kolkas/.local/share/wallpaper/blurred")
def _get_first_file(dir: Path) -> Path | None:
return next(dir.glob("*"), None)
def _get_first_file(dir: Path, pattern: str = "*") -> Path | None:
return next(dir.glob(pattern), None)
def get_niri_socket():
@@ -22,7 +22,8 @@ def get_niri_socket():
def _log(msg: str):
print(msg)
# print(msg)
# logFIle = Path("/tmp/niri-autoblur.log")
# try:
# with logFIle.open("a") as f:
@@ -30,8 +31,10 @@ def _log(msg: str):
# except Exception:
# pass
pass
def swwwCommand(namespace: str, wallpaper: Path):
def swwwLoadImg(namespace: str, wallpaper: Path):
cmd = [
"swww",
"img",
@@ -58,6 +61,31 @@ def swwwCommand(namespace: str, wallpaper: Path):
return True
def swwwStartDaemon(namespace: str):
# Check if daemon is already running
cmd = ["pgrep", "-f", f"swww daemon -n {namespace}"]
try:
output = subprocess.check_output(cmd, text=True)
pids = output.strip().splitlines()
if pids:
_log(f"[SWWW] daemon already running with PIDs: {', '.join(pids)}")
return True
except subprocess.CalledProcessError:
# pgrep returns non-zero exit code if no process is found
pass
except Exception as e:
_log(f"[SWWW] failed to check if daemon is running: {e}")
pass
try:
subprocess.Popen(["swww-daemon", "-n", namespace], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
_log(f"[SWWW] daemon started for namespace: {namespace}")
return True
except Exception as e:
_log(f"[SWWW] failed to start daemon non-blockingly: {e}")
return False
class AutoBlur:
_interval: float
_normalDir: Path
@@ -90,9 +118,9 @@ class AutoBlur:
def setBlurred(self, isBlurred: bool) -> None:
# Cache state, avoid starting thread unnecessarily
if not self._isFirst and self._isBlurred.is_set() == isBlurred:
_log("[AutoBlur] state unchanged")
return
# if not self._isFirst and self._isBlurred.is_set() == isBlurred:
# _log("[AutoBlur] state unchanged")
# return
self._isFirst = False
if isBlurred:
@@ -106,16 +134,6 @@ class AutoBlur:
self._thread = threading.Thread(target=self._run, daemon=True)
self._thread.start()
def _apply(self, wallpaper: Path) -> bool:
if wallpaper == self._lastWallpaer:
return True
if not swwwCommand("background", wallpaper):
return False
self._lastWallpaer = wallpaper
return True
def _run(self) -> None:
'''Wait until wallpapers are ready & apply the correct one according to the current state'''
while True:
@@ -130,12 +148,23 @@ class AutoBlur:
sleep(self._interval)
def _apply(self, wallpaper: Path) -> bool:
if wallpaper == self._lastWallpaer:
return True
if not swwwLoadImg("background", wallpaper):
return False
self._lastWallpaer = wallpaper
return True
autoBlurInst = AutoBlur(NORMAL_WALLPAPER_DIR, BLURRED_WALLPAPER_DIR)
def handleEvent(event_name, payload):
if event_name == "WindowFocusChanged":
_log(f"[EventHandler] WindowFocusChanged event received")
id = payload.get("id", "")
if isinstance(id, int):
_log(f"[EventHandler] focused window id: {id}")
@@ -147,6 +176,7 @@ def handleEvent(event_name, payload):
_log(f"[EventHandler] unknown id: {id}, assuming no focused window")
autoBlurInst.setBlurred(False)
elif event_name == "WindowsChanged":
_log(f"[EventHandler] WindowsChanged event received")
windows = payload.get("windows", [])
for window in windows:
if window.get("is_focused", False):
@@ -156,6 +186,7 @@ def handleEvent(event_name, payload):
_log("[EventHandler] no focused window found")
autoBlurInst.setBlurred(False)
elif event_name == "WindowOpenedOrChanged":
_log(f"[EventHandler] WindowOpenedOrChanged event received")
window = payload.get("window", {})
if window.get("is_focused", False):
_log(f"[EventHandler] opened/changed focused window")
@@ -174,7 +205,7 @@ def connect_niri(niriSocket: str, handler) -> bool:
sock.connect(niriSocket)
except Exception as e:
sock.close()
_log(f"[Socket] Failed to connect to {niriSocket}: {e}")
_log(f"[Socket] failed to connect to {niriSocket}: {e}")
return False
f = sock.makefile("rwb")
@@ -229,15 +260,47 @@ def connect_niri(niriSocket: str, handler) -> bool:
if __name__ == "__main__":
# Init wallpaper for backdrop
wallpaper = _get_first_file(BLURRED_WALLPAPER_DIR)
if wallpaper:
swwwCommand("backdrop", wallpaper)
desktop = environ.get("XDG_CURRENT_DESKTOP", "")
if desktop == "niri":
_log("[Main] running in Niri")
_log("[Main] starting swww daemons")
if not swwwStartDaemon("background"):
exit(1)
if not swwwStartDaemon("backdrop"):
exit(1)
sleep(1) # give some time to start
niri_socket = get_niri_socket()
if not niri_socket:
_log("[Main] NIRI_SOCKET environment variable is not set.")
exit(1)
_log("[Main] loading initial wallpapers")
# Init wallpaper for backdrop
blurred = _get_first_file(BLURRED_WALLPAPER_DIR)
if blurred:
swwwLoadImg("backdrop", blurred)
# Init wallpaper for background
normal = _get_first_file(NORMAL_WALLPAPER_DIR)
if normal:
swwwLoadImg("background", normal)
if not connect_niri(niri_socket, handleEvent):
exit(1)
# Connect to Niri socket
_log(f"[Main] connecting to Niri socket")
niri_socket = get_niri_socket()
if not niri_socket:
_log("[Main] NIRI_SOCKET environment variable is not set.")
exit(1)
if not connect_niri(niri_socket, handleEvent):
exit(1)
elif desktop == "Hyprland":
_log("[Main] running in Hyprland")
_log("[Main] starting swww daemon")
if not swwwStartDaemon("background"):
exit(1)
sleep(1) # similarly
_log("[Main] loading initial wallpaper")
normal = _get_first_file(NORMAL_WALLPAPER_DIR)
if normal:
swwwLoadImg("background", normal)
# Wait indefinitely
while True:
sleep(3600)

View File

@@ -3,8 +3,7 @@ exec-once = config-switch Hyprland
# Bar, wallpaper
exec-once = waybar
exec-once = swww-daemon -n background
exec-once = sleep 1 && swww img -n background $(find $HOME/.local/share/wallpaper/current -type f | head -n 1) --transition-type fade --transition-duration 2
exec-once = wallpaper-daemon
# Input method
exec-once = fcitx5

View File

@@ -1,2 +0,0 @@
preload = /home/kolkas/.local/share/wallpaper/current/wallpaper.jpg
wallpaper = , /home/kolkas/.local/share/wallpaper/current/wallpaper.jpg

View File

@@ -122,9 +122,7 @@ spawn-sh-at-startup "config-switch niri"
spawn-at-startup "waybar"
// Wallpaper
spawn-sh-at-startup "swww-daemon -n background"
spawn-sh-at-startup "swww-daemon -n backdrop"
spawn-at-startup "niri-autoblur"
spawn-at-startup "wallpaper-daemon"
// Not necessary maybe ...
spawn-at-startup "fcitx5"

View File

@@ -122,9 +122,7 @@ spawn-sh-at-startup "config-switch niri"
spawn-at-startup "waybar"
// Wallpaper
spawn-sh-at-startup "swww-daemon -n background"
spawn-sh-at-startup "swww-daemon -n backdrop"
spawn-at-startup "niri-autoblur"
spawn-at-startup "wallpaper-daemon"
// Not necessary maybe ...
spawn-at-startup "fcitx5"