Do not crash if dispatch the mouse events before the tooltip overlay detached (#97268)
This commit is contained in:
parent
a288bd5e3f
commit
839bd6317f
@ -522,12 +522,16 @@ class _TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
|
||||
static final Set<_TooltipState> _mouseIn = <_TooltipState>{};
|
||||
|
||||
void _handleMouseEnter() {
|
||||
_showTooltip();
|
||||
if (mounted) {
|
||||
_showTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void _handleMouseExit({bool immediately = false}) {
|
||||
// If the tip is currently covered, we can just remove it without waiting.
|
||||
_dismissTooltip(immediately: _isConcealed || immediately);
|
||||
if (mounted) {
|
||||
// If the tip is currently covered, we can just remove it without waiting.
|
||||
_dismissTooltip(immediately: _isConcealed || immediately);
|
||||
}
|
||||
}
|
||||
|
||||
void _createNewEntry() {
|
||||
|
@ -863,6 +863,62 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('Dispatch the mouse events before tip overlay detached', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/96890
|
||||
const Duration waitDuration = Duration.zero;
|
||||
TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||
addTearDown(() async {
|
||||
if (gesture != null)
|
||||
return gesture.removePointer();
|
||||
});
|
||||
await gesture.addPointer();
|
||||
await gesture.moveTo(const Offset(1.0, 1.0));
|
||||
await tester.pump();
|
||||
await gesture.moveTo(Offset.zero);
|
||||
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Center(
|
||||
child: Tooltip(
|
||||
message: tooltipText,
|
||||
waitDuration: waitDuration,
|
||||
child: SizedBox(
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Trigger the tip overlay.
|
||||
final Finder tooltip = find.byType(Tooltip);
|
||||
await gesture.moveTo(tester.getCenter(tooltip));
|
||||
await tester.pump();
|
||||
// Wait for it to appear.
|
||||
await tester.pump(waitDuration);
|
||||
|
||||
// Remove the `Tooltip` widget.
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Center(
|
||||
child: SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// The tooltip overlay still on the tree and it will removed in the next frame.
|
||||
|
||||
// Dispatch the mouse in and out events before the overlay detached.
|
||||
await gesture.moveTo(tester.getCenter(find.text(tooltipText)));
|
||||
await gesture.moveTo(Offset.zero);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Go without crashes.
|
||||
await gesture.removePointer();
|
||||
gesture = null;
|
||||
});
|
||||
|
||||
testWidgets('Tooltip shows/hides when hovered', (WidgetTester tester) async {
|
||||
const Duration waitDuration = Duration.zero;
|
||||
TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||
|
Loading…
x
Reference in New Issue
Block a user