diff --git a/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_actions.dart b/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_actions.dart index bca8ffa7a..1da38cce0 100644 --- a/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_actions.dart +++ b/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_actions.dart @@ -148,8 +148,6 @@ final List kKeyboardShortcutActionGroups = [ KeyboardShortcutActionEntry( kShortcutActionKeyboardModeTranslate, 'Translate mode'), ]), - KeyboardShortcutActionEntry( - kShortcutActionToggleInputSource, 'Toggle input source'), KeyboardShortcutActionEntry(kShortcutActionToggleViewOnly, 'View Mode'), KeyboardShortcutActionEntry( kShortcutActionToggleShowMyCursor, 'Show my cursor'), @@ -258,10 +256,6 @@ List filterKeyboardShortcutActionGroupsForPlatform( id == kShortcutActionViewModeCustom)) { return false; } - if (!cap.includeInputSourceShortcut && - id == kShortcutActionToggleInputSource) { - return false; - } if (!cap.includeVoiceCallShortcut && id == kShortcutActionToggleVoiceCall) { return false; } diff --git a/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_constants.dart b/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_constants.dart index 05c2fc174..3d265199d 100644 --- a/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_constants.dart +++ b/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_constants.dart @@ -61,7 +61,6 @@ const kShortcutActionImageQualityBest = 'image_quality_best'; const kShortcutActionImageQualityBalanced = 'image_quality_balanced'; const kShortcutActionImageQualityLow = 'image_quality_low'; const kShortcutActionSendClipboardKeystrokes = 'send_clipboard_keystrokes'; -const kShortcutActionToggleInputSource = 'toggle_input_source'; const kShortcutActionToggleVoiceCall = 'toggle_voice_call'; const kShortcutActionToggleViewOnly = 'toggle_view_only'; diff --git a/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_utils.dart b/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_utils.dart index 965d4e985..58f85fbdd 100644 --- a/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_utils.dart +++ b/flutter/lib/common/widgets/keyboard_shortcuts/shortcut_utils.dart @@ -117,7 +117,6 @@ class ShortcutPlatformCapabilities { final bool includeResetCanvasShortcut; final bool includePinToolbarShortcut; final bool includeViewModeShortcut; - final bool includeInputSourceShortcut; final bool includeVoiceCallShortcut; const ShortcutPlatformCapabilities({ @@ -131,7 +130,6 @@ class ShortcutPlatformCapabilities { required this.includeResetCanvasShortcut, required this.includePinToolbarShortcut, required this.includeViewModeShortcut, - required this.includeInputSourceShortcut, required this.includeVoiceCallShortcut, }); } @@ -185,10 +183,6 @@ List> filterDefaultBindingsForPlatform( action == kShortcutActionViewModeCustom)) { continue; } - if (!cap.includeInputSourceShortcut && - action == kShortcutActionToggleInputSource) { - continue; - } if (!cap.includeVoiceCallShortcut && action == kShortcutActionToggleVoiceCall) { continue; diff --git a/flutter/lib/models/shortcut_model.dart b/flutter/lib/models/shortcut_model.dart index 128ed6a2e..7745c4d0c 100644 --- a/flutter/lib/models/shortcut_model.dart +++ b/flutter/lib/models/shortcut_model.dart @@ -203,9 +203,6 @@ class ShortcutModel { /// `recordingModel.toggle()`; Web has no implementation. /// * Reset Canvas: only the mobile toolbar builds the menu entry /// (`isDefaultConn && isMobile` in `toolbarControls`). - /// * Input Source: Web only ships a single source so toggling is a - /// no-op; the toolbar menu hides itself when fewer than 2 sources are - /// advertised. /// * Voice Call: Web bridge throws `UnimplementedError` for both /// `sessionRequestVoiceCall` and `sessionCloseVoiceCall`. static ShortcutPlatformCapabilities currentPlatformCapabilities() { @@ -221,7 +218,6 @@ class ShortcutModel { includeResetCanvasShortcut: isMobile, includePinToolbarShortcut: desktopLayout, includeViewModeShortcut: desktopLayout, - includeInputSourceShortcut: !isWeb, includeVoiceCallShortcut: !isWeb, ); } @@ -605,36 +601,4 @@ void registerSessionShortcutActions( ffi.inputModel.toggleRelativeMouseMode(); }); } - - // Toggle Input Source — flips between the available keyboard-event capture - // backends (e.g. JS vs Flutter on desktop). Mirrors the radio menu in - // remote_toolbar.dart::inputSource(); when fewer than 2 sources are - // available the menu hides itself, so this handler is a no-op too. - // Useful for accessibility: screen-reader users sometimes need to swap - // sources to regain control of the local keyboard (discussion #1933). - // Web only ships a single source, so we don't register on web. - if (!isWeb) { - ffi.shortcutModel.register(kShortcutActionToggleInputSource, () async { - final raw = bind.mainSupportedInputSource(); - if (raw.isEmpty) return; - final List list; - try { - list = jsonDecode(raw) as List; - } catch (_) { - return; - } - if (list.length < 2) return; - final ids = list - .map((e) => (e is List && e.isNotEmpty) ? e[0] as String : '') - .where((s) => s.isNotEmpty) - .toList(); - if (ids.length < 2) return; - final current = stateGlobal.getInputSource(); - final idx = ids.indexOf(current); - final next = ids[(idx < 0 ? 0 : idx + 1) % ids.length]; - await stateGlobal.setInputSource(sessionId, next); - await ffi.ffiModel.checkDesktopKeyboardMode(); - await ffi.inputModel.updateKeyboardMode(); - }); - } } diff --git a/flutter/test/keyboard_shortcuts_test.dart b/flutter/test/keyboard_shortcuts_test.dart index 57ddce6e3..373a76a2e 100644 --- a/flutter/test/keyboard_shortcuts_test.dart +++ b/flutter/test/keyboard_shortcuts_test.dart @@ -18,7 +18,6 @@ ShortcutPlatformCapabilities capabilities({ bool includeResetCanvasShortcut = true, bool includePinToolbarShortcut = true, bool includeViewModeShortcut = true, - bool includeInputSourceShortcut = true, bool includeVoiceCallShortcut = true, }) { return ShortcutPlatformCapabilities( @@ -32,7 +31,6 @@ ShortcutPlatformCapabilities capabilities({ includeResetCanvasShortcut: includeResetCanvasShortcut, includePinToolbarShortcut: includePinToolbarShortcut, includeViewModeShortcut: includeViewModeShortcut, - includeInputSourceShortcut: includeInputSourceShortcut, includeVoiceCallShortcut: includeVoiceCallShortcut, ); } @@ -197,7 +195,6 @@ void main() { includeResetCanvasShortcut: false, includePinToolbarShortcut: false, includeViewModeShortcut: false, - includeInputSourceShortcut: false, includeVoiceCallShortcut: false, ), ); @@ -248,7 +245,6 @@ void main() { includeResetCanvasShortcut: true, includePinToolbarShortcut: false, includeViewModeShortcut: false, - includeInputSourceShortcut: false, includeVoiceCallShortcut: false, ), ); @@ -358,7 +354,6 @@ void main() { ' $kShortcutActionKeyboardModeLegacy', ' $kShortcutActionKeyboardModeMap', ' $kShortcutActionKeyboardModeTranslate', - kShortcutActionToggleInputSource, kShortcutActionToggleViewOnly, kShortcutActionToggleShowMyCursor, kShortcutActionToggleSwapCtrlCmd, @@ -394,7 +389,6 @@ void main() { includeResetCanvasShortcut: false, includePinToolbarShortcut: false, includeViewModeShortcut: false, - includeInputSourceShortcut: false, includeVoiceCallShortcut: false, ), ); @@ -503,8 +497,13 @@ void main() { // legacy IDs (toggle_audio, view_mode_shrink/stretch, view_mode_1_to_1) // were renamed: their replacements are kShortcutActionToggleMute and // kShortcutActionViewModeOriginal/Adaptive/Custom. + // + // `toggle_input_source` was removed on purpose: it switches the key + // capture backend between key down and key up, so the matcher that + // consumed the press never sees the repeats and the release. const knownRemoved = [ 'toggle_audio', + 'toggle_input_source', 'view_mode_1_to_1', 'view_mode_shrink', 'view_mode_stretch', diff --git a/src/keyboard/shortcuts.rs b/src/keyboard/shortcuts.rs index 67c390a3c..46919be94 100644 --- a/src/keyboard/shortcuts.rs +++ b/src/keyboard/shortcuts.rs @@ -68,7 +68,6 @@ pub mod action_id { pub const IMAGE_QUALITY_BALANCED: &str = "image_quality_balanced"; pub const IMAGE_QUALITY_LOW: &str = "image_quality_low"; pub const SEND_CLIPBOARD_KEYSTROKES: &str = "send_clipboard_keystrokes"; - pub const TOGGLE_INPUT_SOURCE: &str = "toggle_input_source"; pub const SWITCH_TAB_NEXT: &str = "switch_tab_next"; pub const SWITCH_TAB_PREV: &str = "switch_tab_prev"; pub const TOGGLE_VOICE_CALL: &str = "toggle_voice_call";