-
Notifications
You must be signed in to change notification settings - Fork 29.2k
Description
#89944 has updated GestureDetector
so that onPan
and others are now triggered via trackpad gestures.
Previously onPan...
was triggered only via click-and-drag on trackpads (like with a regular mouse).
This is still the behaviour in web.
This changes behaviour of existing apps.
Take the following example, which implements a selection box via click-and-drag.
Minimal Example + Workaround
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Offset? dragStart;
Offset? dragEnd;
bool workaround = true;
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton(
child: Icon(workaround ? Icons.alt_route_rounded : Icons.bug_report),
onPressed: () => setState(() {
workaround = !workaround;
}),
),
body: GestureDetector(
onPanStart: (details) => setState(() {
if (workaround && details.kind == PointerDeviceKind.trackpad) {
return;
}
dragStart = details.localPosition;
}),
onPanUpdate: (details) => setState(() {
if (workaround && dragStart == null) {
return;
}
dragEnd = details.localPosition;
}),
onPanEnd: (details) => setState(() {
dragStart = null;
dragEnd = null;
}),
child: Stack(
children: [
Container(
color: Colors.black,
),
if (dragEnd != null)
Positioned.fromRect(
rect: Rect.fromPoints(dragStart!, dragEnd!),
child: Container(
color: Colors.blue,
),
),
],
),
),
),
);
}
}
Without adding the following workarounds:
onPanStart: (details) => setState(() {
if (workaround && details.kind == PointerDeviceKind.trackpad) {
return;
}
dragStart = details.localPosition;
}),
onPanUpdate: (details) => setState(() {
if (workaround && dragStart == null) {
return;
}
dragEnd = details.localPosition;
}),
this drag behaviour is now also triggered by two-finger scroll on the trackpad:
Screen.Recording.2022-07-02.at.18.08.19.mov
This happens only on desktop
(macos
at least), not in web
.
On Web
only click-and-drag triggers onPan
.
Similarly Listener
reports trackpad pan on desktop
via onPointerPanZoomUpdate
while on the web
you must use onPointerSignal
with if (event is PointerScrollEvent)
.
(This was previously also called for trackpad scroll on macos)
// web
onPointerSignal: (event) {
if (event is PointerScrollEvent) {
// do stuff
}
},
// macos
onPointerPanZoomUpdate: (PointerPanZoomUpdateEvent event) {
// do stuff
},
$ flutter doctor -v
[✓] Flutter (Channel master, 3.1.0-0.0.pre.1400, on macOS 12.1 21C52 darwin-arm, locale en-DE)
• Flutter version 3.1.0-0.0.pre.1400 on channel master at /Users/omni/development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 7ac9fc5bae (4 days ago), 2022-06-28 08:39:08 -0400
• Engine revision 6cff45c25c
• Dart version 2.18.0 (build 2.18.0-232.0.dev)
• DevTools version 2.14.1
[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 13C100
• CocoaPods version 1.11.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Connected device (2 available)
• macOS (desktop) • macos • darwin-arm64 • macOS 12.1 21C52 darwin-arm
• Chrome (web) • chrome • web-javascript • Google Chrome 103.0.5060.53