Add mouseCursor to Tooltip (#159922)

Part of https://github.com/flutter/flutter/issues/58192

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md

---------

Co-authored-by: Bruno Leroux <bruno.leroux@gmail.com>
This commit is contained in:
Valentin Vignal 2024-12-10 08:25:20 +08:00 committed by GitHub
parent 6a019d2f7d
commit 129a35a5e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 0 deletions

View File

@ -46,6 +46,7 @@ class _ExclusiveMouseRegion extends MouseRegion {
const _ExclusiveMouseRegion({
super.onEnter,
super.onExit,
super.cursor,
super.child,
});
@ -54,6 +55,7 @@ class _ExclusiveMouseRegion extends MouseRegion {
return _RenderExclusiveMouseRegion(
onEnter: onEnter,
onExit: onExit,
cursor: cursor,
);
}
}
@ -62,6 +64,7 @@ class _RenderExclusiveMouseRegion extends RenderMouseRegion {
_RenderExclusiveMouseRegion({
super.onEnter,
super.onExit,
super.cursor,
});
static bool isOutermostMouseRegion = true;
@ -195,6 +198,7 @@ class Tooltip extends StatefulWidget {
this.triggerMode,
this.enableFeedback,
this.onTriggered,
this.mouseCursor,
this.child,
}) : assert((message == null) != (richMessage == null), 'Either `message` or `richMessage` must be specified'),
assert(
@ -363,6 +367,12 @@ class Tooltip extends StatefulWidget {
/// or after a long press when [triggerMode] is [TooltipTriggerMode.longPress].
final TooltipTriggeredCallback? onTriggered;
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// If this property is null, [MouseCursor.defer] will be used.
final MouseCursor? mouseCursor;
static final List<TooltipState> _openedTooltips = <TooltipState>[];
/// Dismiss all of the tooltips that are currently shown on the screen,
@ -839,6 +849,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
result = _ExclusiveMouseRegion(
onEnter: _handleMouseEnter,
onExit: _handleMouseExit,
cursor: widget.mouseCursor ?? MouseCursor.defer,
child: Listener(
onPointerDown: _handlePointerDown,
behavior: HitTestBehavior.opaque,

View File

@ -3091,6 +3091,38 @@ void main() {
expect(selectedText, isNot(contains('A')));
});
testWidgets('Tooltip mouse cursor behavior', (WidgetTester tester) async {
const SystemMouseCursor customCursor = SystemMouseCursors.grab;
await tester.pumpWidget(
const MaterialApp(
home: Center(
child: Tooltip(
message: tooltipText,
mouseCursor: customCursor,
child: SizedBox.square(dimension: 50),
),
),
),
);
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
await gesture.addPointer(location: const Offset(10, 10));
await tester.pump();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
SystemMouseCursors.basic,
);
final Offset chip = tester.getCenter(find.byType(Tooltip));
await gesture.moveTo(chip);
await tester.pump();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
customCursor,
);
});
}
Future<void> setWidgetForTooltipMode(