Skip to content

Commit 61ddade

Browse files
authored
fix(windows): restore keyboard focus when the cursor re-enters the remote image (rustdesk#15880)
* fix(windows): restore keyboard focus when the cursor re-enters the remote image On Windows the raw key focus node is unfocused on window blur and nothing requests it back, so returning to an already connected session left the keyboard dead until the remote image was clicked. Request focus from enterView(), gated on the window being active, the tab being selected and no blocking overlay, so a background window cannot grab system keys. enterOrLeave(true) is still driven by RawKeyFocusScope's onFocusChange, so it is not called twice. * fix(windows): refocus on window focus when the cursor already hovers the image Alt+Tab or a taskbar click returns focus without a PointerEnter, so enterView() cannot restore the keyboard. Reuse _cursorOverImage, gated on the selected tab and no blocking overlay. * refactor(windows): share one focus predicate for every requestFocus path The relative-mouse-mode restore on window focus could hand remote input to this page while a blocking dialog was up or the tab was not selected.
1 parent c78bdef commit 61ddade

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

flutter/lib/desktop/pages/remote_page.dart

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ class _RemotePageState extends State<RemotePage>
273273
tabState.tabs[selected].key == widget.id;
274274
}
275275

276+
// Every Windows requestFocus() must pass this, or a blocking dialog or an
277+
// inactive tab could hand remote input to this page.
278+
bool get _windowsCanFocusRemoteInput =>
279+
_isSelectedTab && _blockableOverlayState.middleBlocked.isFalse;
280+
276281
bool get _isMacOSKeyboardContextActive {
277282
return stateGlobal.isFocused.value && !_isWindowBlur && _isSelectedTab;
278283
}
@@ -513,6 +518,15 @@ class _RemotePageState extends State<RemotePage>
513518
_queueMacOSKeyboardAfterFullScreen(allowHiddenLifecycle: true);
514519
}
515520

521+
// Refocus without PointerEnter: the cursor already hovers the image when
522+
// focus returns (Alt+Tab, taskbar), so enterView() never fires again.
523+
if (isWindows &&
524+
_cursorOverImage.value &&
525+
_windowsCanFocusRemoteInput &&
526+
!_rawKeyFocusNode.hasFocus) {
527+
_rawKeyFocusNode.requestFocus();
528+
}
529+
516530
// Restore relative mouse mode constraints when window regains focus.
517531
if (_ffi.inputModel.relativeMouseMode.value) {
518532
if (isMacOS) {
@@ -523,7 +537,7 @@ class _RemotePageState extends State<RemotePage>
523537
_cursorOverImage.value = true;
524538
_macOSLocalFocusLost = false;
525539
}
526-
} else {
540+
} else if (!isWindows || _windowsCanFocusRemoteInput) {
527541
_rawKeyFocusNode.requestFocus();
528542
}
529543
_ffi.inputModel.onWindowFocus();
@@ -835,7 +849,16 @@ class _RemotePageState extends State<RemotePage>
835849
_macOSLocalFocusLost = false;
836850
stateGlobal.getInputSource(force: true);
837851
_syncMacOSKeyboardGrab(reassert: true, allowInactiveLifecycle: true);
838-
} else if (!isWindows) {
852+
} else if (isWindows) {
853+
// Blur unfocuses this node and nothing restores it, so the keyboard stayed
854+
// dead until a click. Focus only while the window is really active, or a
855+
// background window would grab system keys. onFocusChange does enterOrLeave.
856+
if (!_isWindowBlur &&
857+
_windowsCanFocusRemoteInput &&
858+
!_rawKeyFocusNode.hasFocus) {
859+
_rawKeyFocusNode.requestFocus();
860+
}
861+
} else {
839862
if (!_rawKeyFocusNode.hasFocus) {
840863
_rawKeyFocusNode.requestFocus();
841864
}

0 commit comments

Comments
 (0)