Skip to content

Re-resolve workspace detail children while waiting for layout - #442

Merged
coneilen merged 1 commit into
mainfrom
gate-workspace-detail-remount
Sep 24, 2026
Merged

coneilen merged 1 commit into
mainfrom
gate-workspace-detail-remount

Conversation

@coneilen

Copy link
Copy Markdown
Collaborator

Problem

#441 added a settle loop so the workspace right-panel detail children are laid out before their bounds are asserted. It waited on the correct condition but against the wrong objects, so it did not fix the failure.

These four children are served by a custom fragment provider (AccessibilityProvider.cpp), and the provider destroys and recreates them when the loop panel re-lays out. That invalidates any AutomationElement reference captured beforehand. A dead fragment does not throw — it reports an empty AutomationId and an empty BoundingRectangle indefinitely. #441's loop polled references captured before the wait, so once a remount happened it could never recover: it burned the full 10s budget and then failed.

The decisive tell was in the failure text itself:

workspace right panel child  has empty bounds

The AutomationId interpolates blank. All four children are selected by an AutomationId regex (^workspace-detail-sparkline- and friends), so every one of them provably had a matching, non-empty id at the moment the mount loop selected it. An id that is non-empty at selection and blank at assertion cannot be a slow layout — it is a different, dead object. This also explains the earlier observation that one commit produced two different failure sites in this block with no code change: it is a remount race, and which assertion you land on depends on when the remount falls relative to the mount loop's break.

Fix

Re-resolve the four children from the live tree on every attempt, and require a single observed generation of the tree to satisfy existence and layout together. The four variables are then rebound to those live references so the InvokePattern call further down cannot run against a stale fragment either — the same latent bug, one assertion later.

The bounds assertion itself is unchanged and still runs.

Evidence

RED: CI run 35950217001 on the pre-fix code -> FAIL workspace right panel child has empty bounds at uia-live-gate.ps1:447, with the AutomationId interpolated blank, after #441's settle loop had already been given its full 10s budget. That blank id is the proof the polled reference was dead rather than merely unlaid-out.

GREEN: the same windows-shell live gate now advances past the workspace right-panel block, resolving all four detail children in one generation of the tree and invoking the collapse control against a live reference -> see the windows-shell check on this PR.

REGRESSION: Tools\windows\Tests\WindowsShell.Tests.ps1 -ZigExecutable $env:GRAPHCODE_ZIG0152 -> All 266 tests passed, Windows shell scaffold contract: PASS (40 source files executed).

Verification

  • Parses clean.
  • Every Require predicate on main is still present: 378 on main, 379 here, the single addition being the new $null -ne $resolvedDetails guard. No predicate weakened or dropped.
  • No C# touched, so the shared Add-Type block and its declaration counts are unaffected.

The settle loop added in #441 polled cached AutomationElement references.
These children are served by a custom fragment provider that destroys and
recreates them when the loop panel re-lays out, and a dead fragment reports
an empty AutomationId and empty BoundingRectangle instead of throwing, so a
cached reference can never recover from a remount. The loop burned its whole
budget and then failed with a blank id in the message.

Re-resolve the four children from the live tree on every attempt and require
one observed generation to satisfy existence and layout together, then rebind
the variables so the later Invoke cannot run against a stale fragment.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Colin Neilens <coneilen@microsoft.com>
@coneilen
coneilen merged commit 84cde1d into main Sep 24, 2026
10 checks passed
@coneilen
coneilen deleted the gate-workspace-detail-remount branch September 24, 2026 04:02
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