From afea99b668137b565d54d4e6cab89aacb008f059 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Thu, 11 Apr 2024 15:13:16 +0200 Subject: [PATCH] feat: Port FocusController --- .../UI/Xaml/Hosting/FocusController.h.mux.cs | 2 +- .../UI/Xaml/Hosting/FocusController.mux.cs | 99 +++++++++---------- .../Xaml/Hosting/NavigateFocusResult.mux.cs | 14 +++ 3 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 src/Uno.UI/UI/Xaml/Hosting/NavigateFocusResult.mux.cs diff --git a/src/Uno.UI/UI/Xaml/Hosting/FocusController.h.mux.cs b/src/Uno.UI/UI/Xaml/Hosting/FocusController.h.mux.cs index 8e772fc99387..968476b473fe 100644 --- a/src/Uno.UI/UI/Xaml/Hosting/FocusController.h.mux.cs +++ b/src/Uno.UI/UI/Xaml/Hosting/FocusController.h.mux.cs @@ -13,7 +13,7 @@ namespace DirectUI; partial class FocusController { private readonly SerialDisposable _focusDepartingEvent = new(); - private CoreComponentFocusable? _coreComponentFocusable; + //private CoreComponentFocusable? _coreComponentFocusable; private InputFocusController? _inputObjectFocusable; private readonly SerialDisposable _gotFocusToken = new(); diff --git a/src/Uno.UI/UI/Xaml/Hosting/FocusController.mux.cs b/src/Uno.UI/UI/Xaml/Hosting/FocusController.mux.cs index e548d96c2f77..e815fdd03609 100644 --- a/src/Uno.UI/UI/Xaml/Hosting/FocusController.mux.cs +++ b/src/Uno.UI/UI/Xaml/Hosting/FocusController.mux.cs @@ -1,12 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. // MUX Reference dxaml\xcp\components\UIBridgeFocus\FocusController.cpp, tag winui3/release/1.5.1, commit 3d10001ba8e12336cad392846b1030ba691b784a +#nullable enable using System; using Microsoft.UI.Dispatching; using Microsoft.UI.Input; using Microsoft.UI.Xaml.Hosting; using Uno.Disposables; +using Uno.UI.Xaml.Input; using Windows.Foundation; using Windows.UI.Core; @@ -14,10 +16,10 @@ namespace DirectUI; internal partial class FocusController { - public FocusController(CoreComponentFocusable pFocusable) - { - _coreComponentFocusable = pFocusable; - } + //public FocusController(CoreComponentFocusable pFocusable) + //{ + // _coreComponentFocusable = pFocusable; + //} public FocusController(InputFocusController pFocusable) { @@ -32,12 +34,12 @@ public FocusController(InputFocusController pFocusable) public void Init() { - if (_coreComponentFocusable != null) - { - _coreComponentFocusable.GotFocus += OnCoreInputGotFocus; - _gotFocusToken.Disposable = Disposable.Create(() => _coreComponentFocusable.GotFocus -= OnCoreInputGotFocus); - } - else + //if (_coreComponentFocusable != null) + //{ + // _coreComponentFocusable.GotFocus += OnCoreInputGotFocus; + // _gotFocusToken.Disposable = Disposable.Create(() => _coreComponentFocusable.GotFocus -= OnCoreInputGotFocus); + //} + //else { var wrThis = new WeakReference(this); void OnInputControllerGotFocus(object sender, FocusChangedEventArgs args) @@ -48,7 +50,7 @@ void OnInputControllerGotFocus(object sender, FocusChangedEventArgs args) focusController.OnGotFocusCommon(); } } - _inputObjectFocusable.GotFocus += OnInputControllerGotFocus; + _inputObjectFocusable!.GotFocus += OnInputControllerGotFocus; _gotFocusToken.Disposable = Disposable.Create(() => _inputObjectFocusable.GotFocus -= OnInputControllerGotFocus); } } @@ -58,40 +60,39 @@ void OnInputControllerGotFocus(object sender, FocusChangedEventArgs args) // _gotFocusToken.Disposable = null; //} - public static IAsyncOperation CreateAsync(CoreComponentFocusable pFocusable) - { - var focusController = new FocusController(pFocusable); - focusController.Init(); - return AsyncOperation.FromTask(() => focusController); - } + //public static FocusController Create(CoreComponentFocusable pFocusable) + //{ + // var focusController = new FocusController(pFocusable); + // focusController.Init(); + // return focusController; + //} - public static IAsyncOperation CreateAsync(InputFocusController pFocusable) + public static FocusController Create(InputFocusController focusable) { - var focusController = new FocusController(pFocusable); + var focusController = new FocusController(focusable); focusController.Init(); - return AsyncOperation.FromTask(() => focusController); + return focusController; } - public IAsyncOperation NavigateFocusAsync(XamlSourceFocusNavigationRequest pRequest, FocusObserver pFocusObserver) + public XamlSourceFocusNavigationResult NavigateFocus(XamlSourceFocusNavigationRequest request, FocusObserver focusObserver) { - _currentRequest = pRequest; - var scopeExit = new Deferral(() => + _currentRequest = request; + using var scopeExit = Disposable.Create(() => { _currentRequest = null; }); - bool isHandled = false; - pFocusObserver.ProcessNavigateFocusRequest(pRequest, out isHandled); + bool isHandled = focusObserver.ProcessNavigateFocusRequest(request); var result = new NavigateFocusResult(isHandled); - return AsyncOperation.FromTask(() => result); + return result; } - internal event TypedEventHandler FocusDeparting; + internal event TypedEventHandler? FocusDeparting; - internal event TypedEventHandler GotFocus; + internal event TypedEventHandler? GotFocus; - public FocusNavigationResult DepartFocus(XamlSourceFocusNavigationRequest request) + public void DepartFocus(XamlSourceFocusNavigationRequest request) { var spLosingFocusRequest = new NavigationLosingFocusEventArgs(request); var departingEventArgs = spLosingFocusRequest as DesktopWindowXamlSourceTakeFocusRequestedEventArgs; @@ -134,23 +135,16 @@ public FocusNavigationResult DepartFocus(XamlSourceFocusNavigationRequest reques var correlationId = request.CorrelationId; var ixpRequest = FocusNavigationRequest.Create(ixpReason, hintRect, correlationId); - var inputFocusController2 = _inputObjectFocusable as InputFocusController; - var result = inputFocusController2.DepartFocusAsync(ixpRequest); + _inputObjectFocusable!.DepartFocus(ixpRequest); // WinUI may wish to respond to the result (Moved/NotMoved/NoFocusableElements) here in some way - - return AsyncOperation.FromTask(() => result); } - private IAsyncAction OnCoreInputGotFocus(object sender, CoreWindowEventArgs e) - { - return OnGotFocusCommon().AsAsyncAction(); - } + private void OnCoreInputGotFocus(object sender, CoreWindowEventArgs e) => OnGotFocusCommon(); - private IAsyncAction OnGotFocusCommon() + private void OnGotFocusCommon() { - var spDispatcherQueueStatics = DispatcherQueue.GetForCurrentThread(); - var spDispatcherQueue = spDispatcherQueueStatics as DispatcherQueue; + var dispatcherQueue = DispatcherQueue.GetForCurrentThread(); var currentRequest = _currentRequest; _currentRequest = null; @@ -160,23 +154,24 @@ private IAsyncAction OnGotFocusCommon() FireGotFocus(currentRequest); }); - spDispatcherQueue.TryEnqueue(callback); + dispatcherQueue.TryEnqueue(callback); } - public bool HasFocus => _coreComponentFocusable != null ? _coreComponentFocusable.HasFocus : _inputObjectFocusable.HasFocus; + public bool HasFocus => + //_coreComponentFocusable != null ? _coreComponentFocusable.HasFocus : + _inputObjectFocusable!.HasFocus; - private void FireGotFocus(XamlSourceFocusNavigationRequest pCurrentRequest) + private void FireGotFocus(XamlSourceFocusNavigationRequest? currentRequest) { - var spRequest = pCurrentRequest ?? CreateActivationFactory_XamlSourceFocusNavigationRequest().CreateInstance(XamlSourceFocusNavigationReason.Restore); - - var spArgs = new NavigationGotFocusEventArgs(spRequest); - var gotFocusEventArgs = spArgs as DesktopWindowXamlSourceGotFocusEventArgs; + var request = currentRequest; + if (request is null) + { + request = new XamlSourceFocusNavigationRequest(XamlSourceFocusNavigationReason.Restore); + } - _gotFocusEvent.InvokeAll(this, gotFocusEventArgs); - } + var args = new NavigationGotFocusEventArgs(request); + var gotFocusEventArgs = args as DesktopWindowXamlSourceGotFocusEventArgs; - private IActivationFactory CreateActivationFactory_XamlSourceFocusNavigationRequest() - { - throw new NotImplementedException(); + GotFocus?.Invoke(this, gotFocusEventArgs); } } diff --git a/src/Uno.UI/UI/Xaml/Hosting/NavigateFocusResult.mux.cs b/src/Uno.UI/UI/Xaml/Hosting/NavigateFocusResult.mux.cs new file mode 100644 index 000000000000..9a20fb40540d --- /dev/null +++ b/src/Uno.UI/UI/Xaml/Hosting/NavigateFocusResult.mux.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// MUX Reference dxaml\xcp\components\UIBridgeFocus\NavigateFocusResult.cpp, tag winui3/release/1.5.1, commit 3d10001ba8e12336cad392846b1030ba691b784a + +#nullable enable + +namespace Microsoft.UI.Xaml.Hosting; + +internal class NavigateFocusResult : XamlSourceFocusNavigationResult +{ + public NavigateFocusResult(bool focusMoved) : base(focusMoved) + { + } +}