Repository navigation
Description
Environment
- OpenCode Desktop 2.2.2 (AppImage, Linux x64)
- Omarchy 4.0.6, Hyprland, Wayland
Summary
In the right pane's New tab view, some launcher rows do not respond to mouse clicks, while their keyboard shortcut still works. The rows that break are exactly the ones whose host menu item is registered with a factory function, so the item object is rebuilt on every recomputation of the shared menu memo.
Steps to reproduce
- Open a session with the right pane visible.
- Focus the composer so the session streams a response (or use a session with uncommitted file changes).
- Click a launcher row such as
Review.
Actual behaviour
Nothing happens. The row highlights on hover, so hit testing works, but the click never reaches item.run().
Expected behaviour
Clicking the row opens the panel, exactly as Ctrl+Alt+R does.
Evidence
A MutationObserver on the New tab view counted repeated creation of the same launcher buttons while the app sat idle:
thẻ mới được tạo: 145 ReviewCtrlAltR
thẻ mới được tạo: 146 Git & GitHubChanges,
thẻ mới được tạo: 147 ReviewCtrlAltR
thẻ mới được tạo: 148 Git & GitHubChanges,
... 160+
Only Review and Git & GitHub were recreated. Terminal and Open file stayed put.
Root cause
app/src/runtime/plugin/panel-menu.ts builds the shared list in a memo:
return createMemo(() =>
host
.list(MenuItem)
.flatMap((item) => (item.menu === "session.panel" ? [item] : []))
.toSorted((a, b) => (a.order ?? 0) - (b.order ?? 0)),
)host.list(MenuItem) invokes every registered factory inside that memo's tracking scope, so reactive reads inside any factory become dependencies of the whole memo. When one of those reads changes, the memo recomputes and every factory-registered item comes back as a new object.
Two of the four items read fast-changing state:
gui-plugins/src/review/renderer.tsxreads the routed session and its changed-file count.- The
Git & GitHubitem inopencode-github-panel/src/window.tsx:107readsctx.sessions.current()andctx.layout.state(...).
Terminal is registered as a static object, and Open file's factory reads no reactive session state, so both keep their identity.
app/src/runtime/plugin/side-region.tsx then renders those items with <For>, which reconciles by object identity:
<For each={props.items}>A new object identity makes Solid destroy the existing <button> and create a replacement. Because a click requires mousedown and mouseup on the same node, the replacement between the two events cancels the click. The keyboard shortcut still works because it is registered as a command and calls run() directly.
Impact
A third-party plugin can break the clicks of a core launcher (Review is shipped with the app). Removing opencode-github-panel reduced the churn to zero and the launcher clicks started working again, which confirms the mechanism.
Suggested fix
Make the list stable per item id, so a recomputation keeps DOM nodes:
- Deduplicate and key items by
${plugin}:${id}increateSessionPanelMenu(), returning the previous object when its id is unchanged. - Or render with a keyed list instead of
<For>on raw objects.
Either change makes click handling independent of how often item factories run.
Activity
opencodejr commentedon Oct 30, 2026
Thanks for the detailed root-cause analysis. It matches what we found. I think this is a duplicate of #60381, which reports the same 2.2.2 regression: New tab launcher rows other than Terminal and Open file ignore clicks.
The fix was merged in #60436. Side-panel menu entries are now keyed by
${plugin}:${id}, and<Launchers>and<AddMenu>loop over those stable keys, so a factory rebuilding itsMenuItemupdates the existingLauncherRowinstead of replacing its<button>mid-click. That's essentially the first fix you suggested. It isn't in a tagged release yet, so 2.2.2 still behaves as you describe.Related issues, ordered by likelihood:
+menu items by plugin and idThe bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different, for example if it still happens on a build that includes #60436.
Hona commentedon Oct 30, 2026
Fixed in 2.2.3 by #60430 and #60436, the same 2.2.2 regression as #60381.
New tab launchers respond to clicks again, and side-panel tabs can be closed.
Please update to 2.2.3. In the desktop app, use Check for Updates, or install it from the release page. If launchers still ignore clicks afterwards, please reopen this issue.
opencodejr commentedon Oct 31, 2026
Closing this as a duplicate of #60381, since we haven't heard that your problem is different. Thanks again for the thorough root-cause analysis.
The fix is #60436. It keys side-panel launchers and
+menu items by${plugin}:${id}, so a factory rebuilding aMenuItemno longer replaces the<button>mid-click. It isn't in a tagged release yet. If launcher clicks still fail on a release that includes #60436, please comment here or open a new issue and link this one.