[gnome-shell] appDisplay: Make refiltering folders more efficient
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] appDisplay: Make refiltering folders more efficient
- Date: Wed, 29 Jan 2014 19:05:04 +0000 (UTC)
commit 10147ee3318ac0d0da2dae07bab4266b7264fd1d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Tue Jan 28 11:36:57 2014 -0500
appDisplay: Make refiltering folders more efficient
Rather than queueing a full redisplay, simply filter the apps inside
folders by toggling the icon's visibility.
https://bugzilla.gnome.org/show_bug.cgi?id=723179
js/ui/appDisplay.js | 118 +++++++++++++++++++++++++++++++++++++-------------
js/ui/iconGrid.js | 4 ++
2 files changed, 91 insertions(+), 31 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 1e15087..165fa59 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -115,6 +115,10 @@ const BaseAppView = new Lang.Class({
this._loadApps();
},
+ getAllItems: function() {
+ return this._allItems;
+ },
+
addItem: function(icon) {
let id = icon.id;
if (this._items[id] !== undefined)
@@ -124,10 +128,12 @@ const BaseAppView = new Lang.Class({
this._items[id] = icon;
},
+ _compareItems: function(a, b) {
+ return a.name.localeCompare(b.name);
+ },
+
loadGrid: function() {
- this._allItems.sort(Lang.bind(this, function(a, b) {
- return a.name.localeCompare(b.name);
- }));
+ this._allItems.sort(this._compareItems);
this._allItems.forEach(Lang.bind(this, function(item) {
this._grid.addItem(item);
}));
@@ -363,6 +369,32 @@ const AllView = new Lang.Class({
this.parent();
},
+ _itemNameChanged: function(item) {
+ // If an item's name changed, we can pluck it out of where it's
+ // supposed to be and reinsert it where it's sorted.
+ let oldIdx = this._allItems.indexOf(item);
+ this._allItems.splice(oldIdx, 1);
+ let newIdx = Util.insertSorted(this._allItems, item, this._compareItems);
+
+ this._grid.removeItem(item);
+ this._grid.addItem(item, newIdx);
+ },
+
+ _refilterApps: function() {
+ this._allItems.forEach(function(icon) {
+ if (icon instanceof AppIcon)
+ icon.actor.visible = true;
+ });
+
+ this.folderIcons.forEach(Lang.bind(this, function(folder) {
+ let folderApps = folder.getAppIds();
+ folderApps.forEach(Lang.bind(this, function(appId) {
+ let appIcon = this._items[appId];
+ appIcon.actor.visible = false;
+ }));
+ }));
+ },
+
_loadApps: function() {
let apps = Gio.AppInfo.get_all().filter(function(appInfo) {
return appInfo.should_show();
@@ -374,20 +406,10 @@ const AllView = new Lang.Class({
let folders = this._folderSettings.get_strv('folder-children');
folders.forEach(Lang.bind(this, function(id) {
- let folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
- path: this._folderSettings.path + 'folders/' + id + '/' });
- folder.connect('changed', Lang.bind(this, function() {
- Main.queueDeferredWork(this._redisplayWorkId);
- }));
-
- let folderName = _getFolderName(folder);
- let folderApps = folder.get_strv('apps');
- folderApps.forEach(function(appId) {
- let idx = apps.indexOf(appId);
- if (idx >= 0)
- apps.splice(idx, 1);
- });
- let icon = new FolderIcon(id, folderName, folderApps, this);
+ let path = this._folderSettings.path + 'folders/' + id + '/';
+ let icon = new FolderIcon(id, path, this);
+ icon.connect('name-changed', Lang.bind(this, this._itemNameChanged));
+ icon.connect('apps-changed', Lang.bind(this, this._refilterApps));
this.addItem(icon);
this.folderIcons.push(icon);
}));
@@ -399,6 +421,7 @@ const AllView = new Lang.Class({
}));
this.loadGrid();
+ this._refilterApps();
},
getCurrentPageY: function() {
@@ -986,11 +1009,12 @@ const FolderView = new Lang.Class({
const FolderIcon = new Lang.Class({
Name: 'FolderIcon',
- _init: function(id, name, apps, parentView) {
+ _init: function(id, path, parentView) {
this.id = id;
- this.name = name;
this._parentView = parentView;
+ this._folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
+ path: path });
this.actor = new St.Button({ style_class: 'app-well-app app-folder',
button_mask: St.ButtonMask.ONE,
toggle_mode: true,
@@ -1001,22 +1025,11 @@ const FolderIcon = new Lang.Class({
// whether we need to update arrow side, position etc.
this._popupInvalidated = false;
- this.icon = new IconGrid.BaseIcon(this.name,
- { createIcon: Lang.bind(this, this._createIcon), setSizeManually:
true });
+ this.icon = new IconGrid.BaseIcon('', { createIcon: Lang.bind(this, this._createIcon),
setSizeManually: true });
this.actor.set_child(this.icon.actor);
this.actor.label_actor = this.icon.label;
this.view = new FolderView();
- let appSys = Shell.AppSystem.get_default();
- apps.forEach(Lang.bind(this, function(appId) {
- let app = appSys.lookup_app(appId);
- if (!app)
- return;
-
- let icon = new AppIcon(app);
- this.view.addItem(icon);
- }));
- this.view.loadGrid();
this.actor.connect('clicked', Lang.bind(this,
function() {
@@ -1029,6 +1042,48 @@ const FolderIcon = new Lang.Class({
if (!this.actor.mapped && this._popup)
this._popup.popdown();
}));
+
+ this._folder.connect('changed', Lang.bind(this, this._redisplay));
+ this._redisplay();
+ },
+
+ getAppIds: function() {
+ return this.view.getAllItems().map(function(item) {
+ return item.id;
+ });
+ },
+
+ _updateName: function() {
+ let name = _getFolderName(this._folder);
+ if (this.name == name)
+ return;
+
+ this.name = name;
+ this.icon.label.text = this.name;
+ this.emit('name-changed');
+ },
+
+ _redisplay: function() {
+ this._updateName();
+
+ this.view.removeAll();
+
+ let appSys = Shell.AppSystem.get_default();
+
+ let folderApps = this._folder.get_strv('apps');
+ folderApps.forEach(Lang.bind(this, function(appId) {
+ let app = appSys.lookup_app(appId);
+ if (!app)
+ return;
+
+ if (!app.get_app_info().should_show())
+ return;
+
+ let icon = new AppIcon(app);
+ this.view.addItem(icon);
+ }));
+ this.view.loadGrid();
+ this.emit('apps-changed');
},
_createIcon: function(iconSize) {
@@ -1107,6 +1162,7 @@ const FolderIcon = new Lang.Class({
this._popupInvalidated = true;
},
});
+Signals.addSignalMethods(FolderIcon.prototype);
const AppFolderPopup = new Lang.Class({
Name: 'AppFolderPopup',
diff --git a/js/ui/iconGrid.js b/js/ui/iconGrid.js
index 64a5442..d35c97b 100644
--- a/js/ui/iconGrid.js
+++ b/js/ui/iconGrid.js
@@ -433,6 +433,10 @@ const IconGrid = new Lang.Class({
this._grid.add_actor(item.actor);
},
+ removeItem: function(item) {
+ this._grid.remove_child(item.actor);
+ },
+
getItemAtIndex: function(index) {
return this._grid.get_child_at_index(index);
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]