From c7a37660ce2fa5d601bc228a323a6534c69d0752 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sat, 12 Nov 2011 04:40:56 +0000 Subject: [PATCH] searchDisplay, viewSelector: use St keynav in Applications and Search https://bugzilla.gnome.org/show_bug.cgi?id=663901 --- data/theme/gnome-shell.css | 2 ++ js/ui/contactDisplay.js | 1 + js/ui/searchDisplay.js | 2 ++ js/ui/viewSelector.js | 51 +++++++++++++++++++++++++++++++------- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index d1bb16375..7484aee32 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -308,6 +308,7 @@ StScrollBar StButton#vhandle:hover } .dash-search-button:selected, +.dash-search-button:focus, .notification-button:focus, .notification-icon-button:focus, .hotplug-notification-item:focus, @@ -693,6 +694,7 @@ StScrollBar StButton#vhandle:hover font-weight: bold; } +.dash-search-button:focus, .dash-search-button:selected { padding-top: 3px; padding-bottom: 4px; diff --git a/js/ui/contactDisplay.js b/js/ui/contactDisplay.js index e501d801c..5c4a330fd 100644 --- a/js/ui/contactDisplay.js +++ b/js/ui/contactDisplay.js @@ -29,6 +29,7 @@ const Contact = new Lang.Class({ this.actor = new St.Bin({ style_class: 'contact', reactive: true, + can_focus: true, track_hover: true }); let content = new St.BoxLayout( { style_class: 'contact-content', diff --git a/js/ui/searchDisplay.js b/js/ui/searchDisplay.js index 984a55a97..23bdb1e06 100644 --- a/js/ui/searchDisplay.js +++ b/js/ui/searchDisplay.js @@ -32,6 +32,7 @@ const SearchResult = new Lang.Class({ if (content == null) { content = new St.Bin({ style_class: 'search-result-content', reactive: true, + can_focus: true, track_hover: true }); let icon = new IconGrid.BaseIcon(this.metaInfo['name'], { createIcon: this.metaInfo['createIcon'] }); @@ -267,6 +268,7 @@ const SearchResults = new Lang.Class({ _createOpenSearchProviderButton: function(provider) { let button = new St.Button({ style_class: 'dash-search-button', reactive: true, + can_focus: true, x_fill: true, y_align: St.Align.MIDDLE }); let bin = new St.Bin({ x_fill: false, diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js index 20e107789..363d4df26 100644 --- a/js/ui/viewSelector.js +++ b/js/ui/viewSelector.js @@ -151,6 +151,23 @@ const SearchTab = new Lang.Class({ global.stage.connect('notify::key-focus', Lang.bind(this, this._updateCursorVisibility)); this._capturedEventId = 0; + + // Since the entry isn't inside the results container we install this + // dummy widget as the last results container child so that we can + // include the entry in the keynav tab path... + this._focusTrap = new St.Bin({ can_focus: true }); + this._focusTrap.connect('key-focus-in', Lang.bind(this, function() { + this._entry.grab_key_focus(); + })); + // ... but make it unfocusable using arrow keys keynav by making its + // bounding box always contain the possible focus source's bounding + // box since StWidget's keynav logic won't ever select it as a target + // in that case. + this._focusTrap.add_constraint(new Clutter.BindConstraint({ source: this._searchResults.actor, + coordinate: Clutter.BindCoordinate.ALL })); + this._searchResults.actor.add_actor(this._focusTrap); + + global.focus_manager.add_group(this._searchResults.actor); }, hide: function() { @@ -271,8 +288,17 @@ const SearchTab = new Lang.Class({ this._reset(); return true; } + } else if (this.active) { + if (symbol == Clutter.Tab) { + this._searchResults.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + return true; + } else if (symbol == Clutter.ISO_Left_Tab) { + this._focusTrap.can_focus = false; + this._searchResults.actor.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false); + this._focusTrap.can_focus = true; + return true; + } } - return false; }, @@ -517,18 +543,25 @@ const ViewSelector = new Lang.Class({ if (symbol == Clutter.Escape) { Main.overview.hide(); return true; - } else if (modifiers & Clutter.ModifierType.CONTROL_MASK) { - if (symbol == Clutter.Page_Up) { - if (!this._searchTab.active) + } else if (Clutter.keysym_to_unicode(symbol) || + (symbol == Clutter.BackSpace && this._searchTab.active)) { + this._searchTab.startSearch(event); + } else if (!this._searchTab.active) { + if (modifiers & Clutter.ModifierType.CONTROL_MASK) { + if (symbol == Clutter.Page_Up) { this._prevTab(); - return true; - } else if (symbol == Clutter.Page_Down) { - if (!this._searchTab.active) + return true; + } else if (symbol == Clutter.Page_Down) { this._nextTab(); + return true; + } + } else if (symbol == Clutter.Tab) { + this._activeTab.page.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + return true; + } else if (symbol == Clutter.ISO_Left_Tab) { + this._activeTab.page.navigate_focus(null, Gtk.DirectionType.TAB_BACKWARD, false); return true; } - } else if (Clutter.keysym_to_unicode(symbol)) { - this._searchTab.startSearch(event); } return false; },