-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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)
Details
// 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