diff --git a/lib/liveWallpaper.js b/lib/liveWallpaper.js index 342cf4d..36cf6e5 100644 --- a/lib/liveWallpaper.js +++ b/lib/liveWallpaper.js @@ -7,6 +7,8 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import {SettingsKey} from './settingsKeys.js'; import {loadGstreamerModules, GSTREAMER_INSTALL_HINT} from './gstreamerAvailability.js'; +Gio._promisify(Gio.DBusProxy, 'new_for_bus', 'new_for_bus_finish'); + /** * Ways to get a decoded frame onto an actor, tried in order and "pinned" * once one works. `new Clutter.Image()` failed with "is not a constructor" @@ -79,6 +81,7 @@ export class LiveWallpaperManager { this._fullscreenChangedId = 0; this._upowerProxy = null; this._upowerSignalId = 0; + this._powerWatchGeneration = 0; this._frameCount = 0; this._pollCount = 0; @@ -428,19 +431,33 @@ export class LiveWallpaperManager { this._logger.debug(`Fullscreen tracking unavailable, pause-when-fullscreen disabled (${e.message ?? e})`); } - try { - this._upowerProxy = Gio.DBusProxy.new_for_bus_sync( - Gio.BusType.SYSTEM, Gio.DBusProxyFlags.NONE, null, - 'org.freedesktop.UPower', '/org/freedesktop/UPower', 'org.freedesktop.UPower', null); - this._upowerSignalId = this._upowerProxy.connect( - 'g-properties-changed', () => this._checkBattery()); - this._checkBattery(); - } catch (e) { - this._logger.debug(`UPower unavailable, pause-on-battery disabled (${e.message ?? e})`); - } + // Deliberately async: the *_sync() variant blocks gnome-shell's + // single main thread (it *is* the compositor) until the system bus + // replies, which can take many seconds — or the full ~25s GDBus + // timeout — if upowerd is still starting up or the bus is busy, + // exactly the conditions right after login. That froze the entire + // screen (and could make the session look hung/crashed) since this + // runs every time live wallpaper starts, including automatically + // at login whenever it was left enabled. + const watchGeneration = ++this._powerWatchGeneration; + Gio.DBusProxy.new_for_bus( + Gio.BusType.SYSTEM, Gio.DBusProxyFlags.NONE, null, + 'org.freedesktop.UPower', '/org/freedesktop/UPower', 'org.freedesktop.UPower', null) + .then(proxy => { + if (watchGeneration !== this._powerWatchGeneration) + return; // Superseded by a _stop()/_connectPowerWatches() while this was in flight. + this._upowerProxy = proxy; + this._upowerSignalId = proxy.connect('g-properties-changed', () => this._checkBattery()); + this._checkBattery(); + }) + .catch(e => { + this._logger.debug(`UPower unavailable, pause-on-battery disabled (${e.message ?? e})`); + }); } _disconnectPowerWatches() { + this._powerWatchGeneration++; + if (this._fullscreenChangedId) { global.display.disconnect(this._fullscreenChangedId); this._fullscreenChangedId = 0;