Skip to content

Commit 129a35a

Browse files
Add mouseCursor to Tooltip (#159922)
Part of flutter/flutter#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>
1 parent 6a019d2 commit 129a35a

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

packages/flutter/lib/src/material/tooltip.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class _ExclusiveMouseRegion extends MouseRegion {
4646
const _ExclusiveMouseRegion({
4747
super.onEnter,
4848
super.onExit,
49+
super.cursor,
4950
super.child,
5051
});
5152

@@ -54,6 +55,7 @@ class _ExclusiveMouseRegion extends MouseRegion {
5455
return _RenderExclusiveMouseRegion(
5556
onEnter: onEnter,
5657
onExit: onExit,
58+
cursor: cursor,
5759
);
5860
}
5961
}
@@ -62,6 +64,7 @@ class _RenderExclusiveMouseRegion extends RenderMouseRegion {
6264
_RenderExclusiveMouseRegion({
6365
super.onEnter,
6466
super.onExit,
67+
super.cursor,
6568
});
6669

6770
static bool isOutermostMouseRegion = true;
@@ -195,6 +198,7 @@ class Tooltip extends StatefulWidget {
195198
this.triggerMode,
196199
this.enableFeedback,
197200
this.onTriggered,
201+
this.mouseCursor,
198202
this.child,
199203
}) : assert((message == null) != (richMessage == null), 'Either `message` or `richMessage` must be specified'),
200204
assert(
@@ -363,6 +367,12 @@ class Tooltip extends StatefulWidget {
363367
/// or after a long press when [triggerMode] is [TooltipTriggerMode.longPress].
364368
final TooltipTriggeredCallback? onTriggered;
365369

370+
/// The cursor for a mouse pointer when it enters or is hovering over the
371+
/// widget.
372+
///
373+
/// If this property is null, [MouseCursor.defer] will be used.
374+
final MouseCursor? mouseCursor;
375+
366376
static final List<TooltipState> _openedTooltips = <TooltipState>[];
367377

368378
/// Dismiss all of the tooltips that are currently shown on the screen,
@@ -839,6 +849,7 @@ class TooltipState extends State<Tooltip> with SingleTickerProviderStateMixin {
839849
result = _ExclusiveMouseRegion(
840850
onEnter: _handleMouseEnter,
841851
onExit: _handleMouseExit,
852+
cursor: widget.mouseCursor ?? MouseCursor.defer,
842853
child: Listener(
843854
onPointerDown: _handlePointerDown,
844855
behavior: HitTestBehavior.opaque,

packages/flutter/test/material/tooltip_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,6 +3091,38 @@ void main() {
30913091

30923092
expect(selectedText, isNot(contains('A')));
30933093
});
3094+
3095+
testWidgets('Tooltip mouse cursor behavior', (WidgetTester tester) async {
3096+
const SystemMouseCursor customCursor = SystemMouseCursors.grab;
3097+
3098+
await tester.pumpWidget(
3099+
const MaterialApp(
3100+
home: Center(
3101+
child: Tooltip(
3102+
message: tooltipText,
3103+
mouseCursor: customCursor,
3104+
child: SizedBox.square(dimension: 50),
3105+
),
3106+
),
3107+
),
3108+
);
3109+
3110+
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
3111+
await gesture.addPointer(location: const Offset(10, 10));
3112+
await tester.pump();
3113+
expect(
3114+
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
3115+
SystemMouseCursors.basic,
3116+
);
3117+
3118+
final Offset chip = tester.getCenter(find.byType(Tooltip));
3119+
await gesture.moveTo(chip);
3120+
await tester.pump();
3121+
expect(
3122+
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
3123+
customCursor,
3124+
);
3125+
});
30943126
}
30953127

30963128
Future<void> setWidgetForTooltipMode(

0 commit comments

Comments
 (0)