Animate GIF wallpapers in the shell

This commit is contained in:
SirBlob committed 2026-09-24 12:37:35 -04:00
1 parent 5419a35cd1
commit 59259e88b5
5 files changed
+27 -27

No files matched your search

-23
View File
@@ -107,32 +107,9 @@ fi
NEW_BACKGROUND="$THEME_DIR/backgrounds/$(basename "$IMAGE_PATH")" NEW_BACKGROUND="$THEME_DIR/backgrounds/$(basename "$IMAGE_PATH")"
# Stop a gif daemon left over from a previous wallpaper. `awww kill` shuts the
# daemon down via its own IPC so it cleans up its socket, unlike a raw `pkill`.
awww kill --all >/dev/null 2>&1 awww kill --all >/dev/null 2>&1
pkill -x awww-daemon 2>/dev/null pkill -x awww-daemon 2>/dev/null
# blob-bg-set updates ~/.local/state/blob/current/background and
# tells the running Blob shell to repaint, which is what draws the desktop
# background in Blob 4 (swaybg is no longer involved).
blob-bg-set "$NEW_BACKGROUND" blob-bg-set "$NEW_BACKGROUND"
if [[ "${IMAGE_PATH,,}" == *.gif ]]; then
# The shell renders a still frame from the symlink above; awww layers the
# animation on top of it.
echo "GIF detected, using awww for animation..."
setsid uwsm-app -- awww-daemon >>"$HOME/.cache/awww-daemon.log" 2>&1 &
# Poll until the daemon's IPC socket is ready instead of guessing a fixed sleep
IMG_ERROR=""
for _ in {1..15}; do
IMG_ERROR=$(awww img "$NEW_BACKGROUND" 2>&1) && break
sleep 0.3
done
if [[ -n "$IMG_ERROR" ]]; then
echo "awww failed to set the wallpaper: $IMG_ERROR"
echo "See $HOME/.cache/awww-daemon.log for daemon output."
fi
fi
echo "Wallpaper and dynamic theme applied successfully: $IMAGE_PATH" echo "Wallpaper and dynamic theme applied successfully: $IMAGE_PATH"
-1
View File
@@ -133,7 +133,6 @@ Omarchy's own package list, because they were installed by hand on this machine:
| --- | --- | | --- | --- |
| `python-pywal16` | `blob-wallpaper-set`, palette extraction | | `python-pywal16` | `blob-wallpaper-set`, palette extraction |
| `python-terminaltexteffects` | `blob-screensaver`, the effects it draws | | `python-terminaltexteffects` | `blob-screensaver`, the effects it draws |
| `awww` | the wallpaper daemon `blob-wallpaper-set` and `blob-theme-menu` drive |
| `playerctl` | the quick settings media row | | `playerctl` | the quick settings media row |
`playerctl` is in official `extra`, so it sits in the repo list. `playerctl` is in official `extra`, so it sits in the repo list.
+10
View File
@@ -88,6 +88,16 @@ Keys in the clock popup:
| Enter | back to today, or pick the highlighted month | | Enter | back to today, or pick the highlighted month |
| Esc | close the month picker, then the popup | | Esc | close the month picker, then the popup |
## Animated wallpapers
The background plugin draws a GIF wallpaper with `AnimatedImage`, so it moves
however it was set: the wallpaper picker, `blob wallpaper set`, `blob bg set`,
or a theme's own background. The transition into it shows the first frame, and
the animation starts once the transition finishes. Per-monitor wallpapers from
`blob bg monitor` animate the same way. `awww` is no longer needed;
`blob-wallpaper-set` and `blob-theme-menu` still stop a leftover `awww-daemon`
so it cannot paint over the shell.
## Differences from upstream ## Differences from upstream
This shell was forked from Omarchy 4.0.4 and is not tracked against it. The This shell was forked from Omarchy 4.0.4 and is not tracked against it. The
-3
View File
@@ -114,9 +114,6 @@ libvips
webp-pixbuf-loader webp-pixbuf-loader
ffmpegthumbnailer ffmpegthumbnailer
# Theming
awww
# Capture # Capture
grim grim
slurp slurp
+17
View File
@@ -41,6 +41,10 @@ Item {
return Util.fileUrl(path) return Util.fileUrl(path)
} }
function isAnimated(path) {
return /\.gif$/i.test(String(path || ""))
}
function refreshBackground() { function refreshBackground() {
if (!readlinkProc.running) readlinkProc.running = true if (!readlinkProc.running) readlinkProc.running = true
if (!monitorBackgroundProc.running) monitorBackgroundProc.running = true if (!monitorBackgroundProc.running) monitorBackgroundProc.running = true
@@ -274,6 +278,19 @@ Item {
} }
} }
AnimatedImage {
id: animatedBase
readonly property string path: panel.hasAssignment ? panel.assignedBackground : root.displayedBackground
readonly property bool wanted: root.isAnimated(path)
anchors.fill: parent
source: wanted ? root.imageUrl(path) : ""
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: false
visible: wanted && status === AnimatedImage.Ready
playing: visible
}
Image { Image {
id: oldFrame id: oldFrame
anchors.fill: parent anchors.fill: parent