Commit Graph

15 Commits

Author SHA1 Message Date
Carlos Garnacho
ea881ed077 swipeTracker: Reject touch swipes in the wrong directions
We now have multiple touch swipe gestures with matching fingers and
different directions set on the overview hierarchy. Accepting all
touch swipes without checking the direction makes one of these gestures
take control of input, without other gestures having a say on this.

So, look for the direction of the touch events and look if it matches
the expected orientation before accepting the gesture.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>
2021-02-17 14:06:11 +01:00
Carlos Garnacho
504ca7d4c3 swipeTracker: Try harder to start touchpad gestures with a direction
Make the touchpad gesture keep track of its state, and enter in a
rejected state if the swipe is happening in the wrong direction.

Effectively, this means touchpad gestures are locked on a single
direction, and horizontal+vertical swipeTrackers won't be handling
events at the same time.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>
2021-02-17 14:06:11 +01:00
Florian Müllner
e135f077fb swipeTracker: Reject touchpad swipes in the wrong directions
We now have multiple touch swipe gestures with matching fingers and
different directions set on the overview hierarchy. Accepting all
touchpad swipes without checking the direction makes one of these gestures
take control of input, without other gestures having a say on this.

So, look for the direction of the swipe events and look if it matches
the expected orientation.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>
2021-02-17 14:06:11 +01:00
Alexander Mikhaylenko
16f74ebc57 swipeTracker: Add allowLongSwipes property
Since we now have the ability to support swiping through multiple pages,
expose it as a property.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1647>
2021-02-08 22:20:26 +00:00
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
Alexander Mikhaylenko
cf87ab04aa swipeTracker: Calculate velocity using scroll history
In some cases we may get anevent with very low delta at the end of the
swipe. While we can't completely ignore them, we can smooth them using a
scroll history, similarly to what GTK kinetic scrolling does: keep track
of the last 150ms of events, and sum their deltas when calculating the
velocity.

The logic is based on what GTK does in GtkGestureSwipe and
GtkEventControllerScroll.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1647>
2021-02-08 22:20:26 +00:00
Florian Müllner
ac8246050d swipeTracker: Optionally require modifiers for scrolling
The design now calls for super-scroll for workspace switching
in the session, however it is currently only possible for
SwipeTracker to either handle scroll events or not.

In order to support the new use case, add a new :scroll-modifiers
property that allows specifying modifiers for which scroll events
are handled.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1612>
2021-02-04 20:04:15 +00:00
Florian Müllner
0f1b566918 js: Use gjs-defined GObject accessors where possible
Nowadays gjs allows to omit get/set accessors for read-write properties,
and will define reasonable defaults in that case. In many cases we don't
need anything more than the default handling, let gjs handle those props.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1611>
2021-02-03 20:19:29 +01:00
Georges Basile Stavracas Neto
35d8041656 swipeTracker: Switch to 3-finger gestures
As per design feedback, it's time to switch to 3-finger gestures.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3528

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1562>
2021-01-08 14:28:39 -03:00
Georges Basile Stavracas Neto
1134afd12a swipeTracker: Use AFTER trigger edge for TouchSwipeGesture
Otherwise, we can get stray 'begin' signals from the touch gesture.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1562>
2021-01-08 14:27:02 -03:00
Georges Basile Stavracas Neto
853644d7fe appDisplay: Properly destroy SwipeTracker on destroy
SwipeTracker connects to signals of the stage, but doesn't disconnect on
destroy, leaving them hanging and potentially running callbacks for
destroyed objects.

This is visible when removing a folder by dragging all icons out, and
running the swipe gestures, which will produce a bunch of warnings.

Explicitly destroy, remove, and disconnect the swipe tracker.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1518>
2020-12-02 22:43:04 +00:00
Georges Basile Stavracas Neto
8154728d09 environment: Add Math.clamp
The good old clamp function, now part of the Math family.
Clamp is happy after so many years of loneliness.

This is a strict implementation of the draft ECMAScript
proposal.

https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1295
2020-06-03 12:55:53 -03:00
Daniel van Vugt
bd197789c1 js/ui: Subscribe touchpad gesture handlers to only touchpad events
The touchpad gesture handlers were receiving all events, all the time.
This meant that even mouse movements were getting translated into
JavaScript calls and then discarded by the handlers, which wasted CPU.

Now we subscribe the touchpad gesture handlers to only touchpad events.

Prequisite: https://gitlab.gnome.org/GNOME/mutter/merge_requests/1000

Closes: https://gitlab.gnome.org/GNOME/mutter/issues/283

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/925
2020-02-29 13:39:17 +00:00
Alexander Mikhaylenko
a06a418ac1 swipeTracker: Reset scroll gesture state on disabling
Ensure that scrolling works correctly next time it's enabled.

https://gitlab.gnome.org/GNOME/gnome-shell/issues/2177
2020-02-06 17:36:05 +00:00
Alexander Mikhaylenko
a0c0e52229 swipeTracker: Introduce swipe tracker
Add a unified swipe tracker supporting dragging, four-finger swipe on both
touchscreen and touchpad, and touchpad scrolling.

The shared logic is largely same as the one in WebKit and libhandy.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/826
2020-01-10 18:20:22 +01:00