microsoft / microsoft/microsoft-ui-xaml

Mouse cursor flicker with windowed popup

Open
#11,543 1 comment 0 reactions 0 assignees View on GitHub
bug needs-triage
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

In an unpackaged WinUI 3 desktop app, a windowed Popup (ShouldConstrainToRootBounds="False")
is sized by its content and has thin edge/corner grips that resize it on drag by setting the
content's Width/Height, plus the Popup's HorizontalOffset/VerticalOffset for the left and top
edges. Each grip sets its resize cursor from PointerEntered via InputPointerSource.Cursor on
the element's ContentIsland (UIElement.ProtectedCursor has no effect at all, so this is the
only mechanism available). While a grip is being dragged, the mouse cursor rapidly alternates
between the requested resize cursor and the default arrow for the whole duration of the drag,
instead of holding the resize cursor.

Bisected to the 2.0 major release: the identical code is steady on 1.7.250310001 and
1.8.260710003, and flickers on 2.0.1, 2.1.3 and 2.3.1. This is not a deployment-mode artifact
— 1.8.260710003 is steady both framework-dependent and self-contained, and 2.3.1 flickers in
both. (2.0.1 and 2.1.3 were tested self-contained because no matching framework runtime was
installed.)

Re-asserting the cursor on every PointerMoved while the pointer is captured does not fix it,
so there appears to be no in-app workaround.

[WinUICursorPopup-repro.zip](https://github.com/user-attachments/files/31201784/WinUICursorPopup-repro.zip)

### Why is this important?

I have an overlay that needs to be resized

### Steps to reproduce the bug

## Steps to reproduce
1. Build and run; open the popup.
2. Hover the popup's right edge. The cursor correctly becomes SizeWestEast.
3. Press and drag horizontally to resize the popup.
4. Observe the cursor for the duration of the drag.
Expected: the SizeWestEast cursor is held for the whole drag.
Actual: the cursor alternates rapidly between SizeWestEast and the default arrow
until the button is released.
## Version comparison
Change the PackageReference to 1.7.250310001, delete obj/ and bin/, rebuild: the cursor is
steady throughout the drag. No source changes.
Re-asserting the cursor on every PointerMoved while the pointer is captured does not fix the
2.3.1 behaviour.

### Actual behavior

On hover, the requested resize cursor appears immediately and stays stable for as long as the
pointer rests on the grip — hovering alone shows no problem.
As soon as the drag starts (pointer pressed and moving), the cursor begins alternating rapidly
between the requested resize cursor and the default arrow, and keeps doing so for the entire
duration of the drag. It is fast enough to read as a flicker rather than as distinct switches.

### Expected behavior

While a resize grip is being dragged, the cursor should remain the resize cursor the app set
(SizeWestEast for a left/right edge) for the entire drag, from pointer-press through to release,
with no reversion to the default arrow. This is the behaviour of standard window-edge resizing
and of the same code on WindowsAppSDK 1.7.250310001.
More generally: once an app assigns InputPointerSource.Cursor, that cursor should persist until
the app changes it. It should not be intermittently overwritten by the framework's default while
the pointer is captured by the element that set it — a captured pointer means the app owns the
interaction, including the cursor, until capture ends.

### Screenshots

_No response_

### NuGet package version

2.0.1

### Windows version

_No response_

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the attached WinUICursorPopup reproduction and compare the cursor behavior between Windows App SDK 1.7.250310001 and 2.3.1 during a captured resize drag. Investigate how InputPointerSource.Cursor is handled for the Popup and its ContentIsland while the pointer is captured; done means the resize cursor remains steady until release.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.