2012-12-24 09:20:39 -05:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
// READ THIS FIRST
|
|
|
|
// Background handling is a maze of objects, both objects in this file, and
|
|
|
|
// also objects inside Mutter. They all have a role.
|
|
|
|
//
|
|
|
|
// BackgroundManager
|
|
|
|
// The only object that other parts of GNOME Shell deal with; a
|
|
|
|
// BackgroundManager creates background actors and adds them to
|
|
|
|
// the specified container. When the background is changed by the
|
|
|
|
// user it will fade out the old actor and fade in the new actor.
|
|
|
|
// (This is separate from the fading for an animated background,
|
|
|
|
// since using two actors is quite inefficient.)
|
|
|
|
//
|
|
|
|
// MetaBackgroundImage
|
|
|
|
// An object represented an image file that will be used for drawing
|
|
|
|
// the background. MetaBackgroundImage objects asynchronously load,
|
|
|
|
// so they are first created in an unloaded state, then later emit
|
|
|
|
// a ::loaded signal when the Cogl object becomes available.
|
|
|
|
//
|
|
|
|
// MetaBackgroundImageCache
|
|
|
|
// A cache from filename to MetaBackgroundImage.
|
|
|
|
//
|
|
|
|
// BackgroundSource
|
|
|
|
// An object that is created for each GSettings schema (separate
|
|
|
|
// settings schemas are used for the lock screen and main background),
|
|
|
|
// and holds a reference to shared Background objects.
|
|
|
|
//
|
|
|
|
// MetaBackground
|
|
|
|
// Holds the specification of a background - a background color
|
|
|
|
// or gradient and one or two images blended together.
|
|
|
|
//
|
|
|
|
// Background
|
|
|
|
// JS delegate object that Connects a MetaBackground to the GSettings
|
|
|
|
// schema for the background.
|
|
|
|
//
|
|
|
|
// Animation
|
|
|
|
// A helper object that handles loading a XML-based animation; it is a
|
|
|
|
// wrapper for GnomeDesktop.BGSlideShow
|
|
|
|
//
|
|
|
|
// MetaBackgroundActor
|
|
|
|
// An actor that draws the background for a single monitor
|
|
|
|
//
|
|
|
|
// BackgroundCache
|
|
|
|
// A cache of Settings schema => BackgroundSource and of a single Animation.
|
|
|
|
// Also used to share file monitors.
|
|
|
|
//
|
|
|
|
// A static image, background color or gradient is relatively straightforward. The
|
|
|
|
// calling code creates a separate BackgroundManager for each monitor. Since they
|
|
|
|
// are created for the same GSettings schema, they will use the same BackgroundSource
|
|
|
|
// object, which provides a single Background and correspondingly a single
|
|
|
|
// MetaBackground object.
|
|
|
|
//
|
|
|
|
// BackgroundManager BackgroundManager
|
|
|
|
// | \ / |
|
|
|
|
// | BackgroundSource | looked up in BackgroundCache
|
|
|
|
// | | |
|
|
|
|
// | Background |
|
|
|
|
// | | |
|
|
|
|
// MetaBackgroundActor | MetaBackgroundActor
|
|
|
|
// \ | /
|
|
|
|
// `------- MetaBackground ------'
|
|
|
|
// |
|
|
|
|
// MetaBackgroundImage looked up in MetaBackgroundImageCache
|
|
|
|
//
|
|
|
|
// The animated case is tricker because the animation XML file can specify different
|
|
|
|
// files for different monitor resolutions and aspect ratios. For this reason,
|
|
|
|
// the BackgroundSource provides different Background share a single Animation object,
|
|
|
|
// which tracks the animation, but use different MetaBackground objects. In the
|
|
|
|
// common case, the different MetaBackground objects will be created for the
|
|
|
|
// same filename and look up the *same* MetaBackgroundImage object, so there is
|
|
|
|
// little wasted memory:
|
|
|
|
//
|
|
|
|
// BackgroundManager BackgroundManager
|
|
|
|
// | \ / |
|
|
|
|
// | BackgroundSource | looked up in BackgroundCache
|
|
|
|
// | / \ |
|
|
|
|
// | Background Background |
|
|
|
|
// | | \ / | |
|
|
|
|
// | | Animation | | looked up in BackgroundCache
|
|
|
|
// MetaBackgroundA|tor Me|aBackgroundActor
|
|
|
|
// \ | | /
|
|
|
|
// MetaBackground MetaBackground
|
|
|
|
// \ /
|
|
|
|
// MetaBackgroundImage looked up in MetaBackgroundImageCache
|
|
|
|
// MetaBackgroundImage
|
|
|
|
//
|
|
|
|
// But the case of different filenames and different background images
|
|
|
|
// is possible as well:
|
|
|
|
// ....
|
|
|
|
// MetaBackground MetaBackground
|
|
|
|
// | |
|
|
|
|
// MetaBackgroundImage MetaBackgroundImage
|
|
|
|
// MetaBackgroundImage MetaBackgroundImage
|
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
import Clutter from 'gi://Clutter';
|
|
|
|
import GDesktopEnums from 'gi://GDesktopEnums';
|
|
|
|
import Gio from 'gi://Gio';
|
|
|
|
import GLib from 'gi://GLib';
|
|
|
|
import GObject from 'gi://GObject';
|
|
|
|
import GnomeBG from 'gi://GnomeBG';
|
|
|
|
import GnomeDesktop from 'gi://GnomeDesktop';
|
|
|
|
import Meta from 'gi://Meta';
|
|
|
|
import * as Signals from '../misc/signals.js';
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
import * as LoginManager from '../misc/loginManager.js';
|
|
|
|
import * as Main from './main.js';
|
|
|
|
import * as Params from '../misc/params.js';
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
2014-10-16 16:45:02 -04:00
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
|
|
|
|
const PRIMARY_COLOR_KEY = 'primary-color';
|
|
|
|
const SECONDARY_COLOR_KEY = 'secondary-color';
|
|
|
|
const COLOR_SHADING_TYPE_KEY = 'color-shading-type';
|
|
|
|
const BACKGROUND_STYLE_KEY = 'picture-options';
|
|
|
|
const PICTURE_URI_KEY = 'picture-uri';
|
2021-11-27 07:53:14 -05:00
|
|
|
const PICTURE_URI_DARK_KEY = 'picture-uri-dark';
|
|
|
|
|
|
|
|
const INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
|
|
|
|
const COLOR_SCHEME_KEY = 'color-scheme';
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
const FADE_ANIMATION_TIME = 1000;
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2013-02-04 16:50:36 -05:00
|
|
|
// These parameters affect how often we redraw.
|
|
|
|
// The first is how different (percent crossfaded) the slide show
|
|
|
|
// has to look before redrawing and the second is the minimum
|
|
|
|
// frequency (in seconds) we're willing to wake up
|
2023-07-10 05:53:00 -04:00
|
|
|
const ANIMATION_OPACITY_STEP_INCREMENT = 4.0;
|
|
|
|
const ANIMATION_MIN_WAKEUP_INTERVAL = 1.0;
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
let _backgroundCache = null;
|
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
function _fileEqual0(file1, file2) {
|
2023-08-06 20:51:19 -04:00
|
|
|
if (file1 === file2)
|
2014-09-18 21:32:52 -04:00
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!file1 || !file2)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return file1.equal(file2);
|
|
|
|
}
|
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
class BackgroundCache extends Signals.EventEmitter {
|
2017-10-30 21:19:44 -04:00
|
|
|
constructor() {
|
2022-07-04 18:30:44 -04:00
|
|
|
super();
|
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
this._fileMonitors = {};
|
|
|
|
this._backgroundSources = {};
|
2014-12-12 15:57:11 -05:00
|
|
|
this._animations = {};
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
monitorFile(file) {
|
2014-09-18 21:32:52 -04:00
|
|
|
let key = file.hash();
|
|
|
|
if (this._fileMonitors[key])
|
2012-12-24 09:20:39 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
let monitor = file.monitor(Gio.FileMonitorFlags.NONE, null);
|
2014-08-11 12:15:45 -04:00
|
|
|
monitor.connect('changed',
|
2023-08-06 19:45:22 -04:00
|
|
|
(obj, theFile, otherFile, eventType) => {
|
|
|
|
// Ignore CHANGED and CREATED events, since in both cases
|
|
|
|
// we'll get a CHANGES_DONE_HINT event when done.
|
2023-08-06 20:51:19 -04:00
|
|
|
if (eventType !== Gio.FileMonitorEvent.CHANGED &&
|
|
|
|
eventType !== Gio.FileMonitorEvent.CREATED)
|
2023-08-06 19:45:22 -04:00
|
|
|
this.emit('file-changed', file);
|
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
this._fileMonitors[key] = monitor;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
getAnimation(params) {
|
2020-03-29 17:51:13 -04:00
|
|
|
params = Params.parse(params, {
|
|
|
|
file: null,
|
|
|
|
settingsSchema: null,
|
|
|
|
onLoaded: null,
|
|
|
|
});
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-03-30 11:56:30 -04:00
|
|
|
let animation = this._animations[params.settingsSchema];
|
|
|
|
if (animation && _fileEqual0(animation.file, params.file)) {
|
2013-02-04 16:50:36 -05:00
|
|
|
if (params.onLoaded) {
|
2017-10-30 20:38:18 -04:00
|
|
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
2014-12-12 15:57:11 -05:00
|
|
|
params.onLoaded(this._animations[params.settingsSchema]);
|
2013-11-28 19:45:39 -05:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
|
2013-02-04 16:50:36 -05:00
|
|
|
}
|
2014-10-27 11:45:31 -04:00
|
|
|
return;
|
2013-02-04 16:50:36 -05:00
|
|
|
}
|
|
|
|
|
2023-08-06 18:40:20 -04:00
|
|
|
animation = new Animation({file: params.file});
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2021-10-30 18:11:10 -04:00
|
|
|
animation.load_async(null, () => {
|
2017-10-30 20:38:18 -04:00
|
|
|
this._animations[params.settingsSchema] = animation;
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-10-30 20:38:18 -04:00
|
|
|
if (params.onLoaded) {
|
|
|
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
|
|
|
params.onLoaded(this._animations[params.settingsSchema]);
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] params.onLoaded');
|
|
|
|
}
|
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-08-11 12:15:45 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
getBackgroundSource(layoutManager, settingsSchema) {
|
2014-08-11 12:15:45 -04:00
|
|
|
// The layoutManager is always the same one; we pass in it since
|
|
|
|
// Main.layoutManager may not be set yet
|
|
|
|
|
|
|
|
if (!(settingsSchema in this._backgroundSources)) {
|
|
|
|
this._backgroundSources[settingsSchema] = new BackgroundSource(layoutManager, settingsSchema);
|
|
|
|
this._backgroundSources[settingsSchema]._useCount = 1;
|
|
|
|
} else {
|
|
|
|
this._backgroundSources[settingsSchema]._useCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this._backgroundSources[settingsSchema];
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-08-11 12:15:45 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
releaseBackgroundSource(settingsSchema) {
|
2014-08-11 12:15:45 -04:00
|
|
|
if (settingsSchema in this._backgroundSources) {
|
|
|
|
let source = this._backgroundSources[settingsSchema];
|
|
|
|
source._useCount--;
|
2023-08-06 20:51:19 -04:00
|
|
|
if (source._useCount === 0) {
|
2014-08-11 12:15:45 -04:00
|
|
|
delete this._backgroundSources[settingsSchema];
|
|
|
|
source.destroy();
|
|
|
|
}
|
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
}
|
2023-07-10 05:53:00 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2023-07-30 08:56:59 -04:00
|
|
|
/**
|
|
|
|
* @returns {BackgroundCache}
|
|
|
|
*/
|
2012-12-24 09:20:39 -05:00
|
|
|
function getBackgroundCache() {
|
|
|
|
if (!_backgroundCache)
|
|
|
|
_backgroundCache = new BackgroundCache();
|
|
|
|
return _backgroundCache;
|
|
|
|
}
|
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
const Background = GObject.registerClass({
|
2023-08-06 18:40:20 -04:00
|
|
|
Signals: {'loaded': {}, 'bg-changed': {}},
|
2019-07-16 05:24:13 -04:00
|
|
|
}, class Background extends Meta.Background {
|
|
|
|
_init(params) {
|
2021-11-27 07:53:14 -05:00
|
|
|
params = Params.parse(params, {
|
|
|
|
monitorIndex: 0,
|
|
|
|
layoutManager: Main.layoutManager,
|
|
|
|
settings: null,
|
|
|
|
file: null,
|
|
|
|
style: null,
|
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2023-08-06 18:40:20 -04:00
|
|
|
super._init({meta_display: global.display});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2013-08-19 18:48:56 -04:00
|
|
|
this._settings = params.settings;
|
2014-09-18 21:32:52 -04:00
|
|
|
this._file = params.file;
|
2014-08-11 12:15:45 -04:00
|
|
|
this._style = params.style;
|
2012-12-24 09:20:39 -05:00
|
|
|
this._monitorIndex = params.monitorIndex;
|
2013-02-04 16:50:36 -05:00
|
|
|
this._layoutManager = params.layoutManager;
|
2012-12-24 09:20:39 -05:00
|
|
|
this._fileWatches = {};
|
|
|
|
this._cancellable = new Gio.Cancellable();
|
|
|
|
this.isLoaded = false;
|
|
|
|
|
2023-08-06 18:40:20 -04:00
|
|
|
this._interfaceSettings = new Gio.Settings({schema_id: INTERFACE_SCHEMA});
|
2021-11-27 07:53:14 -05:00
|
|
|
|
2015-12-02 10:44:05 -05:00
|
|
|
this._clock = new GnomeDesktop.WallClock();
|
2021-08-15 18:36:59 -04:00
|
|
|
this._clock.connectObject('notify::timezone',
|
2017-10-30 20:38:18 -04:00
|
|
|
() => {
|
2015-12-02 10:44:05 -05:00
|
|
|
if (this._animation)
|
|
|
|
this._loadAnimation(this._animation.file);
|
2021-08-15 18:36:59 -04:00
|
|
|
}, this);
|
2015-12-02 10:44:05 -05:00
|
|
|
|
2017-01-30 07:29:13 -05:00
|
|
|
let loginManager = LoginManager.getLoginManager();
|
2021-08-15 18:36:59 -04:00
|
|
|
loginManager.connectObject('prepare-for-sleep',
|
2016-10-21 08:09:32 -04:00
|
|
|
(lm, aboutToSuspend) => {
|
|
|
|
if (aboutToSuspend)
|
|
|
|
return;
|
|
|
|
this._refreshAnimation();
|
2021-08-15 18:36:59 -04:00
|
|
|
}, this);
|
2016-10-21 08:09:32 -04:00
|
|
|
|
2021-08-15 18:36:59 -04:00
|
|
|
this._settings.connectObject('changed',
|
|
|
|
this._emitChangedSignal.bind(this), this);
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2021-08-15 18:36:59 -04:00
|
|
|
this._interfaceSettings.connectObject(`changed::${COLOR_SCHEME_KEY}`,
|
|
|
|
this._emitChangedSignal.bind(this), this);
|
2021-11-27 07:53:14 -05:00
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
this._load();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
destroy() {
|
2012-12-24 09:20:39 -05:00
|
|
|
this._cancellable.cancel();
|
2014-09-12 17:07:31 -04:00
|
|
|
this._removeAnimationTimeout();
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2013-02-04 16:50:36 -05:00
|
|
|
let i;
|
2012-12-24 09:20:39 -05:00
|
|
|
let keys = Object.keys(this._fileWatches);
|
2019-08-19 20:51:42 -04:00
|
|
|
for (i = 0; i < keys.length; i++)
|
2012-12-24 09:20:39 -05:00
|
|
|
this._cache.disconnect(this._fileWatches[keys[i]]);
|
2019-08-19 20:51:42 -04:00
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
this._fileWatches = null;
|
|
|
|
|
2021-08-15 18:36:59 -04:00
|
|
|
this._clock.disconnectObject(this);
|
2017-12-15 10:05:34 -05:00
|
|
|
this._clock = null;
|
|
|
|
|
2021-08-15 18:36:59 -04:00
|
|
|
LoginManager.getLoginManager().disconnectObject(this);
|
|
|
|
this._settings.disconnectObject(this);
|
|
|
|
this._interfaceSettings.disconnectObject(this);
|
2021-11-27 07:53:14 -05:00
|
|
|
|
2019-05-28 00:18:34 -04:00
|
|
|
if (this._changedIdleId) {
|
|
|
|
GLib.source_remove(this._changedIdleId);
|
|
|
|
this._changedIdleId = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_emitChangedSignal() {
|
|
|
|
if (this._changedIdleId)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._changedIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
|
|
|
this._changedIdleId = 0;
|
2019-07-12 18:56:12 -04:00
|
|
|
this.emit('bg-changed');
|
2019-05-28 00:18:34 -04:00
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
2019-07-12 18:56:12 -04:00
|
|
|
GLib.Source.set_name_by_id(this._changedIdleId,
|
|
|
|
'[gnome-shell] Background._emitChangedSignal');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
updateResolution() {
|
2016-10-21 08:09:32 -04:00
|
|
|
if (this._animation)
|
|
|
|
this._refreshAnimation();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2016-10-21 08:09:32 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_refreshAnimation() {
|
2016-10-21 08:09:32 -04:00
|
|
|
if (!this._animation)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._removeAnimationTimeout();
|
|
|
|
this._updateAnimation();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-09-12 17:07:31 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_setLoaded() {
|
2012-12-24 09:20:39 -05:00
|
|
|
if (this.isLoaded)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.isLoaded = true;
|
2022-04-13 14:51:55 -04:00
|
|
|
if (this._cancellable?.is_cancelled())
|
|
|
|
return;
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:38:18 -04:00
|
|
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
2012-12-24 09:20:39 -05:00
|
|
|
this.emit('loaded');
|
2013-11-28 19:45:39 -05:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2019-07-16 05:24:13 -04:00
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] Background._setLoaded Idle');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_loadPattern() {
|
2019-01-31 09:08:00 -05:00
|
|
|
let colorString, res_, color, secondColor;
|
2012-12-24 09:20:39 -05:00
|
|
|
|
|
|
|
colorString = this._settings.get_string(PRIMARY_COLOR_KEY);
|
2019-01-31 09:08:00 -05:00
|
|
|
[res_, color] = Clutter.Color.from_string(colorString);
|
2012-12-24 09:20:39 -05:00
|
|
|
colorString = this._settings.get_string(SECONDARY_COLOR_KEY);
|
2019-01-31 09:08:00 -05:00
|
|
|
[res_, secondColor] = Clutter.Color.from_string(colorString);
|
2012-12-24 09:20:39 -05:00
|
|
|
|
|
|
|
let shadingType = this._settings.get_enum(COLOR_SHADING_TYPE_KEY);
|
|
|
|
|
2023-08-06 20:51:19 -04:00
|
|
|
if (shadingType === GDesktopEnums.BackgroundShading.SOLID)
|
2019-07-16 05:24:13 -04:00
|
|
|
this.set_color(color);
|
2014-08-11 12:15:45 -04:00
|
|
|
else
|
2019-07-16 05:24:13 -04:00
|
|
|
this.set_gradient(shadingType, color, secondColor);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_watchFile(file) {
|
2014-09-18 21:32:52 -04:00
|
|
|
let key = file.hash();
|
|
|
|
if (this._fileWatches[key])
|
2012-12-24 09:20:39 -05:00
|
|
|
return;
|
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
this._cache.monitorFile(file);
|
2012-12-24 09:20:39 -05:00
|
|
|
let signalId = this._cache.connect('file-changed',
|
2023-08-06 19:45:22 -04:00
|
|
|
(cache, changedFile) => {
|
|
|
|
if (changedFile.equal(file)) {
|
|
|
|
let imageCache = Meta.BackgroundImageCache.get_default();
|
|
|
|
imageCache.purge(changedFile);
|
|
|
|
this._emitChangedSignal();
|
|
|
|
}
|
|
|
|
});
|
2014-09-18 21:32:52 -04:00
|
|
|
this._fileWatches[key] = signalId;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_removeAnimationTimeout() {
|
2014-09-12 17:07:31 -04:00
|
|
|
if (this._updateAnimationTimeoutId) {
|
|
|
|
GLib.source_remove(this._updateAnimationTimeoutId);
|
|
|
|
this._updateAnimationTimeoutId = 0;
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-09-12 17:07:31 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_updateAnimation() {
|
2013-03-14 17:00:57 -04:00
|
|
|
this._updateAnimationTimeoutId = 0;
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2013-03-14 17:03:25 -04:00
|
|
|
this._animation.update(this._layoutManager.monitors[this._monitorIndex]);
|
|
|
|
let files = this._animation.keyFrameFiles;
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-10-30 20:38:18 -04:00
|
|
|
let finish = () => {
|
2013-02-04 16:50:36 -05:00
|
|
|
this._setLoaded();
|
2014-08-11 12:15:45 -04:00
|
|
|
if (files.length > 1) {
|
2019-07-16 05:24:13 -04:00
|
|
|
this.set_blend(files[0], files[1],
|
2023-08-06 19:45:22 -04:00
|
|
|
this._animation.transitionProgress,
|
|
|
|
this._style);
|
2014-08-11 12:15:45 -04:00
|
|
|
} else if (files.length > 0) {
|
2019-07-16 05:24:13 -04:00
|
|
|
this.set_file(files[0], this._style);
|
2014-08-11 12:15:45 -04:00
|
|
|
} else {
|
2019-07-16 05:24:13 -04:00
|
|
|
this.set_file(null, this._style);
|
2014-08-11 12:15:45 -04:00
|
|
|
}
|
2013-03-14 17:00:57 -04:00
|
|
|
this._queueUpdateAnimation();
|
2017-10-30 20:38:18 -04:00
|
|
|
};
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
let cache = Meta.BackgroundImageCache.get_default();
|
2013-02-04 16:50:36 -05:00
|
|
|
let numPendingImages = files.length;
|
|
|
|
for (let i = 0; i < files.length; i++) {
|
2014-08-11 12:15:45 -04:00
|
|
|
this._watchFile(files[i]);
|
|
|
|
let image = cache.load(files[i]);
|
|
|
|
if (image.is_loaded()) {
|
2013-02-04 16:50:36 -05:00
|
|
|
numPendingImages--;
|
2023-08-06 20:51:19 -04:00
|
|
|
if (numPendingImages === 0)
|
2014-08-11 12:15:45 -04:00
|
|
|
finish();
|
|
|
|
} else {
|
2019-09-14 20:51:40 -04:00
|
|
|
// eslint-disable-next-line no-loop-func
|
2017-10-30 20:38:18 -04:00
|
|
|
let id = image.connect('loaded', () => {
|
|
|
|
image.disconnect(id);
|
|
|
|
numPendingImages--;
|
2023-08-06 20:51:19 -04:00
|
|
|
if (numPendingImages === 0)
|
2017-10-30 20:38:18 -04:00
|
|
|
finish();
|
|
|
|
});
|
2013-02-04 16:50:36 -05:00
|
|
|
}
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_queueUpdateAnimation() {
|
2023-08-06 20:51:19 -04:00
|
|
|
if (this._updateAnimationTimeoutId !== 0)
|
2013-02-04 16:50:36 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!this._cancellable || this._cancellable.is_cancelled())
|
|
|
|
return;
|
|
|
|
|
2013-03-14 16:58:52 -04:00
|
|
|
if (!this._animation.transitionDuration)
|
2013-02-04 16:50:36 -05:00
|
|
|
return;
|
|
|
|
|
2013-03-14 16:58:20 -04:00
|
|
|
let nSteps = 255 / ANIMATION_OPACITY_STEP_INCREMENT;
|
2013-03-14 16:58:52 -04:00
|
|
|
let timePerStep = (this._animation.transitionDuration * 1000) / nSteps;
|
2013-03-14 16:58:20 -04:00
|
|
|
|
2023-08-06 19:45:22 -04:00
|
|
|
let interval = Math.max(
|
|
|
|
ANIMATION_MIN_WAKEUP_INTERVAL * 1000,
|
|
|
|
timePerStep);
|
2013-03-25 10:42:21 -04:00
|
|
|
|
|
|
|
if (interval > GLib.MAXUINT32)
|
|
|
|
return;
|
|
|
|
|
2013-03-14 17:00:57 -04:00
|
|
|
this._updateAnimationTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
|
2023-08-06 19:45:22 -04:00
|
|
|
interval,
|
|
|
|
() => {
|
|
|
|
this._updateAnimationTimeoutId = 0;
|
|
|
|
this._updateAnimation();
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(this._updateAnimationTimeoutId, '[gnome-shell] this._updateAnimation');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_loadAnimation(file) {
|
2019-02-12 09:02:09 -05:00
|
|
|
this._cache.getAnimation({
|
2019-08-19 15:06:04 -04:00
|
|
|
file,
|
2019-02-12 09:02:09 -05:00
|
|
|
settingsSchema: this._settings.schema_id,
|
|
|
|
onLoaded: animation => {
|
|
|
|
this._animation = animation;
|
|
|
|
|
|
|
|
if (!this._animation || this._cancellable.is_cancelled()) {
|
|
|
|
this._setLoaded();
|
|
|
|
return;
|
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2019-02-12 09:02:09 -05:00
|
|
|
this._updateAnimation();
|
|
|
|
this._watchFile(file);
|
2019-08-20 17:43:54 -04:00
|
|
|
},
|
2019-02-12 09:02:09 -05:00
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_loadImage(file) {
|
2019-07-16 05:24:13 -04:00
|
|
|
this.set_file(file, this._style);
|
2014-09-18 21:32:52 -04:00
|
|
|
this._watchFile(file);
|
2014-08-11 12:15:45 -04:00
|
|
|
|
|
|
|
let cache = Meta.BackgroundImageCache.get_default();
|
2014-09-18 21:32:52 -04:00
|
|
|
let image = cache.load(file);
|
2019-01-29 16:02:57 -05:00
|
|
|
if (image.is_loaded()) {
|
2014-08-11 12:15:45 -04:00
|
|
|
this._setLoaded();
|
2019-01-29 16:02:57 -05:00
|
|
|
} else {
|
2017-10-30 20:38:18 -04:00
|
|
|
let id = image.connect('loaded', () => {
|
|
|
|
this._setLoaded();
|
|
|
|
image.disconnect(id);
|
|
|
|
});
|
2014-08-11 12:15:45 -04:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2021-04-16 10:17:33 -04:00
|
|
|
async _loadFile(file) {
|
2022-02-12 08:33:51 -05:00
|
|
|
let info;
|
|
|
|
try {
|
|
|
|
info = await file.query_info_async(
|
|
|
|
Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
|
|
|
Gio.FileQueryInfoFlags.NONE,
|
|
|
|
0,
|
2022-04-13 14:14:47 -04:00
|
|
|
this._cancellable);
|
2022-02-12 08:33:51 -05:00
|
|
|
} catch (e) {
|
|
|
|
this._setLoaded();
|
|
|
|
return;
|
|
|
|
}
|
2021-04-16 10:17:33 -04:00
|
|
|
|
|
|
|
const contentType = info.get_content_type();
|
|
|
|
if (contentType === 'application/xml')
|
2014-09-18 21:32:52 -04:00
|
|
|
this._loadAnimation(file);
|
2013-12-03 15:56:12 -05:00
|
|
|
else
|
2014-09-18 21:32:52 -04:00
|
|
|
this._loadImage(file);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_load() {
|
2012-12-24 09:20:39 -05:00
|
|
|
this._cache = getBackgroundCache();
|
|
|
|
|
2014-01-13 18:21:03 -05:00
|
|
|
this._loadPattern();
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
if (!this._file) {
|
2013-06-13 15:48:32 -04:00
|
|
|
this._setLoaded();
|
|
|
|
return;
|
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
this._loadFile(this._file);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2019-07-16 05:24:13 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
let _systemBackground;
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
export const SystemBackground = GObject.registerClass({
|
2023-08-06 18:40:20 -04:00
|
|
|
Signals: {'loaded': {}},
|
2019-07-16 05:24:13 -04:00
|
|
|
}, class SystemBackground extends Meta.BackgroundActor {
|
|
|
|
_init() {
|
2014-08-11 12:15:45 -04:00
|
|
|
if (_systemBackground == null) {
|
2023-08-06 18:40:20 -04:00
|
|
|
_systemBackground = new Meta.Background({meta_display: global.display});
|
2014-10-16 16:45:02 -04:00
|
|
|
_systemBackground.set_color(DEFAULT_BACKGROUND_COLOR);
|
2014-08-11 12:15:45 -04:00
|
|
|
}
|
|
|
|
|
2019-07-16 05:24:13 -04:00
|
|
|
super._init({
|
|
|
|
meta_display: global.display,
|
|
|
|
monitor: 0,
|
|
|
|
});
|
2020-06-09 13:36:21 -04:00
|
|
|
this.content.background = _systemBackground;
|
2014-08-11 12:15:45 -04:00
|
|
|
|
2020-02-05 09:21:30 -05:00
|
|
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
|
|
|
this.emit('loaded');
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2019-07-16 05:24:13 -04:00
|
|
|
});
|
2014-08-11 12:15:45 -04:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
class BackgroundSource {
|
2017-10-30 21:19:44 -04:00
|
|
|
constructor(layoutManager, settingsSchema) {
|
2014-08-11 12:15:45 -04:00
|
|
|
// Allow override the background image setting for performance testing
|
|
|
|
this._layoutManager = layoutManager;
|
|
|
|
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
|
2023-08-06 18:40:20 -04:00
|
|
|
this._settings = new Gio.Settings({schema_id: settingsSchema});
|
2014-08-11 12:15:45 -04:00
|
|
|
this._backgrounds = [];
|
2014-09-12 17:07:31 -04:00
|
|
|
|
2022-09-07 14:24:44 -04:00
|
|
|
const monitorManager = global.backend.get_monitor_manager();
|
2018-01-03 02:55:38 -05:00
|
|
|
this._monitorsChangedId =
|
|
|
|
monitorManager.connect('monitors-changed',
|
2023-08-06 19:45:22 -04:00
|
|
|
this._onMonitorsChanged.bind(this));
|
2021-11-27 07:53:14 -05:00
|
|
|
|
2023-08-06 18:40:20 -04:00
|
|
|
this._interfaceSettings = new Gio.Settings({schema_id: INTERFACE_SCHEMA});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-09-12 17:07:31 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onMonitorsChanged() {
|
2014-09-12 17:07:31 -04:00
|
|
|
for (let monitorIndex in this._backgrounds) {
|
|
|
|
let background = this._backgrounds[monitorIndex];
|
|
|
|
|
|
|
|
if (monitorIndex < this._layoutManager.monitors.length) {
|
|
|
|
background.updateResolution();
|
|
|
|
} else {
|
|
|
|
background.disconnect(background._changedId);
|
|
|
|
background.destroy();
|
|
|
|
delete this._backgrounds[monitorIndex];
|
|
|
|
}
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
getBackground(monitorIndex) {
|
2014-09-18 21:32:52 -04:00
|
|
|
let file = null;
|
2014-08-11 12:15:45 -04:00
|
|
|
let style;
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2015-03-20 15:39:01 -04:00
|
|
|
// We don't watch changes to settings here,
|
|
|
|
// instead we rely on Background to watch those
|
2019-07-12 18:56:12 -04:00
|
|
|
// and emit 'bg-changed' at the right time
|
2015-03-20 15:39:01 -04:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
if (this._overrideImage != null) {
|
2014-09-18 21:32:52 -04:00
|
|
|
file = Gio.File.new_for_path(this._overrideImage);
|
2014-08-11 12:15:45 -04:00
|
|
|
style = GDesktopEnums.BackgroundStyle.ZOOM; // Hardcode
|
|
|
|
} else {
|
|
|
|
style = this._settings.get_enum(BACKGROUND_STYLE_KEY);
|
2023-08-06 20:51:19 -04:00
|
|
|
if (style !== GDesktopEnums.BackgroundStyle.NONE) {
|
2021-11-27 07:53:14 -05:00
|
|
|
const colorScheme = this._interfaceSettings.get_enum('color-scheme');
|
|
|
|
const uri = this._settings.get_string(
|
|
|
|
colorScheme === GDesktopEnums.ColorScheme.PREFER_DARK
|
|
|
|
? PICTURE_URI_DARK_KEY
|
|
|
|
: PICTURE_URI_KEY);
|
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
file = Gio.File.new_for_commandline_arg(uri);
|
2014-08-11 12:15:45 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
// Animated backgrounds are (potentially) per-monitor, since
|
|
|
|
// they can have variants that depend on the aspect ratio and
|
|
|
|
// size of the monitor; for other backgrounds we can use the
|
|
|
|
// same background object for all monitors.
|
2014-09-18 21:32:52 -04:00
|
|
|
if (file == null || !file.get_basename().endsWith('.xml'))
|
2014-08-11 12:15:45 -04:00
|
|
|
monitorIndex = 0;
|
|
|
|
|
|
|
|
if (!(monitorIndex in this._backgrounds)) {
|
|
|
|
let background = new Background({
|
2019-08-19 15:06:04 -04:00
|
|
|
monitorIndex,
|
2014-08-11 12:15:45 -04:00
|
|
|
layoutManager: this._layoutManager,
|
|
|
|
settings: this._settings,
|
2019-08-19 15:06:04 -04:00
|
|
|
file,
|
2019-08-20 17:43:54 -04:00
|
|
|
style,
|
2014-08-11 12:15:45 -04:00
|
|
|
});
|
|
|
|
|
2019-07-12 18:56:12 -04:00
|
|
|
background._changedId = background.connect('bg-changed', () => {
|
2014-09-12 17:07:31 -04:00
|
|
|
background.disconnect(background._changedId);
|
2014-08-11 12:15:45 -04:00
|
|
|
background.destroy();
|
|
|
|
delete this._backgrounds[monitorIndex];
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2014-08-11 12:15:45 -04:00
|
|
|
|
|
|
|
this._backgrounds[monitorIndex] = background;
|
|
|
|
}
|
2013-02-21 14:32:23 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
return this._backgrounds[monitorIndex];
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-12-03 17:05:06 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
destroy() {
|
2022-09-07 14:24:44 -04:00
|
|
|
const monitorManager = global.backend.get_monitor_manager();
|
2018-01-03 02:55:38 -05:00
|
|
|
monitorManager.disconnect(this._monitorsChangedId);
|
2014-09-12 17:07:31 -04:00
|
|
|
|
|
|
|
for (let monitorIndex in this._backgrounds) {
|
|
|
|
let background = this._backgrounds[monitorIndex];
|
|
|
|
background.disconnect(background._changedId);
|
|
|
|
background.destroy();
|
|
|
|
}
|
2014-06-26 12:45:06 -04:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
this._backgrounds = null;
|
|
|
|
}
|
2023-07-10 05:53:00 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
const Animation = GObject.registerClass(
|
2023-02-21 19:39:21 -05:00
|
|
|
class Animation extends GnomeBG.BGSlideShow {
|
2019-05-28 19:21:51 -04:00
|
|
|
_init(params) {
|
|
|
|
super._init(params);
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2013-03-14 17:03:25 -04:00
|
|
|
this.keyFrameFiles = [];
|
2013-02-04 16:50:36 -05:00
|
|
|
this.transitionProgress = 0.0;
|
2013-03-14 16:58:52 -04:00
|
|
|
this.transitionDuration = 0.0;
|
2013-02-04 16:50:36 -05:00
|
|
|
this.loaded = false;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2021-10-30 18:11:10 -04:00
|
|
|
// eslint-disable-next-line camelcase
|
|
|
|
load_async(cancellable, callback) {
|
|
|
|
super.load_async(cancellable, () => {
|
2017-10-30 20:38:18 -04:00
|
|
|
this.loaded = true;
|
2021-10-30 18:11:10 -04:00
|
|
|
|
|
|
|
callback?.();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
update(monitor) {
|
2013-03-14 17:03:25 -04:00
|
|
|
this.keyFrameFiles = [];
|
|
|
|
|
2019-05-28 19:21:51 -04:00
|
|
|
if (this.get_num_slides() < 1)
|
2013-03-14 17:03:25 -04:00
|
|
|
return;
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2019-05-28 19:21:51 -04:00
|
|
|
let [progress, duration, isFixed_, filename1, filename2] =
|
|
|
|
this.get_current_slide(monitor.width, monitor.height);
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2013-03-14 16:58:52 -04:00
|
|
|
this.transitionDuration = duration;
|
2013-02-04 16:50:36 -05:00
|
|
|
this.transitionProgress = progress;
|
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
if (filename1)
|
|
|
|
this.keyFrameFiles.push(Gio.File.new_for_path(filename1));
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2014-09-18 21:32:52 -04:00
|
|
|
if (filename2)
|
|
|
|
this.keyFrameFiles.push(Gio.File.new_for_path(filename2));
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2019-05-28 19:21:51 -04:00
|
|
|
});
|
2013-02-04 16:50:36 -05:00
|
|
|
|
2023-07-10 05:53:00 -04:00
|
|
|
export class BackgroundManager extends Signals.EventEmitter {
|
2017-10-30 21:19:44 -04:00
|
|
|
constructor(params) {
|
2022-07-04 18:30:44 -04:00
|
|
|
super();
|
2020-06-09 17:18:00 -04:00
|
|
|
params = Params.parse(params, {
|
|
|
|
container: null,
|
|
|
|
layoutManager: Main.layoutManager,
|
|
|
|
monitorIndex: null,
|
|
|
|
vignette: false,
|
|
|
|
controlPosition: true,
|
|
|
|
settingsSchema: BACKGROUND_SCHEMA,
|
2020-06-09 17:18:21 -04:00
|
|
|
useContentSize: true,
|
2020-06-09 17:18:00 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
let cache = getBackgroundCache();
|
|
|
|
this._settingsSchema = params.settingsSchema;
|
|
|
|
this._backgroundSource = cache.getBackgroundSource(params.layoutManager, params.settingsSchema);
|
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
this._container = params.container;
|
|
|
|
this._layoutManager = params.layoutManager;
|
2014-08-11 12:15:45 -04:00
|
|
|
this._vignette = params.vignette;
|
2012-12-24 09:20:39 -05:00
|
|
|
this._monitorIndex = params.monitorIndex;
|
ScreenShield: fix positioning of background with multimonitor
Previously, we would create one StBin per monitor, but each was positioned
at 0,0 and sized as the screen, so they would overlap and draw the box shadows
on top of the other backgrounds.
Instead, we need to size appropriately the bin, and then we need to position
the actual MetaBacgroundActor at 0,0, so add a flag to BackgroundManager
for this.
Also, get rid of MetaBackgroundGroup, they do nothing because the screenshield
is not a descendant of the MetaWindowGroup and because the widget in between
blocks the propagation of the visible region. At the same time, use a
widget, not a bin, because StBin requires you to set .child, not call add_child().
https://bugzilla.gnome.org/show_bug.cgi?id=694394
2013-02-21 17:32:25 -05:00
|
|
|
this._controlPosition = params.controlPosition;
|
2020-06-09 17:18:21 -04:00
|
|
|
this._useContentSize = params.useContentSize;
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
this.backgroundActor = this._createBackgroundActor();
|
|
|
|
this._newBackgroundActor = null;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
destroy() {
|
2014-08-11 12:15:45 -04:00
|
|
|
let cache = getBackgroundCache();
|
|
|
|
cache.releaseBackgroundSource(this._settingsSchema);
|
|
|
|
this._backgroundSource = null;
|
|
|
|
|
|
|
|
if (this._newBackgroundActor) {
|
|
|
|
this._newBackgroundActor.destroy();
|
|
|
|
this._newBackgroundActor = null;
|
2012-12-24 09:20:39 -05:00
|
|
|
}
|
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
if (this.backgroundActor) {
|
|
|
|
this.backgroundActor.destroy();
|
|
|
|
this.backgroundActor = null;
|
2012-12-24 09:20:39 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_swapBackgroundActor() {
|
2014-08-11 12:15:45 -04:00
|
|
|
let oldBackgroundActor = this.backgroundActor;
|
|
|
|
this.backgroundActor = this._newBackgroundActor;
|
|
|
|
this._newBackgroundActor = null;
|
|
|
|
this.emit('changed');
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2021-09-23 03:45:14 -04:00
|
|
|
if (Main.layoutManager.screenTransition.visible) {
|
|
|
|
oldBackgroundActor.destroy();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-07-20 15:46:19 -04:00
|
|
|
oldBackgroundActor.ease({
|
|
|
|
opacity: 0,
|
|
|
|
duration: FADE_ANIMATION_TIME,
|
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-08-20 17:43:54 -04:00
|
|
|
onComplete: () => oldBackgroundActor.destroy(),
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_updateBackgroundActor() {
|
2014-08-11 12:15:45 -04:00
|
|
|
if (this._newBackgroundActor) {
|
|
|
|
/* Skip displaying existing background queued for load */
|
|
|
|
this._newBackgroundActor.destroy();
|
|
|
|
this._newBackgroundActor = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
let newBackgroundActor = this._createBackgroundActor();
|
2020-07-01 06:51:33 -04:00
|
|
|
|
|
|
|
const oldContent = this.backgroundActor.content;
|
|
|
|
const newContent = newBackgroundActor.content;
|
|
|
|
|
|
|
|
newContent.vignette_sharpness = oldContent.vignette_sharpness;
|
|
|
|
newContent.brightness = oldContent.brightness;
|
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
newBackgroundActor.visible = this.backgroundActor.visible;
|
|
|
|
|
|
|
|
this._newBackgroundActor = newBackgroundActor;
|
|
|
|
|
2023-08-06 18:40:20 -04:00
|
|
|
const {background} = newBackgroundActor.content;
|
2014-08-11 12:15:45 -04:00
|
|
|
|
|
|
|
if (background.isLoaded) {
|
|
|
|
this._swapBackgroundActor();
|
|
|
|
} else {
|
|
|
|
newBackgroundActor.loadedSignalId = background.connect('loaded',
|
2017-10-30 20:38:18 -04:00
|
|
|
() => {
|
2014-08-11 12:15:45 -04:00
|
|
|
background.disconnect(newBackgroundActor.loadedSignalId);
|
|
|
|
newBackgroundActor.loadedSignalId = 0;
|
|
|
|
|
|
|
|
this._swapBackgroundActor();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2014-08-11 12:15:45 -04:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-08-11 12:15:45 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_createBackgroundActor() {
|
2014-08-11 12:15:45 -04:00
|
|
|
let background = this._backgroundSource.getBackground(this._monitorIndex);
|
2019-02-12 09:02:09 -05:00
|
|
|
let backgroundActor = new Meta.BackgroundActor({
|
|
|
|
meta_display: global.display,
|
|
|
|
monitor: this._monitorIndex,
|
2020-06-09 17:18:21 -04:00
|
|
|
request_mode: this._useContentSize
|
|
|
|
? Clutter.RequestMode.CONTENT_SIZE
|
|
|
|
: Clutter.RequestMode.HEIGHT_FOR_WIDTH,
|
|
|
|
x_expand: !this._useContentSize,
|
|
|
|
y_expand: !this._useContentSize,
|
2020-06-09 13:36:21 -04:00
|
|
|
});
|
|
|
|
backgroundActor.content.set({
|
2019-07-16 05:24:13 -04:00
|
|
|
background,
|
2019-02-12 09:02:09 -05:00
|
|
|
vignette: this._vignette,
|
|
|
|
vignette_sharpness: 0.5,
|
|
|
|
brightness: 0.5,
|
|
|
|
});
|
2014-08-11 12:15:45 -04:00
|
|
|
|
|
|
|
this._container.add_child(backgroundActor);
|
2012-12-24 09:20:39 -05:00
|
|
|
|
ScreenShield: fix positioning of background with multimonitor
Previously, we would create one StBin per monitor, but each was positioned
at 0,0 and sized as the screen, so they would overlap and draw the box shadows
on top of the other backgrounds.
Instead, we need to size appropriately the bin, and then we need to position
the actual MetaBacgroundActor at 0,0, so add a flag to BackgroundManager
for this.
Also, get rid of MetaBackgroundGroup, they do nothing because the screenshield
is not a descendant of the MetaWindowGroup and because the widget in between
blocks the propagation of the visible region. At the same time, use a
widget, not a bin, because StBin requires you to set .child, not call add_child().
https://bugzilla.gnome.org/show_bug.cgi?id=694394
2013-02-21 17:32:25 -05:00
|
|
|
if (this._controlPosition) {
|
2017-08-03 09:52:06 -04:00
|
|
|
let monitor = this._layoutManager.monitors[this._monitorIndex];
|
2014-08-11 12:15:45 -04:00
|
|
|
backgroundActor.set_position(monitor.x, monitor.y);
|
2019-11-05 14:17:19 -05:00
|
|
|
this._container.set_child_below_sibling(backgroundActor, null);
|
ScreenShield: fix positioning of background with multimonitor
Previously, we would create one StBin per monitor, but each was positioned
at 0,0 and sized as the screen, so they would overlap and draw the box shadows
on top of the other backgrounds.
Instead, we need to size appropriately the bin, and then we need to position
the actual MetaBacgroundActor at 0,0, so add a flag to BackgroundManager
for this.
Also, get rid of MetaBackgroundGroup, they do nothing because the screenshield
is not a descendant of the MetaWindowGroup and because the widget in between
blocks the propagation of the visible region. At the same time, use a
widget, not a bin, because StBin requires you to set .child, not call add_child().
https://bugzilla.gnome.org/show_bug.cgi?id=694394
2013-02-21 17:32:25 -05:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2019-07-12 18:56:12 -04:00
|
|
|
let changeSignalId = background.connect('bg-changed', () => {
|
2014-08-11 12:15:45 -04:00
|
|
|
background.disconnect(changeSignalId);
|
|
|
|
changeSignalId = null;
|
|
|
|
this._updateBackgroundActor();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2020-07-22 06:32:49 -04:00
|
|
|
let loadedSignalId;
|
|
|
|
if (background.isLoaded) {
|
|
|
|
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
|
|
|
this.emit('loaded');
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
loadedSignalId = background.connect('loaded', () => {
|
|
|
|
background.disconnect(loadedSignalId);
|
|
|
|
loadedSignalId = null;
|
|
|
|
this.emit('loaded');
|
|
|
|
});
|
|
|
|
}
|
2020-07-20 20:00:32 -04:00
|
|
|
|
2017-10-30 20:38:18 -04:00
|
|
|
backgroundActor.connect('destroy', () => {
|
2014-08-11 12:15:45 -04:00
|
|
|
if (changeSignalId)
|
|
|
|
background.disconnect(changeSignalId);
|
2013-03-19 15:26:05 -04:00
|
|
|
|
2020-07-20 20:00:32 -04:00
|
|
|
if (loadedSignalId)
|
|
|
|
background.disconnect(loadedSignalId);
|
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
if (backgroundActor.loadedSignalId)
|
2014-09-04 10:01:52 -04:00
|
|
|
background.disconnect(backgroundActor.loadedSignalId);
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2014-08-11 12:15:45 -04:00
|
|
|
return backgroundActor;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2023-07-10 05:53:00 -04:00
|
|
|
}
|