Add AppPopup window system; move pickers, menus, and Resource usage into it#424
Merged
Conversation
Introduce a shared, always-on-top popup window (panel-type Electron window at screen-saver level) with anchoring/placement helpers, an IPC bridge, and a renderer that dispatches on a request 'kind'. Wire the bridge into shell, pill, and logs preloads so any window can open anchored popups. This replaces ad-hoc inline dropdowns and native context menus with a uniform mechanism that stacks above other floating windows (like the Automating pill).
Render the engine picker and the BrowserCode model picker inside the shared popup window instead of inline dropdowns so they stack above other floating windows and share menu chrome. For the BrowserCode submenu, replace the right-side hover flyout with a drill-in: clicking BrowserCode swaps the engine list for the provider list with a back button, keeping a single panel and consistent styling instead of two disconnected floating boxes.
Replace inline dropdowns and native context menus in the sidebar, agent pane, and logs view with anchored popup-window menus so they match the shared menu chrome and stack predictably above other floating windows.
The Resource usage panel was rendered as an in-shell DOM dropdown, so the always-on-top Automating pill window was z-ordered above it and covered it. Render the panel content inside the shared popup window (screen-saver level) so it stacks above the pill. The popup uses plain useEffect-based polling instead of useQuery since the popup window does not host a QueryClientProvider.
There was a problem hiding this comment.
4 issues found across 27 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="app/src/renderer/shared/appPopup.ts">
<violation number="1" location="app/src/renderer/shared/appPopup.ts:79">
P2: Guard delayed listener attachment so disposed popups do not attach stale global handlers.</violation>
</file>
<file name="app/src/renderer/popup/AppPopup.tsx">
<violation number="1" location="app/src/renderer/popup/AppPopup.tsx:162">
P2: Popup content is reused across opens, so internal menu state can leak between sessions. Force a remount per popup request to reset drill-in state and rerun mount-time data fetches.</violation>
</file>
<file name="app/src/renderer/logs/LogsApp.tsx">
<violation number="1" location="app/src/renderer/logs/LogsApp.tsx:102">
P2: The menu items are generated from a potentially stale empty `editors` snapshot, so opening the popup before editor discovery finishes can hide all "Open in ..." actions until reopen.</violation>
</file>
<file name="app/src/main/index.ts">
<violation number="1" location="app/src/main/index.ts:295">
P2: Register the popup IPC handlers before warming the popup window, otherwise early launches can drop the renderer-ready handshake and leave popups stuck.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| createPillWindow(); | ||
| // Create logs overlay window (hidden) and anchor it to the hub | ||
| createLogsWindow(); | ||
| warmAppPopup(); |
There was a problem hiding this comment.
P2: Register the popup IPC handlers before warming the popup window, otherwise early launches can drop the renderer-ready handshake and leave popups stuck.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/index.ts, line 295:
<comment>Register the popup IPC handlers before warming the popup window, otherwise early launches can drop the renderer-ready handshake and leave popups stuck.</comment>
<file context>
@@ -291,6 +292,7 @@ function openShellAndWire(): BrowserWindow {
createPillWindow();
// Create logs overlay window (hidden) and anchor it to the hub
createLogsWindow();
+ warmAppPopup();
attachLogsToHub(shellWindow);
mainLogger.info('main.tray.beforeCreate', { typeofCreateTray: typeof createTray });
</file context>
- appPopup.ts: track a disposed flag so the deferred listener-attach setTimeout(0) does not register stale global handlers when a popup is closed before the listeners get a chance to mount. - AppPopup.tsx: key inner content components by request.id so each open remounts and resets internal state (drill-in, fetched data) instead of leaking it across opens. - LogsApp.tsx: await getEditors() before opening the file menu so the popup always shows the discovered editors instead of an empty snapshot when the user clicks before discovery resolves. - main/appPopup.ts: warmAppPopup self-invokes registerAppPopupHandlers so the renderer-ready handshake cannot be dropped if a future caller warms the popup before the handlers are wired.
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
screen-saverlevel) with anchoring/placement helpers, IPC bridge, and a renderer that dispatches on akindfield. Wired into shell, pill, and logs preloads.Automatingpill window was z-ordered above the in-shell dropdown and covered it; now the panel renders in a popup window at the same z-level as the pill.Test plan
Automatingpill visible, open Resource usage; confirm it stacks above the pill.cd app && npx vitest run(380 tests).cd app && npx tsc --noEmit.Summary by cubic
Adds a shared, always-on-top AppPopup window with anchoring and IPC, and moves engine/model pickers, menus, and Resource usage into it. Also hardens the popup lifecycle to avoid stale listeners and dropped handshakes, and ensures menus render with complete data.
New Features
popuprenderer and preload; introducedwindow.electronAPI.popupbridge and shared helpers.Bug Fixes
Written for commit 6aa64f7. Summary will update on new commits.