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:
parent
c7a37660ce
commit
b864b03a65
@ -190,6 +190,13 @@ const GridSearchResults = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
let targetActor = this._grid.getItemAtIndex(this.selectionIndex);
|
let targetActor = this._grid.getItemAtIndex(this.selectionIndex);
|
||||||
targetActor._delegate.activate();
|
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._openSearchProviders = [];
|
||||||
this._openSearchSystem.connect('changed', Lang.bind(this, this._updateOpenSearchProviderButtons));
|
this._openSearchSystem.connect('changed', Lang.bind(this, this._updateOpenSearchProviderButtons));
|
||||||
this._updateOpenSearchProviderButtons();
|
this._updateOpenSearchProviderButtons();
|
||||||
|
|
||||||
|
this._highlightDefault = false;
|
||||||
|
this._defaultResult = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateOpenSearchProviderButtons: function() {
|
_updateOpenSearchProviderButtons: function() {
|
||||||
@ -284,6 +294,16 @@ const SearchResults = new Lang.Class({
|
|||||||
button.set_child(bin);
|
button.set_child(bin);
|
||||||
provider.actor = button;
|
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);
|
this._searchProvidersBox.add(button);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -364,17 +384,31 @@ const SearchResults = new Lang.Class({
|
|||||||
if (this._selectedOpenSearchButton > -1 || this._selectedProvider > -1)
|
if (this._selectedOpenSearchButton > -1 || this._selectedProvider > -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let newDefaultResult = null;
|
||||||
|
|
||||||
for (let i = 0; i < this._providerMeta.length; i++) {
|
for (let i = 0; i < this._providerMeta.length; i++) {
|
||||||
let meta = this._providerMeta[i];
|
let meta = this._providerMeta[i];
|
||||||
if (meta.hasPendingResults)
|
if (meta.hasPendingResults)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (meta.actor.visible)
|
let firstResult = meta.resultDisplay.getFirstResult();
|
||||||
|
if (firstResult && firstResult.actor.visible) {
|
||||||
|
newDefaultResult = firstResult;
|
||||||
break; // select this one!
|
break; // select this one!
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.selectDown(false);
|
if (!newDefaultResult)
|
||||||
this._initialSelectionSet = true;
|
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) {
|
_updateCurrentResults: function(searchSystem, results) {
|
||||||
@ -428,11 +462,9 @@ const SearchResults = new Lang.Class({
|
|||||||
let terms = searchSystem.getTerms();
|
let terms = searchSystem.getTerms();
|
||||||
this._openSearchSystem.setSearchTerms(terms);
|
this._openSearchSystem.setSearchTerms(terms);
|
||||||
|
|
||||||
// To avoid CSS transitions causing flickering
|
// To avoid CSS transitions causing flickering when the first search
|
||||||
// of the selection when the first search result
|
// result stays the same, we hide the content while filling in the
|
||||||
// stays the same, we hide the content while
|
// results.
|
||||||
// filling in the results and setting the initial
|
|
||||||
// selection.
|
|
||||||
this._content.hide();
|
this._content.hide();
|
||||||
|
|
||||||
for (let i = 0; i < results.length; i++) {
|
for (let i = 0; i < results.length; i++) {
|
||||||
@ -535,5 +567,27 @@ const SearchResults = new Lang.Class({
|
|||||||
let resultDisplay = meta.resultDisplay;
|
let resultDisplay = meta.resultDisplay;
|
||||||
resultDisplay.activateSelected();
|
resultDisplay.activateSelected();
|
||||||
Main.overview.hide();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -133,14 +133,14 @@ const SearchTab = new Lang.Class({
|
|||||||
this._text.connect('text-changed', Lang.bind(this, this._onTextChanged));
|
this._text.connect('text-changed', Lang.bind(this, this._onTextChanged));
|
||||||
this._text.connect('key-press-event', Lang.bind(this, function (o, e) {
|
this._text.connect('key-press-event', Lang.bind(this, function (o, e) {
|
||||||
// We can't connect to 'activate' here because search providers
|
// 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();
|
let symbol = e.get_key_symbol();
|
||||||
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
|
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
|
||||||
if (this._searchTimeoutId > 0) {
|
if (this._searchTimeoutId > 0) {
|
||||||
Mainloop.source_remove(this._searchTimeoutId);
|
Mainloop.source_remove(this._searchTimeoutId);
|
||||||
this._doSearch();
|
this._doSearch();
|
||||||
}
|
}
|
||||||
this._searchResults.activateSelected();
|
this._searchResults.activateDefault();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -152,6 +152,13 @@ const SearchTab = new Lang.Class({
|
|||||||
|
|
||||||
this._capturedEventId = 0;
|
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
|
// Since the entry isn't inside the results container we install this
|
||||||
// dummy widget as the last results container child so that we can
|
// dummy widget as the last results container child so that we can
|
||||||
// include the entry in the keynav tab path...
|
// include the entry in the keynav tab path...
|
||||||
@ -271,30 +278,18 @@ const SearchTab = new Lang.Class({
|
|||||||
|
|
||||||
_onKeyPress: function(entry, event) {
|
_onKeyPress: function(entry, event) {
|
||||||
let symbol = event.get_key_symbol();
|
let symbol = event.get_key_symbol();
|
||||||
if (symbol == Clutter.Up) {
|
if (symbol == Clutter.Escape) {
|
||||||
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 (this._isActivated()) {
|
if (this._isActivated()) {
|
||||||
this._reset();
|
this._reset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (this.active) {
|
} else if (this.active) {
|
||||||
if (symbol == Clutter.Tab) {
|
if (symbol == Clutter.Tab) {
|
||||||
this._searchResults.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
this._searchResults.navigateFocus(Gtk.DirectionType.TAB_FORWARD);
|
||||||
return true;
|
return true;
|
||||||
} else if (symbol == Clutter.ISO_Left_Tab) {
|
} else if (symbol == Clutter.ISO_Left_Tab) {
|
||||||
this._focusTrap.can_focus = false;
|
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;
|
this._focusTrap.can_focus = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user