It was previously possible for event dispatch to occurr during the
brief window where the tree had been marked dirty but before it had
been relaid out by reassemble, which would cause assertions to fire if
someone did a hot reload while touching the device.
It was 8.0. It's now arbitrarily 18.0.
Changing this required adjusting some tests. Adjusting the tests
required debugging the tests. Debugging the tests required some tools
to help debugging gesture recognizers and gesture arenas, so I added
some. It also required updating some toString() methods which resulted
in some changes to the tree diagnostics logic.
Also I cleaned up some docs while I was at it.
Fixes https://github.com/flutter/flutter/issues/8476
More detailed list of changes in this patch:
* Replaced the didTouch special logic with more generic logic that
uses Activities instead. Now instead when you tap down the
Scrollable calls `hold()` which begins a HoldScrollActivity which is
a hybrid of DragStartDetails and IdleScrollActivity and can be
canceled. When you let go, it gets canceled and that goes ballistic.
* Make DragGestureRecognizer more aggressive about grabbing pointers,
otherwise a second pointer in a situation with competing horizontal
and vertical recognizers always gets taken by the other one.
* Fixed the _GestureSemantics widget to call the "down" callbacks so
that it follows the same pattern as "real" interactions.
* Added tests for the above.
* Added a hashCode to ScrollActivity.toString (and subclasses).
* Added a toString to ScrollDragController, and include it in
DragScrollActivity's toString.
* s/coorindator/coordinator/
* Add a comment in DragStartDetails to distinguish it from the
otherwise identical DragDownDetails, so we're not tempted to merge
them.
* Manually fix every use of Point.x and Point.y
Some of these were moved to dx/dy, but not all.
* Manually convert uses of the old gradient API
* Remove old reference to Point.
* Mechanical changes
I applied the following at the root of the Flutter repository:
git ls-files -z | xargs -0 sed -i 's/\bPoint[.]origin\b/Offset.zero/g'
git ls-files -z | xargs -0 sed -i 's/\bPoint[.]lerp\b/Offset.lerp/g'
git ls-files -z | xargs -0 sed -i 's/\bnew Point\b/new Offset/g'
git ls-files -z | xargs -0 sed -i 's/\bconst Point\b/const Offset/g'
git ls-files -z | xargs -0 sed -i 's/\bstatic Point /static Offset /g'
git ls-files -z | xargs -0 sed -i 's/\bfinal Point /final Offset /g'
git ls-files -z | xargs -0 sed -i 's/^\( *\)Point /\1Offset /g'
git ls-files -z | xargs -0 sed -i 's/ui[.]Point\b/ui.Offset/g'
git ls-files -z | xargs -0 sed -i 's/(Point\b/(Offset/g'
git ls-files -z | xargs -0 sed -i 's/\([[{,]\) Point\b/\1 Offset/g'
git ls-files -z | xargs -0 sed -i 's/@required Point\b/@required Offset/g'
git ls-files -z | xargs -0 sed -i 's/<Point>/<Offset>/g'
git ls-files -z | xargs -0 sed -i 's/[.]toOffset()//g'
git ls-files -z | xargs -0 sed -i 's/[.]toPoint()//g'
git ls-files -z | xargs -0 sed -i 's/\bshow Point, /show /g'
git ls-files -z | xargs -0 sed -i 's/\bshow Point;/show Offset;/g'
* Mechanical changes - dartdocs
I applied the following at the root of the Flutter repository:
git ls-files -z | xargs -0 sed -i 's/\ba \[Point\]/an [Offset]/g'
git ls-files -z | xargs -0 sed -i 's/\[Point\]/[Offset]/g'
* Further improvements and a test
* Fix minor errors from rebasing...
* Roll engine
Now the scale gesture will accept if its focal point moves more than the pan
slop. This change lets it compete with a drag gesture (e.g., a containing scrol
view) in the same way that the pan gesture does.
Fixes#8735
* MultiTapGestureRecognizer previously would assert if there was no
competition.
* GestureArenaTeam would always select the first recongizer as the
winner even if a later recognizer actually accepted the pointer
sequence.
* debugPrintStack would fail a type check if maxFrames was non-null.
* FractionalOffset.lerp would throw a null-pointer exception if its
second argument was null.
Also, add a number of tests for previously untested lines of code.
- more dartdocs for the drag typedefs
- more toStrings to aid debugging
- require the position for DragUpdateDetails since we were omitting it
in some places
- add the primaryVelocity to DragEndDetails so that consumers don't
have to themselves track the axis in question
- fix the velocity tracker so that it doesn't walk the null data.
Previously, near time t=0 (which pretty much only matters in tests,
but it does matter there) we would walk the velocity data and then
also walk missing data, treating it as Point.zero with t=0.
- simplify some of the velocity tracker; e.g. instead of trying (and
failing?) to clear the velocity tracker when the pointer stalls,
just drop the data before a stall during the velocity estimation
(where we redundantly had another bigger horizon anyway).
Previously we were relying on the gesture arena to call us back to
cancel our timer. However, in the case where we've already been
accepted, asking the gesture arena to reject us doesn't lead to a
callback and we fail to stop the timer (and hence trigger an assert).
Fixes#6156
This rewrites imports of various mojom.dart files from the Flutter
engine repo to instead import normal-looking dart files from the
(new) flutter_services package. This package handles exporting the
correct symbols from generated code wherever that may live.
Includes an engine roll to 3551e7a48e2e336777b15c7637af92fd7605b6c5
which contains the new flutter_services package.
* Change how navigator prevents redundant operations
Instead of requiring transactions, we now cancel all active pointers that are
interacting with the navigator and absorb future pointers until we get a chance
to build. This approach isn't perfect (e.g., events that trigger off the
cancelled pointers could still interact with the navigator), but it should be
better than the current transaction-based approach.
Fixes#4716
* Remove openTransaction
* test
* fixup
Previously we supplied individual parameters to the various drag and pan
callbacks. However, that approach isn't extensible because each new
parameter is a breaking change to the API.
This patch makes a one-time breaking change to the API to provide a
"details" object that we can extend over time as we need to expose more
information. The first planned extension is adding enough information to
accurately produce an overscroll glow on Android.
This makes it possible to substitute 'flutter run' for 'flutter test'
and actually watch a test run on a device.
For any test that depends on flutter_test:
1. Remove any import of 'package:test/test.dart'.
2. Replace `testWidgets('...', (WidgetTester tester) {`
with `testWidgets('...', (WidgetTester tester) async {`
3. Add an "await" in front of calls to any of the following:
* tap()
* tapAt()
* fling()
* flingFrom()
* scroll()
* scrollAt()
* pump()
* pumpWidget()
4. Replace any calls to `tester.flushMicrotasks()` with calls to
`await tester.idle()`.
There's a guarding API that you can use, if you have particularly
complicated tests, to get better error messages. Search for
TestAsyncUtils.
Wait until the end of the microtask to tell gesture recognizers that
they've won in the gesture arena. This lets recognizers dispose reject
themselves at arbitrary times without triggering gestures in awkward
call stacks.
Fixes#3183
There's no reason to make clients supply a PointerRounter and a
GestureArena when constructing gesture recognizers. These objects are
statics and the gesture recognizers can just grab them directly.
Also, remove the callback constructor arguments. Almost no code used
them. Instead, people seem to prefer using the `..` operator to set
callbacks on the recognizers. Removing the arguments removes a bunch of
boilerplate.
We were using an Offset, which represented pixels/second, but it wasn't
clear to clients whether that was pixels/ms. Now we use a Velocity class
that is explict about the units.
Fixes#1510Fixes#785
The pointer router was using an iteration pattern that always delivers
handleEvent calls even if you remove a route during the iteration.
That's awkward to program against and causes trouble for the double-tap
gesture.
This patch switches PointerRouter to using a re-entrant iteration
pattern that supports removing routes (but not adding routes) during the
iteration.