Windowing Backends¶
SimVX ships three Vulkan windowing backends behind a single WindowBackend
protocol (simvx.graphics.platform._base). The default selection order is
SDL3 → GLFW → Qt (platform/__init__.py:_BACKENDS), and the first import
that succeeds wins. You can pin one explicitly:
from simvx.graphics import App
app = App(width=1280, height=720, title="Game", backend="glfw")
Each backend implements every method of the WindowBackend Protocol; the
matrix below describes behaviour and feature coverage, not protocol
completeness.
Feature matrix¶
Legend: ✓ supported · partial · ✗ not supported.
Capability |
SDL3 |
GLFW |
Qt (PySide6) |
|---|---|---|---|
Keyboard input |
✓ |
✓ |
✓ |
Mouse buttons + cursor pos |
✓ |
✓ |
✓ |
Mouse scroll wheel |
✓ |
✓ |
✓ (mouse_button) |
Cursor shape |
✓ |
✓ |
✓ |
Gamepad (buttons + axes) |
✓ |
✓ |
✗ |
Touch events |
✓ ( |
✗ |
✗ |
IME / text input (Unicode) |
✓ (always-on; see TODO #181) |
✓ (always-on) |
✓ |
Clipboard read/write |
✗ (use OS shim) |
✗ (use OS shim) |
✗ (use OS shim) |
Drag-and-drop (file paths) |
✗ |
✗ |
✗ |
Native file dialogs |
✗ (use SimVX UI |
✗ (use SimVX UI |
✗ (use SimVX UI |
Multi-window |
✗ (single window) |
✗ (single window) |
✗ (single window) |
Headless / hidden window |
✓ ( |
✓ ( |
partial (Qt creates a real window) |
Fullscreen toggle |
✗ |
✓ ( |
✗ |
App lifecycle hooks |
✓ ( |
✗ |
✗ |
Pause-when-backgrounded |
✓ ( |
✗ |
✗ |
HiDPI content scale |
✓ |
✓ |
✓ |
Vulkan surface creation |
✓ |
✓ |
✓ |
When to pick each backend¶
SimVX is backend-agnostic: any windowing library that can hand out a Vulkan surface works. The three implementations shipped today differ only in their input/lifecycle feature set:
SDL3: default at autoselect time. Picked first because it is the only backend with multi-touch (mobile, touchscreen kiosks) and full app-lifecycle callbacks. Loaded via
PySDL3; falls back to GLFW if the binding is missing.GLFW: desktop fallback. Smaller dependency, faster cold start, and the only backend with built-in fullscreen toggle. Use for kiosk-style desktop apps and headless rendering. No touch and no app-lifecycle callbacks.
Qt (PySide6): embedding into Qt host apps. Pick this only when the Vulkan surface needs to live inside an existing Qt main loop (third-party tooling). Touch, gamepad, fullscreen toggle, and headless are all missing :
App(visible=False)will still spawn a window. PySide6 is an optional install (simvx-graphics[qt]).
Headless rendering¶
All three backends support an invisible window via App(visible=False) and
App.run_headless(scene, frames=N), but only SDL3 and GLFW honour the
window-visibility flag fully. Qt creates a real (off-screen-positioned)
window because PySide6 cannot create a Vulkan-capable surface without one.
For CI and pytest captures use SDL3 or GLFW.
Gaps tracked in TODO.md¶
Per-focus SDL3 text input toggle (mobile IME flicker): see
## Cross-Platform Preparation.Drag-and-drop file path delivery, not yet plumbed on any backend.
Multi-window: out of scope until the multi-threaded renderer entry lands.