From 2ae38c93f08d09e0ad02597c20090ae7b7446bfa Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 21 Dec 2022 22:39:30 +0800 Subject: [PATCH] opt: use whole focus instead to trigger session enter or leave --- flutter/lib/common/widgets/remote_input.dart | 25 +++++++++++----- flutter/lib/desktop/pages/remote_page.dart | 31 +++++++++++++++----- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/flutter/lib/common/widgets/remote_input.dart b/flutter/lib/common/widgets/remote_input.dart index 3a79d24fb..017850cf5 100644 --- a/flutter/lib/common/widgets/remote_input.dart +++ b/flutter/lib/common/widgets/remote_input.dart @@ -9,11 +9,12 @@ class RawKeyFocusScope extends StatelessWidget { final InputModel inputModel; final Widget child; - RawKeyFocusScope( - {this.focusNode, - this.onFocusChange, - required this.inputModel, - required this.child}); + RawKeyFocusScope({ + this.focusNode, + this.onFocusChange, + required this.inputModel, + required this.child, + }); @override Widget build(BuildContext context) { @@ -35,11 +36,15 @@ class RawPointerMouseRegion extends StatelessWidget { final MouseCursor? cursor; final PointerEnterEventListener? onEnter; final PointerExitEventListener? onExit; + final PointerDownEventListener? onPointerDown; + final PointerUpEventListener? onPointerUp; RawPointerMouseRegion( {this.onEnter, this.onExit, this.cursor, + this.onPointerDown, + this.onPointerUp, required this.inputModel, required this.child}); @@ -47,8 +52,14 @@ class RawPointerMouseRegion extends StatelessWidget { Widget build(BuildContext context) { return Listener( onPointerHover: inputModel.onPointHoverImage, - onPointerDown: inputModel.onPointDownImage, - onPointerUp: inputModel.onPointUpImage, + onPointerDown: (evt) { + onPointerDown?.call(evt); + inputModel.onPointDownImage(evt); + }, + onPointerUp: (evt) { + onPointerUp?.call(evt); + inputModel.onPointUpImage(evt); + }, onPointerMove: inputModel.onPointMoveImage, onPointerSignal: inputModel.onPointerSignalImage, /* diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 4061fb74d..8fd4ee07c 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -52,6 +52,7 @@ class _RemotePageState extends State with AutomaticKeepAliveClientMixin, MultiWindowListener { Timer? _timer; String keyboardMode = "legacy"; + bool _isWindowBlur = false; final _cursorOverImage = false.obs; late RxBool _showRemoteCursor; late RxBool _zoomCursor; @@ -59,7 +60,6 @@ class _RemotePageState extends State late RxBool _keyboardEnabled; final FocusNode _rawKeyFocusNode = FocusNode(debugLabel: "rawkeyFocusNode"); - var _imageFocused = false; Function(bool)? _onEnterOrLeaveImage4Menubar; @@ -104,7 +104,6 @@ class _RemotePageState extends State if (!Platform.isLinux) { Wakelock.enable(); } - _rawKeyFocusNode.requestFocus(); _ffi.ffiModel.updateEventListener(widget.id); _ffi.qualityMonitorModel.checkShowQualityMonitor(widget.id); // Session option should be set after models.dart/FFI.start @@ -129,11 +128,18 @@ class _RemotePageState extends State @override void onWindowBlur() { super.onWindowBlur(); + _isWindowBlur = true; // unfocus the key focus when the whole window is lost focus, // and let OS to handle events instead. _rawKeyFocusNode.unfocus(); } + @override + void onWindowFocus() { + super.onWindowFocus(); + _isWindowBlur = false; + } + @override void dispose() { debugPrint("REMOTE PAGE dispose ${widget.id}"); @@ -166,9 +172,16 @@ class _RemotePageState extends State color: Colors.black, child: RawKeyFocusScope( focusNode: _rawKeyFocusNode, - onFocusChange: (bool v) { - _imageFocused = v; - if (_imageFocused) { + onFocusChange: (bool imageFocused) { + debugPrint( + "onFocusChange(window active:${!_isWindowBlur}) $imageFocused"); + if (_isWindowBlur) { + imageFocused = false; + Future.delayed(Duration.zero, () { + _rawKeyFocusNode.unfocus(); + }); + } + if (imageFocused) { _ffi.inputModel.enterOrLeave(true); } else { _ffi.inputModel.enterOrLeave(false); @@ -199,9 +212,6 @@ class _RemotePageState extends State } void enterView(PointerEnterEvent evt) { - if (!_imageFocused) { - _rawKeyFocusNode.requestFocus(); - } _cursorOverImage.value = true; _firstEnterImage.value = true; if (_onEnterOrLeaveImage4Menubar != null) { @@ -244,6 +254,11 @@ class _RemotePageState extends State listenerBuilder: (child) => RawPointerMouseRegion( onEnter: enterView, onExit: leaveView, + onPointerDown: (event) { + if (!_rawKeyFocusNode.hasFocus) { + _rawKeyFocusNode.requestFocus(); + } + }, inputModel: _ffi.inputModel, child: child, ),