[AppSwitcher] Implement window cycling

This commit is contained in:
Dan Winship 2009-09-21 13:04:30 -04:00
parent 67bfbc9b4b
commit 9fee99bc7a
2 changed files with 80 additions and 26 deletions

View File

@ -56,6 +56,8 @@ AltTabPopup.prototype = {
appIcon.connect('activate', Lang.bind(this, this._appClicked)); appIcon.connect('activate', Lang.bind(this, this._appClicked));
appIcon.connect('activate-window', Lang.bind(this, this._windowClicked)); appIcon.connect('activate-window', Lang.bind(this, this._windowClicked));
appIcon.connect('highlight-window', Lang.bind(this, this._windowHovered)); 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? // FIXME?
appIcon.actor.border = 2; appIcon.actor.border = 2;
@ -118,6 +120,8 @@ AltTabPopup.prototype = {
if (keysym == Clutter.Tab) if (keysym == Clutter.Tab)
this._updateSelection(backwards ? -1 : 1); this._updateSelection(backwards ? -1 : 1);
else if (keysym == Clutter.grave)
this._updateWindowSelection(backwards ? -1 : 1);
else if (keysym == Clutter.Escape) else if (keysym == Clutter.Escape)
this.destroy(); this.destroy();
@ -171,12 +175,41 @@ AltTabPopup.prototype = {
_updateSelection : function(delta) { _updateSelection : function(delta) {
this._icons[this._selected].setHighlight(false); 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._selected = (this._selected + this._icons.length + delta) % this._icons.length;
this._icons[this._selected].setHighlight(true); this._icons[this._selected].setHighlight(true);
this._highlightWindow(this._icons[this._selected].windows[0]); 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) { _highlightWindow : function(metaWin) {
this._highlightedWindow = metaWin; this._highlightedWindow = metaWin;
this._lightbox.highlight(this._highlightedWindow.get_compositor_private()); this._lightbox.highlight(this._highlightedWindow.get_compositor_private());

View File

@ -205,12 +205,15 @@ AppIcon.prototype = {
if (this._menuTimeoutId != 0) if (this._menuTimeoutId != 0)
Mainloop.source_remove(this._menuTimeoutId); Mainloop.source_remove(this._menuTimeoutId);
this._menuTimeoutId = Mainloop.timeout_add(APPICON_MENU_POPUP_TIMEOUT_MS, this._menuTimeoutId = Mainloop.timeout_add(APPICON_MENU_POPUP_TIMEOUT_MS,
Lang.bind(this, this._popupMenu)); Lang.bind(this, this.popupMenu));
return false; return false;
}, },
_popupMenu: function() { popupMenu: function() {
this._menuTimeoutId = 0; if (this._menuTimeoutId != 0) {
Mainloop.source_remove(this._menuTimeoutId);
this._menuTimeoutId = 0;
}
this.actor.fake_release(); this.actor.fake_release();
@ -244,8 +247,13 @@ AppIcon.prototype = {
this.emit('activate-window', window); this.emit('activate-window', window);
}, },
menuPoppedUp: function() {}, menuPoppedUp: function() {
menuPoppedDown: function() {} this.emit('menu-popped-up', this._menu);
},
menuPoppedDown: function() {
this.emit('menu-popped-down', this._menu);
}
}; };
Signals.addSignalMethods(AppIcon.prototype); Signals.addSignalMethods(AppIcon.prototype);
@ -392,6 +400,8 @@ AppIconMenu.prototype = {
this._appendSeparator(); this._appendSeparator();
this._newWindowMenuItem = this._appendMenuItem(null, _("New Window")); this._newWindowMenuItem = this._appendMenuItem(null, _("New Window"));
this._highlightedItem = null;
}, },
_appendSeparator: function () { _appendSeparator: function () {
@ -464,6 +474,16 @@ AppIconMenu.prototype = {
this.actor.show(); this.actor.show();
}, },
popdown: function() {
this._windowContainer.popdown();
this.emit('popup', false);
this.actor.hide();
},
selectWindow: function(metaWindow) {
this._selectMenuItemForWindow(metaWindow);
},
_findMetaWindowForActor: function (actor) { _findMetaWindowForActor: function (actor) {
if (actor._delegate instanceof Workspaces.WindowClone) if (actor._delegate instanceof Workspaces.WindowClone)
return actor._delegate.metaWindow; 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(); let children = this._windowContainer.get_children();
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
let child = children[i]; let child = children[i];
let menuMetaWindow = child._window; let menuMetaWindow = child._window;
if (menuMetaWindow == metaWindow) if (menuMetaWindow == metaWindow)
return child; this._updateHighlight(child);
} }
return null;
}, },
// Called while menu has a pointer grab // Called while menu has a pointer grab
_onMenuEnter: function (actor, event) { _onMenuEnter: function (actor, event) {
let metaWindow = this._findMetaWindowForActor(event.get_source()); let metaWindow = this._findMetaWindowForActor(event.get_source());
if (metaWindow) { if (metaWindow) {
let menu = this._lookupMenuItemForWindow(metaWindow); this._selectMenuItemForWindow(metaWindow);
menu.background_color = APPICON_MENU_SELECTED_COLOR;
this.emit('highlight-window', metaWindow);
} }
}, },
@ -506,24 +537,16 @@ AppIconMenu.prototype = {
_onMenuLeave: function (actor, event) { _onMenuLeave: function (actor, event) {
let metaWindow = this._findMetaWindowForActor(event.get_source()); let metaWindow = this._findMetaWindowForActor(event.get_source());
if (metaWindow) { if (metaWindow) {
let menu = this._lookupMenuItemForWindow(metaWindow); this._updateHighlight(null);
menu.background_color = TRANSPARENT_COLOR;
this.emit('highlight-window', null);
} }
}, },
_onItemUnselected: function (actor, child) { _onItemUnselected: function (actor, child) {
child.background_color = TRANSPARENT_COLOR; this._updateHighlight(null);
if (child._window) {
this.emit('highlight-window', null);
}
}, },
_onItemSelected: function (actor, child) { _onItemSelected: function (actor, child) {
child.background_color = APPICON_MENU_SELECTED_COLOR; this._updateHighlight(child);
if (child._window) {
this.emit('highlight-window', child._window);
}
}, },
_onItemActivate: function (actor, child) { _onItemActivate: function (actor, child) {
@ -534,14 +557,12 @@ AppIconMenu.prototype = {
this._source.appInfo.launch(); this._source.appInfo.launch();
this.emit('activate-window', null); this.emit('activate-window', null);
} }
this.emit('popup', false); this.popdown();
this.actor.hide();
}, },
_onWindowSelectionCancelled: function () { _onWindowSelectionCancelled: function () {
this.emit('highlight-window', null); this.emit('highlight-window', null);
this.emit('popup', false); this.popdown();
this.actor.hide();
} }
}; };