webview2

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Rendered for windows/amd64

Overview

Package webview2 is a hand-written, CGo-free binding for the Microsoft WebView2 runtime.

It exists so that mullion depends on nothing but the standard library and golang.org/x/sys/windows: no third-party WebView2 binding, and - crucially - no WebView2Loader.dll shipped beside the executable. The environment is created by calling CreateWebViewEnvironmentWithOptionsInternal directly out of the runtime's own EmbeddedBrowserWebView.dll (see loader_windows.go).

This file is the outbound COM plumbing that everything else stands on - the call bridge, IUnknown and HRESULT handling. The inbound half - comServer, the shared IUnknown for COM objects implemented in Go - lives in comserver_windows.go, and the rules for reading and writing memory Windows owns, which every inbound method needs, in com_memory_windows.go. Two directions of traffic exist and they have different hazards:

  • Outbound (we call COM): a COM object is a pointer to a pointer to a vtable, so *IUnknown below mirrors that layout exactly. Calls go through ComProc.Call.
  • Inbound (COM calls us): WebView2's async APIs take completion handlers, which are COM objects the *caller* must implement. comServer is the shared implementation of IUnknown for those Go-side objects.

Threading: WebView2 requires a single-threaded apartment and a running message loop. Callers must have called CoInitializeEx(COINIT_APARTMENTTHREADED) on the thread they use this package from, and that thread must be locked (runtime.LockOSThread) for the lifetime of the WebView.

Package webview2 contains hand-written COM bindings for the WebView2 Win32 API.

This file carries the ABI contract and the shared value types and helpers; the interface declarations themselves live in the interfaces_* family, one file per interface group:

interfaces_environment_windows.go  IStream, ICoreWebView2Environment
interfaces_controller_windows.go   the ICoreWebView2Controller chain
interfaces_core_windows.go         ICoreWebView2 itself
interfaces_settings_windows.go     the ICoreWebView2Settings chain
interfaces_webresource_windows.go  request, requested-event args, response
interfaces_events_windows.go       message/navigation/process-failed args

Every layout in this family is derived from Microsoft's official WebView2 SDK (Microsoft.Web.WebView2, build/native/include/WebView2.h and WebView2.idl), which is the MIDL-generated C ABI. Nothing is copied from a third-party Go binding.

ABI contract (read before touching any vtable struct in this family)

COM dispatches by vtable *offset*, not by name. Adding, removing, reordering or misspelling-into-the-wrong-slot a single ComProc field silently retargets every method after it. The failure mode is not an error return: it is a call through a wrong function pointer, i.e. memory corruption or a hard crash inside the runtime, at the point of first use.

Two rules follow, and both are load-bearing:

  1. Vtables list EVERY method of the interface, in IDL order, including the ones this package never calls. Unused slots are still declared, because the slots after them depend on their presence. Do not "clean up" a field just because nothing references it.
  2. Each interface embeds its base interface's vtable, mirroring the C++ inheritance chain (ICoreWebView2Settings9 : ...8 : ...7 : ... : IUnknown). Go lays embedded structs out inline and in order, so the embedding chain reproduces exactly the flattened vtable MIDL emits.

interfaces_windows_test.go pins every slot offset and every IID with unsafe.Offsetof, and runs without a WebView2 runtime. Re-run it after any edit here; a passing build proves nothing about a vtable.

Win64 argument-passing rules that matter here

From the x64 calling convention (learn.microsoft.com/cpp/build/x64-calling-convention): "Structs and unions of size 8, 16, 32, or 64 bits ... are passed as if they were integers of the same size. Structs or unions of other sizes are passed as a pointer to memory allocated by the caller."

  • COREWEBVIEW2_COLOR is 4 bytes (32 bits) -> passed BY VALUE, packed into a register. See Color.pack.
  • RECT is 16 bytes (128 bits) -> passed BY POINTER, even though the C signature says `put_Bounds(RECT bounds)`. See ICoreWebView2Controller.PutBounds.
  • `double` lands in XMM1 for the second argument. Go's syscall bridge copies the first four integer-register arguments into X0-X3 precisely so that floating-point arguments work (see Go's internal/runtime/syscall/windows/asm_windows_amd64.s: "Floating point arguments are passed in the XMM registers. Set them here in case any of the arguments are floating point values."). So passing math.Float64bits(v) as a uintptr reaches the callee correctly. See ICoreWebView2Controller3.PutRasterizationScale.

Index

Constants

View Source
const BrowserExecutableFolderEnv = "WEBVIEW2_BROWSER_EXECUTABLE_FOLDER"

BrowserExecutableFolderEnv pins the runtime to a specific folder. It is the documented override for fixed-version distributions and for developers who need to reproduce a bug against an exact browser build.

View Source
const DefaultTimeout = 60 * time.Second

DefaultTimeout bounds environment and controller creation. WebView2 has to start a browser process, which on a cold machine is slow but not unbounded; a caller that waits forever would hang the UI thread with no diagnosis.

Variables

View Source
var (
	// IIDICoreWebView2WebMessageReceivedEventHandler = {57213f19-00e6-49fa-8e07-898ea01ecbd2}
	IIDICoreWebView2WebMessageReceivedEventHandler = windows.GUID{
		Data1: 0x57213f19, Data2: 0x00e6, Data3: 0x49fa,
		Data4: [8]byte{0x8e, 0x07, 0x89, 0x8e, 0xa0, 0x1e, 0xcb, 0xd2},
	}
	// IIDICoreWebView2WebResourceRequestedEventHandler = {ab00b74c-15f1-4646-80e8-e76341d25d71}
	IIDICoreWebView2WebResourceRequestedEventHandler = windows.GUID{
		Data1: 0xab00b74c, Data2: 0x15f1, Data3: 0x4646,
		Data4: [8]byte{0x80, 0xe8, 0xe7, 0x63, 0x41, 0xd2, 0x5d, 0x71},
	}
	// IIDICoreWebView2NavigationStartingEventHandler = {9adbe429-f36d-432b-9ddc-f8881fbd76e3}
	IIDICoreWebView2NavigationStartingEventHandler = windows.GUID{
		Data1: 0x9adbe429, Data2: 0xf36d, Data3: 0x432b,
		Data4: [8]byte{0x9d, 0xdc, 0xf8, 0x88, 0x1f, 0xbd, 0x76, 0xe3},
	}
	// IIDICoreWebView2NavigationCompletedEventHandler = {d33a35bf-1c49-4f98-93ab-006e0533fe1c}
	IIDICoreWebView2NavigationCompletedEventHandler = windows.GUID{
		Data1: 0xd33a35bf, Data2: 0x1c49, Data3: 0x4f98,
		Data4: [8]byte{0x93, 0xab, 0x00, 0x6e, 0x05, 0x33, 0xfe, 0x1c},
	}
	// IIDICoreWebView2ProcessFailedEventHandler = {79e0aea4-990b-42d9-aa1d-0fcc2e5bc7f1}
	IIDICoreWebView2ProcessFailedEventHandler = windows.GUID{
		Data1: 0x79e0aea4, Data2: 0x990b, Data3: 0x42d9,
		Data4: [8]byte{0xaa, 0x1d, 0x0f, 0xcc, 0x2e, 0x5b, 0xc7, 0xf1},
	}
	// IIDICoreWebView2NewWindowRequestedEventHandler = {d4c185fe-c81c-4989-97af-2d3fa7ab5651}
	IIDICoreWebView2NewWindowRequestedEventHandler = windows.GUID{
		Data1: 0xd4c185fe, Data2: 0xc81c, Data3: 0x4989,
		Data4: [8]byte{0x97, 0xaf, 0x2d, 0x3f, 0xa7, 0xab, 0x56, 0x51},
	}
)

Handler interface IDs, transcribed from the MIDL_INTERFACE attributes in the WebView2 SDK header (build/native/include/WebView2.h). Each of these interfaces is IUnknown + Invoke: 4 slots, Invoke at index 3.

View Source
var (
	// IIDICoreWebView2Controller2 = {c979903e-d4ca-4228-92eb-47ee3fa96eab}
	IIDICoreWebView2Controller2 = windows.GUID{
		Data1: 0xc979903e, Data2: 0xd4ca, Data3: 0x4228,
		Data4: [8]byte{0x92, 0xeb, 0x47, 0xee, 0x3f, 0xa9, 0x6e, 0xab},
	}
	// IIDICoreWebView2Controller3 = {f9614724-5d2b-41dc-aef7-73d62b51543b}
	IIDICoreWebView2Controller3 = windows.GUID{
		Data1: 0xf9614724, Data2: 0x5d2b, Data3: 0x41dc,
		Data4: [8]byte{0xae, 0xf7, 0x73, 0xd6, 0x2b, 0x51, 0x54, 0x3b},
	}
)

Transcribed from the MIDL_INTERFACE attributes in WebView2.h. A single swapped nibble compiles fine and only shows up as a QueryInterface miss at runtime, so interfaces_windows_test.go re-parses each one from its canonical string form and compares.

View Source
var (
	// IIDICoreWebView2Settings3 = {fdb5ab74-af33-4854-84f0-0a631deb5eba}
	IIDICoreWebView2Settings3 = windows.GUID{
		Data1: 0xfdb5ab74, Data2: 0xaf33, Data3: 0x4854,
		Data4: [8]byte{0x84, 0xf0, 0x0a, 0x63, 0x1d, 0xeb, 0x5e, 0xba},
	}
	// IIDICoreWebView2Settings5 = {183e7052-1d03-43a0-ab99-98e043b66b39}
	IIDICoreWebView2Settings5 = windows.GUID{
		Data1: 0x183e7052, Data2: 0x1d03, Data3: 0x43a0,
		Data4: [8]byte{0xab, 0x99, 0x98, 0xe0, 0x43, 0xb6, 0x6b, 0x39},
	}
	// IIDICoreWebView2Settings9 = {0528a73b-e92d-49f4-927a-e547dddaa37d}
	// Requires WebView2 Runtime 1.0.2420.47+ (the app-region / non-client
	// region support release).
	IIDICoreWebView2Settings9 = windows.GUID{
		Data1: 0x0528a73b, Data2: 0xe92d, Data3: 0x49f4,
		Data4: [8]byte{0x92, 0x7a, 0xe5, 0x47, 0xdd, 0xda, 0xa3, 0x7d},
	}
)

Transcribed from the MIDL_INTERFACE attributes in WebView2.h. A single swapped nibble compiles fine and only shows up as a QueryInterface miss at runtime, so interfaces_windows_test.go re-parses each one from its canonical string form and compares.

View Source
var IIDIUnknown = windows.GUID{
	Data1: 0x00000000, Data2: 0x0000, Data3: 0x0000,
	Data4: [8]byte{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46},
}

IIDIUnknown is the identity every COM object must answer QueryInterface for.

Functions

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions orders two WebView2 version strings, returning -1, 0 or 1. It follows CompareBrowserVersions: compare dot-separated numbers left to right, with missing components treated as zero, so "150.0.4078" sorts before "150.0.4078.65".

Browser version strings may carry a channel suffix ("94.0.992.31 dev"). The suffix names a channel, not a rank, so it takes no part in the ordering.

func FindRuntime

func FindRuntime() (folder string, version string, err error)

FindRuntime locates the WebView2 runtime this process should use.

Order of precedence, which mirrors the official loader:

  1. WEBVIEW2_BROWSER_EXECUTABLE_FOLDER, if set. This is a pin, not a hint: if the folder has no usable runtime we fail instead of silently falling back to the installed one, because running a different browser build than the one that was pinned is worse than not running at all.
  2. The per-user Evergreen install (HKCU).
  3. The machine-wide Evergreen install (HKLM), 32-bit registry view first - EdgeUpdate is a 32-bit process and writes under WOW6432Node - then the 64-bit view for hosts that do not have one.

Every candidate is verified against the disk before it is accepted; the registry outlives uninstalls and half-finished updates.

func HandlerPanicHook added in v0.0.2

func HandlerPanicHook() func(event string, recovered any, stack []byte)

HandlerPanicHook returns the reporter currently installed, or nil if there is none and recovered panics are still going to stderr.

It exists for the host's wiring test. "A recovered handler panic reaches Config.Logger" is only true if the hook this package will actually call routes there, and the installed hook is otherwise unobservable from outside the package - a test that called the host's own reporter directly would keep passing with the SetHandlerPanicHook call deleted, which is exactly the state this hook spent its whole life in.

func NewNavigationCompletedHandler

func NewNavigationCompletedHandler(fn func(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs)) unsafe.Pointer

NewNavigationCompletedHandler wraps fn as an ICoreWebView2NavigationCompletedEventHandler.

func NewNavigationStartingHandler added in v0.0.2

func NewNavigationStartingHandler(fn func(sender *ICoreWebView2, args *ICoreWebView2NavigationStartingEventArgs)) unsafe.Pointer

NewNavigationStartingHandler wraps fn as an ICoreWebView2NavigationStartingEventHandler.

func NewNewWindowRequestedHandler added in v0.0.2

func NewNewWindowRequestedHandler(fn func(sender *ICoreWebView2, args *ICoreWebView2NewWindowRequestedEventArgs)) unsafe.Pointer

NewNewWindowRequestedHandler wraps fn as an ICoreWebView2NewWindowRequestedEventHandler.

func NewProcessFailedHandler

func NewProcessFailedHandler(fn func(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs)) unsafe.Pointer

NewProcessFailedHandler wraps fn as an ICoreWebView2ProcessFailedEventHandler.

func NewWebMessageReceivedHandler

func NewWebMessageReceivedHandler(fn func(sender *ICoreWebView2, args *ICoreWebView2WebMessageReceivedEventArgs)) unsafe.Pointer

NewWebMessageReceivedHandler wraps fn as an ICoreWebView2WebMessageReceivedEventHandler.

func NewWebResourceRequestedHandler

func NewWebResourceRequestedHandler(fn func(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs)) unsafe.Pointer

NewWebResourceRequestedHandler wraps fn as an ICoreWebView2WebResourceRequestedEventHandler.

This one is synchronous by contract: the response must be set on args before the callback returns, or the runtime proceeds without it. There is a deferral API for the async case, which this binding does not expose.

func ReleaseHandler

func ReleaseHandler(handler unsafe.Pointer)

ReleaseHandler drops the reference that a New*Handler constructor returned.

Call it exactly once, after the handler has been registered with its add_* method (or immediately, if registration failed). See the ownership note above.

func RuntimeClientPath

func RuntimeClientPath() (string, error)

RuntimeClientPath returns the full path of the runtime DLL that will be loaded. It exists for diagnostics: when the browser fails to start, the first question is always which binary was actually used.

func SetHandlerPanicHook

func SetHandlerPanicHook(hook func(event string, recovered any, stack []byte))

SetHandlerPanicHook installs the reporter for panics recovered inside an event handler.

Swallowing a panic silently would be worse than crashing: the window keeps running with a callback that never completed, and nothing says so. The host should route this into its logger. Set it before creating any handler; a nil hook falls back to a one-line note on stderr, because a lost panic is a bug that has to be visible somewhere.

Types

type BoundsMode

type BoundsMode int32

BoundsMode is COREWEBVIEW2_BOUNDS_MODE.

const (
	// BoundsModeUseRawPixels makes Bounds mean physical (device) pixels.
	//
	// This is the mode this host wants: it computes bounds from the window's
	// client rect, which is already in physical pixels, and manages DPI itself.
	// The alternative would have WebView2 rescale bounds by RasterizationScale
	// behind our back, which double-applies DPI.
	BoundsModeUseRawPixels BoundsMode = 0
	// BoundsModeUseRasterizationScale makes Bounds be interpreted in logical
	// pixels, scaled by RasterizationScale.
	BoundsModeUseRasterizationScale BoundsMode = 1
)

type Browser

type Browser struct {
	// Callbacks. Set them before Embed; they are registered during Embed and
	// must not change afterwards.
	MessageCallback              func(message string, source string, sender *ICoreWebView2)
	WebResourceRequestedCallback func(request *ICoreWebView2WebResourceRequest, args *ICoreWebView2WebResourceRequestedEventArgs)
	// NavigationStartingCallback fires when a top-level navigation begins.
	// navigationID is the runtime's identity for it; the matching completion
	// reports the same id, which is what lets the host attribute completions
	// to the navigation that caused them (decisions/0021). A redirect fires
	// this again with the same id and isRedirected set. Returning true cancels
	// the navigation - the runtime abandons it and the current document stays;
	// that is the navigation-cancel gate (decisions/0023).
	NavigationStartingCallback func(uri string, navigationID uint64, isUserInitiated bool, isRedirected bool) bool
	// NavigationCancelledCallback fires after a navigation the callback above
	// asked to cancel has actually been cancelled - put_Cancel returned success.
	// It is where a host commits to the cancel: remembering the id so the
	// resulting completion is not read as a load failure, and handing the target
	// somewhere else. Doing that work from the callback above instead would
	// commit to a cancel that may not have taken, which is issue #73: the
	// document loads anyway, the target opens twice, and the completion of a
	// navigation that succeeded is consumed as though it had been abandoned.
	// The split mirrors the PutHandled guard on NewWindowRequested
	// (decisions/0022), which has always worked this way.
	NavigationCancelledCallback func(uri string, navigationID uint64, isUserInitiated bool)
	NavigationCompletedCallback func(success bool, status WebErrorStatus, navigationID uint64)
	ProcessFailedCallback       func(kind ProcessFailedKind)
	// NewWindowRequestedCallback fires when content asks for a new window
	// (window.open, a target=_blank link). The runtime's default new window is
	// always suppressed first; the host decides what to do with the URI - a
	// single-window host routes it to the system browser (issue #6). isUserInitiated
	// counts host-API-driven opens as true too, as with navigation starting.
	NewWindowRequestedCallback func(uri string, isUserInitiated bool)
	ErrorCallback              func(err error)
	// WarningCallback receives conditions the browser tolerates by design - an
	// older runtime answering E_NOINTERFACE for an optional interface - as
	// opposed to ErrorCallback's real failures. Splitting the channels is what
	// lets the host keep its severity contract: ERROR is reserved for events
	// that need attention (issue #32).
	WarningCallback func(err error)

	// UserDataFolder is where WebView2 keeps its profile. Empty means "a folder
	// under the user's local app data, named after the executable".
	UserDataFolder string
	// AdditionalBrowserArguments is passed to the Chromium command line. This is
	// the main performance lever the runtime exposes.
	AdditionalBrowserArguments string
	// contains filtered or unexported fields
}

Browser is one WebView2 control embedded in a host window.

It owns the environment, the controller and the CoreWebView2 behind them, and it turns the six COM events the host cares about into plain Go callbacks.

A Browser is bound to the thread that called Embed: WebView2 requires a single-threaded apartment and delivers every event on that thread's message loop. The host already locks its OS thread and pumps the loop, so callbacks arrive there and may touch the window directly.

func New

func New() *Browser

New returns an unembedded Browser.

func (*Browser) AddWebResourceRequestedFilter

func (browser *Browser) AddWebResourceRequestedFilter(uri string, context WebResourceContext) error

AddWebResourceRequestedFilter subscribes the resource handler to a URI pattern. Without a filter the event never fires.

func (*Browser) Controller

func (browser *Browser) Controller() *ICoreWebView2Controller

Controller returns the underlying ICoreWebView2Controller, or nil before Embed.

func (*Browser) CoreWebView2

func (browser *Browser) CoreWebView2() *ICoreWebView2

CoreWebView2 returns the underlying ICoreWebView2, or nil before Embed.

func (*Browser) Embed

func (browser *Browser) Embed(parent uintptr) error

Embed creates the WebView2 environment and controller as children of parent.

It blocks: environment and controller creation are asynchronous COM operations whose completion handlers are delivered on the message loop, and the loader pumps the loop until they land. On a warm runtime this takes a few hundred milliseconds; on a cold one, longer.

func (*Browser) Environment

func (browser *Browser) Environment() *ICoreWebView2Environment

Environment returns the underlying ICoreWebView2Environment, or nil before Embed.

func (*Browser) Eval

func (browser *Browser) Eval(script string) error

Eval runs a script in the current document.

func (*Browser) Hide

func (browser *Browser) Hide() error

Hide makes the control invisible.

func (*Browser) Init

func (browser *Browser) Init(script string) error

Init registers a script to run in every document before any page script.

func (*Browser) IsShuttingDown

func (browser *Browser) IsShuttingDown() bool

IsShuttingDown reports whether ShuttingDown has run.

func (*Browser) Navigate

func (browser *Browser) Navigate(url string) error

Navigate loads a URL.

func (*Browser) NotifyParentWindowPositionChanged

func (browser *Browser) NotifyParentWindowPositionChanged() error

NotifyParentWindowPositionChanged tells the control its host moved. Without it, anything the control positions in screen coordinates - the caret, an autofill popup - stays where the window used to be.

func (*Browser) SetBackgroundColour

func (browser *Browser) SetBackgroundColour(r, g, b, a uint8) error

SetBackgroundColour paints behind the page. It is what the user sees between the window appearing and the first frame being rendered, and during a resize.

func (*Browser) SetRasterizationScale

func (browser *Browser) SetRasterizationScale(scale float64) error

SetRasterizationScale updates the scale WebView2 rasterizes content at - the devicePixelRatio the frontend renders against.

applyBoundsPolicy turns the runtime's own monitor-scale detection off, so the runtime never revises this scale on its own. After the host moves the window to a monitor with a different DPI it must set the new scale here, or the content keeps rendering at the scale of the monitor the controller was created on - too large on a lower-DPI monitor, too small on a higher one. The matching bounds are fed separately, in raw pixels, by the host's own DPI handling; the two do not compound because only the host drives either.

The scale lives on ICoreWebView2Controller3. An older runtime without it is a warning to the caller, not a crash, exactly as in applyBoundsPolicy.

func (*Browser) Settings

func (browser *Browser) Settings() (*ICoreWebView2Settings, error)

Settings returns the base settings object. The pointer carries a reference the caller owns and must Release once it is done configuring.

func (*Browser) Show

func (browser *Browser) Show() error

Show makes the control visible.

Showing the host window is not enough: the controller has its own visibility, and a controller left invisible renders nothing into a perfectly visible window.

func (*Browser) ShuttingDown

func (browser *Browser) ShuttingDown()

ShuttingDown closes the controller and drops the browser's references.

It is called from the window procedure while the HWND is still alive: closing the controller after its parent window is gone leaves the runtime's own child windows orphaned, and the teardown reports failures nobody can act on.

type Color

type Color struct {
	A byte
	R byte
	G byte
	B byte
}

Color is COREWEBVIEW2_COLOR.

Field order is A,R,G,B - NOT R,G,B,A. This is a real trap: the struct is declared `{ BYTE A; BYTE R; BYTE G; BYTE B; }` in WebView2.idl, so a binding that reorders the fields compiles fine and silently renders the wrong colour (and, worse, the wrong alpha - swapping A and B turns an opaque background transparent).

type ComProc

type ComProc uintptr

ComProc is one slot of a COM vtable: the address of a method whose first argument is the `this` pointer.

func (ComProc) Call

func (p ComProc) Call(args ...uintptr) (uintptr, uintptr, error)

Call invokes the method. The first return value is the HRESULT; feed it to hres. The error return only reports a failure of the syscall machinery itself and is nil in practice - it is not the COM status.

The //go:uintptrescapes directive is load-bearing, not decoration. Callers write `p.Call(uintptr(unsafe.Pointer(&out)))` to receive out-parameters. Go may grow (and therefore move) a goroutine stack at any call boundary, which would leave COM writing its result into an address that no longer belongs to `out`. The directive forces every pointer converted to uintptr at this call site onto the heap, where it cannot move, for the duration of the call. This is exactly why syscall.Proc.Call carries the same directive.

type Environment

type Environment struct {
	// contains filtered or unexported fields
}

Environment is a live ICoreWebView2Environment.

It deliberately holds nothing but the COM pointer: the interface's methods are declared elsewhere (interfaces_environment_windows.go), and duplicating them here would mean two vtable layouts to keep in step with each other.

func CreateEnvironment

func CreateEnvironment(userDataFolder string, additionalBrowserArgs string) (*Environment, error)

CreateEnvironment creates a WebView2 environment for the runtime installed on this machine.

The call is synchronous even though the underlying API is not: WebView2 delivers the result to a completion handler on the calling thread's message queue, so this pumps messages until the handler fires. That means it must be called on a thread with a message queue and an initialised STA apartment - the same thread that will own the window.

func CreateEnvironmentWithOptions

func CreateEnvironmentWithOptions(opts Options) (*Environment, error)

CreateEnvironmentWithOptions is CreateEnvironment with the full option set.

func (*Environment) CreateController

func (e *Environment) CreateController(parent windows.Handle) (*IUnknown, error)

CreateController creates the ICoreWebView2Controller that hosts the browser inside parent, and returns it as a raw interface pointer for the interface bindings to wrap. The caller owns a reference and must Release it.

Like CreateEnvironment, this pumps messages until the completion handler fires, and must run on the window's own thread.

func (*Environment) Interface

func (e *Environment) Interface() *ICoreWebView2Environment

Interface exposes the environment as its typed COM interface.

func (*Environment) Release

func (e *Environment) Release()

Release drops the reference taken when the environment was created.

func (*Environment) Unknown

func (e *Environment) Unknown() *IUnknown

Unknown exposes the raw ICoreWebView2Environment pointer.

type EventRegistrationToken

type EventRegistrationToken int64

EventRegistrationToken is the token an add_* method writes back. The C type is a struct wrapping a single __int64; an 8-byte scalar is layout-identical and is always passed by pointer, so nothing is lost by flattening it.

type HResultError

type HResultError uint32

HResultError is a failed COM status code.

func (HResultError) Error

func (e HResultError) Error() string

func (HResultError) HResult

func (e HResultError) HResult() uint32

HResult returns the raw status code, so callers can branch on a specific failure (E_NOINTERFACE from an older runtime, say) instead of on text.

type ICoreWebView2

type ICoreWebView2 struct {
	Vtbl *ICoreWebView2Vtbl
}

func (*ICoreWebView2) AddNavigationCompleted

func (w *ICoreWebView2) AddNavigationCompleted(handler unsafe.Pointer) (EventRegistrationToken, error)

func (*ICoreWebView2) AddNavigationStarting added in v0.0.2

func (w *ICoreWebView2) AddNavigationStarting(handler unsafe.Pointer) (EventRegistrationToken, error)

func (*ICoreWebView2) AddNewWindowRequested added in v0.0.2

func (w *ICoreWebView2) AddNewWindowRequested(handler unsafe.Pointer) (EventRegistrationToken, error)

AddNewWindowRequested registers a handler for a new-window request (window.open, a target=_blank link). See the ownership note on the handler constructors in handlers_windows.go.

func (*ICoreWebView2) AddProcessFailed

func (w *ICoreWebView2) AddProcessFailed(handler unsafe.Pointer) (EventRegistrationToken, error)

func (*ICoreWebView2) AddScriptToExecuteOnDocumentCreated

func (w *ICoreWebView2) AddScriptToExecuteOnDocumentCreated(script string, handler unsafe.Pointer) error

AddScriptToExecuteOnDocumentCreated queues a script to run before any page script on every future navigation. It only affects navigations that start after it is registered, so it has to be called before the first Navigate.

handler receives the script id and may be nil - see the note on ExecuteScript.

func (*ICoreWebView2) AddWebMessageReceived

func (w *ICoreWebView2) AddWebMessageReceived(handler unsafe.Pointer) (EventRegistrationToken, error)

func (*ICoreWebView2) AddWebResourceRequested

func (w *ICoreWebView2) AddWebResourceRequested(handler unsafe.Pointer) (EventRegistrationToken, error)

func (*ICoreWebView2) AddWebResourceRequestedFilter

func (w *ICoreWebView2) AddWebResourceRequestedFilter(uri string, context WebResourceContext) error

AddWebResourceRequestedFilter narrows which requests raise WebResourceRequested. Without at least one filter the event never fires, so this is not optional decoration: it is what turns the handler on.

func (*ICoreWebView2) ExecuteScript

func (w *ICoreWebView2) ExecuteScript(script string, handler unsafe.Pointer) error

ExecuteScript runs script in the current document.

handler is the completion callback that receives the script's JSON result.

UNVERIFIED: passing nil for handler. WebView2.idl annotates the parameter plainly as `[in] ICoreWebView2ExecuteScriptCompletedHandler* handler`, with no [optional] and no unique, and Microsoft's reference never states that NULL is accepted. It is widely done and appears to work, but it is not a documented contract, so this binding does not rely on it: pass a handler when you need the result, and treat a nil handler as "best effort, unsupported by the docs".

func (*ICoreWebView2) GetSettings

func (w *ICoreWebView2) GetSettings() (*ICoreWebView2Settings, error)

GetSettings returns the base settings interface. The pointer is a new reference; the caller must Release it. Settings3/5/9 are reached by QueryInterface from here.

func (*ICoreWebView2) Navigate

func (w *ICoreWebView2) Navigate(uri string) error

func (*ICoreWebView2) PostWebMessageAsString

func (w *ICoreWebView2) PostWebMessageAsString(message string) error

PostWebMessageAsString delivers message to the page as a string, surfacing on window.chrome.webview's message event with .data set to the string.

type ICoreWebView2Controller

type ICoreWebView2Controller struct {
	Vtbl *ICoreWebView2ControllerVtbl
}

func (*ICoreWebView2Controller) Close

func (c *ICoreWebView2Controller) Close() error

func (*ICoreWebView2Controller) GetBounds

func (c *ICoreWebView2Controller) GetBounds() (Rect, error)

func (*ICoreWebView2Controller) GetCoreWebView2

func (c *ICoreWebView2Controller) GetCoreWebView2() (*ICoreWebView2, error)

GetCoreWebView2 returns a new reference; the caller must Release it.

func (*ICoreWebView2Controller) NotifyParentWindowPositionChanged

func (c *ICoreWebView2Controller) NotifyParentWindowPositionChanged() error

NotifyParentWindowPositionChanged keeps WebView2's idea of where it is on screen in sync. Without it the control renders in the right place but places popups, IME candidate windows and the on-screen keyboard against a stale origin.

func (*ICoreWebView2Controller) PutBounds

func (c *ICoreWebView2Controller) PutBounds(bounds Rect) error

PutBounds sets the WebView rect.

ABI: the C signature is `put_Bounds(RECT bounds)` - by value - but RECT is 16 bytes, and Win64 passes any aggregate that is not 1/2/4/8 bytes as a pointer to caller-allocated memory. So the argument really is &bounds. Passing the struct's contents inline instead would put Left/Top in the register the callee reads as a RECT*, i.e. dereference 0x00000000_00000000 or worse.

func (*ICoreWebView2Controller) PutIsVisible

func (c *ICoreWebView2Controller) PutIsVisible(visible bool) error

func (*ICoreWebView2Controller) QueryController2

func (c *ICoreWebView2Controller) QueryController2() (*ICoreWebView2Controller2, error)

QueryController2 asks for ICoreWebView2Controller2, where the default background colour lives. The caller must Release the result: QueryInterface AddRefs.

func (*ICoreWebView2Controller) QueryController3

func (c *ICoreWebView2Controller) QueryController3() (*ICoreWebView2Controller3, error)

QueryController3 asks for ICoreWebView2Controller3, where the bounds mode and the monitor-scale policy live.

type ICoreWebView2Controller2

type ICoreWebView2Controller2 struct {
	Vtbl *ICoreWebView2Controller2Vtbl
}

func (*ICoreWebView2Controller2) PutDefaultBackgroundColor

func (c *ICoreWebView2Controller2) PutDefaultBackgroundColor(color Color) error

PutDefaultBackgroundColor sets the colour painted behind the document, i.e. what is on screen between controller creation and first paint.

ABI: COREWEBVIEW2_COLOR is 4 bytes, so unlike RECT it goes by VALUE, packed into one register. See Color.pack.

func (*ICoreWebView2Controller2) Release

func (c *ICoreWebView2Controller2) Release()

Release drops a reference obtained from QueryInterface.

type ICoreWebView2Controller2Vtbl

type ICoreWebView2Controller2Vtbl struct {
	ICoreWebView2ControllerVtbl
	GetDefaultBackgroundColor ComProc
	PutDefaultBackgroundColor ComProc
}

type ICoreWebView2Controller3

type ICoreWebView2Controller3 struct {
	Vtbl *ICoreWebView2Controller3Vtbl
}

func (*ICoreWebView2Controller3) PutBoundsMode

func (c *ICoreWebView2Controller3) PutBoundsMode(mode BoundsMode) error

PutBoundsMode pairs with PutShouldDetectMonitorScaleChanges(false): BoundsModeUseRawPixels tells WebView2 that the rect it is given is already in physical pixels.

func (*ICoreWebView2Controller3) PutRasterizationScale

func (c *ICoreWebView2Controller3) PutRasterizationScale(scale float64) error

PutRasterizationScale sets the scale WebView2 rasterizes at.

ABI: `double` is the second argument, so the callee reads it from XMM1, not RDX. That works here only because Go's syscall bridge mirrors the first four integer-register arguments into X0-X3 for exactly this case (see the package comment). math.Float64bits reinterprets the bits without converting them - uintptr(scale) would truncate 1.5 to 1.

func (*ICoreWebView2Controller3) PutShouldDetectMonitorScaleChanges

func (c *ICoreWebView2Controller3) PutShouldDetectMonitorScaleChanges(detect bool) error

PutShouldDetectMonitorScaleChanges must be FALSE for this host: it owns DPI handling and feeds WebView2 raw pixels. Left TRUE, WebView2 would also react to monitor scale changes and re-scale on top of what the host already did.

func (*ICoreWebView2Controller3) Release

func (c *ICoreWebView2Controller3) Release()

Release drops a reference obtained from QueryInterface.

type ICoreWebView2Controller3Vtbl

type ICoreWebView2Controller3Vtbl struct {
	ICoreWebView2Controller2Vtbl
	GetRasterizationScale              ComProc
	PutRasterizationScale              ComProc
	GetShouldDetectMonitorScaleChanges ComProc
	PutShouldDetectMonitorScaleChanges ComProc
	AddRasterizationScaleChanged       ComProc
	RemoveRasterizationScaleChanged    ComProc
	GetBoundsMode                      ComProc
	PutBoundsMode                      ComProc
}

type ICoreWebView2ControllerVtbl

type ICoreWebView2ControllerVtbl struct {
	IUnknownVtbl
	GetIsVisible                      ComProc
	PutIsVisible                      ComProc
	GetBounds                         ComProc
	PutBounds                         ComProc
	GetZoomFactor                     ComProc
	PutZoomFactor                     ComProc
	AddZoomFactorChanged              ComProc
	RemoveZoomFactorChanged           ComProc
	SetBoundsAndZoomFactor            ComProc
	MoveFocus                         ComProc
	AddMoveFocusRequested             ComProc
	RemoveMoveFocusRequested          ComProc
	AddGotFocus                       ComProc
	RemoveGotFocus                    ComProc
	AddLostFocus                      ComProc
	RemoveLostFocus                   ComProc
	AddAcceleratorKeyPressed          ComProc
	RemoveAcceleratorKeyPressed       ComProc
	GetParentWindow                   ComProc
	PutParentWindow                   ComProc
	NotifyParentWindowPositionChanged ComProc
	Close                             ComProc
	GetCoreWebView2                   ComProc
}

type ICoreWebView2Environment

type ICoreWebView2Environment struct {
	Vtbl *ICoreWebView2EnvironmentVtbl
}

func (*ICoreWebView2Environment) CreateWebResourceResponse

func (e *ICoreWebView2Environment) CreateWebResourceResponse(content *IStream, statusCode int32, reasonPhrase, headers string) (*ICoreWebView2WebResourceResponse, error)

CreateWebResourceResponse builds the response handed back to a WebResourceRequested event.

content may be nil, which is how a bodyless response (204, or an error page with no payload) is expressed. Ownership: the returned response is a new reference and the caller must Release it; the runtime AddRefs content itself, but the caller still owns its own reference to the stream.

type ICoreWebView2EnvironmentVtbl

type ICoreWebView2EnvironmentVtbl struct {
	IUnknownVtbl
	CreateCoreWebView2Controller     ComProc
	CreateWebResourceResponse        ComProc
	GetBrowserVersionString          ComProc
	AddNewBrowserVersionAvailable    ComProc
	RemoveNewBrowserVersionAvailable ComProc
}

type ICoreWebView2NavigationCompletedEventArgs

type ICoreWebView2NavigationCompletedEventArgs struct {
	Vtbl *ICoreWebView2NavigationCompletedEventArgsVtbl
}

func (*ICoreWebView2NavigationCompletedEventArgs) GetIsSuccess

func (*ICoreWebView2NavigationCompletedEventArgs) GetNavigationID added in v0.0.2

func (a *ICoreWebView2NavigationCompletedEventArgs) GetNavigationID() (uint64, error)

GetNavigationID is the identity the matching NavigationStarting reported; see ICoreWebView2NavigationStartingEventArgs.GetNavigationID.

func (*ICoreWebView2NavigationCompletedEventArgs) GetWebErrorStatus

type ICoreWebView2NavigationCompletedEventArgsVtbl

type ICoreWebView2NavigationCompletedEventArgsVtbl struct {
	IUnknownVtbl
	GetIsSuccess      ComProc
	GetWebErrorStatus ComProc
	GetNavigationID   ComProc
}

type ICoreWebView2NavigationStartingEventArgs added in v0.0.2

type ICoreWebView2NavigationStartingEventArgs struct {
	Vtbl *ICoreWebView2NavigationStartingEventArgsVtbl
}

func (*ICoreWebView2NavigationStartingEventArgs) GetIsRedirected added in v0.0.2

func (a *ICoreWebView2NavigationStartingEventArgs) GetIsRedirected() (bool, error)

GetIsRedirected reports whether this start is an HTTP redirect of an earlier navigation. A redirect keeps its navigation id, so a correlating caller sees the same id start more than once.

func (*ICoreWebView2NavigationStartingEventArgs) GetIsUserInitiated added in v0.0.2

func (a *ICoreWebView2NavigationStartingEventArgs) GetIsUserInitiated() (bool, error)

GetIsUserInitiated reports whether the navigation came from a user gesture. The runtime counts navigations issued through WebView2 APIs - the host's own Navigate calls - as user initiated too.

func (*ICoreWebView2NavigationStartingEventArgs) GetNavigationID added in v0.0.2

func (a *ICoreWebView2NavigationStartingEventArgs) GetNavigationID() (uint64, error)

GetNavigationID is the runtime-assigned identity of this navigation. The matching completion reports the same id, which is the only channel that ties a NavigationCompleted to the Navigate that caused it.

func (*ICoreWebView2NavigationStartingEventArgs) GetUri added in v0.0.2

GetUri is the URI of the requested navigation, before it commits.

func (*ICoreWebView2NavigationStartingEventArgs) PutCancel added in v0.0.2

PutCancel cancels the navigation when set to true (vtable slot 8). The navigation-cancel gate (issue #6, decisions/0023) uses it to refuse a top-level navigation away from the trusted origin: the runtime abandons the navigation and the current document stays.

type ICoreWebView2NavigationStartingEventArgsVtbl added in v0.0.2

type ICoreWebView2NavigationStartingEventArgsVtbl struct {
	IUnknownVtbl
	GetUri             ComProc
	GetIsUserInitiated ComProc
	GetIsRedirected    ComProc
	GetRequestHeaders  ComProc
	GetCancel          ComProc
	PutCancel          ComProc
	GetNavigationID    ComProc
}

type ICoreWebView2NewWindowRequestedEventArgs added in v0.0.2

type ICoreWebView2NewWindowRequestedEventArgs struct {
	Vtbl *ICoreWebView2NewWindowRequestedEventArgsVtbl
}

func (*ICoreWebView2NewWindowRequestedEventArgs) GetIsUserInitiated added in v0.0.2

func (a *ICoreWebView2NewWindowRequestedEventArgs) GetIsUserInitiated() (bool, error)

GetIsUserInitiated reports whether a user gesture (a click) triggered the new window, as opposed to a bare scripted window.open. The host issues no window.open of its own, so - unlike the navigation-starting flag, which the host's own Navigate also sets - this one is not confounded by host activity; whether the runtime reports it reliably here is unverified until the live probe. It is currently read for the diagnostic line only (decisions/0022).

func (*ICoreWebView2NewWindowRequestedEventArgs) GetUri added in v0.0.2

GetUri is the URI the content asked to open in a new window.

func (*ICoreWebView2NewWindowRequestedEventArgs) PutHandled added in v0.0.2

func (a *ICoreWebView2NewWindowRequestedEventArgs) PutHandled(handled bool) error

PutHandled tells the runtime the host has taken responsibility for the new window. Set true to suppress the runtime's default, which would otherwise create a detached CoreWebView2 with no host chrome - meaningless for a single-window frameless host.

type ICoreWebView2NewWindowRequestedEventArgsVtbl added in v0.0.2

type ICoreWebView2NewWindowRequestedEventArgsVtbl struct {
	IUnknownVtbl
	GetUri             ComProc
	PutNewWindow       ComProc
	GetNewWindow       ComProc
	PutHandled         ComProc
	GetHandled         ComProc
	GetIsUserInitiated ComProc
	GetDeferral        ComProc
	GetWindowFeatures  ComProc
}

type ICoreWebView2ProcessFailedEventArgs

type ICoreWebView2ProcessFailedEventArgs struct {
	Vtbl *ICoreWebView2ProcessFailedEventArgsVtbl
}

func (*ICoreWebView2ProcessFailedEventArgs) GetProcessFailedKind

func (a *ICoreWebView2ProcessFailedEventArgs) GetProcessFailedKind() (ProcessFailedKind, error)

type ICoreWebView2ProcessFailedEventArgsVtbl

type ICoreWebView2ProcessFailedEventArgsVtbl struct {
	IUnknownVtbl
	GetProcessFailedKind ComProc
}

type ICoreWebView2Settings

type ICoreWebView2Settings struct {
	Vtbl *ICoreWebView2SettingsVtbl
}

func (*ICoreWebView2Settings) PutAreDefaultContextMenusEnabled

func (s *ICoreWebView2Settings) PutAreDefaultContextMenusEnabled(enabled bool) error

func (*ICoreWebView2Settings) PutAreDevToolsEnabled

func (s *ICoreWebView2Settings) PutAreDevToolsEnabled(enabled bool) error

func (*ICoreWebView2Settings) PutIsStatusBarEnabled

func (s *ICoreWebView2Settings) PutIsStatusBarEnabled(enabled bool) error

func (*ICoreWebView2Settings) PutIsZoomControlEnabled

func (s *ICoreWebView2Settings) PutIsZoomControlEnabled(enabled bool) error

func (*ICoreWebView2Settings) QuerySettings3

func (s *ICoreWebView2Settings) QuerySettings3() (*ICoreWebView2Settings3, error)

QuerySettings3 asks for ICoreWebView2Settings3, where the browser accelerator keys live.

func (*ICoreWebView2Settings) QuerySettings5

func (s *ICoreWebView2Settings) QuerySettings5() (*ICoreWebView2Settings5, error)

QuerySettings5 asks for ICoreWebView2Settings5, where pinch zoom lives.

func (*ICoreWebView2Settings) QuerySettings9

func (s *ICoreWebView2Settings) QuerySettings9() (*ICoreWebView2Settings9, error)

QuerySettings9 asks for ICoreWebView2Settings9, where non-client region support lives. A runtime older than 131.0.2903.40 does not implement it, and this is the supported way to tell the difference.

func (*ICoreWebView2Settings) Release added in v0.0.2

func (s *ICoreWebView2Settings) Release()

Release drops the reference GetSettings returned. Unlike its Query* siblings below, the base settings object comes from ICoreWebView2.GetSettings rather than QueryInterface, but the ownership is the same: the getter AddRefs on the way out, so every call pairs with exactly one Release.

type ICoreWebView2Settings2Vtbl

type ICoreWebView2Settings2Vtbl struct {
	ICoreWebView2SettingsVtbl
	GetUserAgent ComProc
	PutUserAgent ComProc
}

type ICoreWebView2Settings3

type ICoreWebView2Settings3 struct {
	Vtbl *ICoreWebView2Settings3Vtbl
}

func (*ICoreWebView2Settings3) PutAreBrowserAcceleratorKeysEnabled

func (s *ICoreWebView2Settings3) PutAreBrowserAcceleratorKeysEnabled(enabled bool) error

func (*ICoreWebView2Settings3) Release

func (s *ICoreWebView2Settings3) Release()

Release drops a reference obtained from QueryInterface.

type ICoreWebView2Settings3Vtbl

type ICoreWebView2Settings3Vtbl struct {
	ICoreWebView2Settings2Vtbl
	GetAreBrowserAcceleratorKeysEnabled ComProc
	PutAreBrowserAcceleratorKeysEnabled ComProc
}

type ICoreWebView2Settings4Vtbl

type ICoreWebView2Settings4Vtbl struct {
	ICoreWebView2Settings3Vtbl
	GetIsPasswordAutosaveEnabled ComProc
	PutIsPasswordAutosaveEnabled ComProc
	GetIsGeneralAutofillEnabled  ComProc
	PutIsGeneralAutofillEnabled  ComProc
}

type ICoreWebView2Settings5

type ICoreWebView2Settings5 struct {
	Vtbl *ICoreWebView2Settings5Vtbl
}

func (*ICoreWebView2Settings5) PutIsPinchZoomEnabled

func (s *ICoreWebView2Settings5) PutIsPinchZoomEnabled(enabled bool) error

func (*ICoreWebView2Settings5) Release

func (s *ICoreWebView2Settings5) Release()

Release drops a reference obtained from QueryInterface.

type ICoreWebView2Settings5Vtbl

type ICoreWebView2Settings5Vtbl struct {
	ICoreWebView2Settings4Vtbl
	GetIsPinchZoomEnabled ComProc
	PutIsPinchZoomEnabled ComProc
}

type ICoreWebView2Settings6Vtbl

type ICoreWebView2Settings6Vtbl struct {
	ICoreWebView2Settings5Vtbl
	GetIsSwipeNavigationEnabled ComProc
	PutIsSwipeNavigationEnabled ComProc
}

type ICoreWebView2Settings7Vtbl

type ICoreWebView2Settings7Vtbl struct {
	ICoreWebView2Settings6Vtbl
	GetHiddenPdfToolbarItems ComProc
	PutHiddenPdfToolbarItems ComProc
}

type ICoreWebView2Settings8Vtbl

type ICoreWebView2Settings8Vtbl struct {
	ICoreWebView2Settings7Vtbl
	GetIsReputationCheckingRequired ComProc
	PutIsReputationCheckingRequired ComProc
}

type ICoreWebView2Settings9

type ICoreWebView2Settings9 struct {
	Vtbl *ICoreWebView2Settings9Vtbl
}

func (*ICoreWebView2Settings9) PutIsNonClientRegionSupportEnabled

func (s *ICoreWebView2Settings9) PutIsNonClientRegionSupportEnabled(enabled bool) error

PutIsNonClientRegionSupportEnabled turns on the app-region CSS style, which is the precondition for an HTML title bar that Windows treats as a real caption. Defaults to FALSE, and takes effect on the next navigation.

Requires runtime 1.0.2420.47+; on anything older the QueryInterface for IIDICoreWebView2Settings9 fails and the caller should fall back to a native title bar.

func (*ICoreWebView2Settings9) Release

func (s *ICoreWebView2Settings9) Release()

Release drops a reference obtained from QueryInterface.

type ICoreWebView2Settings9Vtbl

type ICoreWebView2Settings9Vtbl struct {
	ICoreWebView2Settings8Vtbl
	GetIsNonClientRegionSupportEnabled ComProc
	PutIsNonClientRegionSupportEnabled ComProc
}

type ICoreWebView2SettingsVtbl

type ICoreWebView2SettingsVtbl struct {
	IUnknownVtbl
	GetIsScriptEnabled                ComProc
	PutIsScriptEnabled                ComProc
	GetIsWebMessageEnabled            ComProc
	PutIsWebMessageEnabled            ComProc
	GetAreDefaultScriptDialogsEnabled ComProc
	PutAreDefaultScriptDialogsEnabled ComProc
	GetIsStatusBarEnabled             ComProc
	PutIsStatusBarEnabled             ComProc
	GetAreDevToolsEnabled             ComProc
	PutAreDevToolsEnabled             ComProc
	GetAreDefaultContextMenusEnabled  ComProc
	PutAreDefaultContextMenusEnabled  ComProc
	GetAreHostObjectsAllowed          ComProc
	PutAreHostObjectsAllowed          ComProc
	GetIsZoomControlEnabled           ComProc
	PutIsZoomControlEnabled           ComProc
	GetIsBuiltInErrorPageEnabled      ComProc
	PutIsBuiltInErrorPageEnabled      ComProc
}

type ICoreWebView2Vtbl

type ICoreWebView2Vtbl struct {
	IUnknownVtbl
	GetSettings                            ComProc
	GetSource                              ComProc
	Navigate                               ComProc
	NavigateToString                       ComProc
	AddNavigationStarting                  ComProc
	RemoveNavigationStarting               ComProc
	AddContentLoading                      ComProc
	RemoveContentLoading                   ComProc
	AddSourceChanged                       ComProc
	RemoveSourceChanged                    ComProc
	AddHistoryChanged                      ComProc
	RemoveHistoryChanged                   ComProc
	AddNavigationCompleted                 ComProc
	RemoveNavigationCompleted              ComProc
	AddFrameNavigationStarting             ComProc
	RemoveFrameNavigationStarting          ComProc
	AddFrameNavigationCompleted            ComProc
	RemoveFrameNavigationCompleted         ComProc
	AddScriptDialogOpening                 ComProc
	RemoveScriptDialogOpening              ComProc
	AddPermissionRequested                 ComProc
	RemovePermissionRequested              ComProc
	AddProcessFailed                       ComProc
	RemoveProcessFailed                    ComProc
	AddScriptToExecuteOnDocumentCreated    ComProc
	RemoveScriptToExecuteOnDocumentCreated ComProc
	ExecuteScript                          ComProc
	CapturePreview                         ComProc
	Reload                                 ComProc
	PostWebMessageAsJson                   ComProc
	PostWebMessageAsString                 ComProc
	AddWebMessageReceived                  ComProc
	RemoveWebMessageReceived               ComProc
	CallDevToolsProtocolMethod             ComProc
	GetBrowserProcessId                    ComProc
	GetCanGoBack                           ComProc
	GetCanGoForward                        ComProc
	GoBack                                 ComProc
	GoForward                              ComProc
	GetDevToolsProtocolEventReceiver       ComProc
	Stop                                   ComProc
	AddNewWindowRequested                  ComProc
	RemoveNewWindowRequested               ComProc
	AddDocumentTitleChanged                ComProc
	RemoveDocumentTitleChanged             ComProc
	GetDocumentTitle                       ComProc
	AddHostObjectToScript                  ComProc
	RemoveHostObjectFromScript             ComProc
	OpenDevToolsWindow                     ComProc
	AddContainsFullScreenElementChanged    ComProc
	RemoveContainsFullScreenElementChanged ComProc
	GetContainsFullScreenElement           ComProc
	AddWebResourceRequested                ComProc
	RemoveWebResourceRequested             ComProc
	AddWebResourceRequestedFilter          ComProc
	RemoveWebResourceRequestedFilter       ComProc
	AddWindowCloseRequested                ComProc
	RemoveWindowCloseRequested             ComProc
}

type ICoreWebView2WebMessageReceivedEventArgs

type ICoreWebView2WebMessageReceivedEventArgs struct {
	Vtbl *ICoreWebView2WebMessageReceivedEventArgsVtbl
}

func (*ICoreWebView2WebMessageReceivedEventArgs) GetSource

GetSource is the URI of the document that posted the message. Worth checking before trusting a message: it is the only thing distinguishing the app's own page from an iframe.

func (*ICoreWebView2WebMessageReceivedEventArgs) TryGetWebMessageAsString

func (a *ICoreWebView2WebMessageReceivedEventArgs) TryGetWebMessageAsString() (string, error)

TryGetWebMessageAsString fails with E_INVALIDARG when the page posted a non-string (postMessage of an object). That is a normal outcome, not a bug - callers that accept both shapes need the JSON form, which this binding does not wrap - only its vtable slot is declared, to hold the offset.

type ICoreWebView2WebMessageReceivedEventArgsVtbl

type ICoreWebView2WebMessageReceivedEventArgsVtbl struct {
	IUnknownVtbl
	GetSource                ComProc
	GetWebMessageAsJson      ComProc
	TryGetWebMessageAsString ComProc
}

type ICoreWebView2WebResourceRequest

type ICoreWebView2WebResourceRequest struct {
	Vtbl *ICoreWebView2WebResourceRequestVtbl
}

func (*ICoreWebView2WebResourceRequest) GetMethod

func (r *ICoreWebView2WebResourceRequest) GetMethod() (string, error)

func (*ICoreWebView2WebResourceRequest) GetUri

type ICoreWebView2WebResourceRequestVtbl

type ICoreWebView2WebResourceRequestVtbl struct {
	IUnknownVtbl
	GetUri     ComProc
	PutUri     ComProc
	GetMethod  ComProc
	PutMethod  ComProc
	GetContent ComProc
	PutContent ComProc
	GetHeaders ComProc
}

type ICoreWebView2WebResourceRequestedEventArgs

type ICoreWebView2WebResourceRequestedEventArgs struct {
	Vtbl *ICoreWebView2WebResourceRequestedEventArgsVtbl
}

func (*ICoreWebView2WebResourceRequestedEventArgs) GetRequest

GetRequest returns a new reference; the caller must Release it.

func (*ICoreWebView2WebResourceRequestedEventArgs) PutResponse

PutResponse hands the response back to the runtime. The runtime AddRefs it, but the caller still owns the reference it got from CreateWebResourceResponse and must Release that one.

type ICoreWebView2WebResourceRequestedEventArgsVtbl

type ICoreWebView2WebResourceRequestedEventArgsVtbl struct {
	IUnknownVtbl
	GetRequest         ComProc
	GetResponse        ComProc
	PutResponse        ComProc
	GetDeferral        ComProc
	GetResourceContext ComProc
}

type ICoreWebView2WebResourceResponse

type ICoreWebView2WebResourceResponse struct {
	Vtbl *ICoreWebView2WebResourceResponseVtbl
}

func (*ICoreWebView2WebResourceResponse) PutContent

func (r *ICoreWebView2WebResourceResponse) PutContent(content *IStream) error

PutContent attaches the body. The runtime takes its own reference on the stream, but the caller must keep its reference alive until the response has been consumed, then Release both.

func (*ICoreWebView2WebResourceResponse) Release

func (r *ICoreWebView2WebResourceResponse) Release()

type ICoreWebView2WebResourceResponseVtbl

type ICoreWebView2WebResourceResponseVtbl struct {
	IUnknownVtbl
	GetContent      ComProc
	PutContent      ComProc
	GetHeaders      ComProc
	GetStatusCode   ComProc
	PutStatusCode   ComProc
	GetReasonPhrase ComProc
	PutReasonPhrase ComProc
}

type ISequentialStreamVtbl

type ISequentialStreamVtbl struct {
	IUnknownVtbl
	Read  ComProc
	Write ComProc
}

type IStream

type IStream struct {
	Vtbl *IStreamVtbl
}

func NewMemoryStream

func NewMemoryStream(content []byte) (*IStream, error)

NewMemoryStream copies content into a COM memory stream.

The bytes have to be copied because the response outlives the call that produced it: the runtime reads the body asynchronously, long after the WebResourceRequested handler has returned. A stream over a Go slice would be a promise the garbage collector does not keep.

func (*IStream) Release

func (s *IStream) Release()

type IStreamVtbl

type IStreamVtbl struct {
	ISequentialStreamVtbl
	Seek         ComProc
	SetSize      ComProc
	CopyTo       ComProc
	Commit       ComProc
	Revert       ComProc
	LockRegion   ComProc
	UnlockRegion ComProc
	Stat         ComProc
	Clone        ComProc
}

type IUnknown

type IUnknown struct {
	Vtbl *IUnknownVtbl
}

IUnknown is a COM interface pointer: one machine word pointing at a vtable. It is the base for every WebView2 interface. Pointers of this type address memory owned by the WebView2 runtime, not the Go heap.

func (*IUnknown) AddRef

func (u *IUnknown) AddRef() uint32

AddRef takes a reference and returns the new count.

func (*IUnknown) QueryInterface

func (u *IUnknown) QueryInterface(iid *windows.GUID) (unsafe.Pointer, error)

QueryInterface asks the object for another of its interfaces. The returned pointer carries a reference the caller owns and must Release.

It is returned as unsafe.Pointer rather than *IUnknown because the caller knows the concrete interface and will reinterpret it; every WebView2 interface begins with the IUnknown vtable, so the cast is layout-safe.

func (*IUnknown) Release

func (u *IUnknown) Release() uint32

Release drops a reference and returns the remaining count. Releasing more than you own frees the object under the runtime's feet, so pair every AddRef, QueryInterface and out-parameter with exactly one Release.

type IUnknownVtbl

type IUnknownVtbl struct {
	QueryInterface ComProc
	AddRef         ComProc
	Release        ComProc
}

IUnknownVtbl is the head of every COM vtable. Any richer interface embeds it first, in declaration order, so that the method offsets line up with the ABI.

type Options

type Options struct {
	// UserDataFolder is where the browser keeps its profile. Leave empty to let
	// the runtime pick its default (a folder beside the executable), which
	// fails for an executable installed under Program Files.
	UserDataFolder string

	// AdditionalBrowserArguments are Chromium command line switches.
	AdditionalBrowserArguments string

	// Language is a BCP-47 tag for the browser UI. Empty means the system
	// default, which is what the SDK's own options object reports.
	Language string

	// TargetCompatibleBrowserVersion names the browser build the caller was
	// written against. Empty means "the runtime we found", which is what this
	// package wants: the bindings are hand-written and every optional interface
	// is reached through QueryInterface, so the runtime that is installed is by
	// definition the one we are compatible with.
	//
	// It must not end up null. The runtime validates this property and rejects a
	// null with E_INVALIDARG - WebView2Loader.dll always supplies a value, so the
	// official path never discovers this, but we are not going through it.
	// See resolveTargetVersion.
	TargetCompatibleBrowserVersion string

	// AllowSingleSignOnUsingOSPrimaryAccount enables Azure AD SSO. Off by
	// default: it sends the signed-in Windows identity to the web content.
	AllowSingleSignOnUsingOSPrimaryAccount bool

	// Timeout bounds creation. Zero means DefaultTimeout.
	Timeout time.Duration
}

Options configures environment creation. The zero value is valid and asks for the installed runtime with no extra browser arguments.

type ProcessFailedKind

type ProcessFailedKind int32

ProcessFailedKind is COREWEBVIEW2_PROCESS_FAILED_KIND.

const (
	ProcessFailedKindBrowserProcessExited      ProcessFailedKind = 0
	ProcessFailedKindRenderProcessExited       ProcessFailedKind = 1
	ProcessFailedKindRenderProcessUnresponsive ProcessFailedKind = 2
)

type Rect

type Rect struct {
	Left   int32
	Top    int32
	Right  int32
	Bottom int32
}

Rect is the Win32 RECT. Layout is ABI-critical: four 32-bit fields, 16 bytes.

type RuntimeReport

type RuntimeReport struct {
	// Folder is the runtime directory that was selected.
	Folder string

	// ClientDLL is the exact binary that would be loaded. When a browser fails
	// to start, this is the first question, and a version number is not an
	// answer to it.
	ClientDLL string

	// Version is the runtime's version, from the registry when it describes the
	// install, otherwise from the DLL's own version resource.
	Version string

	// Source names how the runtime was found: the environment pin, or which
	// registry view it came out of.
	Source string

	// Fixed is true for a fixed-version runtime pinned through
	// BrowserExecutableFolderEnv, which is a different report from an Evergreen
	// one and has to say so.
	Fixed bool

	// ExportName is the entry point mullion calls.
	ExportName string

	// ExportFound is true when the client DLL really exports it.
	ExportFound bool

	// ExportProblem says why it could not be resolved, when it could not.
	ExportProblem string
}

RuntimeReport describes the WebView2 runtime this process would load.

func DescribeRuntime

func DescribeRuntime() (RuntimeReport, error)

DescribeRuntime runs the same discovery the host runs at startup, then loads the selected client DLL and resolves the export.

Loading the DLL starts no browser process and creates no window: it maps the library and looks up one symbol. That is the same thing TestRuntimeExportsTheEntryPointWeCallDirectly does, deliberately - a diagnostic that exercises a different code path from the one it is diagnosing proves nothing about it.

An error means no runtime could be selected at all. A report with ExportFound false means a runtime was found and cannot be driven.

type WebErrorStatus

type WebErrorStatus int32

WebErrorStatus is COREWEBVIEW2_WEB_ERROR_STATUS. Only carried through, never interpreted here, so the enumerators are not mirrored.

const (
	// WebErrorStatusConnectionAborted is a connection that ended mid-flight. A
	// dead loopback endpoint has been observed producing it (issue #68), and so
	// has a navigation the runtime abandoned and restarted with its asset already
	// served (issue #72) - it says the load stopped, not why, which is why the
	// host decides what it means from the navigation's target (decisions/0024).
	WebErrorStatusConnectionAborted WebErrorStatus = 9
	// WebErrorStatusOperationCanceled is how the losing navigation completes
	// when a newer navigation supersedes it before it commits.
	WebErrorStatusOperationCanceled WebErrorStatus = 14
)

The two COREWEBVIEW2_WEB_ERROR_STATUS values this module branches or reasons on, transcribed from WebView2.h (the enum counts up from UNKNOWN = 0). The rest of the enum reaches logs as its numeric value.

type WebResourceContext

type WebResourceContext int32

WebResourceContext is COREWEBVIEW2_WEB_RESOURCE_CONTEXT.

const (
	// WebResourceContextAll matches every request kind. Verified = 0 in
	// WebView2.h; it is the first enumerator, not a bitmask of the others, so
	// it must not be OR-ed with anything.
	WebResourceContextAll      WebResourceContext = 0
	WebResourceContextDocument WebResourceContext = 1
)

Only the values this package uses are named. The full enum runs to COREWEBVIEW2_WEB_RESOURCE_CONTEXT_OTHER = 16.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL