Claude/gnome wallpaper auto rotation r1ailq #1
+66
-6
@@ -128,6 +128,61 @@ export class LiveWallpaperManager {
|
|||||||
this._start();
|
this._start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds videoconvert ! videoscale ! capsfilter(RGBA) ! appsink using
|
||||||
|
* explicit element creation, linking, and a ghost pad, rather than
|
||||||
|
* Gst.parse_bin_from_description()'s gst-launch mini-language. Both
|
||||||
|
* are meant to be equivalent, but a user's testing showed the
|
||||||
|
* string-parsed version's appsink never fired 'new-sample' even once
|
||||||
|
* inside gnome-shell's process while an equivalent standalone
|
||||||
|
* gst-launch-1.0 pipeline worked fine — this removes the string
|
||||||
|
* parsing (and its automatic ghost-pad detection) as a variable, and
|
||||||
|
* surfaces link() failures explicitly instead of failing silently.
|
||||||
|
*/
|
||||||
|
_buildSinkBin() {
|
||||||
|
const Gst = this._Gst;
|
||||||
|
|
||||||
|
const videoconvert = Gst.ElementFactory.make('videoconvert', 'benthicbloom-convert');
|
||||||
|
const videoscale = Gst.ElementFactory.make('videoscale', 'benthicbloom-scale');
|
||||||
|
const capsfilter = Gst.ElementFactory.make('capsfilter', 'benthicbloom-capsfilter');
|
||||||
|
const appsink = Gst.ElementFactory.make('appsink', 'benthicbloom-appsink');
|
||||||
|
|
||||||
|
if (!videoconvert || !videoscale || !capsfilter || !appsink) {
|
||||||
|
throw new Error(
|
||||||
|
'Failed to create one or more GStreamer elements ' +
|
||||||
|
'(videoconvert/videoscale/capsfilter/appsink) — a required plugin is likely missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
capsfilter.set_property('caps', Gst.Caps.from_string('video/x-raw,format=RGBA'));
|
||||||
|
appsink.set_property('emit-signals', true);
|
||||||
|
appsink.set_property('max-buffers', 2);
|
||||||
|
appsink.set_property('drop', true);
|
||||||
|
appsink.set_property('sync', true);
|
||||||
|
|
||||||
|
const sinkBin = new Gst.Bin({name: 'benthicbloom-sinkbin'});
|
||||||
|
sinkBin.add(videoconvert);
|
||||||
|
sinkBin.add(videoscale);
|
||||||
|
sinkBin.add(capsfilter);
|
||||||
|
sinkBin.add(appsink);
|
||||||
|
|
||||||
|
if (!videoconvert.link(videoscale))
|
||||||
|
throw new Error('Failed to link videoconvert -> videoscale');
|
||||||
|
if (!videoscale.link(capsfilter))
|
||||||
|
throw new Error('Failed to link videoscale -> capsfilter');
|
||||||
|
if (!capsfilter.link(appsink))
|
||||||
|
throw new Error('Failed to link capsfilter -> appsink');
|
||||||
|
|
||||||
|
const sinkPad = videoconvert.get_static_pad('sink');
|
||||||
|
const ghostPad = Gst.GhostPad.new('sink', sinkPad);
|
||||||
|
if (!ghostPad)
|
||||||
|
throw new Error('Failed to create ghost pad for live wallpaper sink bin');
|
||||||
|
ghostPad.set_active(true);
|
||||||
|
sinkBin.add_pad(ghostPad);
|
||||||
|
|
||||||
|
this._appsink = appsink;
|
||||||
|
return sinkBin;
|
||||||
|
}
|
||||||
|
|
||||||
_start() {
|
_start() {
|
||||||
const path = this._settings.get_string(SettingsKey.LIVE_WALLPAPER_PATH);
|
const path = this._settings.get_string(SettingsKey.LIVE_WALLPAPER_PATH);
|
||||||
if (!this._available || !path)
|
if (!this._available || !path)
|
||||||
@@ -143,11 +198,7 @@ export class LiveWallpaperManager {
|
|||||||
Main.layoutManager._backgroundGroup.add_child(this._actor);
|
Main.layoutManager._backgroundGroup.add_child(this._actor);
|
||||||
this._layoutActor();
|
this._layoutActor();
|
||||||
|
|
||||||
const sinkBin = Gst.parse_bin_from_description(
|
const sinkBin = this._buildSinkBin();
|
||||||
'videoconvert ! videoscale ! video/x-raw,format=RGBA ! ' +
|
|
||||||
'appsink name=benthicbloom_sink emit-signals=true max-buffers=2 drop=true sync=true',
|
|
||||||
true);
|
|
||||||
this._appsink = sinkBin.get_by_name('benthicbloom_sink');
|
|
||||||
this._appsink.connect('new-sample', sink => this._onNewSample(sink));
|
this._appsink.connect('new-sample', sink => this._onNewSample(sink));
|
||||||
|
|
||||||
this._playbin = Gst.ElementFactory.make('playbin', 'benthicbloom-live-wallpaper');
|
this._playbin = Gst.ElementFactory.make('playbin', 'benthicbloom-live-wallpaper');
|
||||||
@@ -381,13 +432,22 @@ export class LiveWallpaperManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._playbin) {
|
if (this._playbin) {
|
||||||
|
const Gst = this._Gst;
|
||||||
const bus = this._playbin.get_bus();
|
const bus = this._playbin.get_bus();
|
||||||
if (this._busWatchId) {
|
if (this._busWatchId) {
|
||||||
bus.disconnect(this._busWatchId);
|
bus.disconnect(this._busWatchId);
|
||||||
this._busWatchId = 0;
|
this._busWatchId = 0;
|
||||||
}
|
}
|
||||||
bus.remove_signal_watch();
|
bus.remove_signal_watch();
|
||||||
this._playbin.set_state(this._Gst.State.NULL);
|
|
||||||
|
this._playbin.set_state(Gst.State.NULL);
|
||||||
|
// Block briefly for the (normally fast) transition to actually
|
||||||
|
// finish before dropping our reference — otherwise the element
|
||||||
|
// can get disposed mid-transition, which GStreamer logs as
|
||||||
|
// "Trying to dispose element ..., but it is in PLAYING instead
|
||||||
|
// of the NULL state".
|
||||||
|
this._playbin.get_state(200 * Gst.MSECOND);
|
||||||
|
|
||||||
this._playbin = null;
|
this._playbin = null;
|
||||||
this._appsink = null;
|
this._appsink = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user