From bce07888099af5724b70be88094b48a490e322ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 21 Mar 2023 22:53:05 +0100 Subject: [PATCH] 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: --- js/ui/extensionSystem.js | 90 ++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 23 deletions(-) diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index d9cdf77e4..dd2f44ebb 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -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); } }