[gnome-shell] switcherPopup: Add support for modifier-less keybinding navigation



commit c899453800f1146d10f2fd66c16908c2d2944554
Author: Rui Matos <tiagomatos gmail com>
Date:   Thu Jun 8 14:20:56 2017 +0200

    switcherPopup: Add support for modifier-less keybinding navigation
    
    This drops the requirement that SwitcherPopups need a modifier based
    keybinding to work.
    
    The existing behavior for modifier based keybindings is kept but if
    the popup is triggered from a no modifiers keybinding, instead of
    finishing when the modifier is released, we use a timer that
    automatically finishes the popup. The timer is reset on every key
    release to allow navigation to happen.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=783550

 js/ui/switcherPopup.js |   42 +++++++++++++++++++++++++++++++++---------
 1 files changed, 33 insertions(+), 9 deletions(-)
---
diff --git a/js/ui/switcherPopup.js b/js/ui/switcherPopup.js
index d4da7b6..0e1f710 100644
--- a/js/ui/switcherPopup.js
+++ b/js/ui/switcherPopup.js
@@ -19,6 +19,7 @@ var POPUP_SCROLL_TIME = 0.10; // seconds
 var POPUP_FADE_OUT_TIME = 0.1; // seconds
 
 var DISABLE_HOVER_TIMEOUT = 500; // milliseconds
+var NO_MODS_TIMEOUT = 1500; // milliseconds
 
 function mod(a, b) {
     return (a + b) % b;
@@ -61,6 +62,7 @@ var SwitcherPopup = new Lang.Class({
 
         this._motionTimeoutId = 0;
         this._initialDelayTimeoutId = 0;
+        this._noModsTimeoutId = 0;
 
         // Initially disable hover so we ignore the enter-event if
         // the switcher appears underneath the current pointer location
@@ -145,10 +147,14 @@ var SwitcherPopup = new Lang.Class({
         // https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
         // details.) So we check now. (Have to do this after updating
         // selection.)
-        let [x, y, mods] = global.get_pointer();
-        if (!(mods & this._modifierMask)) {
-            this._finish(global.get_current_time());
-            return false;
+        if (this._modifierMask) {
+            let [x, y, mods] = global.get_pointer();
+            if (!(mods & this._modifierMask)) {
+                this._finish(global.get_current_time());
+                return false;
+            }
+        } else {
+            this._resetNoModsTimeout();
         }
 
         // We delay showing the popup so that fast Alt+Tab users aren't
@@ -192,11 +198,15 @@ var SwitcherPopup = new Lang.Class({
     },
 
     _keyReleaseEvent: function(actor, event) {
-        let [x, y, mods] = global.get_pointer();
-        let state = mods & this._modifierMask;
-
-        if (state == 0)
-            this._finish(event.get_time());
+        if (this._modifierMask) {
+            let [x, y, mods] = global.get_pointer();
+            let state = mods & this._modifierMask;
+
+            if (state == 0)
+                this._finish(event.get_time());
+        } else {
+            this._resetNoModsTimeout();
+        }
 
         return Clutter.EVENT_STOP;
     },
@@ -253,6 +263,18 @@ var SwitcherPopup = new Lang.Class({
         return GLib.SOURCE_REMOVE;
     },
 
+    _resetNoModsTimeout: function() {
+        if (this._noModsTimeoutId != 0)
+            Mainloop.source_remove(this._noModsTimeoutId);
+
+        this._noModsTimeoutId = Mainloop.timeout_add(NO_MODS_TIMEOUT,
+                                                     Lang.bind(this, function () {
+                                                         this._finish(global.get_current_time());
+                                                         this._noModsTimeoutId = 0;
+                                                         return GLib.SOURCE_REMOVE;
+                                                     }));
+    },
+
     _popModal: function() {
         if (this._haveModal) {
             Main.popModal(this.actor);
@@ -287,6 +309,8 @@ var SwitcherPopup = new Lang.Class({
             Mainloop.source_remove(this._motionTimeoutId);
         if (this._initialDelayTimeoutId != 0)
             Mainloop.source_remove(this._initialDelayTimeoutId);
+        if (this._noModsTimeoutId != 0)
+            Mainloop.source_remove(this._noModsTimeoutId);
     },
 
     _select: function(num) {


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