Skip to content

Use the basic cursor when hovering a scrollbar - #196469

Open
victogomez-cs wants to merge 2 commits into
flutter:masterfrom
victogomez-cs:fix-scrollbar-mouse-cursor
Open

victogomez-cs wants to merge 2 commits into
flutter:masterfrom
victogomez-cs:fix-scrollbar-mouse-cursor

Conversation

@victogomez-cs

Copy link
Copy Markdown

Hovering a scrollbar inside a multiline TextField kept the I-beam cursor, because RawScrollbar deferred to the ancestor cursor for the whole scroll view. The pointer now uses SystemMouseCursors.basic while it is over the scrollbar or while the thumb is being dragged. The text area still uses the I-beam.

A mouseCursor value that resolves to null still defers to the ancestor cursor, including over the scrollbar.

Fixes #185813

Pre-launch Checklist

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

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

A multiline TextField kept the I-beam over its scrollbar because the
scrollbar deferred to the ancestor cursor. Default to the arrow while the
pointer is over the scrollbar.

Fixes flutter#185813
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Nov 12, 2026
@github-actions

Copy link
Copy Markdown

This pull request contains changes to Material or Cupertino, which are currently frozen in this repository.

Changes should be made in material_ui and/or cupertino_ui in the flutter/packages repository.

Please refer to #188444 for instructions.

1 similar comment
@github-actions

Copy link
Copy Markdown

This pull request contains changes to Material or Cupertino, which are currently frozen in this repository.

Changes should be made in material_ui and/or cupertino_ui in the flutter/packages repository.

Please refer to #188444 for instructions.

@github-actions github-actions Bot added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages f: scrolling Viewports, list views, slivers, etc. labels Nov 12, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates RawScrollbar to use SystemMouseCursors.basic by default when hovered or dragged if no custom mouseCursor is provided, rather than deferring to ancestor cursors like the text I-beam. It also updates the documentation and adds corresponding tests for TextField and RawScrollbar. Feedback suggests optimizing updateMouseCursor in scrollbar.dart by only resolving widget.mouseCursor when applyScrollbarCursor is true to avoid unnecessary resolution calls during hover and drag events.

Comment on lines +2320 to +2329
final bool applyScrollbarCursor = _hoverIsActive || _dragIsActive;
final MouseCursor? resolved = widget.mouseCursor?.resolve(cursorStates);
final MouseCursor desired = ((_hoverIsActive || _dragIsActive) && resolved != null)
? resolved
: MouseCursor.defer;
final MouseCursor desired;
if (!applyScrollbarCursor) {
desired = MouseCursor.defer;
} else if (widget.mouseCursor == null) {
desired = SystemMouseCursors.basic;
} else {
desired = resolved ?? MouseCursor.defer;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

We can optimize this by only resolving widget.mouseCursor when applyScrollbarCursor is true. Since updateMouseCursor is called frequently during hover and drag events, avoiding unnecessary calls to resolve when the cursor is not being applied (e.g., when the mouse leaves the scrollbar) improves efficiency and simplifies the logic.

    final bool applyScrollbarCursor = _hoverIsActive || _dragIsActive;
    final MouseCursor desired;
    if (!applyScrollbarCursor) {
      desired = MouseCursor.defer;
    } else if (widget.mouseCursor == null) {
      desired = SystemMouseCursors.basic;
    } else {
      desired = widget.mouseCursor!.resolve(cursorStates) ?? MouseCursor.defer;
    }
References
  1. Suggest simplification and refactoring to enhance readability and maintainability. (link)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left the resolve call in place. updateMouseCursor still resolves mouseCursor when the pointer leaves the scrollbar, so a WidgetStateProperty sees WidgetState.hovered drop. RawScrollbar.mouseCursor only applies while the pointer is over the scrollbar checks resolvedStates.last after the pointer moves back to the content area. Skipping resolve there would leave that last callback stuck on hovered

The scrollbar cursor fix is in the widgets library. The TextField
documentation and test touch frozen Material paths.
@github-actions github-actions Bot removed a: text input Entering text in a text field or keyboard related problems p: material_ui material_ui package in flutter/packages labels Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow setting a custom mouse cursor for the scrollbar inside TextField

1 participant