altTab: fix app ordering in certain edge cases
Because we were sorting the Alt+Tab list by user_time rather than stacking order / MRU, it was possible for the currently-focused window to sometimes not be the first app in the list. Fix this by using meta_display_get_tab_list() to get the proper MRU ordering of windows on the current workspace, and then convert that to an ordered list of apps. https://bugzilla.gnome.org/show_bug.cgi?id=645026
This commit is contained in:
parent
a103c028f9
commit
928fbee15b
@ -134,11 +134,40 @@ AltTabPopup.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
show : function(backward, binding, mask) {
|
_getAppLists: function() {
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
let appSys = Shell.AppSystem.get_default();
|
let appSys = Shell.AppSystem.get_default();
|
||||||
let apps = appSys.get_running ();
|
let allApps = appSys.get_running ();
|
||||||
|
|
||||||
if (!apps.length)
|
let screen = global.screen;
|
||||||
|
let display = screen.get_display();
|
||||||
|
let windows = display.get_tab_list(Meta.TabList.NORMAL, screen,
|
||||||
|
screen.get_active_workspace());
|
||||||
|
|
||||||
|
// windows is only the windows on the current workspace. For
|
||||||
|
// each one, if it corresponds to an app we know, move that
|
||||||
|
// app from allApps to apps.
|
||||||
|
let apps = [];
|
||||||
|
for (let i = 0; i < windows.length && allApps.length != 0; i++) {
|
||||||
|
let app = tracker.get_window_app(windows[i]);
|
||||||
|
let index = allApps.indexOf(app);
|
||||||
|
if (index != -1) {
|
||||||
|
apps.push(app);
|
||||||
|
allApps.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now @apps is a list of apps on the current workspace, in
|
||||||
|
// standard Alt+Tab order (MRU except for minimized windows),
|
||||||
|
// and allApps is a list of apps that only appear on other
|
||||||
|
// workspaces, sorted by user_time, which is good enough.
|
||||||
|
return [apps, allApps];
|
||||||
|
},
|
||||||
|
|
||||||
|
show : function(backward, binding, mask) {
|
||||||
|
let [localApps, otherApps] = this._getAppLists();
|
||||||
|
|
||||||
|
if (localApps.length == 0 && otherApps.length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Main.pushModal(this.actor))
|
if (!Main.pushModal(this.actor))
|
||||||
@ -152,7 +181,7 @@ AltTabPopup.prototype = {
|
|||||||
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
|
||||||
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
|
||||||
|
|
||||||
this._appSwitcher = new AppSwitcher(apps, this);
|
this._appSwitcher = new AppSwitcher(localApps, otherApps, this);
|
||||||
this.actor.add_actor(this._appSwitcher.actor);
|
this.actor.add_actor(this._appSwitcher.actor);
|
||||||
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
|
||||||
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
|
||||||
@ -846,34 +875,33 @@ AppIcon.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function AppSwitcher(apps, altTabPopup) {
|
function AppSwitcher() {
|
||||||
this._init(apps, altTabPopup);
|
this._init.apply(this, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSwitcher.prototype = {
|
AppSwitcher.prototype = {
|
||||||
__proto__ : SwitcherList.prototype,
|
__proto__ : SwitcherList.prototype,
|
||||||
|
|
||||||
_init : function(apps, altTabPopup) {
|
_init : function(localApps, otherApps, altTabPopup) {
|
||||||
SwitcherList.prototype._init.call(this, true);
|
SwitcherList.prototype._init.call(this, true);
|
||||||
|
|
||||||
// Construct the AppIcons, sort by time, add to the popup
|
// Construct the AppIcons, add to the popup
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
let workspaceIcons = [];
|
let workspaceIcons = [];
|
||||||
let otherIcons = [];
|
let otherIcons = [];
|
||||||
for (let i = 0; i < apps.length; i++) {
|
for (let i = 0; i < localApps.length; i++) {
|
||||||
let appIcon = new AppIcon(apps[i]);
|
let appIcon = new AppIcon(localApps[i]);
|
||||||
// Cache the window list now; we don't handle dynamic changes here,
|
// Cache the window list now; we don't handle dynamic changes here,
|
||||||
// and we don't want to be continually retrieving it
|
// and we don't want to be continually retrieving it
|
||||||
appIcon.cachedWindows = appIcon.app.get_windows();
|
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||||
if (this._hasWindowsOnWorkspace(appIcon, activeWorkspace))
|
|
||||||
workspaceIcons.push(appIcon);
|
workspaceIcons.push(appIcon);
|
||||||
else
|
}
|
||||||
|
for (let i = 0; i < otherApps.length; i++) {
|
||||||
|
let appIcon = new AppIcon(otherApps[i]);
|
||||||
|
appIcon.cachedWindows = appIcon.app.get_windows();
|
||||||
otherIcons.push(appIcon);
|
otherIcons.push(appIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceIcons.sort(Lang.bind(this, this._sortAppIcon));
|
|
||||||
otherIcons.sort(Lang.bind(this, this._sortAppIcon));
|
|
||||||
|
|
||||||
this.icons = [];
|
this.icons = [];
|
||||||
this._arrows = [];
|
this._arrows = [];
|
||||||
for (let i = 0; i < workspaceIcons.length; i++)
|
for (let i = 0; i < workspaceIcons.length; i++)
|
||||||
@ -1012,19 +1040,6 @@ AppSwitcher.prototype = {
|
|||||||
|
|
||||||
if (appIcon.cachedWindows.length == 1)
|
if (appIcon.cachedWindows.length == 1)
|
||||||
arrow.hide();
|
arrow.hide();
|
||||||
},
|
|
||||||
|
|
||||||
_hasWindowsOnWorkspace: function(appIcon, workspace) {
|
|
||||||
let windows = appIcon.cachedWindows;
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
if (windows[i].get_workspace() == workspace)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_sortAppIcon : function(appIcon1, appIcon2) {
|
|
||||||
return appIcon1.app.compare(appIcon2.app);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user