/* exported init, cleanup, add, bind, unbind */ const Me = imports.misc.extensionUtils.getCurrentExtension(); const Params = imports.misc.params; const Convenience = Me.imports.convenience; const Intellifade = Me.imports.intellifade; const GLib = imports.gi.GLib; const Gio = imports.gi.Gio; /* This might impair visibility of the code, but it makes my life a thousand times simpler */ /* settings.js takes a key and watches for it to change in Gio.Settings & creates a getter for it. */ /* Also can parse, handle, etc. a setting. */ const OVERRIDES_SCHEMA_ID = 'org.gnome.shell.extensions.dynamic-panel-transparency.appOverrides'; const GNOME_BACKGROUND_SCHEMA = 'org.gnome.desktop.wm.keybindings'; const SETTINGS_SHOW_DESKTOP = 'show-desktop'; const GNOME_INTERFACE_SCHEMA = 'org.gnome.desktop.interface'; const SETTINGS_ENABLE_ANIMATIONS = 'enable-animations'; function init() { this._settings = Convenience.getSettings(); this._background_settings = null; this._interface_settings = null; /* Setup background settings. */ try { let schemaObj = Convenience.getSchemaObj(GNOME_BACKGROUND_SCHEMA, true); if (schemaObj) { this._background_settings = new Gio.Settings({ settings_schema: schemaObj }); } } catch (error) { } // eslint-disable-line try { let schemaObj = Convenience.getSchemaObj(GNOME_INTERFACE_SCHEMA, true); if (schemaObj) { this._interface_settings = new Gio.Settings({ settings_schema: schemaObj }); } } catch (error) { } // eslint-disable-line this._keys = []; this._app_keys = {}; this._overriden_keys = []; this.settingsBoundIds = []; this._show_desktop = null; if (this._background_settings) { this._show_desktop = this._background_settings.get_strv(SETTINGS_SHOW_DESKTOP).length > 0; this.settingsBoundIds.push(this._background_settings.connect('changed::' + SETTINGS_SHOW_DESKTOP, (function() { this._show_desktop = this._background_settings.get_strv(SETTINGS_SHOW_DESKTOP).length > 0; }).bind(this))); } if (this._interface_settings) { this._enable_animations = this._interface_settings.get_boolean(SETTINGS_ENABLE_ANIMATIONS); this.settingsBoundIds.push(this._interface_settings.connect('changed::' + SETTINGS_ENABLE_ANIMATIONS, (function() { this._enable_animations = this._interface_settings.get_boolean(SETTINGS_ENABLE_ANIMATIONS); }).bind(this))); } this.gs_show_desktop = function() { return this._show_desktop; }; this.gs_enable_animations = function() { return this._enable_animations; }; } function cleanup() { for (let i = 0; i < this._keys.length; ++i) { let setting = this._keys[i]; if (!setting.getter) { this['get_' + setting.name] = null; } else { this[setting.getter] = null; } } this._keys = null; this.settingsBoundIds = null; this._settings = null; } /* Settings Management */ function add(params) { let key = { key: params.key, name: params.name, type: params.type, parser: null, getter: null, handler: null }; if (typeof (params.getter) !== 'undefined') key.getter = params.getter; if (typeof (params.handler) !== 'undefined') key.handler = params.handler; if (typeof (params.parser) !== 'undefined') key.parser = params.parser; this._keys.push(key); } function bind() { this.settings_manager = new SettingsManager(this._settings, this._keys); for (let i = 0; i < this._keys.length; ++i) { let setting = this._keys[i]; /* Watch for changes */ this.settingsBoundIds.push(this._settings.connect('changed::' + setting.key, (function() { this.settings_manager.update(setting); }).bind(this))); if (setting.handler) { this.settingsBoundIds.push(this._settings.connect('changed::' + setting.key, function() { // TODO: Find a better way to handle settings being changed right as the extension starts up. try { setting.handler.call(this); } catch (error) { log('[Dynamic Panel Transparency] Error handling setting (' + setting.key + ') change.'); log(error); } })); } let parser = (setting.parser !== null ? setting.parser : function(input) { return input; }); let getter = function() { return parser(this.settings_manager[setting.name]); }; if (!setting.getter) { this['get_' + setting.name] = getter; } else { this[setting.getter] = getter; } } } function unbind() { for (let i = 0; i < this.settingsBoundIds.length; ++i) { this._settings.disconnect(this.settingsBoundIds[i]); } } /* Basic class to hold settings values */ class SettingsManager { constructor(settings, params) { this.values = []; this.settings = settings; for (let i = 0; i < params.length; ++i) { let setting = params[i]; this.values.push(setting); if (this.settings.list_keys().indexOf(setting.key) === -1 || !setting) continue; let variant = GLib.VariantType.new(setting.type); if (variant.is_array() || variant.is_tuple()) { this[setting.name] = this.settings.get_value(setting.key).deep_unpack(); } else { this[setting.name] = this.settings.get_value(setting.key).unpack(); } } } update(setting) { if (this.settings.list_keys().indexOf(setting.key) === -1) return; let variant = GLib.VariantType.new(setting.type); if (variant.is_array() || variant.is_tuple()) { this[setting.name] = this.settings.get_value(setting.key).deep_unpack(); } else { this[setting.name] = this.settings.get_value(setting.key).unpack(); } } } class AppSettingsManager { constructor(params, apps, path) { this.values = []; this.settings = {}; this.settingsBoundIds = {}; for (let setting_key of Object.keys(params)) { let setting = params[setting_key]; this[setting.name] = {}; this.values.push(setting); } for (let a = 0; a < apps.length; ++a) { let app_id = apps[a]; let app_path = path + app_id + '/'; let sett = null; let obj = Convenience.getSchemaObj(OVERRIDES_SCHEMA_ID); sett = new Gio.Settings({ path: app_path, settings_schema: obj }); this.settings[app_id] = sett; for (let setting_key of Object.keys(params)) { let setting = params[setting_key]; if (!setting || this.settings[app_id].list_keys().indexOf(setting.key) === -1) { continue; } if (!this.settingsBoundIds[app_id]) { this.settingsBoundIds[app_id] = []; } this.settingsBoundIds[app_id].push(this.settings[app_id].connect('changed::' + setting.key, (function() { this.update(setting, app_id); }).bind(this))); let variant = GLib.VariantType.new(setting.type); if (variant.is_array() || variant.is_tuple()) { this[setting.name][app_id] = this.settings[app_id].get_value(setting.key).deep_unpack(); } else { this[setting.name][app_id] = this.settings[app_id].get_value(setting.key).unpack(); } } } } update(setting, app_id) { if (!setting || this.settings[app_id].list_keys().indexOf(setting.key) === -1) return; let variant = GLib.VariantType.new(setting.type); if (!this[setting.name]) this[setting.name] = {}; if (variant.is_array() || variant.is_tuple()) { this[setting.name][app_id] = this.settings[app_id].get_value(setting.key).deep_unpack(); } else { this[setting.name][app_id] = this.settings[app_id].get_value(setting.key).unpack(); } } unbind() { for (let app_id of Object.keys(this.settings)) { for (let id of this.settingsBoundIds[app_id]) { this.settings[app_id].disconnect(id); } } } }