@@ -45,23 +45,37 @@ class _MacosPopupMenuItemButton<T> extends StatefulWidget {
4545
4646class _MacosPopupMenuItemButtonState <T >
4747 extends State <_MacosPopupMenuItemButton <T >> {
48- bool _isHovered = false ;
48+ final _focusNode = FocusNode ();
49+
50+ bool _isFocused = false ;
51+
52+ bool get _isHighlighted => _isFocused;
53+
54+ /// The last time the mouse entered this item.
55+ static DateTime _lastMouseEnterTime = DateTime .now ();
56+
57+ /// The last time the focus changed that wasn’t caused by the mouse.
58+ static DateTime _lastNonMouseFocusChange = DateTime .now ();
4959
5060 void _handleFocusChange (bool focused) {
5161 if (focused) {
52- final _MenuLimits menuLimits = widget.route.getMenuLimits (
53- widget.buttonRect,
54- widget.constraints.maxHeight,
55- widget.itemIndex,
56- );
57- widget.route.scrollController! .animateTo (
58- menuLimits.scrollOffset,
59- curve: Curves .easeInOut,
60- duration: const Duration (milliseconds: 100 ),
61- );
62- setState (() => _isHovered = true );
62+ final timeSinceMouseEnter =
63+ DateTime .now ().difference (_lastMouseEnterTime);
64+ if (timeSinceMouseEnter > const Duration (milliseconds: 50 )) {
65+ _lastNonMouseFocusChange = DateTime .now ();
66+
67+ final _MenuLimits menuLimits = widget.route.getMenuLimits (
68+ widget.buttonRect,
69+ widget.constraints.maxHeight,
70+ widget.itemIndex,
71+ );
72+ widget.route.scrollController! .jumpTo (
73+ menuLimits.scrollOffset,
74+ );
75+ }
76+ setState (() => _isFocused = true );
6377 } else {
64- setState (() => _isHovered = false );
78+ setState (() => _isFocused = false );
6579 }
6680 }
6781
@@ -91,14 +105,20 @@ class _MacosPopupMenuItemButtonState<T>
91105 child = MouseRegion (
92106 cursor: SystemMouseCursors .basic,
93107 onEnter: (_) {
94- setState (() => _isHovered = true );
95- },
96- onExit: (_) {
97- setState (() => _isHovered = false );
108+ final timeSinceLastNonMouseFocusChange =
109+ DateTime .now ().difference (_lastNonMouseFocusChange);
110+ if (timeSinceLastNonMouseFocusChange <
111+ const Duration (milliseconds: 200 )) {
112+ return ;
113+ }
114+
115+ _lastMouseEnterTime = DateTime .now ();
116+ FocusScope .of (context).requestFocus (_focusNode);
98117 },
99118 child: GestureDetector (
100119 onTap: _handleOnTap,
101120 child: Focus (
121+ focusNode: _focusNode,
102122 onKeyEvent: (FocusNode node, KeyEvent event) {
103123 if (event.logicalKey == LogicalKeyboardKey .enter) {
104124 _handleOnTap ();
@@ -110,7 +130,7 @@ class _MacosPopupMenuItemButtonState<T>
110130 autofocus: widget.itemIndex == widget.route.selectedIndex,
111131 child: Container (
112132 decoration: BoxDecoration (
113- color: _isHovered
133+ color: _isHighlighted
114134 ? MacosPopupButtonTheme .of (context).highlightColor
115135 : Colors .transparent,
116136 borderRadius: _kBorderRadius,
@@ -123,7 +143,7 @@ class _MacosPopupMenuItemButtonState<T>
123143 child: MacosIcon (
124144 CupertinoIcons .checkmark_alt,
125145 size: 16.0 ,
126- color: _isHovered
146+ color: _isHighlighted
127147 ? MacosColors .white
128148 : brightness.resolve (
129149 MacosColors .black,
@@ -135,7 +155,7 @@ class _MacosPopupMenuItemButtonState<T>
135155 DefaultTextStyle (
136156 style: TextStyle (
137157 fontSize: 13.0 ,
138- color: _isHovered
158+ color: _isHighlighted
139159 ? MacosColors .white
140160 : brightness.resolve (
141161 MacosColors .black,
0 commit comments