Skip to content

fix(Input): clear focus on detached element when PresentationSource is torn down#21800

Open
deeferentleeg wants to merge 1 commit into
AvaloniaUI:mainfrom
deeferentleeg:fix/issue-21759-focus-detached-menu-item
Open

fix(Input): clear focus on detached element when PresentationSource is torn down#21800
deeferentleeg wants to merge 1 commit into
AvaloniaUI:mainfrom
deeferentleeg:fix/issue-21759-focus-detached-menu-item

Conversation

@deeferentleeg

Copy link
Copy Markdown

Summary

Fixes #21759 — after clicking a menu item in a popup menu (e.g. "Delete"), the menu item is detached from the visual tree but keyboard focus stays on it, so shortcuts (Up arrow, Ctrl+Z, …) stop working until the user clicks another element.

Root cause

In src/Avalonia.Base/Input/InputElement.cs, OnDetachedFromVisualTreeCore clears focus with:

((FocusManager?)e.PresentationSource.InputRoot.FocusManager)
    ?.ClearFocusOnElementRemoved(this, root);

The ?. only guards the final ClearFocusOnElementRemoved call. When a popup closes, Popup.CloseCore()popupHost.SetChild(null) detaches the menu items, and at that point the popup host's PresentationSource (or its InputRoot) may already be torn down. The direct chain e.PresentationSource.InputRoot.FocusManager is not null-safe on the intermediate accesses, so it either throws a NullReferenceException or silently skips ClearFocusOnElementRemoved — leaving KeyboardDevice.FocusedElement pointing at the detached element, which then has no visual parent to bubble key events to the window.

The fix

Use the existing FocusManager.GetFocusManager(this) helper, which already has a locator fallback (AvaloniaLocator.Current.GetService<IFocusManager>()) and is the pattern the Focus() method in this same file already uses. Null-guard the PresentationSource chain and fall back to GetFocusManager:

var focusManager = (FocusManager?)e.PresentationSource?.InputRoot?.FocusManager
    ?? FocusManager.GetFocusManager(this);
focusManager?.ClearFocusOnElementRemoved(this, root);

Minimal, no public-API change, and mirrors an established in-file pattern.

Notes

  • I have not been able to run the full Avalonia build/test matrix locally; I'd welcome guidance on the preferred test for this (a headless focus/popup test) and am happy to add one.
  • .NET Foundation CLA: please point me to the sign-in flow if one is required and I'll complete it before merge.

AI usage

An AI assistant was used to help locate the relevant code and draft this change. I have reviewed and understand every line of the diff, and I am the sole author of this contribution.

Fixes #21759

…s torn down

When a focused element is detached from the visual tree (e.g. a menu item
in a popup that closes), OnDetachedFromVisualTreeCore cleared focus via
e.PresentationSource.InputRoot.FocusManager. That chain is not null-safe on
the intermediate accesses: during popup teardown the PresentationSource (or
its InputRoot) may already be gone, so the code either threw a
NullReferenceException or silently skipped focus clearing, leaving keyboard
focus on the detached element so shortcuts stopped working until the user
clicked elsewhere.

Use FocusManager.GetFocusManager(this), which falls back to the locator, and
null-guard the PresentationSource chain — mirroring the existing Focus()
method which already uses GetFocusManager.

Fixes AvaloniaUI#21759
@avaloniaui-bot

Copy link
Copy Markdown

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

@cla-avalonia

cla-avalonia commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator
  • All contributors have signed the CLA.

@deeferentleeg

Copy link
Copy Markdown
Author

@cla-avalonia agree

@MrJul MrJul added bug backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Focus stays on detached menu item after click

4 participants