summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js
blob: 8d17b6251f1e2b01de7b16ed3b927317bd70f039 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import GObject from 'gi://GObject';

function supports_destroy_signal(object) {
    const gtype = object?.constructor?.$gtype;
    return gtype && GObject.signal_lookup('destroy', gtype) !== 0;
}

export const Connections = class Connections {
    constructor() {
        this.records = new Map();
    }

    connect(object, signals, handler) {
        const names = Array.isArray(signals) ? signals : [signals];
        const record = this.get_record(object);
        const ids = [];

        for (const signal of names) {
            const id = object.connect(signal, handler);
            record.ids.add(id);
            ids.push(id);
        }
        return Array.isArray(signals) ? ids : ids[0];
    }

    get_record(object) {
        let record = this.records.get(object);
        if (record)
            return record;

        record = {
            ids: new Set(),
            destroy_id: null,
        };
        this.records.set(object, record);

        if (supports_destroy_signal(object))
            record.destroy_id = object.connect('destroy', () => {
                this.records.delete(object);
                record.ids.clear();
                record.destroy_id = null;
            });

        return record;
    }

    disconnect_all_for(object) {
        const record = this.records.get(object);
        if (!record)
            return;

        this.records.delete(object);
        for (const id of record.ids)
            this.raw_disconnect(object, id);
        if (record.destroy_id)
            this.raw_disconnect(object, record.destroy_id);
    }

    disconnect_all() {
        for (const object of [...this.records.keys()])
            this.disconnect_all_for(object);
    }

    disconnect(object, id) {
        const record = this.records.get(object);
        if (record)
            record.ids.delete(id);

        this.raw_disconnect(object, id);

        if (record && record.ids.size === 0) {
            this.records.delete(object);
            if (record.destroy_id)
                this.raw_disconnect(object, record.destroy_id);
        }
    }

    raw_disconnect(object, id) {
        if (!id)
            return;

        try {
            if (
                object instanceof GObject.Object
                && !GObject.signal_handler_is_connected(object, id)
            )
                return;

            object.disconnect(id);
        } catch (error) {
            this._warn(`error removing connection: ${error}; continuing`);
        }
    }

    _warn(str) {
        console.warn(`[Blur my Shell > connections]  ${str}`);
    }
};