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
This commit is contained in:
parent
3779ac2c8a
commit
10147ee331
@ -115,6 +115,10 @@ const BaseAppView = new Lang.Class({
|
|||||||
this._loadApps();
|
this._loadApps();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getAllItems: function() {
|
||||||
|
return this._allItems;
|
||||||
|
},
|
||||||
|
|
||||||
addItem: function(icon) {
|
addItem: function(icon) {
|
||||||
let id = icon.id;
|
let id = icon.id;
|
||||||
if (this._items[id] !== undefined)
|
if (this._items[id] !== undefined)
|
||||||
@ -124,10 +128,12 @@ const BaseAppView = new Lang.Class({
|
|||||||
this._items[id] = icon;
|
this._items[id] = icon;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadGrid: function() {
|
_compareItems: function(a, b) {
|
||||||
this._allItems.sort(Lang.bind(this, function(a, b) {
|
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
}));
|
},
|
||||||
|
|
||||||
|
loadGrid: function() {
|
||||||
|
this._allItems.sort(this._compareItems);
|
||||||
this._allItems.forEach(Lang.bind(this, function(item) {
|
this._allItems.forEach(Lang.bind(this, function(item) {
|
||||||
this._grid.addItem(item);
|
this._grid.addItem(item);
|
||||||
}));
|
}));
|
||||||
@ -363,6 +369,32 @@ const AllView = new Lang.Class({
|
|||||||
this.parent();
|
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() {
|
_loadApps: function() {
|
||||||
let apps = Gio.AppInfo.get_all().filter(function(appInfo) {
|
let apps = Gio.AppInfo.get_all().filter(function(appInfo) {
|
||||||
return appInfo.should_show();
|
return appInfo.should_show();
|
||||||
@ -374,20 +406,10 @@ const AllView = new Lang.Class({
|
|||||||
|
|
||||||
let folders = this._folderSettings.get_strv('folder-children');
|
let folders = this._folderSettings.get_strv('folder-children');
|
||||||
folders.forEach(Lang.bind(this, function(id) {
|
folders.forEach(Lang.bind(this, function(id) {
|
||||||
let folder = new Gio.Settings({ schema_id: 'org.gnome.desktop.app-folders.folder',
|
let path = this._folderSettings.path + 'folders/' + id + '/';
|
||||||
path: this._folderSettings.path + 'folders/' + id + '/' });
|
let icon = new FolderIcon(id, path, this);
|
||||||
folder.connect('changed', Lang.bind(this, function() {
|
icon.connect('name-changed', Lang.bind(this, this._itemNameChanged));
|
||||||
Main.queueDeferredWork(this._redisplayWorkId);
|
icon.connect('apps-changed', Lang.bind(this, this._refilterApps));
|
||||||
}));
|
|
||||||
|
|
||||||
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);
|
|
||||||
this.addItem(icon);
|
this.addItem(icon);
|
||||||
this.folderIcons.push(icon);
|
this.folderIcons.push(icon);
|
||||||
}));
|
}));
|
||||||
@ -399,6 +421,7 @@ const AllView = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
this.loadGrid();
|
this.loadGrid();
|
||||||
|
this._refilterApps();
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentPageY: function() {
|
getCurrentPageY: function() {
|
||||||
@ -986,11 +1009,12 @@ const FolderView = new Lang.Class({
|
|||||||
const FolderIcon = new Lang.Class({
|
const FolderIcon = new Lang.Class({
|
||||||
Name: 'FolderIcon',
|
Name: 'FolderIcon',
|
||||||
|
|
||||||
_init: function(id, name, apps, parentView) {
|
_init: function(id, path, parentView) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
|
||||||
this._parentView = parentView;
|
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',
|
this.actor = new St.Button({ style_class: 'app-well-app app-folder',
|
||||||
button_mask: St.ButtonMask.ONE,
|
button_mask: St.ButtonMask.ONE,
|
||||||
toggle_mode: true,
|
toggle_mode: true,
|
||||||
@ -1001,22 +1025,11 @@ const FolderIcon = new Lang.Class({
|
|||||||
// whether we need to update arrow side, position etc.
|
// whether we need to update arrow side, position etc.
|
||||||
this._popupInvalidated = false;
|
this._popupInvalidated = false;
|
||||||
|
|
||||||
this.icon = new IconGrid.BaseIcon(this.name,
|
this.icon = new IconGrid.BaseIcon('', { createIcon: Lang.bind(this, this._createIcon), setSizeManually: true });
|
||||||
{ createIcon: Lang.bind(this, this._createIcon), setSizeManually: true });
|
|
||||||
this.actor.set_child(this.icon.actor);
|
this.actor.set_child(this.icon.actor);
|
||||||
this.actor.label_actor = this.icon.label;
|
this.actor.label_actor = this.icon.label;
|
||||||
|
|
||||||
this.view = new FolderView();
|
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,
|
this.actor.connect('clicked', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
@ -1029,6 +1042,48 @@ const FolderIcon = new Lang.Class({
|
|||||||
if (!this.actor.mapped && this._popup)
|
if (!this.actor.mapped && this._popup)
|
||||||
this._popup.popdown();
|
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) {
|
_createIcon: function(iconSize) {
|
||||||
@ -1107,6 +1162,7 @@ const FolderIcon = new Lang.Class({
|
|||||||
this._popupInvalidated = true;
|
this._popupInvalidated = true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(FolderIcon.prototype);
|
||||||
|
|
||||||
const AppFolderPopup = new Lang.Class({
|
const AppFolderPopup = new Lang.Class({
|
||||||
Name: 'AppFolderPopup',
|
Name: 'AppFolderPopup',
|
||||||
|
@ -433,6 +433,10 @@ const IconGrid = new Lang.Class({
|
|||||||
this._grid.add_actor(item.actor);
|
this._grid.add_actor(item.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeItem: function(item) {
|
||||||
|
this._grid.remove_child(item.actor);
|
||||||
|
},
|
||||||
|
|
||||||
getItemAtIndex: function(index) {
|
getItemAtIndex: function(index) {
|
||||||
return this._grid.get_child_at_index(index);
|
return this._grid.get_child_at_index(index);
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user