[gnome-shell] searchDisplay: Cache result display actors



commit af06b78605b7bbcfce9f2c839909c90bbd91daa5
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Feb 8 18:59:15 2013 -0500

    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

 js/ui/appDisplay.js |    6 ++++-
 js/ui/iconGrid.js   |    5 ++++
 js/ui/search.js     |   57 ++++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 55 insertions(+), 13 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index cc711bd..7186d9f 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -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();
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 8bcb56d..4801ac2 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -414,6 +414,11 @@ const IconGrid = new Lang.Class({
 
     removeAll: function() {
         this._items = [];
+        this._grid.remove_all_children();
+    },
+
+    destroyAll: function() {
+        this._items = [];
         this._grid.destroy_all_children();
     },
 
diff --git a/js/ui/search.js b/js/ui/search.js
index 7cd2195..4fb03ee 100644
--- a/js/ui/search.js
+++ b/js/ui/search.js
@@ -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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]