diff --git a/Perspex.Input/FocusManager.cs b/Perspex.Input/FocusManager.cs index 8d47ec6bf9..04344ba06c 100644 --- a/Perspex.Input/FocusManager.cs +++ b/Perspex.Input/FocusManager.cs @@ -11,6 +11,8 @@ namespace Perspex.Input using System.Linq; using Perspex.VisualTree; using Splat; + using Perspex.Interactivity; + /// /// Manages focus for the application. @@ -23,6 +25,17 @@ namespace Perspex.Input private Dictionary focusScopes = new Dictionary(); + /// + /// Initializes a new instance of the class. + /// + public FocusManager() + { + InputElement.PointerPressedEvent.AddClassHandler( + typeof(IInputElement), + new EventHandler(this.OnPreviewPointerPressed), + RoutingStrategies.Tunnel); + } + /// /// Gets the instance of the . /// @@ -135,6 +148,13 @@ namespace Perspex.Input this.Focus(e); } + /// + /// Checks if the specified element can be focused. + /// + /// The element. + /// True if the element can be focused. + private static bool CanFocus(IInputElement e) => e.Focusable && e.IsEnabledCore && e.IsVisible; + /// /// Gets the focus scope ancestors of the specified control, traversing popups. /// @@ -155,5 +175,31 @@ namespace Perspex.Input ((control as IHostedVisualTreeRoot)?.Host as IInputElement); } } + + /// + /// Global handler for pointer pressed events. + /// + /// The event sender. + /// The event args. + private void OnPreviewPointerPressed(object sender, RoutedEventArgs e) + { + if (sender == e.Source) + { + var ev = (PointerPressEventArgs)e; + var element = (ev.Device.Captured as IInputElement) ?? (e.Source as IInputElement); + + if (element == null || !CanFocus(element)) + { + element = element.GetSelfAndVisualAncestors() + .OfType() + .FirstOrDefault(x => CanFocus(x)); + } + + if (element != null) + { + this.Focus(element); + } + } + } } } diff --git a/Perspex.Input/MouseDevice.cs b/Perspex.Input/MouseDevice.cs index 63f2dffae3..3022acc0d2 100644 --- a/Perspex.Input/MouseDevice.cs +++ b/Perspex.Input/MouseDevice.cs @@ -140,13 +140,6 @@ namespace Perspex.Input source.RaiseEvent(e); } - - IInputElement focusable = this.GetFocusable(hit); - - if (focusable != null && focusable.Focusable && focusable.IsEffectivelyVisible) - { - focusable.Focus(); - } } } @@ -227,22 +220,6 @@ namespace Perspex.Input } } - private IInputElement GetFocusable(IVisual hit) - { - var inputFocus = this.Captured as IInputElement; - - if (inputFocus != null && inputFocus.Focusable) - { - return inputFocus; - } - else - { - return hit.GetSelfAndVisualAncestors() - .OfType() - .FirstOrDefault(x => x.Focusable); - } - } - private IInteractive GetSource(IVisual hit) { return this.Captured ?? diff --git a/TestApplication/App.cs b/TestApplication/App.cs index 40ec041c58..a4cd210465 100644 --- a/TestApplication/App.cs +++ b/TestApplication/App.cs @@ -20,7 +20,6 @@ public App() : base(new DefaultTheme()) { - this.RegisterServices(); #if PERSPEX_CAIRO CairoPlatform.Initialize(); #else