Go + Wails v3 + Vue 3 + SQLite + FreeRDP3 (purego) 183 tests, 76 source files, 9,910 lines of code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.1 KiB
Spike: Multi-Window Support in Wails v3
Status: Research-based (not yet validated on Windows) Date: 2026-03-17 Target platform: Windows (developing on macOS) Wails version: v3.0.0-alpha.74
Context
Wraith needs to support detached sessions — users should be able to pop out an SSH or RDP session into its own window while the main connection manager remains open. This spike evaluates three approaches, ranked by preference.
Plan A: Wails v3 Native Multi-Window
Status: LIKELY WORKS based on API documentation.
How it works
app.Window.NewWithOptions()creates a new OS-level window at runtime.- Each window can load a different URL or frontend route (e.g.,
/session/rdp/3in one window,/in the main window). - All windows share the same Go backend services — no IPC or inter-process marshalling required. Bindings registered on the application are callable from any window.
- Window lifecycle events (
OnClose,OnFocus, etc.) are available for cleanup.
Example (pseudocode)
win, err := app.Window.NewWithOptions(application.WindowOptions{
Title: "RDP — server-01",
Width: 1280,
Height: 720,
URL: "/session/rdp/3",
})
Risks
| Risk | Severity | Mitigation |
|---|---|---|
| Alpha API — method signatures may change before v3 stable | Medium | Pin to a known-good alpha tag; wrap calls behind an internal interface so migration is a single-file change. |
| Platform-specific quirks on Windows (DPI, focus, taskbar grouping) | Low | Test on Windows during Phase 2. Wails uses webview2 on Windows which is mature. |
| Window count limits or resource leaks | Low | Cap concurrent detached windows (e.g., 8). Ensure OnClose releases resources. |
Plan B: Floating Panels (CSS-based)
Status: FALLBACK — no external dependency, purely frontend.
How it works
- Detached sessions render as draggable, resizable
position: fixedpanels within the main Wails window. - Each panel contains its own Vue component instance (terminal emulator or RDP canvas).
- Panels can be minimised, maximised within the viewport, or snapped to edges.
Pros
- Zero dependency on Wails multi-window API.
- Works on any platform without additional testing.
- Simpler state management — everything lives in one window context.
Cons
- Sessions share the same viewport — limited screen real estate.
- Cannot span multiple monitors.
- Feels less native than real OS windows.
Implementation cost
Small. Requires a <FloatingPanel> wrapper component with drag/resize
handlers. Libraries like vue3-draggable-resizable exist but a lightweight
custom implementation (~150 LOC) is preferable to avoid dependency churn.
Plan C: Browser Mode
Status: EMERGENCY — last resort if both Plan A and Plan B are inadequate.
How it works
- Wails v3 supports a server mode where the frontend is served over HTTP on
localhost. - Detached sessions open in the user's default browser via
open(url, '_blank')orruntime.BrowserOpenURL(). - The browser tab communicates with Go services through the same HTTP endpoint.
Pros
- Guaranteed to work — it is just a web page.
- Users can arrange tabs freely across monitors.
Cons
- Breaks the desktop-app experience.
- Browser tabs lack access to Wails runtime bindings; all communication must go through HTTP/WebSocket, requiring a parallel transport layer.
- Security surface increases — localhost HTTP server is accessible to other local processes.
Recommendation
Start with Plan A. The Wails v3 NewWithOptions API is documented and
consistent with how other multi-window desktop frameworks (Electron,
Tauri v2) work. The alpha stability risk is mitigated by wrapping calls
behind an internal interface.
If Plan A fails during Windows validation, Plan B requires only frontend CSS changes — no backend work is wasted. Plan C is reserved for scenarios where neither A nor B is viable.
Next Step
Validate Plan A on Windows during Phase 2 when SSH sessions exist and there is a real payload to render in a second window.