[appSwitcher] Add shortcut to quit application

Allow to quit the currently selected application by hitting Alt-q,
similar to the OS X switcher.

https://bugzilla.gnome.org/show_bug.cgi?id=620106
This commit is contained in:
Florian Müllner 2010-06-01 20:03:45 +02:00 committed by Mario Sanchez Prada
parent ecd9fba514
commit 77c20e3b8e
2 changed files with 70 additions and 4 deletions

View File

@ -175,6 +175,8 @@ var AppSwitcherPopup = new Lang.Class({
this._select(this._selectedIndex, this._nextWindow()); this._select(this._selectedIndex, this._nextWindow());
else if (keysym == Clutter.Up) else if (keysym == Clutter.Up)
this._select(this._selectedIndex, null, true); this._select(this._selectedIndex, null, true);
else if (keysym == Clutter.q)
this._items[this._selectedIndex].app.request_quit();
else else
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} else { } else {
@ -184,6 +186,8 @@ var AppSwitcherPopup = new Lang.Class({
this._select(this._next()); this._select(this._next());
else if (keysym == Clutter.Down) else if (keysym == Clutter.Down)
this._select(this._selectedIndex, 0); this._select(this._selectedIndex, 0);
else if (keysym == Clutter.q)
this._items[this._selectedIndex].app.request_quit();
else else
return Clutter.EVENT_PROPAGATE; return Clutter.EVENT_PROPAGATE;
} }
@ -252,7 +256,7 @@ var AppSwitcherPopup = new Lang.Class({
let appIcon = this._items[this._selectedIndex]; let appIcon = this._items[this._selectedIndex];
if (this._currentWindow < 0) if (this._currentWindow < 0)
appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp); appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp);
else else if (appIcon.cachedWindows[this._currentWindow])
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp); Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
this.parent(); this.parent();
@ -350,6 +354,10 @@ var AppSwitcherPopup = new Lang.Class({
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows); this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
this._thumbnails.connect('item-activated', Lang.bind(this, this._windowActivated)); this._thumbnails.connect('item-activated', Lang.bind(this, this._windowActivated));
this._thumbnails.connect('item-entered', Lang.bind(this, this._windowEntered)); this._thumbnails.connect('item-entered', Lang.bind(this, this._windowEntered));
this._thumbnails.actor.connect('destroy', Lang.bind(this, function() {
this._thumbnails = null;
this._thumbnailsFocused = false;
}));
this.actor.add_actor(this._thumbnails.actor); this.actor.add_actor(this._thumbnails.actor);
@ -645,6 +653,9 @@ var AppSwitcher = new Lang.Class({
_onDestroy: function() { _onDestroy: function() {
if (this._mouseTimeOutId != 0) if (this._mouseTimeOutId != 0)
Mainloop.source_remove(this._mouseTimeOutId); Mainloop.source_remove(this._mouseTimeOutId);
for (let i = 0; i < this.icons.length; i++)
this.icons[i].app.disconnect(this.icons[i]._stateChangedId);
}, },
_setIconSize: function() { _setIconSize: function() {
@ -767,6 +778,12 @@ var AppSwitcher = new Lang.Class({
this.icons.push(appIcon); this.icons.push(appIcon);
let item = this.addItem(appIcon.actor, appIcon.label); let item = this.addItem(appIcon.actor, appIcon.label);
appIcon._stateChangedId = appIcon.app.connect('notify::state',
Lang.bind(this, function(app) {
if (app.state != Shell.AppState.RUNNING)
this._removeIcon(app);
}));
let n = this._arrows.length; let n = this._arrows.length;
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' }); let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
arrow.connect('repaint', function() { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); }); arrow.connect('repaint', function() { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
@ -777,7 +794,22 @@ var AppSwitcher = new Lang.Class({
arrow.hide(); arrow.hide();
else else
item.add_accessible_state (Atk.StateType.EXPANDABLE); item.add_accessible_state (Atk.StateType.EXPANDABLE);
} },
_removeIcon: function(app) {
for (let i = 0; i < this.icons.length; i++)
if (this.icons[i].app == app) {
this.icons.splice(i, 1);
this.removeItem(i);
if (this._curApp == i)
this._curApp = SwitcherPopup.mod(i, this.icons.length);
if (this.icons.length > 0)
this.highlight(this._curApp);
else
this.actor.destroy();
return;
}
},
}); });
var ThumbnailList = new Lang.Class({ var ThumbnailList = new Lang.Class({
@ -816,6 +848,8 @@ var ThumbnailList = new Lang.Class({
} }
} }
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
}, },
addClones : function (availHeight) { addClones : function (availHeight) {
@ -840,12 +874,39 @@ var ThumbnailList = new Lang.Class({
let clone = _createWindowClone(mutterWindow, thumbnailSize); let clone = _createWindowClone(mutterWindow, thumbnailSize);
this._thumbnailBins[i].set_height(binHeight); this._thumbnailBins[i].set_height(binHeight);
this._thumbnailBins[i].add_actor(clone); this._thumbnailBins[i].add_actor(clone);
clone._destroyId = mutterWindow.connect('destroy',
Lang.bind(this, this._removeThumbnail, clone));
this._clones.push(clone); this._clones.push(clone);
} }
// Make sure we only do this once // Make sure we only do this once
this._thumbnailBins = new Array(); this._thumbnailBins = new Array();
} },
_removeThumbnail: function(source, clone) {
for (let i = 0; i < this._clones.length; i++)
if (this._clones[i] == clone) {
this._clones.splice(i, 1);
this._windows.splice(i, 1);
this._labels.splice(i, 1);
this.removeItem(i);
if (this._clones.length > 0)
this.highlight(SwitcherPopup.mod(i, this._clones.length));
else
this.actor.destroy();
return;
}
},
_onDestroy: function() {
for (let i = 0; i < this._clones.length; i++) {
if (this._clones[i].source)
this._clones[i].source.disconnect(this._clones[i]._destroyId);
}
},
}); });
var WindowIcon = new Lang.Class({ var WindowIcon = new Lang.Class({

View File

@ -418,6 +418,11 @@ var SwitcherList = new Lang.Class({
return bbox; return bbox;
}, },
removeItem: function(index) {
let item = this._items.splice(index, 1);
item[0].destroy();
},
_onItemClicked: function (index) { _onItemClicked: function (index) {
this._itemActivated(index); this._itemActivated(index);
}, },
@ -432,7 +437,7 @@ var SwitcherList = new Lang.Class({
}, },
highlight: function(index, justOutline) { highlight: function(index, justOutline) {
if (this._highlighted != -1) { if (this._items[this._highlighted]) {
this._items[this._highlighted].remove_style_pseudo_class('outlined'); this._items[this._highlighted].remove_style_pseudo_class('outlined');
this._items[this._highlighted].remove_style_pseudo_class('selected'); this._items[this._highlighted].remove_style_pseudo_class('selected');
} }