[gnome-shell/wip/rstrode/rhel-8.0.0: 38/50] tweener: Save handlers on target and remove them on destroy
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/rstrode/rhel-8.0.0: 38/50] tweener: Save handlers on target and remove them on destroy
- Date: Sun, 17 Feb 2019 17:32:02 +0000 (UTC)
commit c227be4325b1594ffd5ed718c5146718d726e238
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Tue Dec 5 02:41:50 2017 +0100
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 1a85e2fb1..22818ba4b 100644
--- a/js/ui/tweener.js
+++ b/js/ui/tweener.js
@@ -69,30 +69,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) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]