searchDisplay, viewSelector: add default result activation

Adds a way to highlight and activate the first search result when
pressing enter on the search entry.

https://bugzilla.gnome.org/show_bug.cgi?id=663901
This commit is contained in:
Rui Matos 2011-11-14 03:13:26 +00:00
parent c7a37660ce
commit b864b03a65
2 changed files with 74 additions and 25 deletions

View File

@ -190,6 +190,13 @@ const GridSearchResults = new Lang.Class({
return;
let targetActor = this._grid.getItemAtIndex(this.selectionIndex);
targetActor._delegate.activate();
},
getFirstResult: function() {
if (this.getVisibleResultCount() > 0)
return this._grid.getItemAtIndex(0)._delegate;
else
return null;
}
});
@ -245,6 +252,9 @@ const SearchResults = new Lang.Class({
this._openSearchProviders = [];
this._openSearchSystem.connect('changed', Lang.bind(this, this._updateOpenSearchProviderButtons));
this._updateOpenSearchProviderButtons();
this._highlightDefault = false;
this._defaultResult = null;
},
_updateOpenSearchProviderButtons: function() {
@ -284,6 +294,16 @@ const SearchResults = new Lang.Class({
button.set_child(bin);
provider.actor = button;
button.setSelected = function(selected) {
if (selected)
button.add_style_pseudo_class('selected');
else
button.remove_style_pseudo_class('selected');
};
button.activate = Lang.bind(this, function() {
this._openSearchSystem.activateResult(provider.id);
});
this._searchProvidersBox.add(button);
},
@ -364,17 +384,31 @@ const SearchResults = new Lang.Class({
if (this._selectedOpenSearchButton > -1 || this._selectedProvider > -1)
return;
let newDefaultResult = null;
for (let i = 0; i < this._providerMeta.length; i++) {
let meta = this._providerMeta[i];
if (meta.hasPendingResults)
return;
if (meta.actor.visible)
let firstResult = meta.resultDisplay.getFirstResult();
if (firstResult && firstResult.actor.visible) {
newDefaultResult = firstResult;
break; // select this one!
}
}
this.selectDown(false);
this._initialSelectionSet = true;
if (!newDefaultResult)
newDefaultResult = this._searchProvidersBox.get_first_child();
if (newDefaultResult != this._defaultResult) {
if (this._defaultResult)
this._defaultResult.setSelected(false);
if (newDefaultResult)
newDefaultResult.setSelected(this._highlightDefault);
this._defaultResult = newDefaultResult;
}
},
_updateCurrentResults: function(searchSystem, results) {
@ -428,11 +462,9 @@ const SearchResults = new Lang.Class({
let terms = searchSystem.getTerms();
this._openSearchSystem.setSearchTerms(terms);
// To avoid CSS transitions causing flickering
// of the selection when the first search result
// stays the same, we hide the content while
// filling in the results and setting the initial
// selection.
// To avoid CSS transitions causing flickering when the first search
// result stays the same, we hide the content while filling in the
// results.
this._content.hide();
for (let i = 0; i < results.length; i++) {
@ -535,5 +567,27 @@ const SearchResults = new Lang.Class({
let resultDisplay = meta.resultDisplay;
resultDisplay.activateSelected();
Main.overview.hide();
},
activateDefault: function() {
if (this._defaultResult && this._defaultResult.actor.visible)
this._defaultResult.activate();
},
highlightDefault: function(highlight) {
this._highlightDefault = highlight;
if (this._defaultResult)
this._defaultResult.setSelected(highlight);
},
navigateFocus: function(direction) {
if (direction == Gtk.DirectionType.TAB_FORWARD && this._defaultResult) {
// The default result appears focused, so navigate directly to the
// next result.
this.actor.navigate_focus(null, direction, false);
this.actor.navigate_focus(global.stage.key_focus, direction, false);
} else {
this.actor.navigate_focus(null, direction, false);
}
}
});

View File

@ -133,14 +133,14 @@ const SearchTab = new Lang.Class({
this._text.connect('text-changed', Lang.bind(this, this._onTextChanged));
this._text.connect('key-press-event', Lang.bind(this, function (o, e) {
// We can't connect to 'activate' here because search providers
// might want to do something with the modifiers in activateSelected.
// might want to do something with the modifiers in activateDefault.
let symbol = e.get_key_symbol();
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
if (this._searchTimeoutId > 0) {
Mainloop.source_remove(this._searchTimeoutId);
this._doSearch();
}
this._searchResults.activateSelected();
this._searchResults.activateDefault();
return true;
}
return false;
@ -152,6 +152,13 @@ const SearchTab = new Lang.Class({
this._capturedEventId = 0;
this._text.connect('key-focus-in', Lang.bind(this, function() {
this._searchResults.highlightDefault(true);
}));
this._text.connect('key-focus-out', Lang.bind(this, function() {
this._searchResults.highlightDefault(false);
}));
// 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...
@ -271,30 +278,18 @@ const SearchTab = new Lang.Class({
_onKeyPress: function(entry, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.Up) {
if (!this.active)
return true;
this._searchResults.selectUp(false);
return true;
} else if (symbol == Clutter.Down) {
if (!this.active)
return true;
this._searchResults.selectDown(false);
return true;
} else if (symbol == Clutter.Escape) {
if (symbol == Clutter.Escape) {
if (this._isActivated()) {
this._reset();
return true;
}
} else if (this.active) {
if (symbol == Clutter.Tab) {
this._searchResults.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
this._searchResults.navigateFocus(Gtk.DirectionType.TAB_FORWARD);
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._searchResults.navigateFocus(Gtk.DirectionType.TAB_BACKWARD);
this._focusTrap.can_focus = true;
return true;
}