Skip to content

Spike: pure Win32 HWND + DX12, no XAML #82

@deblasis

Description

@deblasis

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:

  1. Multi-surface support -- two terminal surfaces in the same window (tabs or splits)
  2. Clipboard -- copy/paste via Win32 clipboard APIs
  3. Text input quality -- dead keys, IME composition, surrogate pairs
  4. Resize quality -- smooth resize without flicker (DX12 swap chain resize)
  5. 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:

  1. Embedded apprt + C/Zig host -- keep using embedded apprt (like macOS does with Swift) but with C or Zig host instead of C#
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestos/windowsspikeTime-boxed investigation or proof-of-concept

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions