New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an option to let GestureDetector/InkWell trigger onTap/onTapUp when doubleclick #110300
Comments
This issue affects all widgets using GestureDetector/InkWell, all of them feel lag on desktop if onDoubleTap is enabled. |
Hi @ngugcx, thank you for reporting this issue. However, the behavior you are describing is expected when using a The delay described is necessary when deciding which To achieve tap and double tap behaviors without a delay, you might want to use There is one caveat, being that |
Thanks! @Renzo-Olivares . I've not tried SerialTapGestureRecognizer, after reading the doc, I think it should match my use case. Now the problem is that InkWell/GestureDetector are regarded as the higher level way to handle mouse events. Most of the docs recommend them, and lots of controls including the offical basic ones (tab, list ...) use InkWell/GestureDetector. This makes the default user experience of flutter desktop awful. |
For the desktop, the mouse is very important. If Flutter is perfunctory with the mouse, the user experience of the desktop will be out of the question. Single-tap, double-tap and scrolling, they are all needed to be optimized. |
Hi @Renzo-Olivares and @ngugcx Ngugcx is correct. Gesture detector and Inkwell widgets should absolutely implement some sort of bool to override ontap() delay when ondoubletap() is implemented, especially on desktop. If onTap is benign (doesn't perform a critical action) as it is in most desktop-based systems, there is no reason it can't be implemented sequentially with onDoubleTap. On desktop, the simple act of clicking once on an object to obtain selection focus and double clicking to execute has been around as long as graphical OSs have. It needs to be fixed without a complex implementation on our part to bring it inline with literally 'everything else in the world'. It makes all desktop apps sluggish and unresponsive. |
I'd also prefer a more standard solution to this problem than fiddling around with the SerialTapGestureRecognizer. I mean, look at how much more verbose and janky this code is: RawGestureDetector(
gestures: <Type, GestureRecognizerFactory>{
SerialTapGestureRecognizer: GestureRecognizerFactoryWithHandlers<SerialTapGestureRecognizer>(
() => SerialTapGestureRecognizer(),
(SerialTapGestureRecognizer instance) {
instance
..onSerialTapDown = (SerialTapDownDetails details) {
print(details.count);
if (details.count == 1) {
widget.onTap();
} else if (details.count == 2) {
widget.onDoubleTap();
}
};
},
)
},
child: child
} compared to the relative niceness of the standard GestureDetector: GestureDetector(
onTap: widget.onTap;
onDoubleTap: widget.onDoubeTap,
child: child,
) And like ngugcx says, all the documentation focuses on the easier (but worse) solutions. Some kind of overeride in gesture detector would be nice. Or a way to otherwise specify what kind of algorithm to use. Because on desktop, the standard click/double click interaction feels painfully laggy. |
This issue is assigned but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks! |
@Renzo-Olivares , almost one year passed, any progress on this issue and the new design? thanks. |
Apologies for the lack of updates as I have not been actively working on this issue. I have bumped the priority on this issue and will be giving it another look. Thanks for the patience. |
This issue is affecting a production Google app using desktop web - see internal bug b/322887506 for context. The existing behavior does not break the functionality seeing as it is still possible to do everything, however it creates a perception of jank and makes the user experience feel very wrong. While SerialTapGestureRecognizer works for simpler cases, it seems like there is a usability issue here. There should be an obvious way to achieve this functionality seeing as it's very common on desktop web and desktop native, and it should be possible even when it's not the same widget recognizing the single and double clicks. The widget tree could have a nested single click recognizer that is in a completely different file etc. Here is some minimal repro code in case it's handy for anyone: Repro code for Dartpadimport 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: TappingDemo(),
),
),
);
}
}
class TappingDemo extends StatefulWidget {
@override
State<TappingDemo> createState() => _TappingDemoState();
}
class _TappingDemoState extends State<TappingDemo> {
String text = "";
@override
Widget build(BuildContext context) {
return Column(children: [
Text('Sequence of single and double taps: $text'),
GestureDetector(
onDoubleTap: () {
setState(() {
text = text + 'D';
});
},
child: ElevatedButton(
child: Text('Press me'),
onPressed: () {
setState(() {
text = text + 'S';
});
}),
),
]);
}
} |
Inlining a slightly modified (reduced) version of the duplicate issue I opened at #113906... I'd like a way to disable the delay, implying both events may fire. I've developed a couple small apps for Flutter Desktop and in each app, where I've wanted tap and double tap on the same widget, I've not wanted the delay imposed. Issue #22950 discusses adjusting In one instance I was able to use I'd like an option to disable the I do think "fixing" this experience on desktop is important. It simply doesn't work the way users on desktop platforms expect it to. |
Similar problem to @jibbers42 here: we're using |
It's possible that #106170 should be dup'd to this one. Here is my own workaround for this issue, in case it is helpful: class DoubleTapInkWell extends StatelessWidget {
const DoubleTapInkWell({super.key});
@override
Widget build(BuildContext context) {
return MultiTapListener(
onDoubleTap: () {
// Handle double tap. Adding this handler does not cause the 300ms delay in single-taps.
},
child: InkWell(
onTap: () {
// Handle normal tap. Called on every tap.
},
),
);
}
} using a simple |
Use case
Currently, GestureDetector/InkWell:
This design may not be a big problem on mobile platforms, since double taps are not used very often.
But on desktop, it's everywhere and the user experience is poor due to the onTap latency.
onTapDown is not delayed, but it cannot replace onTap/onTapUp.
Proposal
It's better to add a global option to:
The text was updated successfully, but these errors were encountered: