diff options
| author | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
|---|---|---|
| committer | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
| commit | 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch) | |
| tree | ab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-gnome-theme/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/promiseUtils.js | |
| parent | 5d94c0a7d44a2255b81815a52a7056a94a39842d (diff) | |
| download | RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip | |
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/promiseUtils.js')
| -rw-r--r-- | raveos-gnome-theme/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/promiseUtils.js | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/promiseUtils.js b/raveos-gnome-theme/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/promiseUtils.js new file mode 100644 index 0000000..2749b03 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/appindicatorsupport@rgcjonas.gmail.com/promiseUtils.js @@ -0,0 +1,324 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Meta from 'gi://GdkPixbuf'; + +import * as Signals from 'resource:///org/gnome/shell/misc/signals.js'; + +export class CancellablePromise extends Promise { + constructor(executor, cancellable) { + if (!(executor instanceof Function)) + throw TypeError('executor is not a function'); + + if (cancellable && !(cancellable instanceof Gio.Cancellable)) + throw TypeError('cancellable parameter is not a Gio.Cancellable'); + + let rejector; + let resolver; + super((resolve, reject) => { + resolver = resolve; + rejector = reject; + }); + + const {stack: promiseStack} = new Error(); + this._promiseStack = promiseStack; + + this._resolver = (...args) => { + resolver(...args); + this._resolved = true; + this._cleanup(); + }; + this._rejector = (...args) => { + rejector(...args); + this._rejected = true; + this._cleanup(); + }; + + if (!cancellable) { + executor(this._resolver, this._rejector); + return; + } + + this._cancellable = cancellable; + this._cancelled = cancellable.is_cancelled(); + if (this._cancelled) { + this._rejector(new GLib.Error(Gio.IOErrorEnum, + Gio.IOErrorEnum.CANCELLED, 'Promise cancelled')); + return; + } + + this._cancellationId = cancellable.connect(() => { + const id = this._cancellationId; + this._cancellationId = 0; + GLib.idle_add(GLib.PRIORITY_DEFAULT, () => cancellable.disconnect(id)); + this.cancel(); + }); + + executor(this._resolver, this._rejector); + } + + _cleanup() { + if (this._cancellationId) + this._cancellable.disconnect(this._cancellationId); + } + + get cancellable() { + return this._chainRoot._cancellable || null; + } + + get _chainRoot() { + return this._root ? this._root : this; + } + + then(...args) { + const ret = super.then(...args); + + /* Every time we call then() on this promise we'd get a new + * CancellablePromise however that won't have the properties that the + * root one has set, and then it won't be possible to cancel a promise + * chain from the last one. + * To allow this we keep track of the root promise, make sure that + * the same method on the root object is called during cancellation + * or any destruction method if you want this to work. */ + if (ret instanceof CancellablePromise) + ret._root = this._chainRoot; + + return ret; + } + + resolved() { + return !!this._chainRoot._resolved; + } + + rejected() { + return !!this._chainRoot._rejected; + } + + cancelled() { + return !!this._chainRoot._cancelled; + } + + pending() { + return !this.resolved() && !this.rejected(); + } + + cancel() { + if (this._root) { + this._root.cancel(); + return this; + } + + if (!this.pending()) + return this; + + this._cancelled = true; + const error = new GLib.Error(Gio.IOErrorEnum, + Gio.IOErrorEnum.CANCELLED, 'Promise cancelled'); + error.stack += `## Promise created at:\n${this._promiseStack}`; + this._rejector(error); + + return this; + } +} + +export class SignalConnectionPromise extends CancellablePromise { + constructor(object, signal, cancellable) { + if (arguments.length === 1 && object instanceof Function) { + super(object); + return; + } + + if (!(object.connect instanceof Function)) + throw new TypeError('Not a valid object'); + + if (object instanceof GObject.Object && + !GObject.signal_lookup(signal.split(':')[0], object.constructor.$gtype)) + throw new TypeError(`Signal ${signal} not found on object ${object}`); + + let id; + let destroyId; + super(resolve => { + let connectSignal; + if (object instanceof GObject.Object) + connectSignal = (sig, cb) => GObject.signal_connect(object, sig, cb); + else + connectSignal = (sig, cb) => object.connect(sig, cb); + + id = connectSignal(signal, (_obj, ...args) => { + if (!args.length) + resolve(); + else + resolve(args.length === 1 ? args[0] : args); + }); + + if (signal !== 'destroy' && + (!(object instanceof GObject.Object) || + GObject.signal_lookup('destroy', object.constructor.$gtype))) + destroyId = connectSignal('destroy', () => this.cancel()); + }, cancellable); + + this._object = object; + this._id = id; + this._destroyId = destroyId; + } + + _cleanup() { + if (this._id) { + let disconnectSignal; + + if (this._object instanceof GObject.Object) + disconnectSignal = id => GObject.signal_handler_disconnect(this._object, id); + else + disconnectSignal = id => this._object.disconnect(id); + + disconnectSignal(this._id); + if (this._destroyId) { + disconnectSignal(this._destroyId); + this._destroyId = 0; + } + this._object = null; + this._id = 0; + } + + super._cleanup(); + } + + get object() { + return this._chainRoot._object; + } +} + +export class GSourcePromise extends CancellablePromise { + constructor(gsource, priority, cancellable) { + if (arguments.length === 1 && gsource instanceof Function) { + super(gsource); + return; + } + + if (gsource.constructor.$gtype !== GLib.Source.$gtype) + throw new TypeError(`gsource ${gsource} is not of type GLib.Source`); + + if (priority === undefined) + priority = GLib.PRIORITY_DEFAULT; + else if (!Number.isInteger(priority)) + throw TypeError('Invalid priority'); + + super(resolve => { + gsource.set_priority(priority); + gsource.set_callback(() => { + resolve(); + return GLib.SOURCE_REMOVE; + }); + gsource.attach(null); + }, cancellable); + + this._gsource = gsource; + this._gsource.set_name(`[gnome-shell] ${this.constructor.name} ${ + new Error().stack.split('\n').filter(line => + !line.match(/misc\/promiseUtils\.js/))[0]}`); + + if (this.rejected()) + this._gsource.destroy(); + } + + get gsource() { + return this._chainRoot._gsource; + } + + _cleanup() { + if (this._gsource) { + this._gsource.destroy(); + this._gsource = null; + } + super._cleanup(); + } +} + +export class IdlePromise extends GSourcePromise { + constructor(priority, cancellable) { + if (arguments.length === 1 && priority instanceof Function) { + super(priority); + return; + } + + if (priority === undefined) + priority = GLib.PRIORITY_DEFAULT_IDLE; + + super(GLib.idle_source_new(), priority, cancellable); + } +} + +export class TimeoutPromise extends GSourcePromise { + constructor(interval, priority, cancellable) { + if (arguments.length === 1 && interval instanceof Function) { + super(interval); + return; + } + + if (!Number.isInteger(interval) || interval < 0) + throw TypeError('Invalid interval'); + + super(GLib.timeout_source_new(interval), priority, cancellable); + } +} + +export class TimeoutSecondsPromise extends GSourcePromise { + constructor(interval, priority, cancellable) { + if (arguments.length === 1 && interval instanceof Function) { + super(interval); + return; + } + + if (!Number.isInteger(interval) || interval < 0) + throw TypeError('Invalid interval'); + + super(GLib.timeout_source_new_seconds(interval), priority, cancellable); + } +} + +export class MetaLaterPromise extends CancellablePromise { + constructor(laterType, cancellable) { + if (arguments.length === 1 && laterType instanceof Function) { + super(laterType); + return; + } + + if (laterType && laterType.constructor.$gtype !== Meta.LaterType.$gtype) + throw new TypeError(`laterType ${laterType} is not of type Meta.LaterType`); + else if (!laterType) + laterType = Meta.LaterType.BEFORE_REDRAW; + + let id; + super(resolve => { + id = Meta.later_add(laterType, () => { + this.remove(); + resolve(); + return GLib.SOURCE_REMOVE; + }); + }, cancellable); + + this._id = id; + } + + _cleanup() { + if (this._id) { + Meta.later_remove(this._id); + this._id = 0; + } + super._cleanup(); + } +} + +export function _promisifySignals(proto) { + if (proto.connect_once) + return; + + proto.connect_once = function (signal, cancellable) { + return new SignalConnectionPromise(this, signal, cancellable); + }; +} + +_promisifySignals(GObject.Object.prototype); +_promisifySignals(Signals.EventEmitter.prototype); |