fix(chat): replace NativeElement escape hatch with FunctionalUI ComboBox primitive (supersedes #973)#991
Merged
Conversation
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>
…ComboBox primitive The openclaw#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 openclaw#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>
This was referenced Jul 14, 2026
This was referenced Jul 15, 2026
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.
Supersedes #973 (original NativeElement-based fix by @arturict).
Problem
#970: the chat session picker (and, unfixed, the model picker) collapsed whenever the composer re-rendered — e.g. during agent "thinking"/status streams. The root cause is that FunctionalUI's diff loop recreated the
ComboBoxcontrol on every render, dismissing any open dropdown.PR #973 worked around this with a raw
NativeElementsnapshot that reached around the FunctionalUI diff to hand-manage the session picker. That escape hatch fixes one call site but leaves the framework gap open (the model picker had the identical bug) and is easy to reintroduce.Change
Promote the fix into a first-class rich ComboBox primitive in FunctionalUI so re-render stability is a framework guarantee:
ComboItem(pure data) +ItemComboBoxElementwith staticItemsEqual.ConfigureItemComboBoxrebuildscontrol.Itemsonly when the item list actually changes, so an open flyout survives composer re-renders. Selection is reconciled by tag; the change handler is detached during programmatic mutation so it never fires the user callback.NativeElementand its tests removed entirely.Net −485 lines.
Tests
ItemComboBoxTests— pure coverage ofComboItemdefaults, factory capture, andItemsEqual(equality/order/label/flag/count/reference/empty).ComposerSessionPickerTests— source-contract guard that both pickers use the primitive and the old escape-hatch patterns (border.Child = cb,SessionPickerSnapshot,Native() don't return.Validation
./build.ps1✅dotnet test OpenClaw.Shared.Tests✅ (2739)dotnet test OpenClaw.Tray.Tests✅ (1672)dotnet test OpenClawTray.FunctionalUI.Tests✅ (15/15)Real behavior proof
Rendered the real FunctionalUI composer offline via the accessibility provider (
OPENCLAW_ACCESSIBILITY_TEST_CHAT=1). UI Automation confirmed all three pickers (Session/Model/Reasoning) render, and the Session dropdown expands and populates with grouped seeded sessions. Fully faithful "stays open during a live agent status stream" still needs a paired gateway + LLM.Co-authored-by: arturict arturict@users.noreply.github.com