searchDisplay: Cache result display actors

When we create a result actor, cache it, so it can be used for
subsearches of the same initial. For now, to keep memory usage
and the stage graph relatively clean, don't persist the actors
across searches, but maybe we should do this in the future.

This also means that we don't query getResultMetas for items
that we've seen in the same initial search.

https://bugzilla.gnome.org/show_bug.cgi?id=704912
This commit is contained in:
Jasper St. Pierre 2013-02-08 18:59:15 -05:00
parent 3749b09366
commit af06b78605
3 changed files with 55 additions and 13 deletions

View File

@ -92,7 +92,7 @@ const BaseAppView = new Lang.Class({
},
removeAll: function() {
this._grid.removeAll();
this._grid.destroyAll();
this._items = {};
this._allItems = [];
},
@ -613,6 +613,10 @@ const FrequentView = new Lang.Class({
return this._usage.get_most_used("").length >= MIN_FREQUENT_APPS_COUNT;
},
removeAll: function() {
this._grid.destroyAll();
},
loadApps: function() {
let mostUsed = this._usage.get_most_used ("");
let hasUsefulData = this.hasUsefulData();

View File

@ -413,6 +413,11 @@ const IconGrid = new Lang.Class({
},
removeAll: function() {
this._items = [];
this._grid.remove_all_children();
},
destroyAll: function() {
this._items = [];
this._grid.destroy_all_children();
},

View File

@ -323,6 +323,8 @@ const SearchResultsBase = new Lang.Class({
let separator = new Separator.HorizontalSeparator({ style_class: 'search-section-separator' });
this.actor.add(separator.actor);
this._resultDisplays = {};
},
destroy: function() {
@ -334,6 +336,7 @@ const SearchResultsBase = new Lang.Class({
},
clear: function() {
this._resultDisplays = {};
this._clearResultDisplay();
this.actor.hide();
},
@ -349,6 +352,27 @@ const SearchResultsBase = new Lang.Class({
_setMoreIconVisible: function(visible) {
},
_ensureResultActors: function(results, callback) {
let metasNeeded = results.filter(Lang.bind(this, function(resultId) {
return this._resultDisplays[resultId] === undefined;
}));
if (metasNeeded.length === 0) {
callback();
} else {
this.provider.getResultMetas(metasNeeded, Lang.bind(this, function(metas) {
metasNeeded.forEach(Lang.bind(this, function(resultId, i) {
let meta = metas[i];
let display = this._createResultDisplay(meta);
display.connect('activate', Lang.bind(this, this._activateResult));
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
this._resultDisplays[resultId] = display;
}));
callback();
}));
}
},
updateSearch: function(providerResults, terms, callback) {
this._terms = terms;
@ -361,15 +385,17 @@ const SearchResultsBase = new Lang.Class({
let results = this.provider.filterResults(providerResults, maxResults);
let hasMoreResults = results.length < providerResults.length;
this.provider.getResultMetas(results, Lang.bind(this, function(metas) {
this.clear();
this._ensureResultActors(results, Lang.bind(this, function() {
this._clearResultDisplay();
// To avoid CSS transitions causing flickering when
// the first search result stays the same, we hide the
// content while filling in the results.
this.actor.hide();
this._clearResultDisplay();
this._renderResults(metas);
results.forEach(Lang.bind(this, function(resultId) {
this._addItem(this._resultDisplays[resultId]);
}));
this._setMoreIconVisible(hasMoreResults && this.provider.canLaunchSearch);
this.actor.show();
callback();
@ -414,17 +440,16 @@ const ListSearchResults = new Lang.Class({
return MAX_LIST_SEARCH_RESULTS_ROWS;
},
_renderResults: function(metas) {
for (let i = 0; i < metas.length; i++) {
let display = new ListSearchResult(this.provider, metas[i]);
display.connect('activate', Lang.bind(this, this._activateResult));
display.actor.connect('key-focus-in', Lang.bind(this, this._keyFocusIn));
this._content.add_actor(display.actor);
}
_clearResultDisplay: function () {
this._content.remove_all_children();
},
_clearResultDisplay: function () {
this._content.destroy_all_children();
_createResultDisplay: function(meta) {
return new ListSearchResult(this.provider, meta);
},
_addItem: function(display) {
this._content.add_actor(display.actor);
},
getFirstResult: function() {
@ -468,6 +493,14 @@ const GridSearchResults = new Lang.Class({
this._grid.removeAll();
},
_createResultDisplay: function(meta) {
return new GridSearchResult(this.provider, meta);
},
_addItem: function(display) {
this._grid.addItem(display.actor);
},
getFirstResult: function() {
if (this._grid.visibleItemsCount() > 0)
return this._grid.getItemAtIndex(0)._delegate;