Skip to content

GestureDetector onPan now triggers via trackpad. changed application behaviour #107005

@ltOgt

Description

@ltOgt

#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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: desktopRunning on desktopc: regressionIt was better in the past than it is nowf: gesturesflutter/packages/flutter/gestures repository.found in release: 3.0Found to occur in 3.0found in release: 3.1Found to occur in 3.1frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions