Skip to content

Commit

Permalink
feat: Initial page focus on WASM using browser keyboard navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Jan 7, 2022
1 parent 53943f6 commit 7975615
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
20 changes: 20 additions & 0 deletions src/Uno.UI/UI/Xaml/Input/FocusManager.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ public static void ReceiveFocusNative(int handle)
}
else if (focused != null)
{
// Special handling for RootVisual - which is not focusable on managed side
// but is focusable on native side. The purpose of this trick is to allow
// us to recognize, that the page was focused by tabbing from the address bar
// and focusing the first focusable element on the page instead.
if (focused is RootVisual rootVisual)
{
var firstFocusable = FocusManager.FindFirstFocusableElement(rootVisual);
if (firstFocusable is FrameworkElement frameworkElement)
{
if (_log.Value.IsEnabled(LogLevel.Debug))
{
_log.Value.LogDebug(
$"Root visual focused - caused by browser keyboard navigation to the page, " +
$"moving focus to actual first focusable element - {frameworkElement?.ToString() ?? "[null]"}.");
}
frameworkElement.Focus(FocusState.Keyboard);
}
return;
}

ProcessElementFocused(focused);
}
else
Expand Down
14 changes: 9 additions & 5 deletions src/Uno.UI/UI/Xaml/Internal/RootVisual.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,22 @@ internal partial class RootVisual : Panel
public RootVisual(CoreServices coreServices)
{
_coreServices = coreServices ?? throw new System.ArgumentNullException(nameof(coreServices));
//Uno specific - flag as VisualTreeRoot for interop with existing logic
//Uno specific - flag as VisualTreeRoot for interop with existing logic
IsVisualTreeRoot = true;
#if __WASM__
//Uno WASM specific - set tabindex to 0 so the RootVisual is "native focusable"
SetAttribute("tabindex", "0");
#endif

PointerPressed += RootVisual_PointerPressed;
PointerReleased += RootVisual_PointerReleased;
PointerCanceled += RootVisual_PointerCanceled;
}

/// <summary>
/// Gets or sets the Visual Tree.
/// </summary>
internal VisualTree? AssociatedVisualTree { get; set; }
/// <summary>
/// Gets or sets the Visual Tree.
/// </summary>
internal VisualTree? AssociatedVisualTree { get; set; }

internal PopupRoot? AssociatedPopupRoot =>
AssociatedVisualTree?.PopupRoot ?? this.GetContext().MainPopupRoot;
Expand Down

0 comments on commit 7975615

Please sign in to comment.