[gnome-shell/gbsneto/icon-grid-dnd: 107/117] allView: Add support for custom positioning



commit 6b42a2db802fe19da160c2d7dfc362d5c98834fb
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Jul 2 13:38:11 2019 -0300

    allView: Add support for custom positioning
    
    Use the new 'icon-grid-layout' key to sort the applications and folders
    as it is saved. Applications that are not in the key are appended, and
    when compared to each other, fallback to alphabetical order.
    
    Because the 'icon-grid-layout' key is, by default, empty, this means that
    all icons and folders are sorted alphabetically the first time they are
    displayed, preserving the current behavior.
    
    This commit does not add any way to change the order without modifying
    the GSettings key directly.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/603

 js/ui/appDisplay.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 9b5791dfc..f29cc8c15 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -377,6 +377,12 @@ var AllView = class AllView extends BaseAppView {
             Main.queueDeferredWork(this._redisplayWorkId);
         });
 
+        this._gridSettings = new Gio.Settings({ schema_id: 'org.gnome.shell' });
+        this._gridChangedId = this._gridSettings.connect('changed::icons-data', () => {
+            if (!this._blockGridSettings)
+                Main.queueDeferredWork(this._redisplayWorkId);
+        });
+
         Main.overview.connect('item-drag-begin', this._onDragBegin.bind(this));
         Main.overview.connect('item-drag-end', this._onDragEnd.bind(this));
 
@@ -428,6 +434,7 @@ var AllView = class AllView extends BaseAppView {
         let appSys = Shell.AppSystem.get_default();
 
         this.folderIcons = [];
+        let appsInFolder = [];
 
         let folders = this._folderSettings.get_strv('folder-children');
         folders.forEach(id => {
@@ -439,6 +446,8 @@ var AllView = class AllView extends BaseAppView {
             }
             newApps.push(icon);
             this.folderIcons.push(icon);
+
+            icon.getAppIds().forEach(appId => appsInFolder.push(appId));
         });
 
         // Allow dragging of the icon only if the Dash would accept a drop to
@@ -449,13 +458,54 @@ var AllView = class AllView extends BaseAppView {
         // but we hope that is not used much.
         let favoritesWritable = global.settings.is_writable('favorite-apps');
 
+        // First, add only the app icons that do not have a custom position
+        // set. These icons will be sorted alphabetically.
+        let iconsData = this._gridSettings.get_value('icons-data').deep_unpack();
+        let customPositionedIcons = [];
+
         apps.forEach(appId => {
             let app = appSys.lookup_app(appId);
 
+            if (iconsData[appId]) {
+                customPositionedIcons.push(appId);
+                return;
+            }
+
             let icon = new AppIcon(app, this,
                                    { isDraggable: favoritesWritable });
             newApps.push(icon);
         });
+        newApps.sort((a, b) => a.name.localeCompare(b.name));
+
+        // The stored position is final. That means we need to add the custom
+        // icons in order (first to last) otherwise the custom positioned icons
+        // end up with in the wrong position
+        customPositionedIcons.sort((a, b) => {
+            let indexA = iconsData[a].deep_unpack()['position'].deep_unpack();
+            let indexB = iconsData[b].deep_unpack()['position'].deep_unpack();
+
+            return indexA - indexB;
+        });
+
+        // Now add the icons with a custom position set. Because 'newApps' has
+        // literally all apps -- including the ones that will be hidden -- we
+        // need to translate from visible position to the real position.
+        let visibleApps = newApps.filter(app => !appsInFolder.includes(app.id));
+
+        customPositionedIcons.forEach((appId, index) => {
+            let app = appSys.lookup_app(appId);
+
+            let icon = new AppIcon(app, this,
+                                   { isDraggable: favoritesWritable });
+
+            let position = iconsData[appId].deep_unpack()['position'].deep_unpack();
+
+            // Because we are modifying 'newApps' here, compensate the number
+            // of added items by subtracting 'index'
+            let visibleAppAtPosition = visibleApps[position - index];
+            let realPosition = newApps.indexOf(visibleAppAtPosition);
+            newApps.splice(realPosition, 0, icon);
+        });
 
         return newApps;
     }


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