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
This commit is contained in:
Georges Basile Stavracas Neto 2020-06-23 12:05:27 -03:00 committed by Florian Müllner
parent 701d110493
commit 578ae29ed2

View File

@ -668,6 +668,7 @@ class AppDisplay extends BaseAppView {
this._lastOvershootTimeoutId = 0; this._lastOvershootTimeoutId = 0;
this._delayedMoveId = 0; this._delayedMoveId = 0;
this._targetDropPosition = null; this._targetDropPosition = null;
this._placeholder = null;
Main.overview.connect('hidden', () => this.goToPage(0)); Main.overview.connect('hidden', () => this.goToPage(0));
@ -755,17 +756,44 @@ class AppDisplay extends BaseAppView {
this._pageManager.pages = pages; 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() { getAppInfos() {
return this._appInfoList; return this._appInfoList;
} }
_getItemPosition(item) { _getItemPosition(item) {
if (item === this._placeholder)
return this._grid.getItemPosition(item);
return this._pageManager.getAppPosition(item.id); return this._pageManager.getAppPosition(item.id);
} }
_compareItems(a, b) { _compareItems(a, b) {
const [aPage, aPosition] = this._pageManager.getAppPosition(a.id); const [aPage, aPosition] = this._getItemPosition(a);
const [bPage, bPosition] = this._pageManager.getAppPosition(b.id); const [bPage, bPosition] = this._getItemPosition(b);
if (aPage === -1 && bPage === -1) if (aPage === -1 && bPage === -1)
return a.name.localeCompare(b.name); return a.name.localeCompare(b.name);
@ -843,6 +871,10 @@ class AppDisplay extends BaseAppView {
appIcons.push(icon); appIcons.push(icon);
}); });
// At last, if there's a placeholder available, add it
if (this._placeholder)
appIcons.push(this._placeholder);
return appIcons; return appIcons;
} }
@ -955,7 +987,7 @@ class AppDisplay extends BaseAppView {
if (!success) if (!success)
return; return;
const { source } = dragEvent; const source = this._placeholder ? this._placeholder : dragEvent.source;
const [page, position, dragLocation] = const [page, position, dragLocation] =
this._getDropTarget(x, y, source); this._getDropTarget(x, y, source);
const item = position !== -1 const item = position !== -1
@ -1041,11 +1073,18 @@ class AppDisplay extends BaseAppView {
'[gnome-shell] this._lastOvershootTimeoutId'); '[gnome-shell] this._lastOvershootTimeoutId');
} }
_onDragBegin() { _onDragBegin(_overview, source) {
this._dragMonitor = { this._dragMonitor = {
dragMotion: this._onDragMotion.bind(this), dragMotion: this._onDragMotion.bind(this),
}; };
DND.addDragMonitor(this._dragMonitor); 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) { _onDragMotion(dragEvent) {
@ -1072,6 +1111,7 @@ class AppDisplay extends BaseAppView {
} }
this._resetOvershoot(); this._resetOvershoot();
this._removePlaceholder();
} }
_onDragCancelled(_overview, source) { _onDragCancelled(_overview, source) {