130 lines
4.1 KiB
Markdown
130 lines
4.1 KiB
Markdown
# 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/3` in 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)
|
|
|
|
```go
|
|
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: fixed` panels
|
|
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')` or `runtime.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.
|