From 1589209567b651ef27bf9fd270c6afeb82e29aab Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 29 Nov 2023 20:57:44 +0800 Subject: [PATCH] release keys for flutter input source Signed-off-by: fufesou --- flutter/lib/common/widgets/remote_input.dart | 3 +- flutter/lib/models/input_model.dart | 114 ++++++++++++++++++- 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/flutter/lib/common/widgets/remote_input.dart b/flutter/lib/common/widgets/remote_input.dart index a07bffa47..e073bffc9 100644 --- a/flutter/lib/common/widgets/remote_input.dart +++ b/flutter/lib/common/widgets/remote_input.dart @@ -34,7 +34,8 @@ class RawKeyFocusScope extends StatelessWidget { canRequestFocus: true, focusNode: focusNode, onFocusChange: onFocusChange, - onKey: inputModel.handleRawKeyEvent, + onKey: (FocusNode data, RawKeyEvent e) => + inputModel.handleRawKeyEvent(e), child: child)); } } diff --git a/flutter/lib/models/input_model.dart b/flutter/lib/models/input_model.dart index 156a1201b..322897145 100644 --- a/flutter/lib/models/input_model.dart +++ b/flutter/lib/models/input_model.dart @@ -52,6 +52,111 @@ class PointerEventToRust { } } +class ToReleaseKeys { + RawKeyEvent? lastLShiftKeyEvent; + RawKeyEvent? lastRShiftKeyEvent; + RawKeyEvent? lastLCtrlKeyEvent; + RawKeyEvent? lastRCtrlKeyEvent; + RawKeyEvent? lastLAltKeyEvent; + RawKeyEvent? lastRAltKeyEvent; + RawKeyEvent? lastLCommandKeyEvent; + RawKeyEvent? lastRCommandKeyEvent; + RawKeyEvent? lastSuperKeyEvent; + + reset() { + lastLShiftKeyEvent = null; + lastRShiftKeyEvent = null; + lastLCtrlKeyEvent = null; + lastRCtrlKeyEvent = null; + lastLAltKeyEvent = null; + lastRAltKeyEvent = null; + lastLCommandKeyEvent = null; + lastRCommandKeyEvent = null; + lastSuperKeyEvent = null; + } + + updateKeyDown(LogicalKeyboardKey logicKey, RawKeyDownEvent e) { + if (e.isAltPressed) { + if (logicKey == LogicalKeyboardKey.altLeft) { + lastLAltKeyEvent = e; + } else if (logicKey == LogicalKeyboardKey.altRight) { + lastRAltKeyEvent = e; + } + } else if (e.isControlPressed) { + if (logicKey == LogicalKeyboardKey.controlLeft) { + lastLCtrlKeyEvent = e; + } else if (logicKey == LogicalKeyboardKey.controlRight) { + lastRCtrlKeyEvent = e; + } + } else if (e.isShiftPressed) { + if (logicKey == LogicalKeyboardKey.shiftLeft) { + lastLShiftKeyEvent = e; + } else if (logicKey == LogicalKeyboardKey.shiftRight) { + lastRShiftKeyEvent = e; + } + } else if (e.isMetaPressed) { + if (logicKey == LogicalKeyboardKey.metaLeft) { + lastLCommandKeyEvent = e; + } else if (logicKey == LogicalKeyboardKey.metaRight) { + lastRCommandKeyEvent = e; + } else if (logicKey == LogicalKeyboardKey.superKey) { + lastSuperKeyEvent = e; + } + } + } + + updateKeyUp(LogicalKeyboardKey logicKey, RawKeyUpEvent e) { + if (e.isAltPressed) { + if (logicKey == LogicalKeyboardKey.altLeft) { + lastLAltKeyEvent = null; + } else if (logicKey == LogicalKeyboardKey.altRight) { + lastRAltKeyEvent = null; + } + } else if (e.isControlPressed) { + if (logicKey == LogicalKeyboardKey.controlLeft) { + lastLCtrlKeyEvent = null; + } else if (logicKey == LogicalKeyboardKey.controlRight) { + lastRCtrlKeyEvent = null; + } + } else if (e.isShiftPressed) { + if (logicKey == LogicalKeyboardKey.shiftLeft) { + lastLShiftKeyEvent = null; + } else if (logicKey == LogicalKeyboardKey.shiftRight) { + lastRShiftKeyEvent = null; + } + } else if (e.isMetaPressed) { + if (logicKey == LogicalKeyboardKey.metaLeft) { + lastLCommandKeyEvent = null; + } else if (logicKey == LogicalKeyboardKey.metaRight) { + lastRCommandKeyEvent = null; + } else if (logicKey == LogicalKeyboardKey.superKey) { + lastSuperKeyEvent = null; + } + } + } + + release(KeyEventResult Function(RawKeyEvent e) handleRawKeyEvent) { + for (final key in [ + lastLShiftKeyEvent, + lastRShiftKeyEvent, + lastLCtrlKeyEvent, + lastRCtrlKeyEvent, + lastLAltKeyEvent, + lastRAltKeyEvent, + lastLCommandKeyEvent, + lastRCommandKeyEvent, + lastSuperKeyEvent, + ]) { + if (key != null) { + handleRawKeyEvent(RawKeyUpEvent( + data: key.data, + character: key.character, + )); + } + } + } +} + class InputModel { final WeakReference parent; String keyboardMode = "legacy"; @@ -62,6 +167,8 @@ class InputModel { var alt = false; var command = false; + final ToReleaseKeys toReleaseKeys = ToReleaseKeys(); + // trackpad var _trackpadLastDelta = Offset.zero; var _stopFling = true; @@ -89,7 +196,7 @@ class InputModel { sessionId = parent.target!.sessionId; } - KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) { + KeyEventResult handleRawKeyEvent(RawKeyEvent e) { if (isDesktop && !isInputSourceFlutter) { return KeyEventResult.handled; } @@ -114,6 +221,7 @@ class InputModel { command = true; } } + toReleaseKeys.updateKeyDown(key, e); } if (e is RawKeyUpEvent) { if (key == LogicalKeyboardKey.altLeft || @@ -130,6 +238,8 @@ class InputModel { key == LogicalKeyboardKey.superKey) { command = false; } + + toReleaseKeys.updateKeyUp(key, e); } // * Currently mobile does not enable map mode @@ -319,6 +429,8 @@ class InputModel { } void enterOrLeave(bool enter) { + toReleaseKeys.release(handleRawKeyEvent); + // Fix status if (!enter) { resetModifiers();