Skip to content

fix(chat): keep session picker open during status renders#973

Closed
arturict wants to merge 3 commits into
openclaw:mainfrom
arturict:fix/970-stable-session-picker
Closed

fix(chat): keep session picker open during status renders#973
arturict wants to merge 3 commits into
openclaw:mainfrom
arturict:fix/970-stable-session-picker

Conversation

@arturict

@arturict arturict commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Closes #970

What Problem This Solves

Thinking-status snapshots rerender the chat composer. The grouped session picker was recreated inside the render setter each time, replacing the native ComboBox and closing its open flyout before a user could switch chats.

Why This Change Was Made

The composer now keeps the native session picker hosted as a stable child across FunctionalUI renders. A structural snapshot rebuilds its items only when visible group labels, session IDs, titles, or ordering actually change. Selection is reconciled independently, callbacks stay current, and native lifecycle and event cleanup are handled explicitly.

The renderer also removes stale paths when a caller-owned native element moves, and clears native children when virtualized subtrees recycle. WinUI test controls are created on the UI thread.

This keeps ordinary thinking/status renders from replacing the picker while still reflecting real session-list changes.

User Impact

The chat/session picker can remain open while status updates arrive, so users can reliably select another chat without suppressing live updates.

Validation

Validated from current head 9c1b9268:

  • ./build.ps1 — passed.
  • dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restore — 2,739 passed, 31 skipped, 0 failed.
  • dotnet test ./tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restore — 1,672 passed, 0 failed in a clean CRLF checkout.
  • dotnet test ./tests/OpenClawTray.FunctionalUI.Tests/OpenClawTray.FunctionalUI.Tests.csproj --no-restore — 10 passed, 0 failed.
  • dotnet test ./tests/OpenClaw.Tray.UITests/OpenClaw.Tray.UITests.csproj --filter FullyQualifiedName~FunctionalUiNativeElementTests -p:Platform=x64 -r win-x64 — 6 passed, 0 failed.
  • ./run-app-local.ps1 -NoBuild -AllowNonMain — launched the updated tray from this branch.

Real behavior proof

A non-isolated local run opened openclaw://chat with the Companion Chat page connected. The native Session picker was opened and remained expanded after waiting, with OpenClaw Windows Tray still selected. The live accessibility state reported AXPopUpButton (expanded) Session and AXRow (selected) OpenClaw Windows Tray.

The isolated UI-test environment still cannot complete WinAppSDK bootstrap (Package dependency criteria could not be resolved), so the connected local run is the available runtime proof.

Review

The current implementation was reviewed for stable native-child ownership, stale-path reparenting, virtual-stack cleanup, UI-thread affinity, mount and disposal behavior, event routing, snapshot invalidation, and callback suppression. Regression tests cover path changes and virtualized native-element recycling.

AI-assisted: yes. I reviewed and understand the stable-control lifecycle, item reconciliation, native event cleanup, and regression tests in this change.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 Urgent regression or broken agent/channel workflow affecting real users now. labels Jul 12, 2026
@clawsweeper

clawsweeper Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 13, 2026, 6:33 PM ET / 22:33 UTC.

Summary
The PR keeps the chat session picker’s native WinUI control mounted across FunctionalUI status rerenders and adds lifecycle regression coverage.

Reproducibility: yes. from source and the linked report: status snapshots rerender the composer, and recreating the native ComboBox closes its flyout. A real current-main failing run was not independently executed during this read-only review.

Review metrics: 2 noteworthy metrics.

  • Patch surface: 7 files, +708/-50. The chat fix adds a reusable native-element renderer path, making lifecycle review important beyond the composer symptom.
  • Focused UI coverage: 6 tests passed. The reported current-head suite covers the native mounting and cleanup regressions identified during review.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #970
Summary: This PR is the direct candidate fix for the linked open session-picker regression.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add current-head Windows video or timestamped accessibility diagnostics showing a thinking/status render while the open picker remains expanded and selectable; redact private endpoints, tokens, session names, and other personal details.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: Current-head live accessibility output proves the picker can remain expanded after waiting, but not that it survives an actual thinking/status render; add redacted video or timestamped diagnostics showing that active transition, then update the PR body for automatic re-review or ask a maintainer to comment @clawsweeper re-review.

Risk before merge

  • [P1] The live proof does not show an actual thinking/status render while the picker is open, so the central user-visible behavior remains unproven in a real setup.

Maintainer options:

  1. Decide the mitigation before merge
    Land the stable native-picker design after current-head Windows proof shows at least one active thinking/status render while the session flyout remains expanded and can complete a selection.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Hold merge for contributor-supplied proof of the active status-render scenario; there is no remaining concrete code defect suitable for automated repair.

Security
Cleared: The diff changes local WinUI rendering and tests without adding dependencies, secret handling, downloads, workflow permissions, or external code-execution paths.

Review details

Best possible solution:

Land the stable native-picker design after current-head Windows proof shows at least one active thinking/status render while the session flyout remains expanded and can complete a selection.

Do we have a high-confidence way to reproduce the issue?

Yes from source and the linked report: status snapshots rerender the composer, and recreating the native ComboBox closes its flyout. A real current-main failing run was not independently executed during this read-only review.

Is this the best way to solve the issue?

Yes. Preserving the caller-owned native ComboBox across unrelated declarative renders fixes the remount root cause, while structural snapshot and selection reconciliation preserve legitimate updates.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 77c42440376e.

Label changes

Label justifications:

  • P1: The PR fixes an active chat workflow where live thinking updates can prevent users from switching sessions.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: Current-head live accessibility output proves the picker can remain expanded after waiting, but not that it survives an actual thinking/status render; add redacted video or timestamped diagnostics showing that active transition, then update the PR body for automatic re-review or ask a maintainer to comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Root cause and fix: The branch replaces the render-setter-created grouped ComboBox with a ref-backed caller-owned native control, reconciles structural session changes separately, and keeps callbacks current. (src/OpenClaw.Tray.WinUI/Chat/OpenClawComposer.cs:247, 9c1b92684792)
  • Renderer lifecycle handling: The branch adds NativeElement hosting plus stale-path reparenting and virtualized-subtree cleanup, addressing the concrete findings raised against the earlier head. (src/OpenClawTray.FunctionalUI/FunctionalUI.cs:200, 9c1b92684792)
  • Focused regression coverage: Current-head tests cover stable mounting, render-path movement, virtual-stack recycling, UI-thread creation, and session snapshot equivalence and change detection. (tests/OpenClaw.Tray.UITests/FunctionalUiNativeElementTests.cs:1, 9c1b92684792)
  • Required validation reported: The PR reports the full repository build, Shared tests, Tray tests, FunctionalUI tests, and six focused WinUI tests passing from the current head. (AGENTS.md:1, 9c1b92684792)
  • Real behavior proof gap: The live accessibility state proves the Session picker remained expanded after waiting, but no supplied recording or timestamped transcript shows a thinking/status render occurring during that interval. (9c1b92684792)
  • Still necessary on current main: The PR remains the direct candidate fix for the open canonical issue, and the supplied current-main and related-item context contains no merged implementation of stable picker hosting. (src/OpenClaw.Tray.WinUI/Chat/OpenClawComposer.cs:247, 77c42440376e)

Likely related people:

  • christineyan4: Merged pull request fix(chat): ID-based grouped session dropdown + UI alignment, scroll, multi-agent nav #503 introduced the ID-based grouped session dropdown now being stabilized. (role: introduced behavior; confidence: high; commits: 604e7e195cdb; files: src/OpenClaw.Tray.WinUI/Chat/OpenClawComposer.cs)
  • bkudiess: This repository collaborator contributed the stable native-child implementation, lifecycle hardening, validation, and live accessibility proof. (role: recent reviewer and area contributor; confidence: high; commits: e0da0de62b08; files: src/OpenClawTray.FunctionalUI/FunctionalUI.cs, src/OpenClaw.Tray.WinUI/Chat/OpenClawComposer.cs)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (5 earlier review cycles)
  • reviewed 2026-07-12T09:34:46.688Z sha 2e36a17 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-12T10:19:29.874Z sha 2e36a17 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-13T20:33:00.092Z sha e0da0de :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-13T20:42:02.549Z sha e0da0de :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-13T22:22:37.481Z sha 9c1b926 :: needs real behavior proof before merge. :: none

@arturict

Copy link
Copy Markdown
Contributor Author

I reran the complete required validation from the current PR head in a clean Windows checkout with the repository's expected CRLF line endings. The earlier three failures were checkout-line-ending artifacts; the full tray suite is now clean: 1,672 passed, 0 failed. The full build also passes, and Shared tests report 2,739 passed / 31 skipped / 0 failed. I updated the PR body with the exact results. The connected Agent-thinking WinUI recording remains explicitly blocked because the isolated app has no configured gateway/session, so I am leaving the PR as draft rather than overstating that proof.

Keep the session picker ComboBox attached as a declarative native child across FunctionalUI renders, and harden native control lifecycle handling for mount, ownership, and event routing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bkudiess

Copy link
Copy Markdown
Collaborator

Pushed an update in e0da0de6 to keep the session picker hosted as a stable native child and harden the NativeElement lifecycle/event cleanup.

Proof:

  • ./build.ps1 passed.
  • dotnet test ./tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj --no-restore: 2739 passed, 31 skipped.
  • dotnet test ./tests/OpenClaw.Tray.Tests/OpenClaw.Tray.Tests.csproj --no-restore: 1672 passed.
  • dotnet test ./tests/OpenClawTray.FunctionalUI.Tests/OpenClawTray.FunctionalUI.Tests.csproj --no-restore: 10 passed.
  • Local run: ./run-app-local.ps1 -NoBuild -AllowNonMain launched the updated tray from this branch.

UI proof note: isolated launch reached first-run setup instead of the chat picker, and the focused WinUI UI tests still block before assertions with WinAppSDK bootstrap Package dependency criteria could not be resolved.

@bkudiess

Copy link
Copy Markdown
Collaborator

Follow-up UI proof from a non-isolated local run:

  • Ran ./run-app-local.ps1 -NoBuild -AllowNonMain from e0da0de6 and opened openclaw://chat.
  • Computer-use verified the OpenClaw Companion Chat page was selected with status Connected.
  • Opened the composer Session picker and re-read the live UI after a short wait; it remained expanded with the selected row OpenClaw Windows Tray.

Relevant live AX proof: AXPopUpButton (expanded) SessionAXRow (selected) OpenClaw Windows Tray.

@arturict
arturict marked this pull request as ready for review July 13, 2026 20:31
@arturict

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e0da0de62b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/OpenClawTray.FunctionalUI/FunctionalUI.cs
Comment thread src/OpenClawTray.FunctionalUI/FunctionalUI.cs
Comment thread tests/OpenClaw.Tray.UITests/FunctionalUiNativeElementTests.cs Outdated
@arturict

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 13, 2026
@karkarl

karkarl commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Looking at the code, we should be updating our functionalUI combobox primitive to support our scenario. It apparently is using the new ComboBox() as a bypass since the combobox helper only supports flat string items: openclaw-windows-node/src/OpenClaw.Tray.WinUI/Chat/OpenClawComposer.cs at 77c42440376e2b8cd503290bb2…

The fix should be to update the combobox primitive rather than creating a whole new native element UI lifecycle path.

shanselman pushed a commit that referenced this pull request Jul 14, 2026
…Box primitive (supersedes #973) (#991)

* fix(chat): keep session picker stable during renders

* fix(chat): stabilize native session picker host

Keep the session picker ComboBox attached as a declarative native child across FunctionalUI renders, and harden native control lifecycle handling for mount, ownership, and event routing.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* fix(ui): clean up native controls across render paths

* refactor(chat): replace NativeElement escape hatch with FunctionalUI ComboBox primitive

The #970 fix originally reached around FunctionalUI with a raw NativeElement
snapshot to keep the session picker open across status re-renders. Promote that
into a first-class rich ComboBox primitive so re-render stability is a framework
guarantee, not a per-call escape hatch.

- Add ComboItem + ItemComboBoxElement with static ItemsEqual; ConfigureItemComboBox
  only rebuilds items when the list actually changes, preserving an open flyout.
- Migrate both the session picker and the model picker (which had the same
  unfixed #970-class bug) onto the primitive.
- Remove NativeElement and its tests entirely.
- Add pure ItemComboBoxTests and source-contract ComposerSessionPickerTests
  guarding against escape-hatch regressions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: arturict <arturict@users.noreply.github.com>
Co-authored-by: bakudies@microsoft.com <bakudies@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@shanselman

Copy link
Copy Markdown
Contributor

Superseded by #991, which contains all three commits from this PR and replaces the broad NativeElement lifecycle escape hatch with the reviewed FunctionalUI ComboBox primitive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows Companion: "Agent thinking" animation closes the chat/session selectbox before a different chat can be chosen

4 participants