-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Overview
When SelectionArea wraps another smaller region that specifies a mouse cursor, moving the mouse from the inner region to where there's only SelectionArea behaves incorrectly on Web, where it retains the inner mouse cursor instead returning to default.
Screen.Recording.2025-08-29.at.3.46.47.PM.mp4
Internal: b/437197529
Reproduction
Reproduction:
- Run the following app
- The widget consists of two rectangles. The outer one is a
SelectionArea. The inner one is aMouseRegionwith mouse cursorforbidden.
- The widget consists of two rectangles. The outer one is a
- Hover mouse into the inner region. The mouse cursor should be
.forbidden. - Now hover mouse into the outer region.
Expected behavior (observable on -d macos):
The cursor becomes default (the arrow).
Actual behavior (observable on -d chrome):
The cursor stays .forbidden.
Repro code
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('SelectionArea Sample')),
body: Center(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: const Color(0xFF000000), width: 1),
),
child: SelectionArea(
child: Padding(
padding: const EdgeInsetsGeometry.all(40),
child: MouseRegion(
cursor: SystemMouseCursors.forbidden,
onHover: (_) {},
child: Container(
color: const Color(0xFFAA9933),
padding: const EdgeInsets.all(30),
width: 200,
height: 50,
),
),
),
),
),
),
),
);
}
}Analysis
This is because how platform views implements mouse cursors. Platform views apply MouseCursor.uncontrolled onto their regions so that Flutter can transfer the control of mouse cursors to the view contents.
Since desktop platforms control mouse cursors imperitively, i.e. by sending messages to change them, MouseCursor.uncontrolled is implemented by having the cursor do nothing, so that desktop embeddings will send no messages that change the cursor.
However, since Web controls mouse cursors declaratively, implementing MouseCursor.uncontrolled in the same way will retain the cursor property.