[gnome-shell] workspace: Simplify detecting added dialogs after closing a window



commit da2fc2c9d3135d59bb355e739f24d540f844fb3d
Author: verdre <gitlab v0yd nl>
Date:   Tue Jun 19 12:45:18 2018 +0200

    workspace: Simplify detecting added dialogs after closing a window
    
    When trying to close a window in the overview by clicking the close
    button and the window doesn't get closed but a dialog is added to the
    window afterwards, we close the overview and show the dialog.
    
    Instead of adding a separate listener for the window-added signal to the
    WindowOverlay, let the WindowClones remember that the close button was
    pressed and activate themselves if a dialog is added after that.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/180

 js/ui/workspace.js | 80 +++++++++++++++++++-----------------------------------
 1 file changed, 28 insertions(+), 52 deletions(-)
---
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 6a8e92447..5aa9ba66c 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -179,6 +179,7 @@ var WindowClone = new Lang.Class({
         this.inDrag = false;
 
         this._selected = false;
+        this._closeRequested = false;
     },
 
     set slot(slot) {
@@ -194,7 +195,6 @@ var WindowClone = new Lang.Class({
 
     deleteAll() {
         // Delete all windows, starting from the bottom-most (most-modal) one
-
         let windows = this.actor.get_children();
         for (let i = windows.length - 1; i >= 1; i--) {
             let realWindow = windows[i].source;
@@ -204,11 +204,24 @@ var WindowClone = new Lang.Class({
         }
 
         this.metaWindow.delete(global.get_current_time());
+        this._closeRequested = true;
     },
 
-    addAttachedDialog(win) {
-        this._doAddAttachedDialog(win, win.get_compositor_private());
-        this._onMetaWindowSizeChanged();
+    addDialog(win) {
+        let parent = win.get_transient_for();
+        while (parent.is_attached_dialog())
+            parent = parent.get_transient_for();
+
+        // Display dialog if it is attached to our metaWindow
+        if (win.is_attached_dialog() && parent == this.metaWindow) {
+            this._doAddAttachedDialog(win, win.get_compositor_private());
+            this._onMetaWindowSizeChanged();
+        }
+
+        // The dialog popped up after the user tried to close the window,
+        // assume it's a close confirmation and leave the overview
+        if (this._closeRequested)
+            this._activate();
     },
 
     hasAttachedDialogs() {
@@ -462,14 +475,12 @@ var WindowOverlay = new Lang.Class({
         button._overlap = 0;
 
         this._idleToggleCloseId = 0;
-        button.connect('clicked', this._closeWindow.bind(this));
+        button.connect('clicked', () => this._windowClone.deleteAll());
 
         windowClone.actor.connect('destroy', this._onDestroy.bind(this));
         windowClone.connect('show-chrome', this._onShowChrome.bind(this));
         windowClone.connect('hide-chrome', this._onHideChrome.bind(this));
 
-        this._windowAddedId = 0;
-
         button.hide();
         title.hide();
 
@@ -590,43 +601,12 @@ var WindowOverlay = new Lang.Class({
         Tweener.addTween(actor, params);
     },
 
-    _closeWindow(actor) {
-        let metaWindow = this._windowClone.metaWindow;
-        this._workspace = metaWindow.get_workspace();
-
-        this._windowAddedId = this._workspace.connect('window-added',
-                                                      this._onWindowAdded.bind(this));
-
-        this._windowClone.deleteAll();
-    },
-
     _windowCanClose() {
         return this._windowClone.metaWindow.can_close() &&
                !this._windowClone.hasAttachedDialogs();
     },
 
-    _onWindowAdded(workspace, win) {
-        let metaWindow = this._windowClone.metaWindow;
-
-        if (win.get_transient_for() == metaWindow) {
-            workspace.disconnect(this._windowAddedId);
-            this._windowAddedId = 0;
-
-            // use an idle handler to avoid mapping problems -
-            // see comment in Workspace._windowAdded
-            let id = Mainloop.idle_add(() => {
-                this._windowClone.emit('selected');
-                return GLib.SOURCE_REMOVE;
-            });
-            GLib.Source.set_name_by_id(id, '[gnome-shell] this._windowClone.emit');
-        }
-    },
-
     _onDestroy() {
-        if (this._windowAddedId > 0) {
-            this._workspace.disconnect(this._windowAddedId);
-            this._windowAddedId = 0;
-        }
         if (this._idleToggleCloseId > 0) {
             Mainloop.source_remove(this._idleToggleCloseId);
             this._idleToggleCloseId = 0;
@@ -1516,21 +1496,17 @@ var Workspace = new Lang.Class({
             return;
 
         if (!this._isOverviewWindow(win)) {
-            if (metaWin.is_attached_dialog()) {
-                let parent = metaWin.get_transient_for();
-                while (parent.is_attached_dialog())
-                    parent = parent.get_transient_for();
-
-                let idx = this._lookupIndex (parent);
-                if (idx < 0) {
-                    // parent was not created yet, it will take care
-                    // of the dialog when created
-                    return;
-                }
+            if (metaWin.get_transient_for() == null)
+                return;
 
-                let clone = this._windows[idx];
-                clone.addAttachedDialog(metaWin);
-            }
+            // Let the top-most ancestor handle all transients
+            let parent = metaWin.find_root_ancestor();
+            let clone = this._windows.find(c => c.metaWindow == parent);
+
+            // If no clone was found, the parent hasn't been created yet
+            // and will take care of the dialog when added
+            if (clone)
+                clone.addDialog(metaWin);
 
             return;
         }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]