appDisplay: Switch page when hovering the next-page indicator during DND

In addition to the "overshoot/bumping into monitor edge" behavior we already
have, we also want to switch pages when simply hovering above the prev/next
page indicators.

This page switch shouldn't happen immediately though, it needs to be kicked
off using a timeout instead. The reason for that is that the next/prev page
indicators are large areas, and simply dragging there isn't enough of a
gesture to really interpret as "the user wants to switch pages".

After this page switch has been toggled once, it can be repeated using the
same "repeat" timeout we introduced with the last commit.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2581>
This commit is contained in:
Jonas Dreßler 2022-12-09 23:43:23 +01:00 committed by Marge Bot
parent 549adf3218
commit 560565d828

View File

@ -43,7 +43,9 @@ const PAGE_PREVIEW_ANIMATION_TIME = 150;
const PAGE_INDICATOR_FADE_TIME = 200;
const PAGE_PREVIEW_RATIO = 0.20;
const DRAG_PAGE_SWITCH_INITIAL_TIMEOUT = 1000;
const DRAG_PAGE_SWITCH_IMMEDIATELY_THRESHOLD_PX = 20;
const DRAG_PAGE_SWITCH_REPEAT_TIMEOUT = 1000;
const DELAYED_MOVE_TIMEOUT = 200;
@ -838,7 +840,12 @@ var BaseAppView = GObject.registerClass({
this._delayedMoveData = null;
}
_resetDragPageSwitchRepeat() {
_resetDragPageSwitch() {
if (this._dragPageSwitchInitialTimeoutId) {
GLib.source_remove(this._dragPageSwitchInitialTimeoutId);
delete this._dragPageSwitchInitialTimeoutId;
}
if (this._dragPageSwitchRepeatTimeoutId) {
GLib.source_remove(this._dragPageSwitchRepeatTimeoutId);
delete this._dragPageSwitchRepeatTimeoutId;
@ -848,8 +855,7 @@ var BaseAppView = GObject.registerClass({
}
_setupDragPageSwitchRepeat(direction) {
if (this._dragPageSwitchRepeatTimeoutId)
GLib.source_remove(this._dragPageSwitchRepeatTimeoutId);
this._resetDragPageSwitch();
this._dragPageSwitchRepeatTimeoutId =
GLib.timeout_add(GLib.PRIORITY_DEFAULT, DRAG_PAGE_SWITCH_REPEAT_TIMEOUT, () => {
@ -864,7 +870,7 @@ var BaseAppView = GObject.registerClass({
_dragMaybeSwitchPageImmediately(dragEvent) {
// Already animating
if (this._adjustment.get_transition('value') !== null)
return;
return false;
const [gridX, gridY] = this.get_transformed_position();
const [gridWidth, gridHeight] = this.get_transformed_size();
@ -887,14 +893,14 @@ var BaseAppView = GObject.registerClass({
// pages.
if (this._lastOvershootCoord >= 0 &&
moveDelta > DRAG_PAGE_SWITCH_IMMEDIATELY_THRESHOLD_PX)
this._resetDragPageSwitchRepeat();
this._resetDragPageSwitch();
return;
return false;
}
// Still in the area of the previous overshoot
if (this._lastOvershootCoord >= 0)
return;
return false;
let direction = dragCoord <= gridStart ? -1 : 1;
if (this.get_text_direction() === Clutter.TextDirection.RTL)
@ -904,6 +910,26 @@ var BaseAppView = GObject.registerClass({
this._setupDragPageSwitchRepeat(direction);
this._lastOvershootCoord = dragCoord;
return true;
}
_maybeSetupDragPageSwitchInitialTimeout(dragEvent) {
if (this._dragPageSwitchInitialTimeoutId || this._dragPageSwitchRepeatTimeoutId)
return;
const {targetActor} = dragEvent;
this._dragPageSwitchInitialTimeoutId =
GLib.timeout_add(GLib.PRIORITY_DEFAULT, DRAG_PAGE_SWITCH_INITIAL_TIMEOUT, () => {
const direction = targetActor === this._prevPageIndicator ? -1 : 1;
this.goToPage(this._grid.currentPage + direction);
this._setupDragPageSwitchRepeat(direction);
delete this._dragPageSwitchInitialTimeoutId;
return GLib.SOURCE_REMOVE;
});
}
_onDragBegin() {
@ -923,8 +949,23 @@ var BaseAppView = GObject.registerClass({
const appIcon = dragEvent.source;
if (appIcon instanceof AppViewItem)
this._dragMaybeSwitchPageImmediately(dragEvent);
if (appIcon instanceof AppViewItem) {
// Two ways of switching pages during DND:
// 1) When "bumping" the cursor against the monitor edge, we switch
// page immediately.
// 2) When hovering over the next-page indicator for a certain time,
// we also switch page.
if (!this._dragMaybeSwitchPageImmediately(dragEvent)) {
const {targetActor} = dragEvent;
if (targetActor === this._prevPageIndicator ||
targetActor === this._nextPageIndicator)
this._maybeSetupDragPageSwitchInitialTimeout(dragEvent);
else
this._resetDragPageSwitch();
}
}
this._maybeMoveItem(dragEvent);
@ -944,7 +985,7 @@ var BaseAppView = GObject.registerClass({
this._dragMonitor = null;
}
this._resetDragPageSwitchRepeat();
this._resetDragPageSwitch();
this._appGridLayout.hidePageIndicators();
this._swipeTracker.enabled = true;