Skip to content

[RFC]: native-render standalone desktop popups #476

Description

@hiqiancheng

Summary

Rewrite TouchAI's standalone popup windows as a native-rendered popup runtime instead of WebView-based popup pages. The first target is the model dropdown popup; the long-term goal is to support the same popup UX across Windows, macOS, and Linux while preserving the current visual design as closely as possible.

Motivation

The current popup system is built from transparent, undecorated WebView windows plus Vue components. That makes the UI feel less native, adds focus/resize/preload complexity, and creates extra failure modes. The desired outcome is a native windowing path with custom rendering so the popup can keep the current appearance while removing the WebView popup stack.

Affected boundaries

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

This change primarily affects desktop shell/windowing, frontend popup data flow, Rust-native popup lifecycle, and cross-platform rendering. It is intentionally not changing agent or database behavior.

Proposed design

Introduce a native popup runtime in �pps/desktop/src-tauri/src/core/window/native_popup/ and move standalone popup rendering out of �pps/desktop/src/views/PopupView/.

Phase 1 should replace only model-dropdown-popup with a native-rendered popup so the visual and interaction contract can be validated quickly.

Design goals:

  • keep the current popup layout, spacing, typography, and interaction order as close as possible
  • preserve keyboard navigation, focus behavior, and close-on-escape/outside-click semantics
  • keep popup positioning anchored to the existing trigger geometry logic
  • support a future shared renderer path for Windows/macOS/Linux instead of platform-specific one-off UI code

The suggested technical direction is a Rust-owned popup window plus a native renderer abstraction. The renderer can start with a Slint-based implementation for the first version, because it gives a cross-platform native UI path without keeping WebView as the popup renderer.

Alternatives and trade-offs

Alternative 1: keep the current WebView popup and keep polishing it.
Trade-off: fastest, but does not meet the native-rendered goal.

Alternative 2: use platform system controls for each popup.
Trade-off: truly native controls, but cannot preserve the current visual design closely enough.

Alternative 3: Rust-owned popup window with a shared native renderer abstraction.
Trade-off: higher upfront cost, but the only path that can reasonably preserve the current design across all three desktop platforms.

Upstream references

  • Current popup registry and renderer: �pps/desktop/src/services/PopupService/registry.ts
  • Current popup window lifecycle: �pps/desktop/src-tauri/src/core/window/popup/manager.rs
  • Current popup host view: �pps/desktop/src/views/PopupView/index.vue
  • Tauri architecture and dialog/windowing docs

Testing and rollout

Verification should cover:

  • popup opens and closes reliably
  • keyboard navigation matches current behavior
  • the first native-rendered popup matches the existing model dropdown visually and spatially
  • the old WebView popup path is still available behind a fallback until the native path is stable

Initial rollout should be limited to the model dropdown popup before migrating session history.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:rfcArchitecture or cross-cutting design discussionstatus:triageNeeds maintainer triage

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions