From d734b117e05703c8834d18151d1f0491d76e95ef Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 28 Jun 2018 17:33:15 +0200 Subject: [PATCH 1/2] 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. --- js/ui/workspace.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/js/ui/workspace.js b/js/ui/workspace.js index 5aa9ba66ca..f09f487142 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -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(); -- GitLab From c8ea06be264ba794986ecb3fa3e47337c1a872db Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 28 Jun 2018 18:08:46 +0200 Subject: [PATCH 2/2] workspaceThumbnail: Pass MetaWindow to _updateDialogPosition This function was mistakenly called with a MetaWindow as first argument inside the ::position-changed callback, instead of a MetaWindowActor as it should. However, that function quickly grabs the MetaWindow from the actor, and all calling places have the MetaWindow readily available, so switch to handing it as first function parameter. Fixes warnings on ::position-changed, because of the aforementioned typo. --- js/ui/workspaceThumbnail.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js index cf21e13170..b648821479 100644 --- a/js/ui/workspaceThumbnail.js +++ b/js/ui/workspaceThumbnail.js @@ -151,7 +151,7 @@ var WindowClone = new Lang.Class({ _doAddAttachedDialog(metaDialog, realDialog) { let clone = new Clutter.Clone({ source: realDialog }); - this._updateDialogPosition(realDialog, clone); + this._updateDialogPosition(metaDialog, clone); clone._updateId = realDialog.connect('notify::position', dialog => { this._updateDialogPosition(dialog, clone); @@ -162,8 +162,7 @@ var WindowClone = new Lang.Class({ this.actor.add_child(clone); }, - _updateDialogPosition(realDialog, cloneDialog) { - let metaDialog = realDialog.meta_window; + _updateDialogPosition(metaDialog, cloneDialog) { let dialogRect = metaDialog.get_frame_rect(); let rect = this.metaWindow.get_frame_rect(); -- GitLab