225 lines
11 KiB
Diff
225 lines
11 KiB
Diff
|
From 76eebb42ed4c76970a9debfc0cd41537923eccde Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
|
||
|
Date: Tue, 5 Dec 2017 02:41:50 +0100
|
||
|
Subject: [PATCH 1/2] tweener: Save handlers on target and remove them on
|
||
|
destroy
|
||
|
|
||
|
Saving handlers we had using the wrapper as a property of the object and delete
|
||
|
them when resetting the object state.
|
||
|
Without doing this an handler could be called on a destroyed target when this
|
||
|
happens on the onComplete callback.
|
||
|
|
||
|
https://bugzilla.gnome.org/show_bug.cgi?id=791233
|
||
|
---
|
||
|
js/ui/tweener.js | 63 ++++++++++++++++++++++++++++++++++++++----------
|
||
|
1 file changed, 50 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/js/ui/tweener.js b/js/ui/tweener.js
|
||
|
index bb9ea557c..c04cede25 100644
|
||
|
--- a/js/ui/tweener.js
|
||
|
+++ b/js/ui/tweener.js
|
||
|
@@ -63,30 +63,67 @@ function _getTweenState(target) {
|
||
|
return target.__ShellTweenerState;
|
||
|
}
|
||
|
|
||
|
+function _ensureHandlers(target) {
|
||
|
+ if (!target.__ShellTweenerHandlers)
|
||
|
+ target.__ShellTweenerHandlers = {};
|
||
|
+ return target.__ShellTweenerHandlers;
|
||
|
+}
|
||
|
+
|
||
|
function _resetTweenState(target) {
|
||
|
let state = target.__ShellTweenerState;
|
||
|
|
||
|
if (state) {
|
||
|
- if (state.destroyedId)
|
||
|
+ if (state.destroyedId) {
|
||
|
state.actor.disconnect(state.destroyedId);
|
||
|
+ delete state.destroyedId;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
+ _removeHandler(target, 'onComplete', _tweenCompleted);
|
||
|
target.__ShellTweenerState = {};
|
||
|
}
|
||
|
|
||
|
function _addHandler(target, params, name, handler) {
|
||
|
- if (params[name]) {
|
||
|
- let oldHandler = params[name];
|
||
|
- let oldScope = params[name + 'Scope'];
|
||
|
- let oldParams = params[name + 'Params'];
|
||
|
- let eventScope = oldScope ? oldScope : target;
|
||
|
-
|
||
|
- params[name] = () => {
|
||
|
- oldHandler.apply(eventScope, oldParams);
|
||
|
- handler(target);
|
||
|
- };
|
||
|
- } else
|
||
|
- params[name] = () => { handler(target); };
|
||
|
+ let wrapperNeeded = false;
|
||
|
+ let tweenerHandlers = _ensureHandlers(target);
|
||
|
+
|
||
|
+ if (!(name in tweenerHandlers)) {
|
||
|
+ tweenerHandlers[name] = [];
|
||
|
+ wrapperNeeded = true;
|
||
|
+ }
|
||
|
+
|
||
|
+ let handlers = tweenerHandlers[name];
|
||
|
+ handlers.push(handler);
|
||
|
+
|
||
|
+ if (wrapperNeeded) {
|
||
|
+ if (params[name]) {
|
||
|
+ let oldHandler = params[name];
|
||
|
+ let oldScope = params[name + 'Scope'];
|
||
|
+ let oldParams = params[name + 'Params'];
|
||
|
+ let eventScope = oldScope ? oldScope : target;
|
||
|
+
|
||
|
+ params[name] = () => {
|
||
|
+ oldHandler.apply(eventScope, oldParams);
|
||
|
+ handlers.forEach((h) => h(target));
|
||
|
+ };
|
||
|
+ } else {
|
||
|
+ params[name] = () => { handlers.forEach((h) => h(target)); };
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+function _removeHandler(target, name, handler) {
|
||
|
+ let tweenerHandlers = _ensureHandlers(target);
|
||
|
+
|
||
|
+ if (name in tweenerHandlers) {
|
||
|
+ let handlers = tweenerHandlers[name];
|
||
|
+ let handlerIndex = handlers.indexOf(handler);
|
||
|
+
|
||
|
+ while (handlerIndex > -1) {
|
||
|
+ handlers.splice(handlerIndex, 1);
|
||
|
+ handlerIndex = handlers.indexOf(handler);
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
function _actorDestroyed(target) {
|
||
|
--
|
||
|
2.21.0
|
||
|
|
||
|
|
||
|
From 730f6f7d708a0cbcfcc75e4a1fba8512ac7c4c82 Mon Sep 17 00:00:00 2001
|
||
|
From: Cosimo Cecchi <cosimo@endlessm.com>
|
||
|
Date: Sun, 26 May 2019 08:31:07 -0700
|
||
|
Subject: [PATCH 2/2] windowAttentionHandler: disconnect signals before
|
||
|
destruction
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
The 'destroy' signal is emitted at the end of the destroy() method.
|
||
|
However the implementation of destroy() can end up emitting one of the
|
||
|
signals we connect to on the window, causing us to re-enter destroy
|
||
|
from its callback.
|
||
|
That will in turn lead to some objects getting disposed twice, which
|
||
|
produces a stack trace like the following one.
|
||
|
|
||
|
This commit fixes the issue by overriding the destroy() method instead
|
||
|
of connecting to the signal, which allows us to disconnect the signal
|
||
|
handlers from the window at an earlier time and avoid re-entrancy.
|
||
|
|
||
|
--
|
||
|
|
||
|
gnome-shell[1082]: Object Gio.Settings (0x7f0af8143f00), has been already deallocated — impossible to access it. This might be caused by the object having been destroyed from C code using something such as destroy(), dispose(), or remove() vfuncs.
|
||
|
org.gnome.Shell.desktop[1082]: == Stack trace for context 0x5627f7d1e220 ==
|
||
|
org.gnome.Shell.desktop[1082]: #0 5627f9e801a8 i resource:///org/gnome/shell/ui/messageTray.js:238 (7f0aefa9eca0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #1 5627f9e80108 i resource:///org/gnome/shell/ui/messageTray.js:802 (7f0aefaa2ee0 @ 28)
|
||
|
org.gnome.Shell.desktop[1082]: #2 5627f9e80070 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:79 (7f0aef7b29d0 @ 62)
|
||
|
org.gnome.Shell.desktop[1082]: #3 7fffa69fbfc0 b self-hosted:979 (7f0aefa515e0 @ 440)
|
||
|
org.gnome.Shell.desktop[1082]: #4 5627f9e7ffe0 i resource:///org/gnome/shell/ui/messageTray.js:121 (7f0aefa9e1f0 @ 71)
|
||
|
org.gnome.Shell.desktop[1082]: #5 5627f9e7ff38 i resource:///org/gnome/shell/ui/messageTray.js:1408 (7f0aefaa58b0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #6 5627f9e7fe80 i resource:///org/gnome/shell/ui/messageTray.js:1237 (7f0aefaa51f0 @ 729)
|
||
|
org.gnome.Shell.desktop[1082]: #7 5627f9e7fde8 i resource:///org/gnome/shell/ui/messageTray.js:1055 (7f0aefaa3d30 @ 124)
|
||
|
org.gnome.Shell.desktop[1082]: #8 7fffa69ff8e0 b self-hosted:979 (7f0aefa515e0 @ 440)
|
||
|
org.gnome.Shell.desktop[1082]: #9 7fffa69ff9d0 b resource:///org/gnome/gjs/modules/signals.js:142 (7f0aefccb670 @ 386)
|
||
|
org.gnome.Shell.desktop[1082]: #10 5627f9e7fd58 i resource:///org/gnome/shell/ui/messageTray.js:479 (7f0aefaa0940 @ 50)
|
||
|
org.gnome.Shell.desktop[1082]: #11 5627f9e7fcb8 i resource:///org/gnome/shell/ui/messageTray.js:808 (7f0aefaa2ee0 @ 99)
|
||
|
org.gnome.Shell.desktop[1082]: #12 5627f9e7fc28 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:69 (7f0aef7b28b0 @ 13)
|
||
|
org.gnome.Shell.desktop[1082]: #13 5627f9e7fb80 i resource:///org/gnome/shell/ui/main.js:566 (7f0aefcd8820 @ 216)
|
||
|
org.gnome.Shell.desktop[1082]: #14 5627f9e7fad0 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:103 (7f0aef7b2c10 @ 27)
|
||
|
org.gnome.Shell.desktop[1082]: #15 5627f9e7fa58 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:43 (7f0aef7b2700 @ 17)
|
||
|
org.gnome.Shell.desktop[1082]: #16 7fffa6a03350 b resource:///org/gnome/gjs/modules/signals.js:142 (7f0aefccb670 @ 386)
|
||
|
org.gnome.Shell.desktop[1082]: #17 5627f9e7f9d0 i resource:///org/gnome/shell/ui/messageTray.js:471 (7f0aefaa08b0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #18 5627f9e7f950 i resource:///org/gnome/shell/ui/calendar.js:752 (7f0aefaabdc0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #19 7fffa6a048f0 b self-hosted:979 (7f0aefa515e0 @ 440)
|
||
|
org.gnome.Shell.desktop[1082]: == Stack trace for context 0x5627f7d1e220 ==
|
||
|
org.gnome.Shell.desktop[1082]: #0 5627f9e801a8 i resource:///org/gnome/shell/ui/messageTray.js:239 (7f0aefa9eca0 @ 42)
|
||
|
org.gnome.Shell.desktop[1082]: #1 5627f9e80108 i resource:///org/gnome/shell/ui/messageTray.js:802 (7f0aefaa2ee0 @ 28)
|
||
|
org.gnome.Shell.desktop[1082]: #2 5627f9e80070 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:79 (7f0aef7b29d0 @ 62)
|
||
|
org.gnome.Shell.desktop[1082]: #3 7fffa69fbfc0 b self-hosted:979 (7f0aefa515e0 @ 440)
|
||
|
org.gnome.Shell.desktop[1082]: #4 5627f9e7ffe0 i resource:///org/gnome/shell/ui/messageTray.js:121 (7f0aefa9e1f0 @ 71)
|
||
|
org.gnome.Shell.desktop[1082]: #5 5627f9e7ff38 i resource:///org/gnome/shell/ui/messageTray.js:1408 (7f0aefaa58b0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #6 5627f9e7fe80 i resource:///org/gnome/shell/ui/messageTray.js:1237 (7f0aefaa51f0 @ 729)
|
||
|
org.gnome.Shell.desktop[1082]: #7 5627f9e7fde8 i resource:///org/gnome/shell/ui/messageTray.js:1055 (7f0aefaa3d30 @ 124)
|
||
|
org.gnome.Shell.desktop[1082]: #8 7fffa69ff8e0 b self-hosted:979 (7f0aefa515e0 @ 440)
|
||
|
org.gnome.Shell.desktop[1082]: #9 7fffa69ff9d0 b resource:///org/gnome/gjs/modules/signals.js:142 (7f0aefccb670 @ 386)
|
||
|
org.gnome.Shell.desktop[1082]: #10 5627f9e7fd58 i resource:///org/gnome/shell/ui/messageTray.js:479 (7f0aefaa0940 @ 50)
|
||
|
org.gnome.Shell.desktop[1082]: #11 5627f9e7fcb8 i resource:///org/gnome/shell/ui/messageTray.js:808 (7f0aefaa2ee0 @ 99)
|
||
|
org.gnome.Shell.desktop[1082]: #12 5627f9e7fc28 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:69 (7f0aef7b28b0 @ 13)
|
||
|
org.gnome.Shell.desktop[1082]: #13 5627f9e7fb80 i resource:///org/gnome/shell/ui/main.js:566 (7f0aefcd8820 @ 216)
|
||
|
org.gnome.Shell.desktop[1082]: #14 5627f9e7fad0 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:103 (7f0aef7b2c10 @ 27)
|
||
|
org.gnome.Shell.desktop[1082]: #15 5627f9e7fa58 i resource:///org/gnome/shell/ui/windowAttentionHandler.js:43 (7f0aef7b2700 @ 17)
|
||
|
org.gnome.Shell.desktop[1082]: #16 7fffa6a03350 b resource:///org/gnome/gjs/modules/signals.js:142 (7f0aefccb670 @ 386)
|
||
|
org.gnome.Shell.desktop[1082]: #17 5627f9e7f9d0 i resource:///org/gnome/shell/ui/messageTray.js:471 (7f0aefaa08b0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #18 5627f9e7f950 i resource:///org/gnome/shell/ui/calendar.js:752 (7f0aefaabdc0 @ 22)
|
||
|
org.gnome.Shell.desktop[1082]: #19 7fffa6a048f0 b self-hosted:979 (7f0aefa515e0 @ 440)
|
||
|
gnome-shell[1082]: g_object_run_dispose: assertion 'G_IS_OBJECT (object)' failed
|
||
|
gnome-shell[1082]: Object Gio.Settings (0x7f0af8161750), has been already deallocated — impossible to access it. This might be caused by the object having been destroyed from C code using something such as destroy(), dispose(), or remove() vfuncs.
|
||
|
gnome-shell[1082]: g_object_run_dispose: assertion 'G_IS_OBJECT (object)' failed
|
||
|
|
||
|
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/555
|
||
|
---
|
||
|
js/ui/windowAttentionHandler.js | 17 ++++++++---------
|
||
|
1 file changed, 8 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git a/js/ui/windowAttentionHandler.js b/js/ui/windowAttentionHandler.js
|
||
|
index abdb8a444..a9a7111ba 100644
|
||
|
--- a/js/ui/windowAttentionHandler.js
|
||
|
+++ b/js/ui/windowAttentionHandler.js
|
||
|
@@ -69,8 +69,6 @@ var Source = class WindowAttentionSource extends MessageTray.Source {
|
||
|
() => { this.destroy(); }));
|
||
|
this.signalIDs.push(this._window.connect('unmanaged',
|
||
|
() => { this.destroy(); }));
|
||
|
-
|
||
|
- this.connect('destroy', this._onDestroy.bind(this));
|
||
|
}
|
||
|
|
||
|
_sync() {
|
||
|
@@ -79,13 +77,6 @@ var Source = class WindowAttentionSource extends MessageTray.Source {
|
||
|
this.destroy();
|
||
|
}
|
||
|
|
||
|
- _onDestroy() {
|
||
|
- for(let i = 0; i < this.signalIDs.length; i++) {
|
||
|
- this._window.disconnect(this.signalIDs[i]);
|
||
|
- }
|
||
|
- this.signalIDs = [];
|
||
|
- }
|
||
|
-
|
||
|
_createPolicy() {
|
||
|
if (this._app && this._app.get_app_info()) {
|
||
|
let id = this._app.get_id().replace(/\.desktop$/,'');
|
||
|
@@ -99,6 +90,14 @@ var Source = class WindowAttentionSource extends MessageTray.Source {
|
||
|
return this._app.create_icon_texture(size);
|
||
|
}
|
||
|
|
||
|
+ destroy(params) {
|
||
|
+ for (let i = 0; i < this.signalIDs.length; i++)
|
||
|
+ this._window.disconnect(this.signalIDs[i]);
|
||
|
+ this.signalIDs = [];
|
||
|
+
|
||
|
+ super.destroy(params);
|
||
|
+ }
|
||
|
+
|
||
|
open() {
|
||
|
Main.activateWindow(this._window);
|
||
|
}
|
||
|
--
|
||
|
2.21.0
|
||
|
|