Repository navigation
Fix stale terminal surfaces, New Tab UIA/cwd, and loop opens after deleting an attached loop - #663
Merged
Merged
Conversation
…leting an attached loop Beta17 Dev Box qualification (4ab2fcf) found, on the Windows shell: - a WinghosttyEmbeddableSurface (480x240 at client 0,0) left drawn over the sidebar while the graph showed, with the canvas New Loop button stranded; - UIA exposing one workspace tab after a native New Tab click drew two; - the New Tab shell starting in the install bin directory; - every loop open failing after the attached loop was deleted. A surface created while the workspace was collapsed (passive re-attach, project rebind restore) was created visible at its placeholder bounds and resize() un-collapsed the workspace. Surfaces now start hidden while collapsed, creation re-applies the layout without un-collapsing, and syncTopology hides everything while collapsed and any pane with no area. A passive re-observation (the ended loop's recreate) cancelled the explicit open of another loop, and attaching a loop into an empty slot left the layout's loop pane naming the dead loop, so the new terminal stayed hidden and later replacements failed. Passive checks no longer displace an explicit open, and the unshown loop pane is rebound to the opened loop. Native New Tab, split, tab cycling and tab select/close clicks republish UIA. New shells start in the loop's worktree, else its project folder (home for a global loop), as on macOS. The canvas New Loop/Open Folder buttons are re-laid-out with every UIA publication, touching the native controls only when their state changes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Colin Neilens <coneilen@microsoft.com>
coneilen
force-pushed
the
coneilen-fix-workspace-surface-and-tabs
branch
from
October 8, 2026 22:27
ea5d87d to
17e685f
Compare
This was referenced Oct 8, 2026
coneilen
added a commit
that referenced
this pull request
Oct 9, 2026
…s folder (#667) #663 started each zmx attach in the loop's worktree or project folder. The installed shell names zmx bare (zmx.exe) and found it only through its own working directory (the install bin), and a child resolves a relative program against its own working directory and then PATH. On a Dev Box whose PATH does not name the install, every sidebar loop open, New Tab, and split failed with FileNotFound (Unable to open selected loop / Unable to create tab). Resolve the configured zmx name against the shell's directory once before the attach spawns, and make the live App terminal fixture use the installed bare-name layout so the gap that hid this is covered. Signed-off-by: Colin Neilens <coneilen@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the Windows workspace terminal-surface and tab findings from the beta17 Dev Box qualification (
0.1.78-windows.beta17, commit4ab2fcf4): a stale terminal surface drawn over the sidebar, a stranded canvas New Loop / Open Folder button, UIA showing fewer tabs than drawn after New Tab, New Tab shells starting in the installbindirectory, and loop opens failing after the attached loop was deleted.Changes
Stale
WinghosttyEmbeddableSurfaceover the sidebar (finding 1, operator report 2). A surface created while the workspace is collapsed (the graph shows) was created visible at its 480x240 placeholder bounds at client 0,0. Two paths did this: a graph refresh re-attaching the open loop's pane, and a project rebind restoring saved panes.resize()then also un-collapsed the workspace. The new App test reproduces the Dev Box geometry exactly (visible terminal over the graph at 0,0 480x240). Surfaces now start hidden and unfocused while collapsed. Creation re-applies the layout without un-collapsing (relayout).syncTopologyhides everything while collapsed, and hides any pane with no area instead of showing it at stale bounds.Stranded canvas New Loop / Open Folder buttons (finding 1, operator report 1). The native-row project switch and graph arrivals (startup restore, Ctrl+O) never re-laid-out these buttons. New Loop stayed at the 220px empty-project centre (the
d6-diag-rows.pngposition), and Open Folder stayed visible after a project opened.syncAccessibilitynow lays them out with every publication.layoutEmptyStateControlstouches the native control only when its position, visibility or text changes.UIA tab count after New Tab (finding 2). A native click on New Tab, a split, tab cycling, or a tab select/close changed the tab strip without republishing UIA. These paths now republish UIA (
publishWorkspaceTabs).New Tab working directory (finding 3). New sessions start in the open loop's directory, as on macOS (
LoopWorkspaceViewworkingDirectory): the loop's worktree, else its project folder, or home for a global loop. A remote project, or a folder that doesn't exist, falls back to the shell's own directory (Workspace.setShellDirectory/sessionDirectory).Loop opens after deleting the attached loop (finding 4). While the graph shows, a deleted loop's exit is not drained. When the next loop opened:
Unable to restore selected terminal focus, and every later replacement failed withUnable to open selected loop.Passive checks no longer displace an explicit open. The unshown loop pane is now rebound to the loop being opened (
bindLoopPane).Tests: there are four App tests (
workspace surface:). Three use real winghostty child windows, a fakezmx.cmd, and nativeWM_LBUTTONDOWN/UPclicks. The fourth uses real native buttons. There is also one TerminalSurface layout and wait test. A test-onlyaccessibility_publication_observerlets the App tests see each productionsyncAccessibilitypublication. It is absent from product builds.Parity ledger: the Tab pills row goes from
ValidatedtoPartial, because the Dev Box found the mismatch and the fix has only unit evidence.Test plan
All commands ran from
graphcode-windowswith the pinned Zig 0.15.2 (C:\gc-tools\zig-0.15.2\zig.exe), the pinned Winghostty6286560d(C:\gc-providers\winghostty), and the same link line as theApp shell executable testssection ofWindowsShell.Tests.ps1. All tests were written and run failing before the fix.RED: zig test src\App.zig (App shell link line) --test-filter "workspace surface:" -> 0 passed, 4 failed: "visible terminal over the graph at 0,0 480x240" (TestUnexpectedVisibleTerminal); UIA tab count "expected 2, found 1" after native New Tab; selected pane "expected loop-b, found loop-a" after deleting the attached loop; New Loop button not visible after the restored graph arrived (TestUnexpectedResult)
GREEN: zig test src\App.zig (App shell link line) --test-filter "workspace surface:" -> All 4 tests passed
REGRESSION: zig test src\App.zig (App shell link line) -> All 892 tests passed; zig test src\TerminalSurface.zig -target x86_64-windows-msvc -lc -luser32 -lgdi32 -ladvapi32 -I...\winghostty\include zig-out\lib\ghostty-vt-static.lib -> All 165 tests passed
Additional evidence:
expected directory ...\wt-a, shell started in ...\bin(TestUnexpectedDirectory).an explicit open rebinds a stale loop pane and survives a passive recreate of the ended loop, run against theHEADTerminalSurface:expected 0, found 1(the stale tab was not selected). With the fix it passes, as part of the 165 above.Limits:
zmxlisting/attach script. No real agent backend, real zmx session, or rendered glyphs were exercised.validate.ps1 -Task windows-shellwas not run locally. It would rebuild the shared provider checkout; CI runs it.make test/make checkare macOS-only and were not run. No macOS or shared Swift code changed.Checklist
git commit -s) per the DCOmake test): macOS-only, not run; Windows Zig suites above passmake check): macOS-only, not run; no newzig fmtdifferences in changed hunks