Commit b19df00c authored by Dwayne Slater's avatar Dwayne Slater Committed by Dan Field

Fix MouseTracker annotation leak (#28990)

* Fix MouseTracker annotation leak

Map's remove method is typed `remove(Object key)`, which can cause bugs.

Modified the existing test to check if the annotation has been removed
from MouseTracker.
parent e9be230a
...@@ -124,7 +124,7 @@ class MouseTracker { ...@@ -124,7 +124,7 @@ class MouseTracker {
for (int deviceId in trackedAnnotation.activeDevices) { for (int deviceId in trackedAnnotation.activeDevices) {
annotation.onExit(PointerExitEvent.fromHoverEvent(_lastMouseEvent[deviceId])); annotation.onExit(PointerExitEvent.fromHoverEvent(_lastMouseEvent[deviceId]));
} }
_trackedAnnotations.remove(trackedAnnotation); _trackedAnnotations.remove(annotation);
} }
void _scheduleMousePositionCheck() { void _scheduleMousePositionCheck() {
...@@ -171,6 +171,16 @@ class MouseTracker { ...@@ -171,6 +171,16 @@ class MouseTracker {
return trackedAnnotation; return trackedAnnotation;
} }
/// Checks if the given [MouseTrackerAnnotation] is attached to this
/// [MouseTracker].
///
/// This function is only public to allow for proper testing of the
/// MouseTracker. Do not call in other contexts.
@visibleForTesting
bool isAnnotationAttached(MouseTrackerAnnotation annotation) {
return _trackedAnnotations[annotation] != null;
}
/// Tells interested objects that a mouse has entered, exited, or moved, given /// Tells interested objects that a mouse has entered, exited, or moved, given
/// a callback to fetch the [MouseTrackerAnnotation] associated with a global /// a callback to fetch the [MouseTrackerAnnotation] associated with a global
/// offset. /// offset.
......
...@@ -2591,6 +2591,13 @@ class RenderPointerListener extends RenderProxyBoxWithHitTestBehavior { ...@@ -2591,6 +2591,13 @@ class RenderPointerListener extends RenderProxyBoxWithHitTestBehavior {
// Object used for annotation of the layer used for hover hit detection. // Object used for annotation of the layer used for hover hit detection.
MouseTrackerAnnotation _hoverAnnotation; MouseTrackerAnnotation _hoverAnnotation;
/// Object used for annotation of the layer used for hover hit detection.
///
/// This is only public to allow for testing of Listener widgets. Do not call
/// in other contexts.
@visibleForTesting
MouseTrackerAnnotation get hoverAnnotation => _hoverAnnotation;
void _updateAnnotations() { void _updateAnnotations() {
if (_hoverAnnotation != null && attached) { if (_hoverAnnotation != null && attached) {
RendererBinding.instance.mouseTracker.detachAnnotation(_hoverAnnotation); RendererBinding.instance.mouseTracker.detachAnnotation(_hoverAnnotation);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
...@@ -109,6 +110,7 @@ void main() { ...@@ -109,6 +110,7 @@ void main() {
onPointerExit: (PointerExitEvent details) => exit = details, onPointerExit: (PointerExitEvent details) => exit = details,
), ),
)); ));
final RenderPointerListener renderListener = tester.renderObject(find.byType(Listener));
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.moveTo(const Offset(400.0, 300.0)); await gesture.moveTo(const Offset(400.0, 300.0));
await tester.pump(); await tester.pump();
...@@ -125,6 +127,7 @@ void main() { ...@@ -125,6 +127,7 @@ void main() {
)); ));
expect(exit, isNotNull); expect(exit, isNotNull);
expect(exit.position, equals(const Offset(400.0, 300.0))); expect(exit.position, equals(const Offset(400.0, 300.0)));
expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener.hoverAnnotation), isFalse);
}); });
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment