fix(input): reset long press state safely

This commit is contained in:
edde746
2026-07-12 08:42:19 +02:00
parent 9c6fcbc841
commit 6d94880c2f
6 changed files with 117 additions and 17 deletions
+13 -3
View File
@@ -86,7 +86,12 @@ mixin FocusableChipStateMixin<T extends StatefulWidget> on State<T> {
void _onFocusChange() {
if (mounted) {
setState(() => _isFocused = focusNode.hasFocus);
final hasFocus = focusNode.hasFocus;
setState(() => _isFocused = hasFocus);
if (!hasFocus) {
_longPressTimer?.cancel();
_isSelectKeyDown = false;
}
// Same convention as FocusableTileStateMixin: a chip inside a
// scrollable strip (TabChipStrip, filter bars) reveals itself on
// focus; a no-op when no ancestor scrollable exists.
@@ -114,6 +119,10 @@ mixin FocusableChipStateMixin<T extends StatefulWidget> on State<T> {
}
if (SelectKeyUpSuppressor.consumeIfSuppressed(event)) {
if (event is KeyUpEvent && key.isSelectKey) {
_longPressTimer?.cancel();
_isSelectKeyDown = false;
}
return KeyEventResult.handled;
}
@@ -125,7 +134,7 @@ mixin FocusableChipStateMixin<T extends StatefulWidget> on State<T> {
_isSelectKeyDown = true;
_longPressTimer?.cancel();
_longPressTimer = Timer(const Duration(milliseconds: 500), () {
if (mounted) {
if (mounted && _isSelectKeyDown) {
SelectKeyUpSuppressor.suppressSelectUntilKeyUp();
callbacks.onLongPress?.call();
}
@@ -150,7 +159,8 @@ mixin FocusableChipStateMixin<T extends StatefulWidget> on State<T> {
// Context menu key triggers long press directly
if (event.isActionable && key.isContextMenuKey && callbacks.onLongPress != null) {
SelectKeyUpSuppressor.suppressSelectUntilKeyUp();
_longPressTimer?.cancel();
_isSelectKeyDown = false;
callbacks.onLongPress!();
return KeyEventResult.handled;
}
+7 -2
View File
@@ -376,6 +376,10 @@ class _FocusableWrapperState extends State<FocusableWrapper> with SingleTickerPr
_logFocusableWrapper('node=${node.debugLabel} received key=(${_describeFocusableKey(event)})');
if (SelectKeyUpSuppressor.consumeIfSuppressed(event)) {
if (event is KeyUpEvent && key.isSelectKey) {
_longPressTimer?.cancel();
_isSelectKeyDown = false;
}
return finish(KeyEventResult.handled, 'select-key-up-suppressed');
}
@@ -404,7 +408,7 @@ class _FocusableWrapperState extends State<FocusableWrapper> with SingleTickerPr
_longPressTimer?.cancel();
_longPressTimer = Timer(widget.longPressDuration, () {
// Long press detected
if (mounted) {
if (mounted && _isSelectKeyDown) {
SelectKeyUpSuppressor.suppressSelectUntilKeyUp();
widget.onLongPress?.call();
}
@@ -437,7 +441,8 @@ class _FocusableWrapperState extends State<FocusableWrapper> with SingleTickerPr
// Context menu key
if (key.isContextMenuKey) {
SelectKeyUpSuppressor.suppressSelectUntilKeyUp();
_longPressTimer?.cancel();
_isSelectKeyDown = false;
widget.onLongPress?.call();
return finish(KeyEventResult.handled, 'context-menu');
}