Skip to content

test(app): wait for the finished ring to hide the donut before the next drag - #1319

Merged
KnifeLemon merged 1 commit into
mainfrom
test/donut-keyboard-ring-race
Nov 10, 2026
Merged

KnifeLemon merged 1 commit into
mainfrom
test/donut-keyboard-ring-race

Conversation

@KnifeLemon

@KnifeLemon KnifeLemon commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

DonutFlipTests.On_macos_the_keyboard_goes_back_after_a_conversion_and_stays_for_a_tools_window fails now and then on portable (macos-15, osx-arm64): Assert.Equal(2, platform.Remembered) gets 1. Seen in runs 42635941264 (main) and 42515220891.

Why it fails

It's a race in the test. The product code is fine.

  1. The first drop starts a job on a 3-byte fake photo.jpg. The headless DragDrop helper runs the dispatcher once more after the drop. If the worker has already ended the job by then, its Refresh lands and OnProgressJobChanged puts the ring into CompleteProgress, which holds for wall-clock time.
  2. radial.Close(animate: false) then sees IsFinishingProgress and returns without hiding the window, leaving the ring to hide it later. If the job is still running, Close hands it to the toast and hides the window at once. That path passes.
  3. The next DragOnto → ShowForDrag → LeaveProgressMode() drops the ring's pending hide, so the window never hides and never deactivates. In headless, TakeKeyboard's fallback calls window.Activate(), but ReturnKeyboard has nothing that undoes it (handle 0, null platform). The window is still IsActive, so TakeKeyboard returns early and RememberFrontApp isn't called again.

This race came in with the test itself (fe3dd6a, 2026-10-30), together with the window.IsActive guard. It wasn't caused by ebadfc7 (PR #1155).

Why the product is fine on a real Mac

ReturnKeyboard → ReleaseKeyWindow orders the panel out and back in, so it stops being the key window and Avalonia gets Deactivated. A new drag over a finishing ring therefore finds the panel inactive and takes the keyboard again. The IsActive guard only skips the take when Filee's own window really has the keyboard: either while _tookKeyboard is already set, or for a click-mode donut, where Filee is the front app and RememberFrontApp would record nothing anyway.

Reproduction

The branch repro/donut-keyboard-ring-race (one commit on main) waits for the job's end before the close, which forces the failing path. A portable.yml run on it, with macOS: https://github.com/KnifeLemon/Filee/actions/runs/42663753064 failed on both macOS jobs (arm64 and Intel) with the same Expected: 2, Actual: 1 at the Remembered check, and nothing else failed. The repro also asserts IsFinishingProgress just before the close, and that check passed, so the failing path is the one described above.

Fix

Only the test changes. It now waits for the job's end before closing, so every run takes the same path (the one that used to fail). It then pumps the dispatcher and the render timer until the ring hides the window, and asserts that the window is inactive before the second drag.

macOS can only be checked on CI. The test is skipped on Windows.

🤖 Generated with Claude Code

…xt drag

The macOS keyboard test failed now and then with Remembered 1 instead of 2.
The fake photo's job can end on a worker before the drop's own dispatcher
run is over. Then the ring is already finishing when the test closes the
donut, Close leaves the window up for the ring to hide, and the next drag
reuses a window that is still active: headless, giving the keyboard back
can't make it resign key as it does on a Mac. TakeKeyboard sees an active
window and doesn't remember the front app again.

The test now waits for the job's end before closing, so every run takes
the same path, then for the window to hide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KnifeLemon
KnifeLemon merged commit e8d3d73 into main Nov 10, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant