extensionSystem: Support stylesheet variants

Since we started to support the color-scheme preference, extensions
should be able to provide appropriate variants (if they deal with
colors).

So look for a variant with -dark/-light suffix before using the
plain stylesheet.css, and reload extension stylesheets on
color scheme changes.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2324>
This commit is contained in:
Florian Müllner 2023-03-21 22:53:05 +01:00
parent 878a0af00d
commit bce0788809

View File

@ -32,6 +32,9 @@ var ExtensionManager = class extends Signals.EventEmitter {
this._extensionOrder = [];
this._checkVersion = false;
St.Settings.get().connect('notify::color-scheme',
() => this._reloadExtensionStylesheets());
Main.sessionMode.connect('updated', () => {
this._sessionUpdated();
});
@ -81,6 +84,63 @@ var ExtensionManager = class extends Signals.EventEmitter {
return [...this._extensions.keys()];
}
_reloadExtensionStylesheets() {
for (const ext of this._extensions.values()) {
// No stylesheet, nothing to reload
if (!ext.stylesheet)
continue;
// No variants, so skip reloading
const path = ext.stylesheet.get_path();
if (!path.endsWith('-dark.css') && !path.endsWith('-light.css'))
continue;
try {
this._unloadExtensionStylesheet(ext);
this._loadExtensionStylesheet(ext);
} catch (e) {
this._callExtensionDisable(ext.uuid);
this.logExtensionError(ext.uuid, e);
}
}
}
_loadExtensionStylesheet(extension) {
if (extension.state !== ExtensionState.ENABLED &&
extension.state !== ExtensionState.ENABLING)
return;
const variant = Main.getStyleVariant();
const stylesheetNames = [
`${global.sessionMode}-${variant}.css`,
`stylesheet-${variant}.css`,
`${global.sessionMode}.css`,
'stylesheet.css',
];
const theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (const name of stylesheetNames) {
try {
const stylesheetFile = extension.dir.get_child(name);
theme.load_stylesheet(stylesheetFile);
extension.stylesheet = stylesheetFile;
break;
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
continue; // not an error
throw e;
}
}
}
_unloadExtensionStylesheet(extension) {
if (!extension.stylesheet)
return;
const theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.unload_stylesheet(extension.stylesheet);
delete extension.stylesheet;
}
_extensionSupportsSessionMode(uuid) {
const extension = this.lookup(uuid);
@ -134,11 +194,7 @@ var ExtensionManager = class extends Signals.EventEmitter {
this.logExtensionError(uuid, e);
}
if (extension.stylesheet) {
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
theme.unload_stylesheet(extension.stylesheet);
delete extension.stylesheet;
}
this._unloadExtensionStylesheet(extension);
for (let i = 0; i < order.length; i++) {
let otherUuid = order[i];
@ -176,20 +232,11 @@ var ExtensionManager = class extends Signals.EventEmitter {
extension.state = ExtensionState.ENABLING;
this.emit('extension-state-changed', extension);
let stylesheetNames = [`${global.session_mode}.css`, 'stylesheet.css'];
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (let i = 0; i < stylesheetNames.length; i++) {
try {
let stylesheetFile = extension.dir.get_child(stylesheetNames[i]);
theme.load_stylesheet(stylesheetFile);
extension.stylesheet = stylesheetFile;
break;
} catch (e) {
if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
continue; // not an error
this.logExtensionError(uuid, e);
return;
}
try {
this._loadExtensionStylesheet(extension);
} catch (e) {
this.logExtensionError(uuid, e);
return;
}
try {
@ -198,10 +245,7 @@ var ExtensionManager = class extends Signals.EventEmitter {
this._extensionOrder.push(uuid);
this.emit('extension-state-changed', extension);
} catch (e) {
if (extension.stylesheet) {
theme.unload_stylesheet(extension.stylesheet);
delete extension.stylesheet;
}
this._unloadExtensionStylesheet(extension);
this.logExtensionError(uuid, e);
}
}