TitleBar with IconSource resets the mouse cursor to the arrow on every layout pass
Describe the bug
When a TitleBar has IconSource set (and is used as the window title bar through ExtendsContentIntoTitleBar + SetTitleBar), the mouse cursor is reset to the default arrow whenever a layout pass happens anywhere in the window while the pointer is not moving.
This affects every cursor in the window: the I-beam of a TextBox, cursors set with UIElement.ProtectedCursor, etc. The correct cursor comes back only when the mouse is physically moved, so any UI that updates continuously (data bindings, a live image, ScrollView animations) shows the arrow most of the time while the pointer rests on it.
Without IconSource, the cursor behaves correctly.
Why is this important?
Setting TitleBar.IconSource, the standard way to show the app icon, breaks the mouse cursor in the whole window: any UI that updates (bindings, live images, scroll animations) resets TextBox I-beams and custom ProtectedCursor cursors to the arrow. App code can't restore the cursor until the mouse moves, and the cause is very hard to trace.
Steps to reproduce the bug
Create an unpackaged WinUI 3 app with this
MainWindow:<Window x:Class="CursorRepro.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid RowDefinitions="Auto,*"> <TitleBar x:Name="AppTitleBar" Title="TitleBar cursor reset repro"> <TitleBar.IconSource> <FontIconSource Glyph="" /> </TitleBar.IconSource> </TitleBar> <StackPanel Grid.Row="1" Margin="20" Spacing="12"> <CheckBox x:Name="IconSourceCheckBox" Content="TitleBar.IconSource set" IsChecked="True" Click="OnIconSourceCheckBoxClick" /> <TextBox Width="400" HorizontalAlignment="Left" PlaceholderText="Rest the pointer here" /> <TextBlock x:Name="ChangingText" /> </StackPanel> </Grid> </Window>public sealed partial class MainWindow : Window { private readonly DispatcherTimer _timer = new() { Interval = TimeSpan.FromMilliseconds(500) }; private int _updates; public MainWindow() { InitializeComponent(); ExtendsContentIntoTitleBar = true; SetTitleBar(AppTitleBar); // Any layout pass triggers the cursor reset: a changing text is enough _timer.Tick += (_, _) => ChangingText.Text = $"Text update #{++_updates}"; _timer.Start(); } private void OnIconSourceCheckBoxClick(object sender, RoutedEventArgs e) => AppTitleBar.IconSource = IconSourceCheckBox.IsChecked == true ? new FontIconSource { Glyph = "" } : null; }Run the app, move the pointer over the
TextBoxand then keep the mouse still.Observe the cursor at every text update (every 0.5 s).
Uncheck "TitleBar.IconSource set" and repeat step 2.
Actual behavior
With IconSource set, the cursor turns into the arrow at every text update and stays so until the mouse is moved. With IconSource cleared (step 4), the cursor stays the I-beam.
Setting the cursor again from the app does not help: once reset, the displayed cursor does not change with ProtectedCursor, InputPointerSource.Cursor or Win32 SetCursor until a real mouse move.
Expected behavior
The cursor stays the I-beam while the pointer rests on the TextBox, whatever happens elsewhere in the window.
Screenshots
No response
NuGet package version
Windows App SDK 2.5.1 (also reproduced with 2.2.0).
Windows version
Windows 11 (25H2): Build 26200
Additional context
Source: microsoft/microsoft-ui-xaml