[gnome-shell/wip/pressure: 8/14] grabHelper: Make a full grab stack, rather than a one-time grab



commit 56e9f3490a21d842e32cec0decd9e829010bfc20
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Feb 29 19:08:06 2012 -0500

    grabHelper: Make a full grab stack, rather than a one-time grab
    
    In order to implement child menus in the context of the grab helper,
    we need to add a full grab stack

 js/ui/grabHelper.js |   57 ++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 41 insertions(+), 16 deletions(-)
---
diff --git a/js/ui/grabHelper.js b/js/ui/grabHelper.js
index cd2c12e..4f680ec 100644
--- a/js/ui/grabHelper.js
+++ b/js/ui/grabHelper.js
@@ -41,7 +41,7 @@ const GrabHelper = new Lang.Class({
         this._modal = params.modal;
         this._grabFocus = params.grabFocus;
 
-        this.grabbed = false;
+        this._grabStack = [];
 
         this._actors = [];
         this._capturedEventId = 0;
@@ -84,6 +84,10 @@ const GrabHelper = new Lang.Class({
         return false;
     },
 
+    get grabbed() {
+        return this._grabStack.length > 0;
+    },
+
     // grab:
     // @newFocus: (allow-none): new focus container
     //
@@ -97,15 +101,26 @@ const GrabHelper = new Lang.Class({
     //   - The keyboard focus is moved outside the grabbed actors
     //   - A window is focused
     grab: function(newFocus) {
-        if (this.grabbed)
-            return;
-        this.grabbed = true;
-
-        let metaDisplay = global.screen.get_display();
-
         let focus = global.stage.key_focus;
         let hadFocus = focus && this._isWithinGrabbedActor(focus);
 
+        if (!this.grabbed)
+            this._fullGrab(focus, hadFocus);
+
+        this._grabStack.push(newFocus);
+        newFocus = hadFocus ? focus : newFocus;
+
+        if (newFocus) {
+            if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
+                newFocus.grab_key_focus();
+        }
+
+        return newFocus;
+    },
+
+    _fullGrab: function(focus, hadFocus) {
+        let metaDisplay = global.screen.get_display();
+
         this._grabbedFromKeynav = hadFocus;
         this._preGrabInputMode = global.stage_input_mode;
         this._prevFocusedWindow = null;
@@ -124,11 +139,6 @@ const GrabHelper = new Lang.Class({
             }
         }
 
-        if (newFocus) {
-            if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
-                newFocus.grab_key_focus();
-        }
-
         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));
@@ -153,9 +163,26 @@ const GrabHelper = new Lang.Class({
     // the same actor as it was on before the grab.)
     ungrab: function(newFocus, userAction) {
         if (!this.grabbed)
-            return;
-        this.grabbed = false;
+            return null;
+
+        let actor = this._grabStack.pop();
+        if (!newFocus)
+            newFocus = actor;
+
+        if (newFocus) {
+            if (!newFocus.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false))
+                newFocus.grab_key_focus();
+        }
+
+        this.emit('ungrabbed', userAction);
+
+        if (!this.grabbed)
+            this._fullUngrab(newFocus, userAction);
 
+        return newFocus;
+    },
+
+    _fullUngrab: function(newFocus, userAction) {
         global.stage.disconnect(this._capturedEventId);
         this._capturedEventId = 0;
         global.stage.disconnect(this._eventId);
@@ -190,8 +217,6 @@ const GrabHelper = new Lang.Class({
                                                    false, global.get_current_time());
             }
         }
-
-        this.emit('ungrabbed', userAction);
     },
 
     _onCapturedEvent: function(actor, event) {



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