Ranvier.View.WebCore.Sdl
0.1.0-rc.1
dotnet add package Ranvier.View.WebCore.Sdl --version 0.1.0-rc.1
NuGet\Install-Package Ranvier.View.WebCore.Sdl -Version 0.1.0-rc.1
<PackageReference Include="Ranvier.View.WebCore.Sdl" Version="0.1.0-rc.1" />
<PackageVersion Include="Ranvier.View.WebCore.Sdl" Version="0.1.0-rc.1" />
<PackageReference Include="Ranvier.View.WebCore.Sdl" />
paket add Ranvier.View.WebCore.Sdl --version 0.1.0-rc.1
#r "nuget: Ranvier.View.WebCore.Sdl, 0.1.0-rc.1"
#:package Ranvier.View.WebCore.Sdl@0.1.0-rc.1
#addin nuget:?package=Ranvier.View.WebCore.Sdl&version=0.1.0-rc.1&prerelease
#tool nuget:?package=Ranvier.View.WebCore.Sdl&version=0.1.0-rc.1&prerelease
Ranvier.View.WebCore.Sdl
Shows a Ranvier.View.WebCore page in an SDL3 window, through
ppy.SDL3-CS. The window paints the page when it asks for a frame. It forwards
mouse, wheel, keyboard, input method and focus events to the page. It also sets the page's cursor and moves its
text/plain clipboard data through SDL.
Install
dotnet add package Ranvier.View.WebCore.Sdl --version 0.1.0-rc.1
Use Ranvier.View.WebCore.Sdl.Traced for a traced build. Backend, shared contracts, canonical interop,
SDL3 and the five-RID native aggregate are transitive dependencies.
For Windows x64 shared GPU presentation, add the matching GPU runtime and suppress the aggregate's Slim win-x64 assets in the application project:
<ItemGroup>
<PackageReference Include="Ranvier.WebCore.Native.win-x64" Version="[0.1.1-rc.2]" ExcludeAssets="all" />
<PackageReference Include="Ranvier.WebCore.Native.Gpu.win-x64" Version="[0.1.1-rc.2]" />
</ItemGroup>
Select the direct3d11 renderer through Window.create's renderer argument. The other four native RID
dependencies remain available; the explicit exclusion prevents conflicting Windows native payloads.
On Windows, a native GPU runtime with the presentation-d3d11 capability uses shared D3D11 textures with
SDL's direct3d11 renderer at display scale 1. Other renderers, unsupported devices and other display scales
use CPU painting. An explicit renderer = "software" keeps CPU presentation. GPU frames are released after
SDL submits its drawing, including readback, and before renderer teardown.
The accessibility-uia capability attaches the page's Windows UI Automation tree to the SDL window. It
detaches before page or window disposal. The bridge uses native COM and also works in a NativeAOT app.
Linux input methods
SDL forwards composition and committed text to the focused page. For an X11 application that needs IBus
surrounding text, an optional patched SDL build selects SDL's direct IBus context when
SDL_RANVIER_IBUS=1 is set before the first SDL window is created. Query
window.ImeSurroundingAvailable to determine whether surrounding text is currently available. It is false
when the context is unavailable or cleared, including while a password field is focused. If direct IBus
cannot initialize, X11 falls back to XIM; that fallback does not provide this extension.
The optional Ranvier.View.WebCore.Sdl.Ibus package and its SDL build are currently private qualification
artifacts, not published packages. The SDL build and packaging instructions
describe the pinned source, prerequisites, explicit linux-x64 publish target, and current limitations.
Wayland text-input-v3 and XIM do not use this direct-IBus extension; single-file publish and other
architectures have not been qualified for the optional package.
Platform support
Experimental, on Windows x64, Windows ARM64, Linux x64 and macOS arm64 (macOS 26), like the backend.
WebCore's run loop and SDL's event pump share the process main thread on macOS, with the same
Window.Step implementation.
macOS CI passed
770 tests, with 16 ignored and no failures. Those tests cover a hidden window, paint readback and SDL input;
the visible sample smoke
also passed (480x320 backing pixels, scale 1, painted content and clipboard). RANVIER_SMOKE=1 closes the
sample automatically. Retina scale 2 and a real IME still need
manual verification; the clipboard bridge supports text/plain only.
The subsequent four-platform CI run passed 773 tests per platform, with 16 existing ignored and no failures, plus the visible sample and both NativeAOT apps. Windows ARM64 ran on a real ARM runner; Linux used Ubuntu 24.04 with Xvfb.
open Ranvier
open Ranvier.View
open Ranvier.View.Dom
open Ranvier.View.WebCore.Sdl
Window.run ("Counter", 480, 320) (fun host ->
let graph = new Graph ()
let container = host.Document.createElement "div"
host.Document.body.appendChild container |> ignore
Mounting.mount graph None (fun errors -> raise (AggregateException errors)) container None (fun context ->
Program.run (Component.render counter 0) context.Backend))
Window.run returns when the window closes. An app that owns its loop calls Window.create and then Step each turn
instead. Step waits for window events until the next timer is due, dispatches them, cycles the host and presents a
frame when one is wanted:
use window = Window.create ("Counter", 480, 320)
// mount into window.Host.Document
while window.Step () do
() // the app's own work
The window's size is in the platform's window units. The page's CSS pixels follow the display's scale, so a 480 by
320 window shows 480 by 320 CSS pixels on any display. NativeHandle is the platform's window (an HWND on
Windows), for an accessibility bridge.
All calls go on the thread that created the window. That thread is the host's thread, and the main thread on macOS.
examples/Ranvier.NativeCounter is a complete app, published with NativeAOT.
NativeAOT
Publish the smoke app and counter on the target OS:
dotnet publish tests/Ranvier.View.WebCore.AotSmoke -c Release -r win-x64 -o artifacts/native-aot/smoke
dotnet publish examples/Ranvier.NativeCounter -c Release -r win-x64 -o artifacts/native-aot/counter
Use -r osx-arm64 on macOS 26. Windows needs the .NET 10 SDK, Visual Studio C++ Build Tools (the Desktop
development with C++ workload) and a Windows SDK; macOS needs the .NET 10 SDK and Xcode command-line tools.
Run the published smoke executable directly; it verifies mount, paint, native click and repaint. Run the
published counter with RANVIER_SMOKE=1 for its bounded visible-window check. Keep all native libraries and
WebKit.resources from the publish folder beside the executable. The app is native; the WebCore libraries
and resources remain separate files.
Size-oriented publishing
For a smaller NativeAOT executable, opt in to the .NET SDK's size optimization at publish time:
dotnet publish examples/Ranvier.NativeCounter -c Release -r win-x64 -p:OptimizationPreference=Size -o artifacts/native-aot/counter-size
Apply the same property to your own application's project and target RID. The default publish remains unchanged; size optimization can trade execution speed for a smaller executable, so measure your own workload.
In a matched Windows x64 Release comparison using public Ranvier.Dom alpha.55, View source 5435298 and the
private ABI 62 GPU native runtime 590e299, the Counter executable changed from 6,450,176 to 5,701,120 bytes
(−11.61%). The backend smoke executable changed from 6,181,376 to 5,463,040 bytes (−11.62%). Both profiles
passed the same Counter and 30-check smoke runs with NativeAOT warnings treated as errors. The 89,778,897-byte
WebCore native payload was identical in both profiles; the Counter runtime files excluding symbols and XML
documentation therefore fell from 99,350,737 to 98,601,681 bytes (−0.75%). These are measurements of one
private Windows GPU cohort, not a size guarantee for other runtimes, applications or platforms.
Both apps published and ran on Windows x64 locally and in Windows and macOS arm64 CI. The counter opened a visible 480x320 window, with scale 1, matching backing dimensions, painted content and a successful text/plain clipboard round-trip on each platform. Retina scale 2 and a real IME remain manual checks. NativeAOT still reports FSharp.Core/view reflection, trimming and generic-recursion warnings; the exercised app paths pass, and broader AOT coverage remains work to do.
Windows presentation and accessibility acceptance
The visible smoke reads SDL's actual backbuffer. RANVIER_SMOKE_GPU=1 requires at least one shared D3D11
frame; RANVIER_SMOKE_UIA=1 requires an attached UI Automation tree. Build the independent OS client with
python tools/native-window-probe.py, then set RANVIER_UIA_PROBE to the absolute path of
artifacts/native-window/UiAutomationProbe.exe. The smoke keeps pumping the owner thread while the client
finds the counter button, invokes it, observes its new accessible name and closes the window. It verifies
that the retained UIA element becomes unavailable after teardown.
Local JIT and NativeAOT checks passed with a private Windows x64 GPU host/WebCore build: the SDL backbuffer was 480x320 at scale 1, shared frames were presented, and the independent tree/action/teardown checks and clipboard round-trip passed. The persisted presenter also passed software-renderer and scale-2 CPU fallback checks, then resumed shared presentation at scale 1. These checks precede the coordinated package release.
Corrected preview.7 native CI packages from run 40729363033 also passed normal/traced package-only CPU consumers under JIT and NativeAOT. Each counter run verified the 480x320 actual backbuffer, clipboard and independent UIA discovery, bounds, Invoke, reactive name updates and provider disconnection. Native and resource payload hashes matched the packages, including the corrected nested icon paths. The same eight normal/traced Smoke/Counter JIT/NativeAOT runs also pass with native packages from official NuGet, matching the clean preview.7 release source. View libraries are locally packed in these runs. The package acceptance workflow checks fully published normal/traced CPU and GPU consumers.
Full source CI passed all four platform jobs with 781 backend tests, 12 existing ignored, 15 NativeAOT smoke checks and both visible counter runs each. Windows x64 verifies the independent external UIA client; Windows ARM64 verifies UIA attachment/smoke without that client.
The manual CI webcore-gpu lane takes an exact gpu_runtime_version, public NuGet v3 gpu_runtime_source
and gpu_runtime_package (default Ranvier.WebCore.Native.Gpu.win-x64). It verifies the package's GPU flavor,
RID, version, clean source revision and file hashes before staging it. Managed interop uses that same version.
Both JIT and NativeAOT must pass the strict shared-frame, actual-backbuffer and independent UIA checks, and
a failing enabled GPU lane fails the aggregate CI result. An empty version disables the lane; CPU CI does
not count as GPU verification. Run 40784192253
passed all 18 jobs with public GPU preview.7: JIT and NativeAOT each presented two shared frames at
480x320/scale 1 and passed clipboard and independent UIA tree/action/teardown checks.
Final fully public acceptance passed all four normal/traced Slim/GPU jobs. Both apps ran under JIT and NativeAOT in each job: all eight visible Counter runs passed clipboard/backbuffer and independent UIA checks. Each GPU Counter recorded two shared frames; Slim Counters recorded zero. NativeAOT stdout/stderr logs are preserved as artifacts. Every selected native/resource file matches its public package manifest (24 Slim or 26 GPU).
Optional Linux accessibility
An optional libRanvierWebCoreAtspi.so sidecar mirrors the native rv_ax_* tree through the desktop AT-SPI bus.
It uses the existing host loop and stays outside the renderer library. Place the matching module beside the app or
on its native library search path. The provider discovers AT_SPI_BUS_ADDRESS or org.a11y.Bus on the session bus;
Window.AccessibilityAttached is false when the module or desktop service is unavailable.
The Window owns the provider lease through the Host's cleanup installations. Direct Host disposal and Window disposal release it before destroying the native page. SDL movement and display-scale changes update its geometry. X11 exposes physical screen positions; Wayland reports screen coordinates unsupported while window coordinates remain available. All operations run on the host owner thread. This integration does not replace Windows UI Automation.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- FSharp.Core (>= 10.1.401)
- ppy.SDL3-CS (>= 2026.1002.1)
- Ranvier.View.WebCore (>= 0.1.0-rc.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-rc.1 | 45 | 11/4/2026 |
| 0.1.0-alpha.48 | 46 | 11/4/2026 |
| 0.1.0-alpha.47 | 41 | 11/3/2026 |
| 0.1.0-alpha.46 | 51 | 11/3/2026 |
| 0.1.0-alpha.45 | 60 | 11/3/2026 |
| 0.1.0-alpha.44 | 60 | 11/1/2026 |
| 0.1.0-alpha.39 | 59 | 11/1/2026 |
| 0.1.0-alpha.8 | 63 | 10/31/2026 |
| 0.1.0-alpha.7 | 56 | 10/31/2026 |
| 0.1.0-alpha.6 | 58 | 10/31/2026 |
| 0.1.0-alpha.5 | 57 | 10/30/2026 |
| 0.1.0-alpha.4 | 60 | 10/30/2026 |
| 0.1.0-alpha.3 | 58 | 10/29/2026 |
| 0.1.0-alpha.2 | 58 | 10/29/2026 |
| 0.1.0-alpha.1 | 69 | 10/29/2026 |
Experimental. The API may change.