[gnome-shell] grabHelper: Rework grabbing code to properly handle stacking



commit b203a95a786af60257e55881c19b45192a0655b8
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sat Sep 15 02:38:40 2012 -0300

    grabHelper: Rework grabbing code to properly handle stacking
    
    When Dan Winship wrote the GrabHelper code originally, it didn't
    handle a grab stack. I wrote the grab stack code hastily when landed
    the message tray, not understanding all of the code that was involved
    here.
    
    Fix it so that we properly do the operations for each type of grab
    when we first need to, and not sometimes when the first grab is taken.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=683546

 js/ui/grabHelper.js |  164 ++++++++++++++++++++++++++-------------------------
 1 files changed, 83 insertions(+), 81 deletions(-)
---
diff --git a/js/ui/grabHelper.js b/js/ui/grabHelper.js
index 7120043..fee72c5 100644
--- a/js/ui/grabHelper.js
+++ b/js/ui/grabHelper.js
@@ -156,19 +156,14 @@ const GrabHelper = new Lang.Class({
         if (this.isActorGrabbed(params.actor))
             return true;
 
-        if (this._grabFocusCount == 0 && this._modalCount == 0) {
-            if (!this._fullGrab(hadFocus, params.modal, params.grabFocus))
-                return false;
-        }
-
         params.savedFocus = focus;
         this._grabStack.push(params);
 
         if (params.modal)
-            this._modalCount++;
+            this._takeModalGrab(hadFocus);
 
         if (params.grabFocus)
-            this._grabFocusCount++;
+            this._takeFocusGrab(hadFocus);
 
         if (hadFocus || params.grabFocus)
             _navigateActor(newFocus);
@@ -176,34 +171,89 @@ const GrabHelper = new Lang.Class({
         return true;
     },
 
-    _fullGrab: function(hadFocus, modal, grabFocus) {
-        let metaDisplay = global.screen.get_display();
+    _takeModalGrab: function(hadFocus) {
+        let firstGrab = (this._modalCount == 0);
+        this._modalCount++;
+        if (!firstGrab)
+            return;
+
+        if (!Main.pushModal(this._owner))
+            return;
+
+        this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
+        this._eventId = global.stage.connect('event', Lang.bind(this, this._onEvent));
+    },
+
+    _releaseModalGrab: function() {
+        this._modalCount--;
+        if (this._modalCount > 0)
+            return;
+
+        if (this._capturedEventId > 0) {
+            global.stage.disconnect(this._capturedEventId);
+            this._capturedEventId = 0;
+        }
 
-        if (modal) {
-            if (!Main.pushModal(this._owner))
-                return false;
+        if (this._eventId > 0) {
+            global.stage.disconnect(this._eventId);
+            this._eventId = 0;
         }
 
-        this._grabbedFromKeynav = hadFocus;
+        Main.popModal(this._owner);
+        global.sync_pointer();
+    },
+
+    _takeFocusGrab: function() {
+        let firstGrab = (this._grabFocusCount == 0);
+        this._grabFocusCount++;
+        if (!firstGrab)
+            return;
+
+        let metaDisplay = global.screen.get_display();
+
         this._preGrabInputMode = global.stage_input_mode;
-        this._prevFocusedWindow = null;
+        this._prevFocusedWindow = metaDisplay.focus_window;
 
-        if (grabFocus) {
-            this._prevFocusedWindow = metaDisplay.focus_window;
-            if (this._preGrabInputMode == Shell.StageInputMode.NONREACTIVE ||
-                this._preGrabInputMode == Shell.StageInputMode.NORMAL) {
-                global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
-            }
+        if (this._preGrabInputMode == Shell.StageInputMode.NONREACTIVE ||
+            this._preGrabInputMode == Shell.StageInputMode.NORMAL) {
+            global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
         }
 
-        if (modal || grabFocus) {
-            this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
-            this._eventId = global.stage.connect('event', Lang.bind(this, this._onEvent));
-            this._keyFocusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
-            this._focusWindowChangedId = metaDisplay.connect('notify::focus-window', Lang.bind(this, this._focusWindowChanged));
+        this._keyFocusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
+        this._focusWindowChangedId = metaDisplay.connect('notify::focus-window', Lang.bind(this, this._focusWindowChanged));
+    },
+
+    _releaseFocusGrab: function() {
+        this._grabFocusCount--;
+        if (this._grabFocusCount > 0)
+            return;
+
+        if (this._keyFocusNotifyId > 0) {
+            global.stage.disconnect(this._keyFocusNotifyId);
+            this._keyFocusNotifyId = 0;
         }
 
-        return true;
+        if (!this._focusWindowChanged > 0) {
+            let metaDisplay = global.screen.get_display();
+            metaDisplay.disconnect(this._focusWindowChangedId);
+            this._focusWindowChangedId = 0;
+        }
+
+        let prePopInputMode = global.stage_input_mode;
+
+        if (this._grabbedFromKeynav) {
+            if (this._preGrabInputMode == Shell.StageInputMode.FOCUSED &&
+                prePopInputMode != Shell.StageInputMode.FULLSCREEN)
+                global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
+        }
+
+        if (this._prevFocusedWindow) {
+            let metaDisplay = global.screen.get_display();
+            if (!metaDisplay.focus_window) {
+                metaDisplay.set_input_focus_window(this._prevFocusedWindow,
+                                                   false, global.get_current_time());
+            }
+        }
     },
 
     // ignoreRelease:
@@ -230,12 +280,14 @@ const GrabHelper = new Lang.Class({
         if (grabStackIndex < 0)
             return;
 
+        let focus = global.stage.key_focus;
+        let hadFocus = focus && this._isWithinGrabbedActor(focus);
+
         let poppedGrabs = this._grabStack.slice(grabStackIndex);
         // "Pop" all newly ungrabbed actors off the grab stack
         // by truncating the array.
         this._grabStack.length = grabStackIndex;
 
-        let wasModal = this._modalCount > 0;
         for (let i = poppedGrabs.length - 1; i >= 0; i--) {
             let poppedGrab = poppedGrabs[i];
 
@@ -243,65 +295,15 @@ const GrabHelper = new Lang.Class({
                 poppedGrab.onUngrab();
 
             if (poppedGrab.modal)
-                this._modalCount--;
+                this._releaseModalGrab();
 
             if (poppedGrab.grabFocus)
-                this._grabFocusCount--;
+                this._releaseFocusGrab();
         }
 
-        let focus = global.stage.key_focus;
-        let hadFocus = focus && this._isWithinGrabbedActor(focus);
-
-        if (this._grabFocusCount == 0 && this._modalCount == 0)
-            this._fullUngrab(wasModal);
-
-        let poppedGrab = poppedGrabs[0];
-
-        if (hadFocus)
+        if (hadFocus) {
+            let poppedGrab = poppedGrabs[0];
             _navigateActor(poppedGrab.savedFocus);
-    },
-
-    _fullUngrab: function(wasModal) {
-        if (this._capturedEventId > 0) {
-            global.stage.disconnect(this._capturedEventId);
-            this._capturedEventId = 0;
-        }
-
-        if (this._eventId > 0) {
-            global.stage.disconnect(this._eventId);
-            this._eventId = 0;
-        }
-
-        if (this._keyFocusNotifyId > 0) {
-            global.stage.disconnect(this._keyFocusNotifyId);
-            this._keyFocusNotifyId = 0;
-        }
-
-        if (!this._focusWindowChanged > 0) {
-            let metaDisplay = global.screen.get_display();
-            metaDisplay.disconnect(this._focusWindowChangedId);
-            this._focusWindowChangedId = 0;
-        }
-
-        let prePopInputMode = global.stage_input_mode;
-
-        if (wasModal) {
-            Main.popModal(this._owner);
-            global.sync_pointer();
-        }
-
-        if (this._grabbedFromKeynav) {
-            if (this._preGrabInputMode == Shell.StageInputMode.FOCUSED &&
-                prePopInputMode != Shell.StageInputMode.FULLSCREEN)
-                global.set_stage_input_mode(Shell.StageInputMode.FOCUSED);
-        }
-
-        if (this._prevFocusedWindow) {
-            let metaDisplay = global.screen.get_display();
-            if (!metaDisplay.focus_window) {
-                metaDisplay.set_input_focus_window(this._prevFocusedWindow,
-                                                   false, global.get_current_time());
-            }
         }
     },
 



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