workspace: Keep accounting of attached dialogs

We may end up with window-added emitted multiple times on the
same window, which results on:

1) Extra clones being created, all taking the same size and
   stacking.
2) JS exceptions because handle each clone actor being destroyed
   one by one, but all clones already have a NULL source when the
   first destroy handler is called, so we step on null objects
   inside _computeBoundingBox().

Keep accounting of those windows in order to avoid multiple
additions, which fixes both issues.
This commit is contained in:
Carlos Garnacho 2018-06-28 17:33:15 +02:00
parent 6b610b26f8
commit d734b117e0

View File

@ -110,6 +110,7 @@ var WindowClone = new Lang.Class({
this.metaWindow = realWindow.meta_window;
this.metaWindow._delegate = this;
this._workspace = workspace;
this._attachedDialogs = [];
this._windowClone = new Clutter.Clone({ source: realWindow });
// We expect this.actor to be used for all interaction rather than
@ -208,6 +209,12 @@ var WindowClone = new Lang.Class({
},
addDialog(win) {
let realWin = win.get_compositor_private();
if (this._attachedDialogs.includes(realWin))
return;
this._attachedDialogs.push(realWin);
let parent = win.get_transient_for();
while (parent.is_attached_dialog())
parent = parent.get_transient_for();
@ -225,7 +232,7 @@ var WindowClone = new Lang.Class({
},
hasAttachedDialogs() {
return this.actor.get_n_children() > 1;
return this._attachedDialogs.length > 1;
},
_doAddAttachedDialog(metaWin, realWin) {
@ -235,6 +242,9 @@ var WindowClone = new Lang.Class({
clone._posChangedId = metaWin.connect('position-changed',
this._onMetaWindowSizeChanged.bind(this));
clone._destroyId = realWin.connect('destroy', () => {
let idx = this._attachedDialogs.indexOf(realWin);
this._attachedDialogs.splice(idx, 1);
clone.destroy();
this._onMetaWindowSizeChanged();