Pure Win32 HWND + DX12 spike -- feasibility evaluation
Time-boxed investigation to determine if a pure Win32 host (no WinUI 3, no .NET) is viable as the primary Windows apprt, using our DX12 renderer.
Parent: #26
Background
Our current bet is C# WinUI 3 wrapping libghostty. An alternative: skip WinUI 3/XAML entirely and drive everything from raw Win32 + DX12. The InsipidPoint/ghostty-windows fork (Win32 + OpenGL) and our own example/c-win32-terminal (Win32 + DX12 embedded apprt) both demonstrate this is feasible.
The C Win32 example already proves the integration works: a C program that creates an HWND, passes it to libghostty, and gets a working terminal with keyboard, mouse, resize, DPI, and focus handling -- all backed by our DX12 renderer.
The DX12 renderer itself is built (PRs #107-#110, #113-#124): D3D12 device, command queue, fence, descriptor heaps, triple-buffered frame lifecycle, all 5 pipelines, HLSL shaders compiled to SM 6.0 DXIL via dxc.exe, and 21 GPU integration tests.
What you lose vs WinUI 3
| Feature |
WinUI 3 |
Pure Win32 |
Impact |
| Mica/Acrylic backdrop |
Built-in |
DwmSetWindowAttribute + DWM composition APIs |
Medium |
| Modern accessibility |
UIA via XAML controls |
Must implement UIA providers manually |
High |
| XAML controls (menus, dialogs) |
Built-in |
Build from scratch or use Win32 common dialogs |
Medium |
| High-DPI scaling |
Automatic |
WM_DPICHANGED (already solved in example) |
Low |
| System theme integration |
Automatic |
DwmSetWindowAttribute for dark mode |
Low |
| Snap layouts |
Automatic |
Works with standard Win32 windows on Win11 |
Free |
Biggest real loss: accessibility baseline from XAML controls. For terminal content itself, both approaches need a custom UIA provider.
What you gain
| Benefit |
Details |
| No .NET runtime |
Single .exe + ghostty.dll, no .NET 8+ required |
| Faster startup |
No CLR JIT warmup, Win32+DX12 init is sub-50ms |
| Smaller binary |
No C# assembly, no WinUI 3 framework package (~150MB) |
| No GC |
Deterministic memory, no pauses during rendering |
| Simpler build |
No MSBuild/NuGet/WindowsAppSDK, just zig build |
| Simpler interop |
Direct C calls, no P/Invoke marshaling |
| Full message loop control |
Optimize input latency, frame pacing, resize |
InsipidPoint/ghostty-windows validation
This fork has a working Win32 apprt in Zig with OpenGL rendering:
- src/apprt/win32/ -- App.zig, Surface.zig (~1586 lines), Window.zig
- Working: tabs (custom GDI tab bar), split panes with drag resize, IME, DPI awareness, fullscreen, background opacity, find-in-terminal, scrollbar, desktop notifications
- Ships as a single .exe
Demonstrates that a pure Win32 terminal can be feature-rich without a UI framework. GDI tab bar and split management are tractable.
Proposed spike
Time-box: 3-5 days
Starting point: Extend example/c-win32-terminal or create new src/apprt/win32/
Deliverables:
- Multi-surface support -- two terminal surfaces in the same window (tabs or splits)
- Clipboard -- copy/paste via Win32 clipboard APIs
- Text input quality -- dead keys, IME composition, surrogate pairs
- Resize quality -- smooth resize without flicker (DX12 swap chain resize)
- Dark mode -- DwmSetWindowAttribute for dark title bar on Win11
Success criteria:
- Open terminal, run shell, type, scroll, copy/paste
- Multiple surfaces (even side by side, no fancy tab bar needed)
- Resize without bad flicker
- Startup under 200ms to first frame
- Code small enough to maintain alongside DX12 renderer
Non-goals:
- Tab bar UI (ugly placeholders OK)
- Settings UI
- Accessibility
- Installer/packaging
- Feature parity with InsipidPoint
Decision point after spike
If successful, two options:
- Embedded apprt + C/Zig host -- keep using embedded apprt (like macOS does with Swift) but with C or Zig host instead of C#
- Native win32 apprt -- build a proper src/apprt/win32/ in Zig like InsipidPoint
Either way, all DX12 renderer work (pipelines, shaders, COM bindings) is shared and not wasted. The .NET runtime tax spike (#51) results will inform whether C# WinUI 3 or pure Win32 is the better path.
Pure Win32 HWND + DX12 spike -- feasibility evaluation
Time-boxed investigation to determine if a pure Win32 host (no WinUI 3, no .NET) is viable as the primary Windows apprt, using our DX12 renderer.
Parent: #26
Background
Our current bet is C# WinUI 3 wrapping libghostty. An alternative: skip WinUI 3/XAML entirely and drive everything from raw Win32 + DX12. The InsipidPoint/ghostty-windows fork (Win32 + OpenGL) and our own example/c-win32-terminal (Win32 + DX12 embedded apprt) both demonstrate this is feasible.
The C Win32 example already proves the integration works: a C program that creates an HWND, passes it to libghostty, and gets a working terminal with keyboard, mouse, resize, DPI, and focus handling -- all backed by our DX12 renderer.
The DX12 renderer itself is built (PRs #107-#110, #113-#124): D3D12 device, command queue, fence, descriptor heaps, triple-buffered frame lifecycle, all 5 pipelines, HLSL shaders compiled to SM 6.0 DXIL via dxc.exe, and 21 GPU integration tests.
What you lose vs WinUI 3
Biggest real loss: accessibility baseline from XAML controls. For terminal content itself, both approaches need a custom UIA provider.
What you gain
InsipidPoint/ghostty-windows validation
This fork has a working Win32 apprt in Zig with OpenGL rendering:
Demonstrates that a pure Win32 terminal can be feature-rich without a UI framework. GDI tab bar and split management are tractable.
Proposed spike
Time-box: 3-5 days
Starting point: Extend example/c-win32-terminal or create new src/apprt/win32/
Deliverables:
Success criteria:
Non-goals:
Decision point after spike
If successful, two options:
Either way, all DX12 renderer work (pipelines, shaders, COM bindings) is shared and not wasted. The .NET runtime tax spike (#51) results will inform whether C# WinUI 3 or pure Win32 is the better path.