summaryrefslogtreecommitdiffstats
path: root/extensions/46/middleclickclose/src/settingsWatch.js
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/46/middleclickclose/src/settingsWatch.js')
-rw-r--r--extensions/46/middleclickclose/src/settingsWatch.js87
1 files changed, 87 insertions, 0 deletions
diff --git a/extensions/46/middleclickclose/src/settingsWatch.js b/extensions/46/middleclickclose/src/settingsWatch.js
new file mode 100644
index 0000000..fd8b8bd
--- /dev/null
+++ b/extensions/46/middleclickclose/src/settingsWatch.js
@@ -0,0 +1,87 @@
+export class SettingsWatch {
+ #settings;
+ #key_data = new Map();
+
+ constructor(settings, ...opts) {
+ this.#settings = settings;
+
+ for (const opt of opts) {
+ if (typeof opt == 'string') {
+ this.#addSetting(opt, {});
+ } else {
+ for (const [prop_name, opts] of Object.entries(opt)) {
+ this.#addSetting(prop_name, opts)
+ }
+ }
+ }
+ }
+
+ #addSetting(prop_name, opts) {
+ let key;
+ if (typeof opts == 'string') {
+ key = opts;
+ opts = {};
+ } else {
+ key = opts.key ?? prop_name.replace('_', '-');
+ }
+
+ const settings = this.#settings;
+ const raw_getter = opts.get_raw ?? this.#defaultRawGetter(settings, key);
+ const getter = opts.get ?? (x => x);
+
+ const update_cb = () => {
+ let value = getter(raw_getter(settings.get_value(key)));
+ this.#key_data.get(prop_name).value = value;
+
+ return value;
+ };
+
+ this.#key_data.set(prop_name, {});
+ Object.defineProperty(this, prop_name, {
+ enumerable: true,
+ configurable: true,
+ get() {
+ let data = this.#key_data.get(prop_name);
+ if (data.value === undefined) {
+ data.handler_id = settings.connect('changed::' + key, update_cb);
+ data.value = update_cb();
+ }
+
+ return data.value;
+ }
+ });
+ }
+
+ #defaultRawGetter(settings, key) {
+ const schema = settings.settings_schema.get_key(key);
+ const [range_ty, _range] = schema.get_range().recursiveUnpack();
+
+ if (range_ty == "enum") {
+ return value => {
+ return {
+ nick: value.unpack(),
+
+ // FIXME: remove unnecessary lookup if/when g_settings_schema_key_to_enum()
+ // becomes available. But for now, an extra lookup will have to do.
+ value: settings.get_enum(key),
+ };
+ };
+ }
+
+ return value => value.recursiveUnpack();
+ }
+
+ clear() {
+ for (const [key, data] of this.#key_data.entries()) {
+ if (data.handler_id !== undefined)
+ this.#settings.disconnect(data.handler_id);
+
+ delete this[key];
+ }
+
+ this.#key_data.clear();
+ }
+}
+
+// Allow calling clear as a static function.
+SettingsWatch.clear = obj => SettingsWatch.prototype.clear.apply(obj);