fix: prevent lost input after remote session shortcuts

Avoid synthetic Alt presses that activate the Windows system menu
and swallow the next character.

Trigger restart, switch-sides, and chat actions on key release so
focus changes cannot leave subsequent shortcut presses ignored.

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2026-09-26 14:53:46 +08:00
parent 18092b403d
commit 01348c762c
3 changed files with 15 additions and 6 deletions
@@ -18,7 +18,7 @@ const kShortcutActionResetCanvas = 'reset_canvas';
const kShortcutActionSwitchTabNext = 'switch_tab_next';
const kShortcutActionSwitchTabPrev = 'switch_tab_prev';
/// Actions that move keyboard focus to another session. They run when the
/// Actions that move keyboard focus to another session or a dialog. They run when the
/// key that fired them is released, not when it is pressed, so the matcher
/// that consumed the press also sees its repeats and its release. On Linux a
/// legacy-mode session matches in Dart while a map-mode session matches in
@@ -29,6 +29,9 @@ const kShortcutActionsRunOnKeyUp = {
kShortcutActionCloseTab,
kShortcutActionSwitchTabNext,
kShortcutActionSwitchTabPrev,
kShortcutActionRestartRemote,
kShortcutActionSwitchSides,
kShortcutActionToggleChat,
};
const kShortcutActionToggleMute = 'toggle_mute';
const kShortcutActionPinToolbar = 'pin_toolbar';
+4 -1
View File
@@ -1,5 +1,8 @@
[
"close_tab",
"switch_tab_next",
"switch_tab_prev"
"switch_tab_prev",
"restart_remote",
"switch_sides",
"toggle_chat"
]
+7 -4
View File
@@ -338,7 +338,7 @@ lazy_static::lazy_static! {
> = Default::default();
}
/// Actions that move keyboard focus to another session. They run when the
/// Actions that move keyboard focus to another session or a dialog. They run when the
/// key that fired them is released, not when it is pressed, so the matcher
/// that consumed the press also sees its repeats and its release. The next
/// session may route its keys through the other matcher (Flutter's legacy
@@ -349,6 +349,9 @@ const RELEASE_ACTION_IDS: &[&str] = &[
action_id::CLOSE_TAB,
action_id::SWITCH_TAB_NEXT,
action_id::SWITCH_TAB_PREV,
action_id::RESTART_REMOTE,
action_id::SWITCH_SIDES,
action_id::TOGGLE_CHAT,
];
pub fn runs_on_release(action_id: &str) -> bool {
@@ -538,9 +541,9 @@ fn release_remote_keys(
};
for (key, mut event) in to_release {
let mut types = vec![EventType::KeyRelease(key)];
// Same as `keyboard::release_remote_keys_for_events`: a lone Alt
// release can leave Alt held on the controlled side.
if key == Key::Alt || key == Key::AltGr {
// Keep the focus-loss workaround for other peers. Tapping Alt on
// Windows activates its system menu and consumes the next character.
if peer != "windows" && (key == Key::Alt || key == Key::AltGr) {
types.push(EventType::KeyPress(key));
types.push(EventType::KeyRelease(key));
}