summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js
blob: 0583db33ad7931c238f002b544332f33008a11e9 (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
99
100
101
102
103
104
105
106
import GObject from 'gi://GObject';

/// An object to easily manage signals.
export const Connections = class Connections {
    constructor() {
        this.buffer = [];
    }

    /// Adds a connection.
    ///
    /// Takes as arguments:
    /// - an actor, which fires the signal
    /// - signal(s) (string or array of strings), which are watched for
    /// - a callback, which is called when the signal is fired
    connect(actor, signals, handler) {
        if (signals instanceof Array) {
            signals.forEach(signal => {
                let id = actor.connect(signal, handler);
                this.process_connection(actor, id);
            });
        } else {
            let id = actor.connect(signals, handler);
            this.process_connection(actor, id);
        }

    }

    /// Process the given actor and id.
    ///
    /// This makes sure that the signal is disconnected when the actor is
    /// destroyed, and that the signal can be managed through other Connections
    /// methods.
    process_connection(actor, id) {
        let infos = {
            actor: actor,
            id: id
        };

        // remove the signal when the actor is destroyed
        if (
            actor.connect &&
            (
                !(actor instanceof GObject.Object) ||
                GObject.signal_lookup('destroy', actor)
            )
        ) {
            let destroy_id = actor.connect('destroy', () => {
                actor.disconnect(id);
                actor.disconnect(destroy_id);

                let index = this.buffer.indexOf(infos);
                if (index >= 0) {
                    this.buffer.splice(index, 1);
                }
            });
            infos.destroy_id = destroy_id;
        }

        this.buffer.push(infos);
    }

    /// Disconnects every connection found for an actor.
    disconnect_all_for(actor) {
        // get every connection stored for the actor
        let actor_connections = this.buffer.filter(
            infos => infos.actor === actor
        );

        // remove each of them
        actor_connections.forEach(connection => {
            // disconnect
            try {
                connection.actor.disconnect(connection.id);
                if ('destroy_id' in connection)
                    connection.actor.disconnect(connection.destroy_id);
            } catch (e) {
                this._warn(`error removing connection: ${e}; continuing`);
            }

            // remove from buffer
            let index = this.buffer.indexOf(connection);
            this.buffer.splice(index, 1);
        });
    }

    /// Disconnect every connection for each actor.
    disconnect_all() {
        this.buffer.forEach(connection => {
            // disconnect
            try {
                connection.actor.disconnect(connection.id);
                if ('destroy_id' in connection)
                    connection.actor.disconnect(connection.destroy_id);
            } catch (e) {
                this._warn(`error removing connection: ${e}; continuing`);
            }
        });

        // reset buffer
        this.buffer = [];
    }

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