[gnome-shell/gbsneto/custom-icon-positions: 19/28] appDisplay: Add placeholder when moving from folder dialog



commit 48e94960be544faca3fa7816a10b92201461d4d5
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Jun 23 12:05:27 2020 -0300

    appDisplay: Add placeholder when moving from folder dialog
    
    When moving an icon from a folder dialog, the app grid doesn't
    really have an icon to move around.
    
    Add a placeholder icon and hijack it in the various places.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1284

 js/ui/appDisplay.js | 48 ++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 4 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index bb5125f9e6..7ced6f8294 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -668,6 +668,7 @@ class AppDisplay extends BaseAppView {
         this._lastOvershootTimeoutId = 0;
         this._delayedMoveId = 0;
         this._targetDropPosition = null;
+        this._placeholder = null;
 
         Main.overview.connect('hidden', () => this.goToPage(0));
 
@@ -755,17 +756,44 @@ class AppDisplay extends BaseAppView {
         this._pageManager.pages = pages;
     }
 
+    _ensurePlaceholder(source) {
+        if (this._placeholder)
+            return;
+
+        const appSys = Shell.AppSystem.get_default();
+        const app = appSys.lookup_app(source.id);
+
+        const isDraggable =
+            global.settings.is_writable('favorite-apps') ||
+            global.settings.is_writable('app-picker-layout');
+
+        this._placeholder = new AppIcon(app, { isDraggable });
+        this._placeholder.scaleAndFade();
+        this._redisplay();
+    }
+
+    _removePlaceholder() {
+        if (this._placeholder) {
+            this._placeholder.undoScaleAndFade();
+            this._placeholder = null;
+            this._redisplay();
+        }
+    }
+
     getAppInfos() {
         return this._appInfoList;
     }
 
     _getItemPosition(item) {
+        if (item === this._placeholder)
+            return this._grid.getItemPosition(item);
+
         return this._pageManager.getAppPosition(item.id);
     }
 
     _compareItems(a, b) {
-        const [aPage, aPosition] = this._pageManager.getAppPosition(a.id);
-        const [bPage, bPosition] = this._pageManager.getAppPosition(b.id);
+        const [aPage, aPosition] = this._getItemPosition(a);
+        const [bPage, bPosition] = this._getItemPosition(b);
 
         if (aPage === -1 && bPage === -1)
             return a.name.localeCompare(b.name);
@@ -843,6 +871,10 @@ class AppDisplay extends BaseAppView {
             appIcons.push(icon);
         });
 
+        // At last, if there's a placeholder available, add it
+        if (this._placeholder)
+            appIcons.push(this._placeholder);
+
         return appIcons;
     }
 
@@ -955,7 +987,7 @@ class AppDisplay extends BaseAppView {
         if (!success)
             return;
 
-        const { source } = dragEvent;
+        const source = this._placeholder ? this._placeholder : dragEvent.source;
         const [page, position, dragLocation] =
             this._getDropTarget(x, y, source);
         const item = position !== -1
@@ -1043,11 +1075,18 @@ class AppDisplay extends BaseAppView {
             '[gnome-shell] this._lastOvershootTimeoutId');
     }
 
-    _onDragBegin() {
+    _onDragBegin(_overview, source) {
         this._dragMonitor = {
             dragMotion: this._onDragMotion.bind(this),
         };
         DND.addDragMonitor(this._dragMonitor);
+
+        // When dragging from a folder dialog, the dragged app icon doesn't
+        // exist in AppDisplay. We work around that by adding a placeholder
+        // icon that is either destroyed on cancel, or becomes the effective
+        // new icon when dropped.
+        if (_getViewFromIcon(source) instanceof FolderView)
+            this._ensurePlaceholder(source);
     }
 
     _onDragMotion(dragEvent) {
@@ -1074,6 +1113,7 @@ class AppDisplay extends BaseAppView {
         }
 
         this._resetOvershoot();
+        this._removePlaceholder();
     }
 
     _onDragCancelled(_overview, source) {


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