From af4fcc831eadcbd1a9da3cabae138eab715feb88 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 7 Feb 2011 11:29:34 -0500 Subject: [PATCH] ctrlAltTab: misc improvements Fix the "panel" icon to be symbolic. Make the overview parts only show up when in the overview, and the non-overview parts (eg, the Desktop window, if there is one) only show up when not in the overview. Sort the different items consistently with their locations on the screen. https://bugzilla.gnome.org/show_bug.cgi?id=618887 --- js/ui/ctrlAltTab.js | 100 +++++++++++++++++++++++++++++------------ js/ui/main.js | 4 +- js/ui/panel.js | 4 ++ js/ui/windowManager.js | 5 +++ 4 files changed, 81 insertions(+), 32 deletions(-) diff --git a/js/ui/ctrlAltTab.js b/js/ui/ctrlAltTab.js index 83bb9b9a9..ff926a476 100644 --- a/js/ui/ctrlAltTab.js +++ b/js/ui/ctrlAltTab.js @@ -10,11 +10,18 @@ const St = imports.gi.St; const AltTab = imports.ui.altTab; const Main = imports.ui.main; +const Params = imports.misc.params; const Tweener = imports.ui.tweener; const POPUP_APPICON_SIZE = 96; const POPUP_FADE_TIME = 0.1; // seconds +const SortGroup = { + TOP: 0, + MIDDLE: 1, + BOTTOM: 2 +}; + function CtrlAltTabManager() { this._init(); } @@ -23,14 +30,18 @@ CtrlAltTabManager.prototype = { _init: function() { this._items = []; this._focusManager = St.FocusManager.get_for_stage(global.stage); - Main.wm.setKeybindingHandler('switch_panels', Lang.bind(this, - function (shellwm, binding, window, backwards) { - this.popup(backwards); - })); }, - addGroup: function(root, name, icon) { - this._items.push({ root: root, name: name, iconName: icon }); + addGroup: function(root, name, icon, params) { + let item = Params.parse(params, { sortGroup: SortGroup.MIDDLE, + proxy: root, + focusCallback: null }); + + item.root = root; + item.name = name; + item.iconName = icon; + + this._items.push(item); root.connect('destroy', Lang.bind(this, function() { this.removeGroup(root); })); this._focusManager.add_group(root); }, @@ -45,38 +56,73 @@ CtrlAltTabManager.prototype = { } }, - focusGroup: function(root) { + focusGroup: function(item) { if (global.stage_input_mode == Shell.StageInputMode.NONREACTIVE || global.stage_input_mode == Shell.StageInputMode.NORMAL) global.set_stage_input_mode(Shell.StageInputMode.FOCUSED); - root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + + if (item.window) + Main.activateWindow(item.window); + else if (item.focusCallback) + item.focusCallback(); + else + item.root.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + }, + + // Sort the items into a consistent order; panel first, tray last, + // and everything else in between, sorted by X coordinate, so that + // they will have the same left-to-right ordering in the + // Ctrl-Alt-Tab dialog as they do onscreen. + _sortItems: function(a, b) { + if (a.sortGroup != b.sortGroup) + return a.sortGroup - b.sortGroup; + + let y; + if (a.x == undefined) { + if (a.window) + a.x = a.window.get_compositor_private().x; + else + [a.x, y] = a.proxy.get_transformed_position(); + } + if (b.x == undefined) { + if (b.window) + b.x = b.window.get_compositor_private().x; + else + [b.x, y] = b.proxy.get_transformed_position(); + } + + return a.x - b.x; }, popup: function(backwards) { // Start with the set of focus groups that are currently mapped - let items = this._items.filter(function (item) { return item.root.mapped; }); + let items = this._items.filter(function (item) { return item.proxy.mapped; }); // And add the windows metacity would show in its Ctrl-Alt-Tab list - let screen = global.screen; - let display = screen.get_display(); - let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ()); - let windowTracker = Shell.WindowTracker.get_default(); - let textureCache = St.TextureCache.get_default(); - for (let i = 0; i < windows.length; i++) { - let icon; - let app = windowTracker.get_window_app(windows[i]); - if (app) - icon = app.create_icon_texture(POPUP_APPICON_SIZE); - else - icon = textureCache.bind_pixbuf_property(windows[i], 'icon'); - items.push({ window: windows[i], - name: windows[i].title, - iconActor: icon }); + if (!Main.overview.visible) { + let screen = global.screen; + let display = screen.get_display(); + let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ()); + let windowTracker = Shell.WindowTracker.get_default(); + let textureCache = St.TextureCache.get_default(); + for (let i = 0; i < windows.length; i++) { + let icon; + let app = windowTracker.get_window_app(windows[i]); + if (app) + icon = app.create_icon_texture(POPUP_APPICON_SIZE); + else + icon = textureCache.bind_pixbuf_property(windows[i], 'icon'); + items.push({ window: windows[i], + name: windows[i].title, + iconActor: icon, + sortGroup: SortGroup.MIDDLE }); + } } if (!items.length) return; + items.sort(Lang.bind(this, this._sortItems)); new CtrlAltTabPopup().show(items, backwards); } }; @@ -211,11 +257,7 @@ CtrlAltTabPopup.prototype = { _finish : function() { this.destroy(); - let item = this._items[this._selection]; - if (item.root) - Main.ctrlAltTabManager.focusGroup(item.root); - else - Main.activateWindow(item.window); + Main.ctrlAltTabManager.focusGroup(this._items[this._selection]); }, _popModal: function() { diff --git a/js/ui/main.js b/js/ui/main.js index 3d3d87c14..fc8acbd61 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -139,6 +139,7 @@ function start() { placesManager = new PlaceDisplay.PlacesManager(); xdndHandler = new XdndHandler.XdndHandler(); + ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); overview = new Overview.Overview(); chrome = new Chrome.Chrome(); magnifier = new Magnifier.Magnifier(); @@ -153,9 +154,6 @@ function start() { overview.init(); statusIconDispatcher.start(messageTray.actor); - ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager(); - ctrlAltTabManager.addGroup(panel.actor, _("Panel"), 'gnome-panel'); - _startDate = new Date(); let recorderSettings = new Gio.Settings({ schema: 'org.gnome.shell.recorder' }); diff --git a/js/ui/panel.js b/js/ui/panel.js index a8d081281..2bb37ab3f 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -13,6 +13,7 @@ const Gettext = imports.gettext.domain('gnome-shell'); const _ = Gettext.gettext; const Config = imports.misc.config; +const CtrlAltTab = imports.ui.ctrlAltTab; const Overview = imports.ui.overview; const PopupMenu = imports.ui.popupMenu; const PanelMenu = imports.ui.panelMenu; @@ -989,6 +990,9 @@ Panel.prototype = { Main.chrome.addActor(this._rightCorner.actor, { visibleInOverview: true, affectsStruts: false, affectsInputRegion: false }); + + Main.ctrlAltTabManager.addGroup(this.actor, _("Panel"), 'start-here', + { sortGroup: CtrlAltTab.SortGroup.TOP }); }, _xdndShowOverview: function (actor) { diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js index d291b8d7f..deca70ed3 100644 --- a/js/ui/windowManager.js +++ b/js/ui/windowManager.js @@ -117,6 +117,7 @@ WindowManager.prototype = { this.setKeybindingHandler('switch_to_workspace_down', Lang.bind(this, this._showWorkspaceSwitcher)); this.setKeybindingHandler('switch_windows', Lang.bind(this, this._startAppSwitcher)); this.setKeybindingHandler('switch_group', Lang.bind(this, this._startAppSwitcher)); + this.setKeybindingHandler('switch_panels', Lang.bind(this, this._startA11ySwitcher)); Main.overview.connect('showing', Lang.bind(this, function() { for (let i = 0; i < this._dimmedWindows.length; i++) @@ -525,6 +526,10 @@ WindowManager.prototype = { tabPopup.destroy(); }, + _startA11ySwitcher : function(shellwm, binding, window, backwards) { + Main.ctrlAltTabManager.popup(backwards); + }, + _showWorkspaceSwitcher : function(shellwm, binding, window, backwards) { if (global.screen.n_workspaces == 1) return;