)]}'
{
  "commit": "04daa25fd5bd458c00c0a0fb43f992e9825de91a",
  "tree": "d343e1f105342a83a6dda198292ca0ccc871fda4",
  "parents": [
    "616b5a5fef001f55ca3fd5fd1c1736c8749fa524"
  ],
  "author": {
    "name": "Soroush Yousefpour",
    "email": "46920873+gabrimatic@users.noreply.github.com",
    "time": "Tue Sep 01 23:40:20 2026 +0000"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Tue Sep 01 23:40:20 2026 +0000"
  },
  "message": "Add mouseCursor to RawScrollbar (#185750)\n\n## Description\n\nAdds a `mouseCursor` property to `RawScrollbar`, allowing callers to\ncustomize the mouse cursor over the scrollbar\u0027s thumb/track via a\n`WidgetStateProperty\u003cMouseCursor?\u003e`. It resolves with\n`WidgetState.hovered` while the pointer is over the painted scrollbar,\n`WidgetState.dragged` while a thumb drag is active, and\n`WidgetState.disabled` while the scrollbar is not interactive.\n\nThe override is gated to apply only while the pointer is over the\npainted scrollbar, using the same hit-test region that already drives\nhover behavior. When the pointer is anywhere else inside the scroll\nview\u0027s child, cursor resolution is deferred to ancestors, so a parent\nwidget\u0027s cursor, such as an enclosing `EditableText`\u0027s I-beam, is\npreserved. This is the core fix for the scenario described in #185733:\ntoday, the scrollbar\u0027s `MouseRegion` swallows the ancestor cursor for\nthe entire scroll-view area. With this change, only the painted\nscrollbar surface participates in cursor resolution.\n\nWhen `mouseCursor` is null, or when its resolved value is null,\n`MouseCursor.defer` is used and ancestor cursors are left unchanged\neverywhere.\n\nThe hover callbacks are only installed while the scrollbar is\ninteractive, and the thumb drag recognizers only exist while the child\nis scrollable. When either stops being true the callbacks simply stop\narriving, and a dropped drag recognizer is disposed without reporting a\ncancel, so the pointer state that feeds the cursor is released\nexplicitly: when a mouse or trackpad thumb drag ends, when `interactive`\nchanges, and when the child stops being scrollable. Without that, the\nresolved cursor could stay applied over the whole scroll view with no\nevent left to clear it.\n\nOne user-visible side effect worth calling out: after a mouse thumb drag\nthat ends away from the scrollbar, the fade-out timer is no longer\nrestarted by the following hover-exit, so the scrollbar can begin fading\nup to `timeToFade` earlier than before. That matches the behavior a\ntouch drag already had.\n\n## Why framework-only\n\n`flutter/flutter` is currently under a Material/Cupertino code freeze\n(#184093). Per the freeze guidance, the framework-side change can land\nnow, and the corresponding `Scrollbar` / `ScrollbarThemeData` surfacing\nrequested in #185733 will be ported to `material_ui` in\n`flutter/packages` once that repo opens for changes. This PR is\ntherefore scoped to `lib/src/widgets/scrollbar.dart` and its\nwidget-layer tests only.\n\nThe framework API alone is enough to fix the reported scenario: an\nI-beam cursor over a `TextField`\u0027s scrollable region remains intact when\nhovering content but switches over the scrollbar. See the test\n`RawScrollbar.mouseCursor only applies while the pointer is over the\nscrollbar`.\n\nThis PR uses a non-closing `Refs #185733` so the issue stays open to\ntrack the remaining `Scrollbar` / `ScrollbarThemeData` work, which will\nland separately in `flutter/packages`.\n\n## Tests\n\nNine widget-layer tests in `test/widgets/scrollbar_test.dart`:\n\n- `RawScrollbar.mouseCursor only applies while the pointer is over the\nscrollbar` verifies an ancestor `MouseRegion(cursor: text)` keeps the\nI-beam over the content area, switches to the scrollbar\u0027s cursor over\nthe thumb, yields back to the I-beam when leaving the scrollbar, and\npasses exactly `WidgetState.hovered` to the cursor resolver while\nhovering.\n- `RawScrollbar.mouseCursor resolves a WidgetStateProperty.fromMap`\nverifies the `WidgetStateProperty` contract end to end: hovered,\ndragged, map precedence, and the fallback back to the hovered entry on\nrelease.\n- `RawScrollbar without mouseCursor preserves the ancestor cursor over\nthe scrollbar` verifies the default behavior: with no override set, the\nancestor cursor wins everywhere, including over the scrollbar.\n- `RawScrollbar.mouseCursor updates when the property changes while\nhovered` verifies that prop changes during hover are picked up.\n- `RawScrollbar.mouseCursor stays applied while a thumb drag is active\neven when the pointer leaves the scrollbar` verifies that a dragged\ncursor remains stable during an active thumb drag.\n- `RawScrollbar.mouseCursor is released when a mouse drag ends off the\nscrollbar` verifies a single-pointer desktop drag: pressing the thumb,\ndragging into the content area, and releasing there hands the cursor\nstraight back to the ancestor.\n- `RawScrollbar.mouseCursor is released when the scrollbar stops being\ninteractive` verifies that flipping `interactive` to false, both while\nhovering and mid-drag, releases the override.\n- `RawScrollbar.mouseCursor is released when the child stops being\nscrollable` verifies that shrinking the child mid-drag releases the\ndragged state.\n- `RawScrollbar.mouseCursor clears dragged state when thumb drag is\ncancelled` verifies that cancellation resets the dragged cursor state.\n\nEach of the three release paths was confirmed to fail without its fix.\n\nVerification run locally:\n\n- `./bin/dart format --output\u003dnone --set-exit-if-changed\npackages/flutter/lib/src/widgets/scrollbar.dart\npackages/flutter/test/widgets/scrollbar_test.dart`\n- `./bin/flutter analyze --current-package --no-pub\npackages/flutter/lib/src/widgets/scrollbar.dart\npackages/flutter/test/widgets/scrollbar_test.dart`\n- `./bin/flutter test packages/flutter/test/widgets/scrollbar_test.dart`\n(112 passing)\n- `./bin/flutter test packages/flutter/test/widgets/` (7181 passing)\n- `./bin/flutter test packages/flutter/test/material/scrollbar_test.dart\npackages/flutter/test/cupertino/scrollbar_test.dart` and the other\nsuites that build a scrollbar\n- `git diff --check upstream/master...HEAD`\n\nRefs #185733\n\n---------\n\nCo-authored-by: Tong Mu \u003cdkwingsmt@users.noreply.github.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "06c0451f6b482cea10d9821ee5d28f8d51a22c6b",
      "old_mode": 33188,
      "old_path": "packages/flutter/lib/src/widgets/scrollbar.dart",
      "new_id": "3beb366317b35659079f8cf2c4ef4de3508b0fdc",
      "new_mode": 33188,
      "new_path": "packages/flutter/lib/src/widgets/scrollbar.dart"
    },
    {
      "type": "modify",
      "old_id": "b261076faf1c91bc26942cada96cbb79286b702f",
      "old_mode": 33188,
      "old_path": "packages/flutter/test/widgets/scrollbar_test.dart",
      "new_id": "82510c9d71c700a73ab2da5cedf11d3b5863d21a",
      "new_mode": 33188,
      "new_path": "packages/flutter/test/widgets/scrollbar_test.dart"
    }
  ]
}
