From 1a4015544941057d12cb8811ada68df67171352b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Mon, 26 Aug 2024 17:38:18 -0400 Subject: [PATCH] utils: Remove signal handler item on object destruction If we're tracking an object destruction and that object gets destroyed, we need to remove the signals handler storage item, or we'd end up trying to disconnect from it again when destroying the signals handler. Closes: #2270 --- utils.js | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/utils.js b/utils.js index e8fb3adc5..2d0b00eda 100644 --- a/utils.js +++ b/utils.js @@ -110,6 +110,21 @@ const BasicHandler = class DashToDockBasicHandler { (this._storage[label] || []).forEach(item => this._unblock(item)); } + _removeByItem(item) { + Object.getOwnPropertySymbols(this._storage).forEach(label => + (this._storage[label] = this._storage[label].filter(it => { + if (it === item) + return false; + if (it.length === item.length && + it.every(i => item.includes(i)) && + item.every(i => it.includes(i))) { + this._remove(item); + return false; + } + return true; + }))); + } + // Virtual methods to be implemented by subclass /** @@ -168,15 +183,27 @@ export class GlobalSignalsHandler extends BasicHandler { `found in ${object.constructor.name}`); } + const item = [object]; + const isDestroy = event === 'destroy'; + const isParentObject = object === this._parentObject; + + if (isDestroy && !isParentObject) { + const originalCallback = callback; + callback = () => { + this._removeByItem(item); + originalCallback(); + }; + } const id = connector.call(object, event, callback); + item.push(id); - if (event === 'destroy' && object === this._parentObject) { + if (isDestroy && isParentObject) { this._parentObject.disconnect(this._destroyId); this._destroyId = this._parentObject.connect('destroy', () => this.destroy()); } - return [object, id]; + return item; } _remove(item) {