Skip to content

[RFC]: unify search overlays in the main window #476

Description

@hiqiancheng

Summary

Unify the search surface in a single main WebView by moving the model dropdown and session history out of standalone popup WebviewWindows and into a shared SearchOverlayHost alongside the existing SearchPanel.

On Windows, main becomes a transparent monitor-sized SearchWindow. The native layer applies a unioned window region for the visible SearchPanel and active search overlay, so unused transparent areas remain absent from native rendering and hit testing. An optional fully click-through SearchBackgroundWindow may be used only for monitor-wide visual effects.

This supersedes the earlier native-rendered standalone-popup proposal in this RFC.

Motivation

The current popup system creates separate transparent WebviewWindows for the model dropdown and session history. This requires separate renderer startup, popup preload and readiness events, DTO replication, screen-coordinate translation, cross-window keyboard forwarding, native focus-family bookkeeping, and extra show/hide synchronization.

It also prevents transitions that move naturally between the search panel and its overlays because the source and destination are rendered by different WebViews and HWNDs.

The intended outcome is:

  • one Vue rendering tree for the complete search surface;
  • direct shared state instead of cross-window popup transport;
  • coordinated panel and overlay animation;
  • no standalone search popup WebViews;
  • native click-through outside visible TouchAI UI;
  • preserved keyboard, focus, outside-click, prefetch, pinning, IME, and blur-to-hide behavior;
  • no global input hook or WM_NCHITTEST-based cross-process pass-through.

Affected boundaries

  • AgentService
  • conversation runtime
  • tool execution
  • session persistence
  • context construction
  • instruction loading
  • agent orchestration
  • MCP integration
  • database schema or migrations

The change affects the desktop frontend, Tauri window runtime, Windows native window regions, search-surface focus behavior, popup rendering, and desktop E2E coverage. It does not change agent, session, MCP, tool, or database semantics.

Proposed design

Search surface structure

Use TouchAI-specific terminology and a direct architecture:

SearchSurface
├── SearchPanel
│   ├── ConversationPanel
│   ├── AskUserPanel
│   ├── SearchBar
│   └── QuickSearchPanel
└── SearchOverlayHost
    ├── ModelDropdown
    └── SessionHistory

SearchPanel is the existing primary search/conversation content. The design does not use the reference project's "island" terminology.

Frontend ownership

Render both search overlays inside main, outside the clipped SearchPanel container and within a shared top-level stacking context.

Use a small explicit active-overlay state for the two current overlay types. Do not introduce a generic plugin registry, native/in-main adapter layer, or long-lived compatibility abstraction.

Preserve existing behavior:

  • model and history prefetch;
  • filter focus on open;
  • Arrow/Enter navigation;
  • Escape, Ctrl+M, and Ctrl+H behavior;
  • mutual exclusion with Quick Search and other overlays;
  • click inside versus outside semantics;
  • stale asynchronous history-search protection;
  • intentional focus restoration after selection or dismissal;
  • existing pin, drag, maximize/expanded, IME, and hide-on-blur behavior.

Position overlays in the shared WebView coordinate system using direct anchor, flip, align, and clamp rules. Remove native screen-coordinate popup placement after the standalone popup path is deleted.

Native window ownership

On Windows, make main a transparent SearchWindow sized to the active monitor. The frontend reports the stable logical rectangles of the visible SearchPanel and active SearchOverlay.

A dedicated native region module:

  1. converts logical rectangles to physical pixels using the active monitor scale factor;
  2. creates rounded Win32 regions;
  3. combines them with CombineRgn(..., RGN_OR);
  4. applies the result with SetWindowRgn;
  5. recomputes after layout, DPI, monitor, or visibility changes.

The native region is updated at stable transition boundaries, not once per animation frame. The animation-start region covers the required panel/overlay animation envelope; the final region is tightened after the transition.

The existing generic rounded-corner fallback must no longer clear or replace the deliberate main search region. Settings keeps its existing DWM/rounded-region behavior.

Optional full-monitor visuals

If monitor-wide visuals are needed, render them in a separate SearchBackgroundWindow that is non-focusable and uses Tauri's whole-window set_ignore_cursor_events(true). It is not part of the interaction or focus model.

Do not rely on CSS transparency, pointer-events: none, WS_EX_TRANSPARENT, layered alpha, or HTTRANSPARENT for selective pass-through to arbitrary external applications.

Animation

Use CSS transform, opacity, and selective clipping for panel/overlay transitions. Do not use CSS height as the primary surface animation, per-frame native window resizing, per-frame region IPC, or a custom WndProc hook.

Removed architecture

Delete the standalone search popup implementation after the unified host is in place:

  • popup WebviewWindow creation and preload;
  • PopupView route and bootstrap;
  • popup-ready/data/keydown event transport;
  • popup DTO replay and window-label identity;
  • Rust popup registry and popup surface sessions;
  • native popup focus-family and close/refocus plumbing.

Settings, tray UI, system dialogs, and other genuinely separate windows remain separate.

Alternatives and trade-offs

Keep standalone WebView popups

Lowest implementation cost, but retains duplicate renderer state, positioning/focus IPC, and prevents seamless same-tree animations.

Rewrite standalone popups with a native renderer

Removes popup WebViews, but duplicates UI logic outside Vue, makes exact visual parity harder, and still keeps cross-window focus, geometry, and animation boundaries. This was the previous direction of this RFC and is superseded.

Use one bounded main window and resize it around each overlay

Avoids a monitor-sized WebView but couples transient overlays to native resize/reposition, reintroduces WebView2 redraw and coordinate-origin changes, and complicates existing content-driven search sizing.

Use a full-screen transparent WebView without a native region

Rejected because transparent HWND pixels still intercept native pointer input. CSS pointer-events cannot route input to another process.

Use WM_NCHITTEST and return HTTRANSPARENT

Rejected as the primary design. Documented HTTRANSPARENT continuation is limited to underlying windows in the same thread and is not a reliable arbitrary cross-process desktop pass-through contract.

Use SetWindowRgn

Selected for the Windows interaction boundary because it removes both rendering and native hit testing outside the unioned UI region without a WndProc hook. The trade-off is Windows-specific region maintenance across DPI, display, layout, and animation-boundary changes.

Upstream references

Testing and rollout

This RFC defines the target architecture directly. The implementation should remain focused and avoid a permanent compatibility path or dual popup architecture.

Verification must cover:

  • model dropdown and session history opening, filtering, selection, and dismissal;
  • Arrow/Enter, Escape, Ctrl+M, and Ctrl+H behavior;
  • focus placement and restoration;
  • trigger, overlay-internal, panel-external, and application-external pointer behavior;
  • Quick Search and overlay mutual exclusion;
  • stale asynchronous result rejection;
  • pinning, drag, expanded state, hide-on-blur, and rapid global-shortcut toggling;
  • Chinese IME and WebView2 focus recovery after hide/show;
  • monitor work areas, negative virtual-screen coordinates, mixed DPI, display changes, and reconnects;
  • native click and wheel pass-through outside the unioned search region;
  • no taskbar or Alt+Tab regression;
  • no per-frame native resize or region IPC;
  • warm shortcut-to-focused-input and overlay animation smoothness.

Required validation includes pnpm test:pr, desktop E2E coverage, relevant Rust tests, and direct Windows interaction verification for cross-application click-through.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:frontendFrontend UI or view-layer changesarea:tauriTauri shell or desktop runtime changeskind:rfcArchitecture or cross-cutting design discussionstatus:acceptedConfirmed and ready for contribution

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions