gnome-shell/js/ui
Alexander Mikhaylenko 10cafc55c1 swipeTracker: Rework end point calculation
Previously we used a bunch of heuristics for this. We checked if velocity
was directed towards the nearest snap point and its value was larger than
a threshold. If it is, we completed the swipe, otherwise we cancelled it.

This was good enough at the time, because this code was originally written
for back/forward swipe. Since then, the swipe tracker was extended to
handle arbitrary snap points and not just 0 and 1, or -1 and 0, depending
on text direction. After that it was iterated on, but never significantly
redone.

This worked well enough, but had two problems:

1. In some cases, notably overview, it may be wanted to be able to swipe
   through multiple pages at once. This wasn't really possible because we
   always picked the adjacent snap point.

2. Since we can't do that well, we want to restrict swipes to one page at a
   time. It was done in a rather hacky way by clamping the position into
   [-1, 1] range from the place where we started the swipe. This works
   if we start the swipe from idle position, but if an animation was
   already going, the range would be clamped to arbitrary values, and very
   likely containing only one snap point, which we already swiped past at
   this point. In this case, finishing the swipe would cancel it regardless
   of velocity. This means that if one tries to quickly move through
   carousel pages via swiping, half of the swipes will be inexplicably
   cancelled.

We'll use the deceleration formula from
https://medium.com/@esskeetit/how-uiscrollview-works-e418adc47060#10ce
to calculate then projection point, then pick the nearest snap point and
calculate the duration as we did before. It works well enough for short
distances, but has two problems:

1. It caps the maximum distance at a pretty low value - about 5 pages in my
testing.

2. With how we pick the nearest snap point, it's too easy to accidentally
cancel the swipe,

To combat the first problem, we can modify the curve: only use linear
function at small distances, and smoothly transition it to a parabola
further.

For the second problem we can add two special cases: first, if the swipe
ended up between the initial snap point and the next one, we always prefer
the latter. Second, a good old velocity threshold for cancelling.

We'll also use a slightly smaller deceleration value for touchpad: 0.997
instead of 0.998.

Now that we can pick any snap point, the [-1, 1] clamping doesn't make
sense anymore, so instead let's replace it with a more flexible
mechanism: if we're near a snap point, pick its adjacent snap points.
Otherwise, take the two nearest snap points, and take their adjacent
snap points. This way we have 3 snap points to choose from when
starting a swipe from an idle position, and 4 if we start during an
ongoing transition.

This way, if we've just swiped from snap point n to n+1, the transition
will pick snap points n-1, n, n+1, n+2 and if we swipe again, we will
likely land on n+2. During that transition, if we swipe again, it will
likely have already passed the snap point n+1, so this time the available
snap points will be n, n+1, n+2, n+3, so we can swipe again and it will
still complete, and so on.

This will make it easy to allow multi-page swipes as well, by just
removing the clamping.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1647>
2021-02-08 22:20:26 +00:00
..
components automountManager: Remove unused volume queue 2021-01-19 20:55:11 +00:00
status accessibility/keyboard: Align the panelMenu button style 2021-02-04 20:08:29 +00:00
accessDialog.js
altTab.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
animation.js st/widget: Remove get_resource_scale function 2020-06-30 13:42:18 +00:00
appDisplay.js appDisplay: Do not bind popdown call to grabHelper onUngrab 2021-02-04 21:55:34 +01:00
appFavorites.js
audioDeviceSelection.js audioDeviceSelection: Center-align icons 2020-10-21 03:29:18 +02:00
background.js background: Add option to not use background content size 2021-01-29 21:56:05 +00:00
backgroundMenu.js
barLevel.js cleanup: Define GObject accessors in camelCase 2021-02-03 20:19:29 +01:00
boxpointer.js util: Remove shell_util_get_transformed_allocation 2020-07-29 18:09:53 +02:00
calendar.js calendar: Vertically center align week numbers 2020-08-21 21:40:22 +03:00
checkBox.js
closeDialog.js
ctrlAltTab.js
dash.js dash: Only show separator when there are running apps 2021-01-30 09:44:11 +00:00
dateMenu.js dateMenu: Fix temperature edge case 2020-12-22 09:27:45 +00:00
dialog.js cleanup: Define GObject accessors in camelCase 2021-02-03 20:19:29 +01:00
dnd.js dnd: Update actor position after scaling even when animations are off 2021-02-04 16:39:55 +00:00
edgeDragAction.js
endSessionDialog.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
environment.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
extensionDownloader.js extensionDownloader: Fix check for updates with several extensions 2020-07-15 18:26:11 -06:00
extensionSystem.js extensionSystem: Fix opening Extensions app from notification 2021-01-26 17:12:04 +01:00
focusCaretTracker.js
grabHelper.js
ibusCandidatePopup.js
iconGrid.js cleanup: Define GObject accessors in camelCase 2021-02-03 20:19:29 +01:00
inhibitShortcutsDialog.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
kbdA11yDialog.js cleanup: Remove empty leading/trailing lines in blocks 2020-11-16 18:04:23 +00:00
keyboard.js cleanup: Remove old compatibility code 2020-08-13 23:00:21 +00:00
layout.js cleanup: Define GObject accessors in camelCase 2021-02-03 20:19:29 +01:00
lightbox.js js: Use gjs-defined GObject accessors where possible 2021-02-03 20:19:29 +01:00
locatePointer.js
lookingGlass.js lookingGlass: Port to paint nodes 2020-12-10 16:15:49 +00:00
magnifier.js magnifier: Stop exposing D-Bus interface 2020-12-06 06:18:07 +01:00
main.js main: Show welcome dialogue on first start 2021-02-05 13:41:26 +00:00
messageList.js cleanup: Remove empty leading/trailing lines in blocks 2020-11-16 18:04:23 +00:00
messageTray.js js: Use gjs-defined GObject accessors where possible 2021-02-03 20:19:29 +01:00
modalDialog.js
mpris.js mpris: Hide unused elements to leave more space for the title 2021-02-04 22:42:08 +00:00
notificationDaemon.js notificationDaemon: Fix icon-choosing logic 2021-02-01 13:58:20 +00:00
osdMonitorLabeler.js
osdWindow.js
overview.js overview: Move background to Workspace 2021-01-29 21:56:05 +00:00
overviewControls.js overviewControls: Remove intermediate box 2021-01-29 17:49:52 +01:00
padOsd.js cleanup: Define GObject accessors in camelCase 2021-02-03 20:19:29 +01:00
pageIndicators.js pageIndicators: Remove animated indicators 2021-02-03 09:55:29 +01:00
panel.js panel: Remove drop down arrows from AppMenu and AggregateMenu 2021-01-26 16:53:42 +01:00
panelMenu.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
pointerA11yTimeout.js
pointerWatcher.js
popupMenu.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
remoteSearch.js
ripples.js
runDialog.js runDialog: Trim input before processing 2021-02-08 08:14:46 +00:00
screenShield.js screenShield: Tie LockedHint to locked state 2021-01-07 22:43:42 +01:00
screenshot.js screenshot: Clean up when creating stream failed 2021-01-28 21:47:50 +00:00
scripting.js scripting: Switch to standard async/await pattern 2020-08-12 15:43:38 +00:00
search.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00
sessionMode.js cleanup: Remove old compatibility code 2020-08-13 23:00:21 +00:00
shellDBus.js dbusServices/screensaver: Split out public ScreenSaver service 2020-12-07 16:24:19 +00:00
shellEntry.js
shellMountOperation.js
slider.js
swipeTracker.js swipeTracker: Rework end point calculation 2021-02-08 22:20:26 +00:00
switcherPopup.js cleanup: Remove empty leading/trailing lines in blocks 2020-11-16 18:04:23 +00:00
switchMonitor.js
unlockDialog.js unlockDialog: Use unique unlock-dialog style class 2020-10-07 16:16:57 +00:00
userWidget.js theme: Don't draw border around symbolic user-icon 2020-12-17 21:46:41 +01:00
viewSelector.js viewSelector: Tie workspace fit mode to adjustment 2021-02-03 20:30:30 +00:00
welcomeDialog.js welcomeDialog: Add “welcome” dialog 2021-02-05 13:41:26 +00:00
windowAttentionHandler.js
windowManager.js windowManager: Allow switching workspaces with super-scroll 2021-02-04 20:04:15 +00:00
windowMenu.js
windowPreview.js data: Rename custom close icon 2021-02-05 01:01:09 +01:00
workspace.js workspacesView: Derive workspace state from fit mode 2021-02-03 20:30:30 +00:00
workspaceAnimation.js windowManager: Allow switching workspaces with super-scroll 2021-02-04 20:04:15 +00:00
workspacesView.js workspacesView: Move workspace scroll code to windowManager 2021-02-04 20:04:15 +00:00
workspaceSwitcherPopup.js cleanup: Remove empty leading/trailing lines in blocks 2020-11-16 18:04:23 +00:00
workspaceThumbnail.js cleanup: Define GObject accessors in camelCase 2021-02-03 20:19:29 +01:00
xdndHandler.js cleanup: Use optional chaining and ?? operator 2020-12-02 15:10:29 +00:00