Skip to content

Focus Traversal Api #18647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Focus Traversal Api #18647

wants to merge 6 commits into from

Conversation

emmauss
Copy link
Contributor

@emmauss emmauss commented Apr 14, 2025

What does the pull request do?

This PR is based on #18373 , and if moved out of draft, will supercede it.
This PR aims to address concern reported in #7607 . It implements a few of the core focus search api, and attempts to keep the core implementation as close to WinUI's as possible.

The following api are provided over the preceding PR;

namespace Avalonia.Input;

// FindNextElementOptions.cs
public sealed class FindNextElementOptions
{
    public InputElement? SearchRoot { get; init; }
    public Rect ExclusionRect { get; init; }
    public Rect? FocusHintRectangle { get; init; }
    public XYFocusNavigationStrategy? NavigationStrategyOverride { get; init; }
    public bool IgnoreOcclusivity { get; init; }
}

// FocusManager.cs
public FocusManager(IInputElement? contentRoot = null);

public bool TryMoveFocus(NavigationDirection direction)

public bool TryMoveFocus(NavigationDirection direction, FindNextElementOptions options)

public IInputElement? FindFirstFocusableElement()

public IInputElement? FindLastFocusableElement()

public static IInputElement? FindFirstFocusableElement(IInputElement searchScope)

public static IInputElement? FindLastFocusableElement(IInputElement searchScope)

public IInputElement? FindNextElement(NavigationDirection focusNavigationDirection)

public IInputElement? FindNextElement(NavigationDirection direction, FindNextElementOptions options)

public bool TryMoveFocus(NavigationDirection direction)

public bool TryMoveFocus(NavigationDirection direction, FindNextElementOptions options)

// InputElement.cs

protected internal virtual InputElement? GetNextTabStopOverride() => null;

protected internal virtual InputElement? GetPreviousTabStopOverride() => null;

protected internal virtual InputElement? GetFirstFocusableElementOverride() => null;

protected internal virtual InputElement? GetLastFocusableElementOverride() => null;

Implementation is as close to WinUI's as possible, with some differences. All api returns a IInputElement instead of AvaloniaObject, the counterpart to WinUI's DependencyObject. WinUI can have focusable DependencyObject without making them UIElements. We can't do this directly in Avalonia, as the special class WinUI made an exception for aren't AvaloniaObjects on our end. This are TextRuns, specifically Hyperlinks. All our TextRuns are plain CLR classes.

What is the current behavior?

What is the updated/expected behavior with this PR?

How was the solution implemented (if it's not obvious)?

Checklist

Breaking changes

Because focus search requires a root visual in all cases, FocusManager is no longer stored as a singleton in AvaloniaLocator, but instead each toplevel has its own FocusManager.

Obsoletions / Deprecations

Fixed issues

@emmauss emmauss requested a review from grokys April 14, 2025 13:01
@robloo
Copy link
Contributor

robloo commented Apr 14, 2025

FYI @amwx. Since you made the previous attempt in #8392 you might want to take a look.

@cyraid
Copy link

cyraid commented Jun 5, 2025

I could definitely change to Avalonia for my Android TV project if this were implemented. You got this. :)

@grokys grokys added the needs-api-review The PR adds new public APIs that should be reviewed. label Jun 24, 2025
@emmauss
Copy link
Contributor Author

emmauss commented Jun 27, 2025

  1. Made FindNextElementOptions sealed
  2. Change return values of new focus element overrides in InputElement to InputElement

Pr should be ready for review.

@emmauss emmauss changed the title [DRAFT] - Focus Traversal Api Focus Traversal Api Jun 27, 2025
@emmauss emmauss marked this pull request as ready for review June 27, 2025 07:42
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 12.0.999-cibuild0057355-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-api-review The PR adds new public APIs that should be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants