[gnome-shell] signalTracker: Add TransientSignalHolder class
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] signalTracker: Add TransientSignalHolder class
- Date: Sat, 5 Mar 2022 00:20:14 +0000 (UTC)
commit cf29ec2f2231a897d25b67fac151e49da451eaeb
Author: Florian Müllner <fmuellner gnome org>
Date: Fri Mar 4 23:32:24 2022 +0100
signalTracker: Add TransientSignalHolder class
There are cases where we want to connect to a number of signals
for the lifetime of an object, but also other signals for a
limited period (say: between show and hide).
It is currently not possible to use disconnectObject() for the
latter, because it will disconnect all signals.
To address this use case, add a small class that can be used as
a transient signal holder, while still benefiting from autocleanup
by proxying the real owner.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2221>
js/misc/signalTracker.js | 44 +++++++++++++++++++++++++++++++-------------
tests/unit/signalTracker.js | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 13 deletions(-)
---
diff --git a/js/misc/signalTracker.js b/js/misc/signalTracker.js
index b7aff10dc8..3e83be7341 100644
--- a/js/misc/signalTracker.js
+++ b/js/misc/signalTracker.js
@@ -1,6 +1,34 @@
-/* exported addObjectSignalMethods */
+/* exported TransientSignalHolder, addObjectSignalMethods */
const { GObject } = imports.gi;
+/**
+ * @private
+ * @param {Object} obj - an object
+ * @returns {bool} - true if obj has a 'destroy' GObject signal
+ */
+function _hasDestroySignal(obj) {
+ return obj instanceof GObject.Object &&
+ GObject.signal_lookup('destroy', obj);
+}
+
+var TransientSignalHolder = GObject.registerClass(
+class TransientSignalHolder extends GObject.Object {
+ static [GObject.signals] = {
+ 'destroy': {},
+ };
+
+ constructor(owner) {
+ super();
+
+ if (_hasDestroySignal(owner))
+ owner.connectObject('destroy', () => this.destroy(), this);
+ }
+
+ destroy() {
+ this.emit('destroy');
+ }
+});
+
class SignalManager {
/**
* @returns {SignalManager} - the SignalManager singleton
@@ -31,23 +59,13 @@ class SignalTracker {
* @param {Object=} owner - object that owns the tracker
*/
constructor(owner) {
- if (this._hasDestroySignal(owner))
+ if (_hasDestroySignal(owner))
this._ownerDestroyId = owner.connect_after('destroy', () => this.clear());
this._owner = owner;
this._map = new Map();
}
- /**
- * @private
- * @param {Object} obj - an object
- * @returns {bool} - true if obj has a 'destroy' GObject signal
- */
- _hasDestroySignal(obj) {
- return obj instanceof GObject.Object &&
- GObject.signal_lookup('destroy', obj);
- }
-
/**
* @typedef SignalData
* @property {number[]} ownerSignals - a list of handler IDs
@@ -89,7 +107,7 @@ class SignalTracker {
* @returns {void}
*/
track(obj, ...handlerIds) {
- if (this._hasDestroySignal(obj))
+ if (_hasDestroySignal(obj))
this._trackDestroy(obj);
this._getSignalData(obj).ownerSignals.push(...handlerIds);
diff --git a/tests/unit/signalTracker.js b/tests/unit/signalTracker.js
index f13327ec14..40398c0b8a 100644
--- a/tests/unit/signalTracker.js
+++ b/tests/unit/signalTracker.js
@@ -8,6 +8,8 @@ const JsUnit = imports.jsUnit;
const Signals = imports.signals;
const Environment = imports.ui.environment;
+const { TransientSignalHolder } = imports.misc.signalTracker;
+
Environment.init();
const Destroyable = GObject.registerClass({
@@ -77,3 +79,39 @@ emitter1.emit('signal');
emitter2.emit('signal');
JsUnit.assertEquals(count, 10);
+
+emitter1.connectObject('signal', handler, tracked1);
+emitter2.connectObject('signal', handler, tracked1);
+
+transientHolder = new TransientSignalHolder(tracked1);
+
+emitter1.connectObject('signal', handler, transientHolder);
+emitter2.connectObject('signal', handler, transientHolder);
+
+emitter1.emit('signal');
+emitter2.emit('signal');
+
+JsUnit.assertEquals(count, 14);
+
+transientHolder.destroy();
+
+emitter1.emit('signal');
+emitter2.emit('signal');
+
+JsUnit.assertEquals(count, 16);
+
+transientHolder = new TransientSignalHolder(tracked1);
+
+emitter1.connectObject('signal', handler, transientHolder);
+emitter2.connectObject('signal', handler, transientHolder);
+
+emitter1.emit('signal');
+emitter2.emit('signal');
+
+JsUnit.assertEquals(count, 20);
+
+tracked1.emit('destroy');
+emitter1.emit('signal');
+emitter2.emit('signal');
+
+JsUnit.assertEquals(count, 20);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]