diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 79f382249..3e98418b1 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -273,6 +273,11 @@ class _RemotePageState extends State tabState.tabs[selected].key == widget.id; } + // Every Windows requestFocus() must pass this, or a blocking dialog or an + // inactive tab could hand remote input to this page. + bool get _windowsCanFocusRemoteInput => + _isSelectedTab && _blockableOverlayState.middleBlocked.isFalse; + bool get _isMacOSKeyboardContextActive { return stateGlobal.isFocused.value && !_isWindowBlur && _isSelectedTab; } @@ -513,6 +518,15 @@ class _RemotePageState extends State _queueMacOSKeyboardAfterFullScreen(allowHiddenLifecycle: true); } + // Refocus without PointerEnter: the cursor already hovers the image when + // focus returns (Alt+Tab, taskbar), so enterView() never fires again. + if (isWindows && + _cursorOverImage.value && + _windowsCanFocusRemoteInput && + !_rawKeyFocusNode.hasFocus) { + _rawKeyFocusNode.requestFocus(); + } + // Restore relative mouse mode constraints when window regains focus. if (_ffi.inputModel.relativeMouseMode.value) { if (isMacOS) { @@ -523,7 +537,7 @@ class _RemotePageState extends State _cursorOverImage.value = true; _macOSLocalFocusLost = false; } - } else { + } else if (!isWindows || _windowsCanFocusRemoteInput) { _rawKeyFocusNode.requestFocus(); } _ffi.inputModel.onWindowFocus(); @@ -835,7 +849,16 @@ class _RemotePageState extends State _macOSLocalFocusLost = false; stateGlobal.getInputSource(force: true); _syncMacOSKeyboardGrab(reassert: true, allowInactiveLifecycle: true); - } else if (!isWindows) { + } else if (isWindows) { + // Blur unfocuses this node and nothing restores it, so the keyboard stayed + // dead until a click. Focus only while the window is really active, or a + // background window would grab system keys. onFocusChange does enterOrLeave. + if (!_isWindowBlur && + _windowsCanFocusRemoteInput && + !_rawKeyFocusNode.hasFocus) { + _rawKeyFocusNode.requestFocus(); + } + } else { if (!_rawKeyFocusNode.hasFocus) { _rawKeyFocusNode.requestFocus(); }