diff --git a/README.md b/README.md
index 426773e..c21639d 100644
--- a/README.md
+++ b/README.md
@@ -10,11 +10,11 @@ protection against OLED burn-in.
through the images inside them on a timer, in sequential or shuffled
order, with an optional crossfade between changes. The chosen wallpaper
can also be applied to the lock screen.
-- **Live wallpapers** — play a looping video file as your desktop
- background. Frames are decoded with GStreamer and rendered directly by
- GNOME Shell's own Clutter stage (no external, incompatible Clutter
- build involved). Playback can automatically pause on battery power or
- while a window is fullscreen.
+- **Live wallpapers** — play a looping video *or animated GIF* as your
+ desktop background. Frames are decoded with GStreamer and rendered
+ directly by GNOME Shell's own Clutter stage (no external, incompatible
+ Clutter build involved). Playback can automatically pause on battery
+ power or while a window is fullscreen.
- **OLED burn-in protection** — three independent, individually toggled
techniques:
- *Pixel shifting*: nudges the background a few pixels on a slow drift
@@ -34,9 +34,9 @@ protection against OLED burn-in.
- GNOME Shell 50.
- For live wallpapers: GStreamer with its `good` and `base` plugin sets
(e.g. `gstreamer1.0-plugins-good` and `gstreamer1.0-plugins-base`, or
- your distribution's equivalent). If these aren't installed, the live
- wallpaper toggle stays disabled and BenthicBloom's other features work
- normally.
+ your distribution's equivalent) — the `good` set is also what provides
+ animated GIF decoding. If these aren't installed, the live wallpaper
+ toggle stays disabled and BenthicBloom's other features work normally.
## Installation
diff --git a/lib/liveWallpaper.js b/lib/liveWallpaper.js
index 3f504c8..58af89e 100644
--- a/lib/liveWallpaper.js
+++ b/lib/liveWallpaper.js
@@ -6,7 +6,10 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import {SettingsKey} from './settingsKeys.js';
/**
- * Plays a video file as a looping animated background.
+ * Plays a video or animated GIF file as a looping animated background.
+ * `playbin` typefinds the source by content rather than extension, so GIFs
+ * are decoded through GStreamer's own GIF element (from the "good" plugin
+ * set) and handled exactly like any other video stream below this point.
*
* Mutter embeds its own private copy of Clutter, so GStreamer video sinks
* that hand back a Clutter actor from a *different* Clutter instance (e.g.
diff --git a/prefs.js b/prefs.js
index da5945f..27e5030 100644
--- a/prefs.js
+++ b/prefs.js
@@ -176,8 +176,9 @@ export default class BenthicBloomPreferences extends ExtensionPreferences {
const group = new Adw.PreferencesGroup({
title: _('Video Wallpaper'),
description: _(
- 'Play a looping video as your desktop background instead of a static image. ' +
- 'Requires GStreamer (with its "good" and "base" plugin sets) to be installed on your system.'),
+ 'Play a looping video or animated GIF as your desktop background instead of a static image. ' +
+ 'Requires GStreamer (with its "good" and "base" plugin sets, which provide GIF decoding) ' +
+ 'to be installed on your system.'),
});
page.add(group);
group.add(this._switchRow(
@@ -185,17 +186,26 @@ export default class BenthicBloomPreferences extends ExtensionPreferences {
_('Enable Live Wallpaper'), _('Overrides the static wallpaper while active')));
const fileRow = new Adw.ActionRow({
- title: _('Video File'),
+ title: _('Video / GIF File'),
subtitle: settings.get_string(SettingsKey.LIVE_WALLPAPER_PATH) || _('None selected'),
});
const chooseButton = new Gtk.Button({label: _('Choose…'), valign: Gtk.Align.CENTER, css_classes: ['flat']});
chooseButton.connect('clicked', () => {
- const dialog = new Gtk.FileDialog({title: _('Select Wallpaper Video')});
- const filter = new Gtk.FileFilter();
- filter.add_mime_type('video/*');
+ const dialog = new Gtk.FileDialog({title: _('Select Wallpaper Video or GIF')});
+
+ const mediaFilter = new Gtk.FileFilter({name: _('Videos and animated GIFs')});
+ mediaFilter.add_mime_type('video/*');
+ mediaFilter.add_mime_type('image/gif');
+ mediaFilter.add_pattern('*.gif');
+
+ const allFilter = new Gtk.FileFilter({name: _('All files')});
+ allFilter.add_pattern('*');
+
const filterList = new Gio.ListStore({item_type: Gtk.FileFilter});
- filterList.append(filter);
+ filterList.append(mediaFilter);
+ filterList.append(allFilter);
dialog.filters = filterList;
+ dialog.default_filter = mediaFilter;
dialog.open(fileRow.get_root(), null, (source, result) => {
try {
diff --git a/schemas/org.gnome.shell.extensions.benthicbloom.gschema.xml b/schemas/org.gnome.shell.extensions.benthicbloom.gschema.xml
index 0cc5fab..8291cf2 100644
--- a/schemas/org.gnome.shell.extensions.benthicbloom.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.benthicbloom.gschema.xml
@@ -70,13 +70,13 @@
false
Enable live wallpaper
- Whether a video is played as an animated desktop background instead of a static image.
+ Whether a video or animated GIF is played as an animated desktop background instead of a static image.
""
- Live wallpaper video file
- Path to the video file used as the live wallpaper.
+ Live wallpaper media file
+ Path to the video or animated GIF file used as the live wallpaper.