mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix unresponsive mouse tooltip (#142282)
Fixes https://github.com/flutter/flutter/issues/142045 The intent of using `??=` was that if the tooltip is already scheduled for showing, rescheduling another show does nothing. But if the tooltip is already scheduled for dismissing, the `??=` won't cancel the dismiss timer and as a result the tooltip won't show. So the `??=` is now replaced by `=` to keep it consistent with the `_scheduleDismissTooltip` implementation.
This commit is contained in:
parent
347403f2ea
commit
43aee92e61
@ -508,7 +508,8 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
|
|||||||
);
|
);
|
||||||
switch (_controller.status) {
|
switch (_controller.status) {
|
||||||
case AnimationStatus.dismissed when withDelay.inMicroseconds > 0:
|
case AnimationStatus.dismissed when withDelay.inMicroseconds > 0:
|
||||||
_timer ??= Timer(withDelay, show);
|
_timer?.cancel();
|
||||||
|
_timer = Timer(withDelay, show);
|
||||||
// If the tooltip is already fading in or fully visible, skip the
|
// If the tooltip is already fading in or fully visible, skip the
|
||||||
// animation and show the tooltip immediately.
|
// animation and show the tooltip immediately.
|
||||||
case AnimationStatus.dismissed:
|
case AnimationStatus.dismissed:
|
||||||
|
@ -1562,6 +1562,89 @@ void main() {
|
|||||||
expect(find.text('last tooltip'), findsOneWidget);
|
expect(find.text('last tooltip'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/142045.
|
||||||
|
testWidgets('Tooltip shows/hides when the mouse hovers, and then exits and re-enters in quick succession', (WidgetTester tester) async {
|
||||||
|
const Duration waitDuration = Durations.extralong1;
|
||||||
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||||
|
addTearDown(() async {
|
||||||
|
return gesture.removePointer();
|
||||||
|
});
|
||||||
|
await gesture.addPointer();
|
||||||
|
await gesture.moveTo(const Offset(1.0, 1.0));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
const MaterialApp(
|
||||||
|
home: Center(
|
||||||
|
child: Tooltip(
|
||||||
|
message: tooltipText,
|
||||||
|
waitDuration: waitDuration,
|
||||||
|
exitDuration: waitDuration,
|
||||||
|
child: SizedBox(
|
||||||
|
width: 100.0,
|
||||||
|
height: 100.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Future<void> mouseEnterAndWaitUntilVisible() async {
|
||||||
|
await gesture.moveTo(tester.getCenter(find.byType(Tooltip)));
|
||||||
|
await tester.pump();
|
||||||
|
await tester.pump(waitDuration);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text(tooltipText), findsOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> mouseExit() async {
|
||||||
|
await gesture.moveTo(Offset.zero);
|
||||||
|
await tester.pump();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> performSequence(Iterable<Future<void> Function()> actions) async {
|
||||||
|
for (final Future<void> Function() action in actions) {
|
||||||
|
await action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await performSequence(<Future<void> Function()>[mouseEnterAndWaitUntilVisible]);
|
||||||
|
expect(find.text(tooltipText), findsOne);
|
||||||
|
|
||||||
|
// Wait for reset.
|
||||||
|
await mouseExit();
|
||||||
|
await tester.pump(const Duration(hours: 1));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text(tooltipText), findsNothing);
|
||||||
|
|
||||||
|
await performSequence(<Future<void> Function()>[
|
||||||
|
mouseEnterAndWaitUntilVisible,
|
||||||
|
mouseExit,
|
||||||
|
mouseEnterAndWaitUntilVisible,
|
||||||
|
]);
|
||||||
|
expect(find.text(tooltipText), findsOne);
|
||||||
|
|
||||||
|
// Wait for reset.
|
||||||
|
await mouseExit();
|
||||||
|
await tester.pump(const Duration(hours: 1));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text(tooltipText), findsNothing);
|
||||||
|
|
||||||
|
await performSequence(<Future<void> Function()>[
|
||||||
|
mouseEnterAndWaitUntilVisible,
|
||||||
|
mouseExit,
|
||||||
|
mouseEnterAndWaitUntilVisible,
|
||||||
|
mouseExit,
|
||||||
|
mouseEnterAndWaitUntilVisible,
|
||||||
|
]);
|
||||||
|
expect(find.text(tooltipText), findsOne);
|
||||||
|
|
||||||
|
// Wait for reset.
|
||||||
|
await mouseExit();
|
||||||
|
await tester.pump(const Duration(hours: 1));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text(tooltipText), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Tooltip text is also hoverable', (WidgetTester tester) async {
|
testWidgets('Tooltip text is also hoverable', (WidgetTester tester) async {
|
||||||
const Duration waitDuration = Duration.zero;
|
const Duration waitDuration = Duration.zero;
|
||||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||||
|
Loading…
Reference in New Issue
Block a user