Skip to content

Keep Show in Graph and the loop bar on the open Windows loop - #658

Merged
coneilen merged 2 commits into
mainfrom
coneilen-fix-show-in-graph-loop-desync
Oct 8, 2026
Merged

coneilen merged 2 commits into
mainfrom
coneilen-fix-show-in-graph-loop-desync

Conversation

@coneilen

@coneilen coneilen commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes the LoopActivation failure from the Dev Box qualification of 0.1.78-windows.beta16 (d75bb952). If a stopped loop was waiting in Needs you, clicking Show in Graph in another loop's workspace didn't show the graph. Instead, the loop bar switched to the Needs-you loop and the pane stayed on the open loop's session. This PR makes Show in Graph show the graph, and it makes every route that changes the selection move the loop bar and the pane together.

Root cause: the graph surface has a "N loops need you" rail at header+12..43, spanning the window width. In a loop workspace, the loop bar is painted over that strip, but the rail was still hit-tested. It was also checked before the loop bar's buttons. The Show in Graph button (header+10..36, near the bar's right edge) falls inside the rail, so the click ran Review attention (cycle_attention). That action re-selected the Needs-you loop without touching the pane. The bar takes its title and workspace-loop-bar UIA identity from that selection, so it showed A while the pane showed B. The earlier "worked from A's / B's workspace" observations fit this cause: Show in Graph only fails when something is in Needs you. The canvas drag on A was not the trigger.

Changes

  • GraphCanvas.attentionRailShown: the Needs-you rail is drawn and hit-tested only on graph surfaces, never in a loop workspace. WM_LBUTTONDOWN and paint both use it.
  • The audit found other routes that changed the selection in a loop workspace without moving the pane. They now open their target through activateLoop, the same path a sidebar row uses:
    • Review attention, from Ctrl+Tab and from the Loop menu's Review What Needs You. It's a no-op when nothing needs you or when the target is already open.
    • The sidebar Needs-you row, by native click and by UIA invoke.
    • Next/Previous Loop.
    • On graph surfaces, all of these keep the existing select-only behavior.
  • Audited and found already correct: the header Needs-you chip (it already opens), the Jump palette (it switches to the graph), Needs-you Stop (it sends stopNode for that loop and doesn't change the selection), and canvas card, attention-action and activity routes (they already go through activateLoop).
  • Added App.zig behavioral tests that drive real WM_LBUTTONDOWN/WM_LBUTTONUP/WM_MOUSEMOVE/WM_COMMAND through onWindowMessage. The fixture is the Core layout: loops A, B and C, with A stopped and awaitingInput (one Needs-you entry), and a short native canvas drag on A's card that leaves A graph-selected.
    • Show in Graph: open B and then C from their sidebar rows, read the workspace-show-graph bounds from the UIA publish, and click their center. The test asserts the click point is inside the rail bounds, which is the Dev Box geometry. Then it asserts:
      • The project graph is shown and the loop panel is hidden.
      • The open loop is still selected.
      • No command was sent.
      • The pane is unchanged.
      • No loop bar is published.
    • It also asserts that, if the click leaves a workspace up, the bar's UIA identity, the drawn selection and the pane all name the same loop.
    • One test per route (Ctrl+Tab, Loop menu review, Needs-you row click, Needs-you UIA invoke, Next/Previous Loop). Each one opens B and then asserts that the bar's UIA identity, the drawn selection, selected_node_id and the visible pane all name the target loop.
    • Needs-you Stop from B's workspace: one stopNode for loop-a is sent, and the bar and pane stay on B.
  • investigation/ui-parity-matrix.md: the Main split view row records the finding and the fix. Its status stays Partial.
  • Tools/windows/uia-live-gate.ps1: the gate's attention rail step got a correction, made after this PR's first CI run.
    • The step selects loop A's card, which opens A's loop workspace (the shell status read "Starting loop"), and then clicked the rail strip. In a workspace that strip is under the loop bar, so the step had been asserting the beta16 defect: the click cycled onto the NEEDS YOU card while A's pane stayed open. With the fix, that click did nothing, and integration failed with attention rail click did not cycle selection onto the NEEDS YOU card.
    • The step now posts a real click at the center of the workspace's UIA workspace-show-graph bounds. It requires the loop bar to go away with A still selected, which is the live Dev Box contract.
    • It then performs the original rail click on the graph surface, where the rail is visible, and still requires that click to cycle onto the NEEDS YOU card.

Not changed, but noted for follow-up: when the loop panel is collapsed, the painted "Loop panel" expand control (client.right-104..-14, header+8..30) is drawn over the loop bar's Show in Graph button. The pointer hit test for the bar also always subtracts loop_detail_width. So with the panel collapsed, the drawn Show in Graph button can't be clicked by pointer. That is a separate layout problem, and the Dev Box failure happened with the panel visible.

Test plan

Toolchain: pinned Zig 0.15.2 from the existing bootstrap output C:\gc-tools\environment.ps1, Winghostty 6286560d (both pins checked with zig version / git rev-parse). The App test command is the same invocation as Tools\windows\Tests\WindowsShell.Tests.ps1 "App shell executable tests". In the lines below it is abbreviated as zig test src\App.zig ....

RED: zig test src\App.zig ... --test-filter "Show in Graph from an open loop" (tests only, on base d75bb95 code) -> 0 passed; 1 failed: expectLoopBarAndPane expected loop-b, instead found loop-a for the workspace-loop-bar UIA identity after the native Show in Graph click (graph not shown, bar on the Needs-you loop, pane still loop-b); separately --test-filter "selection routes with a loop workspace open" -> 1 passed; 5 failed: Ctrl+Tab, Loop menu review and Next/Previous fail expectPaneBoundTo (pane loop-b, bar moved), Needs-you click and UIA invoke fail on selected_node_id loop-b while the bar moved to loop-a; the Needs-you Stop guard passed
GREEN: zig test src\App.zig ... --test-filter "Show in Graph from an open loop" -> All 1 tests passed; --test-filter "selection routes with a loop workspace open" -> All 6 tests passed
REGRESSION: zig test src\App.zig ... (full App shell suite) -> All 884 tests passed; zig test src\GraphCanvas.zig -target x86_64-windows-msvc -lc -> All 211 tests passed; zig build -Doptimize=ReleaseSafe -> exit 0

Limits, stated plainly:

  • All the RED failures are behavioral assertion failures, not compile errors. The RED run used the base App.zig with only the new tests added and an unmodified GraphCanvas.zig.
  • pwsh -NoProfile -File Tools\windows\validate.ps1 -Task windows-shell -SkipTrayLive (run with Pester 5.7.1, because Pester 6 rejects -Script) passed the isolation contract, the source contracts and every executable section through Worktree status, including Graph canvas. It then stopped at "Worktree Git process regression tests" with Worktree Git fixture path budget exceeded (294 > 259 characters), which comes from this long worktree path and not from this change. So validate did not reach the App shell section, which is why I ran it directly as shown above.
  • No installed or live run: I did not drive a real winghostty/zmx session, a real UIA client or the Dev Box. These are unit/native-message tests in a hidden window with a fixture workspace, not a replacement for the creator's Dev Box rerun on a new candidate.
  • I did not run the updated live UIA gate locally, because it would take over the shared desktop. Its evidence is this PR's windows-shell integration CI job.
  • No macOS changes and no macOS validation (this is Windows shell only).

Checklist

  • I have read the Contributing Guidelines
  • I have signed off my commits (git commit -s) per the DCO
  • Tests pass locally (make test): not run. This is a Windows-only change, and the Windows App/GraphCanvas suites above passed.
  • Code follows the existing style (make check): not run, because no Swift changed. zig build passed.
  • I added the test/contract before the implementation and observed the intended RED failure

coneilen and others added 2 commits October 7, 2026 23:03
With a stopped loop waiting in Needs you, the graph's "loops need you" rail
stayed hit-testable in a loop workspace, where the loop bar is painted over
the same strip. Its bounds cover the bar's Show in Graph button, so a click
there ran Review attention instead: the graph stayed hidden and the bar moved
to the Needs-you loop while the pane kept the open loop's session (Dev Box
beta16 qualification, Section 6B, LoopActivation).

The rail is now drawn and hit-tested only on graph surfaces. With a loop
workspace open, Review attention (Ctrl+Tab and the Loop menu), the sidebar
Needs-you row (pointer and UIA), and Next/Previous Loop open their target
through the activation path instead of only re-selecting, so the bar and the
pane always name the same loop. Graph surfaces keep select-only behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Colin Neilens <coneilen@microsoft.com>
The gate's attention rail step selected loop A's card, which opens A's loop
workspace, and then clicked the rail strip. In a workspace that strip is under
the loop bar, so the step was asserting the beta16 defect: the click cycled
the selection onto the NEEDS YOU card while A's pane stayed open.

The step now clicks the workspace's own Show in Graph button (whose bounds lie
inside the rail rect) and requires the loop bar to go away with A still
selected, then performs the existing rail click on the graph surface, where the
rail is visible, and requires it to cycle onto the NEEDS YOU card.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Colin Neilens <coneilen@microsoft.com>
@coneilen
coneilen merged commit 4e0e3b7 into main Oct 8, 2026
25 checks passed
coneilen added a commit that referenced this pull request Oct 8, 2026
Record the immutable, unpublished 0.1.78-windows.beta17 candidate built from
4ab2fcf with #658 and #659 (Show in Graph and collapsed loop panel fixes).
Beta16 and its r2 handoff are failed/superseded and kept unchanged. Approval A
keeps fixture-only Worktrees reclaim. Correct the parity count to the ledger's
actual 98 surfaces: 58 Validated / 40 Partial.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Colin Neilens <coneilen@microsoft.com>
@coneilen coneilen mentioned this pull request Oct 8, 2026
2 of 5 tasks
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