Removed `MouseTracker`'s methods `attachAnnotation`, `detachAnnotation`, and `isAnnotationAttached`.
Original behavior
Mouse events, such as when a mouse pointer has entered a region, exited, or is hovering over a region, are detected with the help of `MouseTrackerAnnotation`s that are placed on interested regions during the render phase. Upon each update (a new frame or a new event), `MouseTracker` compares the annotations hovered by the mouse pointer before and after the update, then dispatches callbacks accordingly.
New behavior
The `MouseTracker` class has removed three methods related to attaching annotations:
- Who is affected
- Applications and packages relying on the previous behaviour or signature. Code that uses MouseTracker, MouseTrackerAnnotation, MouseRegion and related APIs.
- Practical impact
- Behaviour or API differences that can break builds or change runtime behaviour.
- What action should I take?
- Follow the official migration guide below, update affected call sites, run `dart fix --apply` where a fix is available, then run your tests.
Before and after (from the official guide)
| 1 | class MyMouseRegion extends SingleChildRenderObjectWidget { | |
| 2 | const MyMouseRegion({this.onHoverChange}); | |
| 3 | ||
| 4 | final ValueChanged<bool> onHoverChange; | |
| 5 | ||
| 6 | @override | |
| 7 | RenderMouseRegion createRenderObject(BuildContext context) { | |
| 8 | return RenderMouseRegion( | |
| 9 | onEnter: (_) { onHoverChange(true); }, | |
| 10 | onExit: (_) { onHoverChange(false); }, | |
| 11 | ); | |
| 12 | } | |
| 13 | ||
| 14 | @override | |
| 15 | void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) { | |
| 16 | renderObject | |
| 17 | ..onEnter = (_) { onHoverChange(true); } | |
| 18 | ..onExit = (_) { onHoverChange(false); }; | |
| 19 | } | |
| 20 | } |
| 1 | class MyMouseRegion extends SingleChildRenderObjectWidget { | |
| 2 | const MyMouseRegion({this.onHoverChange}); | |
| 3 | ||
| 4 | final ValueChanged<bool> onHoverChange; | |
| 5 | ||
| 6 | @override | |
| 7 | RenderMouseRegion createRenderObject(BuildContext context) { | |
| 8 | return RenderMouseRegion( | |
| 9 | onEnter: (_) { onHoverChange(true); }, | |
| 10 | onExit: (_) { onHoverChange(false); }, | |
| 11 | ); | |
| 12 | } | |
| 13 | ||
| 14 | @override | |
| 15 | void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) { | |
| 16 | renderObject | |
| 17 | ..onEnter = (_) { onHoverChange(true); } | |
| 18 | ..onExit = (_) { onHoverChange(false); }; | |
| 19 | } | |
| 20 | + | |
| 21 | + | @override |
| 22 | + | void didUnmountRenderObject(RenderMouseRegion renderObject) { |
| 23 | + | renderObject |
| 24 | + | ..onExit = onHoverChange == null ? null : (_) {}; |
| 25 | + | } |
| 26 | } |
Raw before / after
class MyMouseRegion extends SingleChildRenderObjectWidget {
const MyMouseRegion({this.onHoverChange});
final ValueChanged<bool> onHoverChange;
@override
RenderMouseRegion createRenderObject(BuildContext context) {
return RenderMouseRegion(
onEnter: (_) { onHoverChange(true); },
onExit: (_) { onHoverChange(false); },
);
}
@override
void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
renderObject
..onEnter = (_) { onHoverChange(true); }
..onExit = (_) { onHoverChange(false); };
}
}class MyMouseRegion extends SingleChildRenderObjectWidget {
const MyMouseRegion({this.onHoverChange});
final ValueChanged<bool> onHoverChange;
@override
RenderMouseRegion createRenderObject(BuildContext context) {
return RenderMouseRegion(
onEnter: (_) { onHoverChange(true); },
onExit: (_) { onHoverChange(false); },
);
}
@override
void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
renderObject
..onEnter = (_) { onHoverChange(true); }
..onExit = (_) { onHoverChange(false); };
}
@override
void didUnmountRenderObject(RenderMouseRegion renderObject) {
renderObject
..onExit = onHoverChange == null ? null : (_) {};
}
}Official migration guide (excerpt, © The Flutter Authors, CC BY 3.0)
Calls to MouseTracker.attachAnnotation and
detachAnnotation should be removed with little to no impact:
- Uses of
MouseRegionshould not be affected at all. - If your code directly uses
RenderMouseRegionorMouseTrackerAnnotation, be aware thatonExitis now called when the exit is caused by events that used to callMouseTracker.detachAnnotation. This should not be a problem if no states are involved, otherwise you might want to add the mounted-exit check, especially if the callback is leaked so that outer widgets might callsetStatein it. For example:
Code before migration:
class MyMouseRegion extends SingleChildRenderObjectWidget {
const MyMouseRegion({this.onHoverChange});
final ValueChanged<bool> onHoverChange;
@override
RenderMouseRegion createRenderObject(BuildContext context) {
return RenderMouseRegion(
onEnter: (_) { onHoverChange(true); },
onExit: (_) { onHoverChange(false); },
);
}
@override
void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
renderObject
..onEnter = (_) { onHoverChange(true); }
..onExit = (_) { onHoverChange(false); };
}
}Code after migration:
class MyMouseRegion extends SingleChildRenderObjectWidget {
const MyMouseRegion({this.onHoverChange});
final ValueChanged<bool> onHoverChange;
@override
RenderMouseRegion createRenderObject(BuildContext context) {
return RenderMouseRegion(
onEnter: (_) { onHoverChange(true); },
onExit: (_) { onHoverChange(false); },
);
}
@override
void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
renderObject
..onEnter = (_) { onHoverChange(true); }
..onExit = (_) { onHoverChange(false); };
}
@override
void didUnmountRenderObject(RenderMouseRegion renderObject) {
renderObject
..onExit = onHoverChange == null ? null : (_) {};
}
}Calls to MouseTracker.isAnnotationAttached must be removed.
This feature is no longer technically possible,
since annotations are no longer tracked.
If you somehow need this feature, please submit an issue.
AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.Listed in the official breaking-changes index (docs.flutter.dev/release/breaking-changes).
An official announcement or migration guide documents an intended behaviour or API change. A verified source change (git diff) shows code changed but does not by itself prove a public API is breaking. AI interpretations are labelled and never used to classify a change.
- Official migration guide
- MouseRegion
- MouseTracker
- MouseTrackerAnnotation
- RenderMouseRegion
- MouseTracker no longer requires annotations attached
- Improve MouseTracker lifecycle: Move checks to post-frame
- Source commit
- b3045439b7c0
- Source last updated
- Oct 21, 2026
- Last synchronized
- Oct 21, 2026
- Publication status
- published
Publication history
- Oct 21, 2026, 8:31 PM: new → published (ingestion) — Backed by an official breaking-change/migration guide.
AI_PROVIDER (for example to openai-compatible with a local Ollama or LM Studio endpoint) to enable grounded explanations. Everything else on this page works without an AI provider.