[gnome-shell] [AppSwitcher] Implement window cycling



commit 9fee99bc7a4307f08c5686ade9f88f6c7d6abf44
Author: Dan Winship <danw gnome org>
Date:   Mon Sep 21 13:04:30 2009 -0400

    [AppSwitcher] Implement window cycling

 js/ui/altTab.js  |   33 ++++++++++++++++++++++++
 js/ui/appIcon.js |   73 ++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 80 insertions(+), 26 deletions(-)
---
diff --git a/js/ui/altTab.js b/js/ui/altTab.js
index f963759..9818d0a 100644
--- a/js/ui/altTab.js
+++ b/js/ui/altTab.js
@@ -56,6 +56,8 @@ AltTabPopup.prototype = {
         appIcon.connect('activate', Lang.bind(this, this._appClicked));
         appIcon.connect('activate-window', Lang.bind(this, this._windowClicked));
         appIcon.connect('highlight-window', Lang.bind(this, this._windowHovered));
+        appIcon.connect('menu-popped-up', Lang.bind(this, this._menuPoppedUp));
+        appIcon.connect('menu-popped-down', Lang.bind(this, this._menuPoppedDown));
 
         // FIXME?
         appIcon.actor.border = 2;
@@ -118,6 +120,8 @@ AltTabPopup.prototype = {
 
         if (keysym == Clutter.Tab)
             this._updateSelection(backwards ? -1 : 1);
+        else if (keysym == Clutter.grave)
+            this._updateWindowSelection(backwards ? -1 : 1);
         else if (keysym == Clutter.Escape)
             this.destroy();
 
@@ -171,12 +175,41 @@ AltTabPopup.prototype = {
 
     _updateSelection : function(delta) {
         this._icons[this._selected].setHighlight(false);
+        if (delta != 0 && this._selectedMenu)
+                this._selectedMenu.popdown();
+
         this._selected = (this._selected + this._icons.length + delta) % this._icons.length;
         this._icons[this._selected].setHighlight(true);
 
         this._highlightWindow(this._icons[this._selected].windows[0]);
     },
 
+    _menuPoppedUp : function(icon, menu) {
+        this._selectedMenu = menu;
+    },
+
+    _menuPoppedDown : function(icon, menu) {
+        this._selectedMenu = null;
+    },
+
+    _updateWindowSelection : function(delta) {
+        let icon = this._icons[this._selected];
+
+        if (!this._selectedMenu)
+            icon.popupMenu();
+        if (!this._selectedMenu)
+            return;
+
+        let next = 0;
+        for (let i = 0; i < icon.windows.length; i++) {
+            if (icon.windows[i] == this._highlightedWindow) {
+                next = (i + icon.windows.length + delta) % icon.windows.length;
+                break;
+            }
+        }
+        this._selectedMenu.selectWindow(icon.windows[next]);
+    },
+
     _highlightWindow : function(metaWin) {
         this._highlightedWindow = metaWin;
         this._lightbox.highlight(this._highlightedWindow.get_compositor_private());
diff --git a/js/ui/appIcon.js b/js/ui/appIcon.js
index 6a74e7d..a0bb243 100644
--- a/js/ui/appIcon.js
+++ b/js/ui/appIcon.js
@@ -205,12 +205,15 @@ AppIcon.prototype = {
         if (this._menuTimeoutId != 0)
             Mainloop.source_remove(this._menuTimeoutId);
         this._menuTimeoutId = Mainloop.timeout_add(APPICON_MENU_POPUP_TIMEOUT_MS,
-                                                   Lang.bind(this, this._popupMenu));
+                                                   Lang.bind(this, this.popupMenu));
         return false;
     },
 
-    _popupMenu: function() {
-        this._menuTimeoutId = 0;
+    popupMenu: function() {
+        if (this._menuTimeoutId != 0) {
+            Mainloop.source_remove(this._menuTimeoutId);
+            this._menuTimeoutId = 0;
+        }
 
         this.actor.fake_release();
 
@@ -244,8 +247,13 @@ AppIcon.prototype = {
         this.emit('activate-window', window);
     },
 
-    menuPoppedUp: function() {},
-    menuPoppedDown: function() {}
+    menuPoppedUp: function() {
+        this.emit('menu-popped-up', this._menu);
+    },
+
+    menuPoppedDown: function() {
+        this.emit('menu-popped-down', this._menu);
+    }
 };
 
 Signals.addSignalMethods(AppIcon.prototype);
@@ -392,6 +400,8 @@ AppIconMenu.prototype = {
         this._appendSeparator();
 
         this._newWindowMenuItem = this._appendMenuItem(null, _("New Window"));
+
+        this._highlightedItem = null;
     },
 
     _appendSeparator: function () {
@@ -464,6 +474,16 @@ AppIconMenu.prototype = {
         this.actor.show();
     },
 
+    popdown: function() {
+        this._windowContainer.popdown();
+        this.emit('popup', false);
+        this.actor.hide();
+    },
+
+    selectWindow: function(metaWindow) {
+        this._selectMenuItemForWindow(metaWindow);
+    },
+
     _findMetaWindowForActor: function (actor) {
         if (actor._delegate instanceof Workspaces.WindowClone)
             return actor._delegate.metaWindow;
@@ -481,24 +501,35 @@ AppIconMenu.prototype = {
         }
     },
 
-    _lookupMenuItemForWindow: function (metaWindow) {
+    _updateHighlight: function (item) {
+        if (this._highlightedItem) {
+            this._highlightedItem.background_color = TRANSPARENT_COLOR;
+            this.emit('highlight-window', null);
+        }
+        this._highlightedItem = item;
+        if (this._highlightedItem) {
+            this._highlightedItem.background_color = APPICON_MENU_SELECTED_COLOR;
+            let window = this._highlightedItem._window;
+            if (window)
+                this.emit('highlight-window', window);
+        }
+    },
+
+    _selectMenuItemForWindow: function (metaWindow) {
         let children = this._windowContainer.get_children();
         for (let i = 0; i < children.length; i++) {
             let child = children[i];
             let menuMetaWindow = child._window;
             if (menuMetaWindow == metaWindow)
-                return child;
+                this._updateHighlight(child);
         }
-        return null;
     },
 
     // Called while menu has a pointer grab
     _onMenuEnter: function (actor, event) {
         let metaWindow = this._findMetaWindowForActor(event.get_source());
         if (metaWindow) {
-            let menu = this._lookupMenuItemForWindow(metaWindow);
-            menu.background_color = APPICON_MENU_SELECTED_COLOR;
-            this.emit('highlight-window', metaWindow);
+            this._selectMenuItemForWindow(metaWindow);
         }
     },
 
@@ -506,24 +537,16 @@ AppIconMenu.prototype = {
     _onMenuLeave: function (actor, event) {
         let metaWindow = this._findMetaWindowForActor(event.get_source());
         if (metaWindow) {
-            let menu = this._lookupMenuItemForWindow(metaWindow);
-            menu.background_color = TRANSPARENT_COLOR;
-            this.emit('highlight-window', null);
+            this._updateHighlight(null);
         }
     },
 
     _onItemUnselected: function (actor, child) {
-        child.background_color = TRANSPARENT_COLOR;
-        if (child._window) {
-            this.emit('highlight-window', null);
-        }
+        this._updateHighlight(null);
     },
 
     _onItemSelected: function (actor, child) {
-        child.background_color = APPICON_MENU_SELECTED_COLOR;
-        if (child._window) {
-            this.emit('highlight-window', child._window);
-        }
+        this._updateHighlight(child);
     },
 
     _onItemActivate: function (actor, child) {
@@ -534,14 +557,12 @@ AppIconMenu.prototype = {
             this._source.appInfo.launch();
             this.emit('activate-window', null);
         }
-        this.emit('popup', false);
-        this.actor.hide();
+        this.popdown();
     },
 
     _onWindowSelectionCancelled: function () {
         this.emit('highlight-window', null);
-        this.emit('popup', false);
-        this.actor.hide();
+        this.popdown();
     }
 };
 



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