signalTracker: Explicitly register destroyable types

We currently assume that any '::destroy' signal on a GObject type
has the semantics of the ClutterActor/GtkWidget signal, and should
therefore result in all signals being disconnected.

But we already have a case where the assumption doesn't hold: ShellWM
uses '::destroy' for the closing animation of windows, and the ShellWM
object itself remains very valid after the emission.

So rather than making assumptions about '::destroy', check objects
against a list of destroyable types that are explicitly registered
as such.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2226>
This commit is contained in:
Florian Müllner
2022-03-06 00:30:16 +01:00
committed by Marge Bot
parent ba23279f1f
commit fc4f9f61fa
4 changed files with 27 additions and 3 deletions

View File

@ -1,14 +1,15 @@
/* exported TransientSignalHolder, addObjectSignalMethods */
const { GObject } = imports.gi;
const destroyableTypes = [];
/**
* @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);
return destroyableTypes.some(type => obj instanceof type);
}
var TransientSignalHolder = GObject.registerClass(
@ -28,6 +29,7 @@ class TransientSignalHolder extends GObject.Object {
this.emit('destroy');
}
});
registerDestroyableType(TransientSignalHolder);
class SignalManager {
/**
@ -230,3 +232,19 @@ function addObjectSignalMethods(proto) {
};
proto['disconnect_object'] = proto['disconnectObject'];
}
/**
* Register a GObject type as having a 'destroy' signal
* that should disconnect all handlers
*
* @param {GObject.Type} gtype - a GObject type
*/
function registerDestroyableType(gtype) {
if (!GObject.type_is_a(gtype, GObject.Object))
throw new Error(`${gtype} is not a GObject subclass`);
if (!GObject.signal_lookup('destroy', gtype))
throw new Error(`${gtype} does not have a destroy signal`);
destroyableTypes.push(gtype);
}