appDisplay: Add a timeout when switching pages during DnD

Currently when dragging an icon to the space above or below the appGrid
to switch pages, we do so very quickly without checking when the last
page-switch happened. This makes it hard to move icons to pages which
are not the first or the last one, since the other pages are skipped
very quickly.

To fix this, add a timeout of 1 second that blocks switching pages after
a page-switch using drag overshoot occured.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1693
This commit is contained in:
Jonas Dreßler 2019-11-23 22:25:00 +01:00 committed by Florian Müllner
parent 48477443fa
commit 19bb459a57

View File

@ -41,6 +41,7 @@ var APP_ICON_SCALE_IN_TIME = 500;
var APP_ICON_SCALE_IN_DELAY = 700; var APP_ICON_SCALE_IN_DELAY = 700;
const OVERSHOOT_THRESHOLD = 20; const OVERSHOOT_THRESHOLD = 20;
const OVERSHOOT_TIMEOUT = 1000;
const SWITCHEROO_BUS_NAME = 'net.hadess.SwitcherooControl'; const SWITCHEROO_BUS_NAME = 'net.hadess.SwitcherooControl';
const SWITCHEROO_OBJECT_PATH = '/net/hadess/SwitcherooControl'; const SWITCHEROO_OBJECT_PATH = '/net/hadess/SwitcherooControl';
@ -354,6 +355,7 @@ var AllView = class AllView extends BaseAppView {
this._availHeight = 0; this._availHeight = 0;
this._lastOvershootY = -1; this._lastOvershootY = -1;
this._lastOvershootTimeoutId = 0;
Main.overview.connect('hidden', () => this.goToPage(0)); Main.overview.connect('hidden', () => this.goToPage(0));
this._grid.connect('space-opened', () => { this._grid.connect('space-opened', () => {
@ -747,6 +749,13 @@ var AllView = class AllView extends BaseAppView {
this.folderIcons[i].adaptToSize(availWidth, availHeight); this.folderIcons[i].adaptToSize(availWidth, availHeight);
} }
_resetOvershoot() {
if (this._lastOvershootTimeoutId)
GLib.source_remove(this._lastOvershootTimeoutId);
this._lastOvershootTimeoutId = 0;
this._lastOvershootY = -1;
}
_handleDragOvershoot(dragEvent) { _handleDragOvershoot(dragEvent) {
let [, gridY] = this.actor.get_transformed_position(); let [, gridY] = this.actor.get_transformed_position();
let [, gridHeight] = this.actor.get_transformed_size(); let [, gridHeight] = this.actor.get_transformed_size();
@ -760,7 +769,8 @@ var AllView = class AllView extends BaseAppView {
if (dragEvent.y > gridY && dragEvent.y < gridBottom) { if (dragEvent.y > gridY && dragEvent.y < gridBottom) {
// Check whether we moved out the area of the last switch // Check whether we moved out the area of the last switch
if (Math.abs(this._lastOvershootY - dragEvent.y) > OVERSHOOT_THRESHOLD) if (Math.abs(this._lastOvershootY - dragEvent.y) > OVERSHOOT_THRESHOLD)
this._lastOvershootY = -1; this._resetOvershoot();
return; return;
} }
@ -768,20 +778,29 @@ var AllView = class AllView extends BaseAppView {
if (this._lastOvershootY >= 0) if (this._lastOvershootY >= 0)
return; return;
let currentY = this._adjustment.value;
let maxY = this._adjustment.upper - this._adjustment.page_size;
if (dragEvent.y <= gridY && currentY > 0)
this.goToPage(this._grid.currentPage - 1);
else if (dragEvent.y >= gridBottom && currentY < maxY)
this.goToPage(this._grid.currentPage + 1);
else
return; // don't go beyond first/last page
this._lastOvershootY = dragEvent.y; this._lastOvershootY = dragEvent.y;
// Moving above the grid if (this._lastOvershootTimeoutId > 0)
let currentY = this._adjustment.value; GLib.source_remove(this._lastOvershootTimeoutId);
if (dragEvent.y <= gridY && currentY > 0) {
this.goToPage(this._grid.currentPage - 1);
return;
}
// Moving below the grid this._lastOvershootTimeoutId =
let maxY = this._adjustment.upper - this._adjustment.page_size; GLib.timeout_add(GLib.PRIORITY_DEFAULT, OVERSHOOT_TIMEOUT, () => {
if (dragEvent.y >= gridBottom && currentY < maxY) { this._resetOvershoot();
this.goToPage(this._grid.currentPage + 1); this._handleDragOvershoot(dragEvent);
} return GLib.SOURCE_REMOVE;
});
GLib.Source.set_name_by_id(this._lastOvershootTimeoutId,
'[gnome-shell] this._lastOvershootTimeoutId');
} }
_onDragBegin() { _onDragBegin() {
@ -815,7 +834,7 @@ var AllView = class AllView extends BaseAppView {
} }
this._eventBlocker.visible = this._currentPopup !== null; this._eventBlocker.visible = this._currentPopup !== null;
this._lastOvershootY = -1; this._resetOvershoot();
} }
_canAccept(source) { _canAccept(source) {