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>{};
|
static final Set<_TooltipState> _mouseIn = <_TooltipState>{};
|
||||||
|
|
||||||
void _handleMouseEnter() {
|
void _handleMouseEnter() {
|
||||||
_showTooltip();
|
if (mounted) {
|
||||||
|
_showTooltip();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleMouseExit({bool immediately = false}) {
|
void _handleMouseExit({bool immediately = false}) {
|
||||||
// If the tip is currently covered, we can just remove it without waiting.
|
if (mounted) {
|
||||||
_dismissTooltip(immediately: _isConcealed || immediately);
|
// If the tip is currently covered, we can just remove it without waiting.
|
||||||
|
_dismissTooltip(immediately: _isConcealed || immediately);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _createNewEntry() {
|
void _createNewEntry() {
|
||||||
|
@ -863,6 +863,62 @@ void main() {
|
|||||||
await gesture.up();
|
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 {
|
testWidgets('Tooltip shows/hides when hovered', (WidgetTester tester) async {
|
||||||
const Duration waitDuration = Duration.zero;
|
const Duration waitDuration = Duration.zero;
|
||||||
TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
TestGesture? gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user