diff --git a/v2/go.mod b/v2/go.mod index c40a121f9..5d45d171f 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -35,6 +35,7 @@ require ( github.com/tidwall/sjson v1.1.7 github.com/tkrajina/go-reflector v0.5.6 github.com/wailsapp/mimetype v1.4.1 + github.com/wailsapp/go-webview2 v1.0.1 github.com/wzshiming/ctc v1.2.3 golang.org/x/mod v0.8.0 golang.org/x/net v0.10.0 @@ -59,6 +60,7 @@ require ( github.com/gorilla/css v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/lithammer/fuzzysearch v1.1.5 // indirect diff --git a/v2/go.sum b/v2/go.sum index 415b4e42d..0a3125661 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -250,6 +250,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II= +github.com/wailsapp/go-webview2 v1.0.1/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index 82289e054..c4186eda6 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -21,9 +21,9 @@ import ( "time" "github.com/bep/debounce" + "github.com/wailsapp/go-webview2/pkg/edge" "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge" "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32" "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc" "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32" diff --git a/v2/internal/frontend/desktop/windows/go-webview2/LICENSE b/v2/internal/frontend/desktop/windows/go-webview2/LICENSE deleted file mode 100644 index ef2a0f485..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2020 John Chadwick -Some portions Copyright (c) 2017 Serge Zaitsev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/v2/internal/frontend/desktop/windows/go-webview2/README.md b/v2/internal/frontend/desktop/windows/go-webview2/README.md deleted file mode 100644 index 7379b3025..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# go-webview2 - -This is a proof of concept for embedding Webview2 into Go without CGo. It is based -on [webview/webview](https://github.com/webview/webview) and provides a compatible API. - -## Notice - -Because this version doesn't currently have an EdgeHTML fallback, it will not work unless you have a Webview2 runtime -installed. In addition, it requires the Webview2Loader DLL in order to function. Adding an EdgeHTML fallback should be -technically possible but will likely require much worse hacks since the API is not strictly COM to my knowledge. - -## Demo - -For now, you'll need to install the Webview2 runtime, as it does not ship with Windows. - -[WebView2 runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) - -After that, you should be able to run go-webview2 directly: - -``` -go run go-webview2/cmd/demo -``` - -This will use go-winloader to load an embedded copy of WebView2Loader.dll. - -If this does not work, please try running from a directory that has an appropriate copy of `WebView2Loader.dll` for your -GOARCH. If _that_ worked, *please* file a bug so we can figure out what's wrong with go-winloader :) \ No newline at end of file diff --git a/v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go b/v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go deleted file mode 100644 index 2b564173f..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go +++ /dev/null @@ -1,157 +0,0 @@ -//go:build windows - -package w32 - -import ( - "syscall" - "unicode/utf16" - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - ole32 = windows.NewLazySystemDLL("ole32") - Ole32CoInitializeEx = ole32.NewProc("CoInitializeEx") - - kernel32 = windows.NewLazySystemDLL("kernel32") - Kernel32GetCurrentThreadID = kernel32.NewProc("GetCurrentThreadId") - - shlwapi = windows.NewLazySystemDLL("shlwapi") - shlwapiSHCreateMemStream = shlwapi.NewProc("SHCreateMemStream") - - user32 = windows.NewLazySystemDLL("user32") - User32LoadImageW = user32.NewProc("LoadImageW") - User32GetSystemMetrics = user32.NewProc("GetSystemMetrics") - User32RegisterClassExW = user32.NewProc("RegisterClassExW") - User32CreateWindowExW = user32.NewProc("CreateWindowExW") - User32DestroyWindow = user32.NewProc("DestroyWindow") - User32ShowWindow = user32.NewProc("ShowWindow") - User32UpdateWindow = user32.NewProc("UpdateWindow") - User32SetFocus = user32.NewProc("SetFocus") - User32GetMessageW = user32.NewProc("GetMessageW") - User32TranslateMessage = user32.NewProc("TranslateMessage") - User32DispatchMessageW = user32.NewProc("DispatchMessageW") - User32DefWindowProcW = user32.NewProc("DefWindowProcW") - User32GetClientRect = user32.NewProc("GetClientRect") - User32PostQuitMessage = user32.NewProc("PostQuitMessage") - User32SetWindowTextW = user32.NewProc("SetWindowTextW") - User32PostThreadMessageW = user32.NewProc("PostThreadMessageW") - User32GetWindowLongPtrW = user32.NewProc("GetWindowLongPtrW") - User32SetWindowLongPtrW = user32.NewProc("SetWindowLongPtrW") - User32AdjustWindowRect = user32.NewProc("AdjustWindowRect") - User32SetWindowPos = user32.NewProc("SetWindowPos") -) - -const ( - SystemMetricsCxIcon = 11 - SystemMetricsCyIcon = 12 -) - -const ( - SWShow = 5 -) - -const ( - SWPNoZOrder = 0x0004 - SWPNoActivate = 0x0010 - SWPNoMove = 0x0002 - SWPFrameChanged = 0x0020 -) - -const ( - WMDestroy = 0x0002 - WMMove = 0x0003 - WMSize = 0x0005 - WMClose = 0x0010 - WMQuit = 0x0012 - WMGetMinMaxInfo = 0x0024 - WMNCLButtonDown = 0x00A1 - WMMoving = 0x0216 - WMApp = 0x8000 -) - -const ( - GWLStyle = -16 -) - -const ( - WSOverlapped = 0x00000000 - WSMaximizeBox = 0x00020000 - WSThickFrame = 0x00040000 - WSCaption = 0x00C00000 - WSSysMenu = 0x00080000 - WSMinimizeBox = 0x00020000 - WSOverlappedWindow = (WSOverlapped | WSCaption | WSSysMenu | WSThickFrame | WSMinimizeBox | WSMaximizeBox) -) - -type WndClassExW struct { - CbSize uint32 - Style uint32 - LpfnWndProc uintptr - CnClsExtra int32 - CbWndExtra int32 - HInstance windows.Handle - HIcon windows.Handle - HCursor windows.Handle - HbrBackground windows.Handle - LpszMenuName *uint16 - LpszClassName *uint16 - HIconSm windows.Handle -} - -type Rect struct { - Left int32 - Top int32 - Right int32 - Bottom int32 -} - -type MinMaxInfo struct { - PtReserved Point - PtMaxSize Point - PtMaxPosition Point - PtMinTrackSize Point - PtMaxTrackSize Point -} - -type Point struct { - X, Y int32 -} - -type Msg struct { - Hwnd syscall.Handle - Message uint32 - WParam uintptr - LParam uintptr - Time uint32 - Pt Point - LPrivate uint32 -} - -func Utf16PtrToString(p *uint16) string { - if p == nil { - return "" - } - // Find NUL terminator. - end := unsafe.Pointer(p) - n := 0 - for *(*uint16)(end) != 0 { - end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) - n++ - } - s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n] - return string(utf16.Decode(s)) -} - -func SHCreateMemStream(data []byte) (uintptr, error) { - ret, _, err := shlwapiSHCreateMemStream.Call( - uintptr(unsafe.Pointer(&data[0])), - uintptr(len(data)), - ) - if ret == 0 { - return 0, err - } - - return ret, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go deleted file mode 100644 index ccf04243f..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go +++ /dev/null @@ -1,239 +0,0 @@ -//go:build windows - -package combridge - -import ( - "fmt" - "runtime" - "sync" - "sync/atomic" -) - -var ( - comIfcePointersL sync.RWMutex - comIfcePointers = map[uintptr]*comObject{} // Map from ComInterfacePointer to the Go ComObject -) - -// Resolve the GoInterface of the specified ComInterfacePointer -func Resolve[T IUnknown](ifceP uintptr) T { - comIfcePointersL.RLock() - comObj := comIfcePointers[ifceP] - comIfcePointersL.RUnlock() - - var n T - if comObj != nil { - t := comObj.resolve(ifceP) - if t != nil { - n = t.(T) - } - } - - return n -} - -// New returns a new ComObject which implements the specified Com Interface, com calls will be redirected -// to the specified go interface. -func New[T IUnknown](obj T) *ComObject[T] { - cObj := new( - ifceDef[T]{obj}, - ) - return newComObject[T](cObj) -} - -// New2 returns a new ComObject which implements the two specified Com Interfaces, com calls will be redirected -// to those interfaces accordingly. -// This is needed if a ComObject should implement two interfaces that are not descendants of each other, -// then you get multiple inheritance. -func New2[T IUnknown, T2 IUnknown](obj T, obj2 T2) *ComObject[T] { - cObj := new( - ifceDef[T]{obj}, - ifceDef[T2]{obj2}, - ) - return newComObject[T](cObj) -} - -// new returns a new ComObject which implements multiple specified Com Interfaces, com calls will be redirected -// to the specified go interfaces accordingly. -// This is needed if a ComObject should implement multiple interfaces that are not descendants of each other, -// then you get multiple inheritance. -func new(impls ...ifceImpl) *comObject { - impls = append([]ifceImpl{ifceDef[IUnknown]{}}, impls...) - - cObj := &comObject{ - refCount: 1, - ifces: map[string]int{}, - ifcesImpl: make([]comInterfaceDesc, len(impls)), - } - - for i, ifceDef := range impls { - vtable, err := ifceDef.ifce() - if err != nil { - panic(err) - } - - needsImplement := false - for table := vtable; table != nil; table = table.Parent { - guid := table.ComGUID - if i, found := cObj.ifces[guid]; found { - // This Interface is already implemented - if guid == iUnknownGUID { - // IUnknown is a special interface and never has an user specific implementation - } else if cObj.ifcesImpl[i].impl != ifceDef.impl() { - panic(fmt.Sprintf("Interface '%s' is already implemented by another object", table.Name)) - } - - break - } - - needsImplement = true - cObj.ifces[guid] = i - } - - if !needsImplement { - continue - } - - ifceP, ifcePSlice := allocUintptrObject(1) - ifcePSlice[0] = vtable.ComVTable - cObj.ifcesImpl[i] = comInterfaceDesc{ifceP, ifceDef.impl()} - } - - comIfcePointersL.Lock() - for _, ifceImpl := range cObj.ifcesImpl { - comIfcePointers[ifceImpl.ref] = cObj - } - comIfcePointersL.Unlock() - - return cObj -} - -func newComObject[T IUnknown](comObj *comObject) *ComObject[T] { - c := &ComObject[T]{obj: comObj} - // Make sure to async release since release needs locks and might block the finalizer goroutine for a longer period - runtime.SetFinalizer(c, func(obj *ComObject[T]) { obj.close(true) }) - return c -} - -// ComObject describes an exported go instance to be used as a ComObject which implements -// the specified Interface. -type ComObject[T IUnknown] struct { - obj *comObject - closed int32 -} - -// Ref returns the native uintptr that points to the ComObject that is an interface pointer to T. -// This can be used in native calls. If the object has been closed this function will panic. -func (o *ComObject[T]) Ref() uintptr { - if atomic.LoadInt32(&o.closed) != 0 { - panic("ComObject has been released") - } - return o.obj.queryInterface(guidOf[T](), false) -} - -// Close releases the native com object from the go side. It will only be destroyed if the ref counter -// reaches zero. -// After closing `Ref()` will panic. -func (o *ComObject[T]) Close() error { - o.close(false) - return nil -} - -// close releases the native com object from the go side. It will only be destroyed if the ref counter -// reaches zero. -// After closing `Ref()` will panic. -func (o *ComObject[T]) close(asyncRelease bool) { - if atomic.CompareAndSwapInt32(&o.closed, 0, 1) { - runtime.SetFinalizer(o, nil) - if asyncRelease { - go o.obj.release() - } else { - o.obj.release() - } - } -} - -type comInterfaceDesc struct { - ref uintptr // The native Com InterfacePointer - impl any // The golang target object -} - -type comObject struct { - l sync.Mutex - - refCount int32 - ifces map[string]int // Map of ComInterfaceGUID to Interface Slots - ifcesImpl []comInterfaceDesc // Slots with InterfaceDescriptors -} - -func (c *comObject) queryInterface(ifceGUID string, withAddRef bool) uintptr { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on released com object") - } - - i, found := c.ifces[ifceGUID] - if !found { - return 0 - } - - if withAddRef { - c.refCount++ - } - return c.ifcesImpl[i].ref -} - -func (c *comObject) resolve(ifceP uintptr) any { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on destroyed com object") - } - - for _, ifce := range c.ifcesImpl { - if ifce.ref != ifceP { - continue - } - - return ifce.impl - } - return nil -} - -func (c *comObject) addRef() int32 { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on destroyed com object") - } - - c.refCount++ - return c.refCount -} - -func (c *comObject) release() int32 { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on destroyed com object") - } - - if c.refCount--; c.refCount == 0 { - comIfcePointersL.Lock() - for _, ref := range c.ifcesImpl { - delete(comIfcePointers, ref.ref) - } - comIfcePointersL.Unlock() - - for _, impl := range c.ifcesImpl { - ref := impl.ref - if ref == 0 { - continue - } - - globalFree(ref) - } - } - - return c.refCount -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go deleted file mode 100644 index 90d7247fe..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build windows - -package combridge - -import ( - "golang.org/x/sys/windows" -) - -const iUnknownGUID = "{00000000-0000-0000-C000-000000000046}" - -func init() { - registerVTableInternal[IUnknown, IUnknown]( - iUnknownGUID, - true, - iUnknownQueryInterface, - iUnknownAddRef, - iUnknownRelease, - ) -} - -type IUnknown interface{} - -func iUnknownQueryInterface(this uintptr, refiid *windows.GUID, ppvObject *uintptr) uintptr { - if refiid == nil || ppvObject == nil { - return uintptr(windows.E_INVALIDARG) - } - - comIfcePointersL.RLock() - obj := comIfcePointers[this] - comIfcePointersL.RUnlock() - - ref := obj.queryInterface(refiid.String(), true) - if ref != 0 { - *ppvObject = ref - return windows.NO_ERROR - } - - *ppvObject = 0 - return uintptr(windows.E_NOINTERFACE) -} - -func iUnknownAddRef(this uintptr) uintptr { - comIfcePointersL.RLock() - obj := comIfcePointers[this] - comIfcePointersL.RUnlock() - - return uintptr(obj.addRef()) -} - -func iUnknownRelease(this uintptr) uintptr { - comIfcePointersL.RLock() - obj := comIfcePointers[this] - comIfcePointersL.RUnlock() - - return uintptr(obj.release()) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go deleted file mode 100644 index 4c748d461..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build windows - -package combridge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -// IUnknownFromPointer cast a generic pointer into a IUnknownImpl pointer -func IUnknownFromPointer(ref unsafe.Pointer) *IUnknownImpl { - return (*IUnknownImpl)(ref) -} - -// IUnknownFromPointer cast native pointer into a IUnknownImpl pointer -func IUnknownFromUintptr(ref uintptr) *IUnknownImpl { - return IUnknownFromPointer(unsafe.Pointer(ref)) -} - -type IUnknownVtbl struct { - queryInterface uintptr - addRef uintptr - release uintptr -} - -func (i *IUnknownVtbl) QueryInterface(this unsafe.Pointer, refiid *windows.GUID, ppvObject **IUnknownImpl) error { - r, _, _ := syscall.SyscallN( - i.queryInterface, - uintptr(this), - uintptr(unsafe.Pointer(refiid)), - uintptr(unsafe.Pointer(ppvObject)), - ) - - if r != uintptr(windows.S_OK) { - return syscall.Errno(r) - } - - return nil -} - -func (i *IUnknownVtbl) AddRef(this unsafe.Pointer) uint32 { - r, _, _ := syscall.SyscallN( - i.addRef, - uintptr(this), - ) - return uint32(r) -} - -func (i *IUnknownVtbl) Release(this unsafe.Pointer) uint32 { - r, _, _ := syscall.SyscallN( - i.release, - uintptr(this), - ) - - return uint32(r) -} - -type IUnknownImpl struct { - vtbl *IUnknownVtbl -} - -func (i *IUnknownImpl) QueryInterface(refiid *windows.GUID, ppvObject **IUnknownImpl) error { - return i.vtbl.QueryInterface(unsafe.Pointer(i), refiid, ppvObject) -} - -func (i *IUnknownImpl) AddRef() uint32 { - return i.vtbl.AddRef(unsafe.Pointer(i)) -} - -func (i *IUnknownImpl) Release() uint32 { - return i.vtbl.Release(unsafe.Pointer(i)) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go deleted file mode 100644 index 17b7f500e..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build windows - -package combridge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalAlloc = modkernel32.NewProc("GlobalAlloc") - procGlobalFree = modkernel32.NewProc("GlobalFree") - - uintptrSize = unsafe.Sizeof(uintptr(0)) -) - -func allocUintptrObject(size int) (uintptr, []uintptr) { - v := globalAlloc(uintptr(size) * uintptrSize) - slice := unsafe.Slice((*uintptr)(unsafe.Pointer(v)), size) - return v, slice -} - -func globalAlloc(dwBytes uintptr) uintptr { - ret, _, _ := procGlobalAlloc.Call(uintptr(0), dwBytes) - if ret == 0 { - panic("globalAlloc failed") - } - - return ret -} - -func globalFree(data uintptr) { - ret, _, _ := procGlobalFree.Call(data) - if ret != 0 { - panic("globalFree failed") - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go deleted file mode 100644 index b099a7848..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go +++ /dev/null @@ -1,147 +0,0 @@ -//go:build windows - -package combridge - -import ( - "fmt" - "reflect" - "sync" - - "golang.org/x/sys/windows" -) - -var ( - vTablesL sync.Mutex - vTables = make(map[string]*vTable) -) - -// RegisterVTable registers the vtable trampoline methods for the specified ComInterface -// TBase is the base interface of T, and must be another ComInterface which roots in IUnknown or IUnknown itself. -// The first paramter of the fn is always the uintptr of the ComObject and the GoObject can be resolved with Resolve(). -// After having resolved the GoObject the call must be redirected to the GoObject. -// Typically a trampoline FN looks like this. -// -// func _ICoreWebView2NavigationCompletedEventHandlerInvoke(this uintptr, sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr { -// return combridge.Resolve[_ICoreWebView2NavigationCompletedEventHandler](this).NavigationCompleted(sender, args) -// } -// -// The order of registration must be in the correct order as specified in the IDL of the interface. -func RegisterVTable[TParent, T IUnknown](guid string, fns ...interface{}) { - registerVTableInternal[TParent, T](guid, false, fns...) -} - -type vTable struct { - Parent *vTable - - Name string - ComGUID string - ComVTable uintptr - ComProcs []uintptr -} - -func registerVTableInternal[TParent, T IUnknown](guid string, isInternal bool, fns ...interface{}) { - vTablesL.Lock() - defer vTablesL.Unlock() - - t, tName := typeInterfaceToString[T]() - tParent, tParentName := typeInterfaceToString[TParent]() - if !t.Implements(tParent) { - panic(fmt.Errorf("RegisterVTable '%s': '%s' must implement '%s'", tName, tName, tParentName)) - } - - if !isInternal { - if t == reflect.TypeOf((*IUnknown)(nil)).Elem() { - panic(fmt.Errorf("RegisterVTable '%s' IUnknown can't be registered", tName)) - } - - if t == tParent { - panic(fmt.Errorf("RegisterVTable '%s': T and TParent can't be the same type", tName)) - } - } - - var parent *vTable - var parentProcs []uintptr - var parentProcsCount int - if t != tParent { - parent = vTables[tParentName] - if parent == nil { - panic(fmt.Errorf("RegisterVTable '%s': Parent VTable '%s' not registered", tName, tParentName)) - } - - parentProcs = parent.ComProcs - parentProcsCount = len(parentProcs) - } - - comGuid, err := windows.GUIDFromString(guid) - if err != nil { - panic(fmt.Errorf("RegisterVTable '%s': invalid guid: %s", tName, err)) - } - - vTable := &vTable{ - Parent: parent, - Name: tName, - ComGUID: comGuid.String(), - } - vTable.ComVTable, vTable.ComProcs = allocUintptrObject(parentProcsCount + len(fns)) - - for i, proc := range parentProcs { - vTable.ComProcs[i] = proc - } - - for i, fn := range fns { - vTable.ComProcs[parentProcsCount+i] = windows.NewCallback(fn) - } - - vTables[tName] = vTable -} - -func typeInterfaceToString[T any]() (reflect.Type, string) { - t := reflect.TypeOf((*T)(nil)) - if t.Kind() != reflect.Pointer { - panic("must be a (*yourInterfaceType)(nil)") - } - t = t.Elem() - return t, t.PkgPath() + "/" + t.Name() -} - -func typeInterfaceToStringOnly[T any]() string { - _, nane := typeInterfaceToString[T]() - return nane -} - -func guidOf[T any]() string { - vtable := vTableOf[T]() - if vtable == nil { - return "" - } - return vtable.ComGUID -} - -func vTableOf[T any]() *vTable { - name := typeInterfaceToStringOnly[T]() - vTablesL.Lock() - defer vTablesL.Unlock() - - return vTables[name] -} - -type ifceImpl interface { - impl() any - ifce() (*vTable, error) -} - -type ifceDef[T any] struct { - objImpl any -} - -func (i ifceDef[T]) impl() any { - return i.objImpl -} - -func (i ifceDef[T]) ifce() (*vTable, error) { - vtable := vTableOf[T]() - if vtable == nil { - return nil, fmt.Errorf("Unable to find vTable for %s", typeInterfaceToStringOnly[T]()) - } - return vtable, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go deleted file mode 100644 index 429ecef24..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_COLOR struct { - A uint8 - R uint8 - G uint8 - B uint8 -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go deleted file mode 100644 index ed106ed44..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND uint32 - -const ( - COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY = iota - COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW - COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go deleted file mode 100644 index 607147535..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_KEY_EVENT_KIND uint32 - -const ( - COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN = 0 - COREWEBVIEW2_KEY_EVENT_KIND_KEY_UP = 1 - COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN = 2 - COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_UP = 3 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go deleted file mode 100644 index c1679cc37..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_MOVE_FOCUS_REASON uint32 - -const ( - COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC = 0 - COREWEBVIEW2_MOVE_FOCUS_REASON_NEXT = 1 - COREWEBVIEW2_MOVE_FOCUS_REASON_PREVIOUS = 2 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go deleted file mode 100644 index dd8834255..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_PHYSICAL_KEY_STATUS struct { - RepeatCount uint32 - ScanCode uint32 - IsExtendedKey bool - IsMenuKeyDown bool - WasKeyDown bool - IsKeyReleased bool -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go deleted file mode 100644 index a7e9aa339..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go +++ /dev/null @@ -1,49 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_PROCESS_FAILED_KIND uint32 - -const ( - // Indicates that the browser process ended unexpectedly. The WebView - // automatically moves to the Closed state. The app has to recreate a new - // WebView to recover from this failure. - COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED = 0 - - // Indicates that the main frame's render process ended unexpectedly. A new - // render process is created automatically and navigated to an error page. - // You can use the `Reload` method to try to reload the page that failed. - COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED = 1 - - // Indicates that the main frame's render process is unresponsive. - // - // Note that this does not seem to work right now. - // Does not fire for simple long running script case, the only related test - // SitePerProcessBrowserTest::NoCommitTimeoutForInvisibleWebContents is - // disabled. - COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE = 2 - - // Indicates that a frame-only render process ended unexpectedly. The process - // exit does not affect the top-level document, only a subset of the - // subframes within it. The content in these frames is replaced with an error - // page in the frame. - COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED = 3 - - // Indicates that a utility process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_UTILITY_PROCESS_EXITED = 4 - - // Indicates that a sandbox helper process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_SANDBOX_HELPER_PROCESS_EXITED = 5 - - // Indicates that the GPU process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_GPU_PROCESS_EXITED = 6 - - // Indicates that a PPAPI plugin process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_PLUGIN_PROCESS_EXITED = 7 - - // Indicates that a PPAPI plugin broker process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_BROKER_PROCESS_EXITED = 8 - - // Indicates that a process of unspecified kind ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_UNKNOWN_PROCESS_EXITED = 9 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go deleted file mode 100644 index 2e9261d0e..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_WEB_RESOURCE_CONTEXT uint32 - -const ( - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL = 0 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT = 1 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_STYLESHEET = 2 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_IMAGE = 3 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MEDIA = 4 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FONT = 5 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SCRIPT = 6 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_XML_HTTP_REQUEST = 7 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FETCH = 8 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_TEXT_TRACK = 9 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_EVENT_SOURCE = 10 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_WEBSOCKET = 11 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MANIFEST = 12 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SIGNED_EXCHANGE = 13 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_PING = 14 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_CSP_VIOLATION_REPORT = 15 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_OTHER = 16 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go deleted file mode 100644 index 2a3a9c823..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go +++ /dev/null @@ -1,79 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2AcceleratorKeyPressedEventArgsVtbl struct { - _IUnknownVtbl - GetKeyEventKind ComProc - GetVirtualKey ComProc - GetKeyEventLParam ComProc - GetPhysicalKeyStatus ComProc - GetHandled ComProc - PutHandled ComProc -} - -type ICoreWebView2AcceleratorKeyPressedEventArgs struct { - vtbl *_ICoreWebView2AcceleratorKeyPressedEventArgsVtbl -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventKind() (COREWEBVIEW2_KEY_EVENT_KIND, error) { - var err error - var keyEventKind COREWEBVIEW2_KEY_EVENT_KIND - _, _, err = i.vtbl.GetKeyEventKind.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&keyEventKind)), - ) - if err != windows.ERROR_SUCCESS { - return 0, err - } - return keyEventKind, nil -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetVirtualKey() (uint, error) { - var err error - var virtualKey uint - _, _, err = i.vtbl.GetVirtualKey.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&virtualKey)), - ) - if err != windows.ERROR_SUCCESS { - return 0, err - } - return virtualKey, nil -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetPhysicalKeyStatus() (COREWEBVIEW2_PHYSICAL_KEY_STATUS, error) { - var err error - var physicalKeyStatus COREWEBVIEW2_PHYSICAL_KEY_STATUS - _, _, err = i.vtbl.GetPhysicalKeyStatus.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&physicalKeyStatus)), - ) - if err != windows.ERROR_SUCCESS { - return COREWEBVIEW2_PHYSICAL_KEY_STATUS{}, err - } - return physicalKeyStatus, nil -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) PutHandled(handled bool) error { - var err error - - _, _, err = i.vtbl.PutHandled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(handled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go deleted file mode 100644 index 2c276560b..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type ICoreWebView2AcceleratorKeyPressedEventHandler struct { - vtbl *_ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl - impl _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownQueryInterface(this *ICoreWebView2AcceleratorKeyPressedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownAddRef(this *ICoreWebView2AcceleratorKeyPressedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownRelease(this *ICoreWebView2AcceleratorKeyPressedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2AcceleratorKeyPressedEventHandlerInvoke(this *ICoreWebView2AcceleratorKeyPressedEventHandler, sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr { - return this.impl.AcceleratorKeyPressed(sender, args) -} - -type _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl interface { - _IUnknownImpl - AcceleratorKeyPressed(sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr -} - -var _ICoreWebView2AcceleratorKeyPressedEventHandlerFn = _ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerInvoke), -} - -func newICoreWebView2AcceleratorKeyPressedEventHandler(impl _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl) *ICoreWebView2AcceleratorKeyPressedEventHandler { - return &ICoreWebView2AcceleratorKeyPressedEventHandler{ - vtbl: &_ICoreWebView2AcceleratorKeyPressedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go deleted file mode 100644 index c95a00ade..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go +++ /dev/null @@ -1,160 +0,0 @@ -//go:build windows - -package edge - -import ( - "math" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "golang.org/x/sys/windows" -) - -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 ICoreWebView2Controller struct { - vtbl *_ICoreWebView2ControllerVtbl -} - -func (i *ICoreWebView2Controller) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2Controller) GetBounds() (*w32.Rect, error) { - var err error - var bounds w32.Rect - _, _, err = i.vtbl.GetBounds.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&bounds)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return &bounds, nil -} - -func (i *ICoreWebView2Controller) PutBounds(bounds w32.Rect) error { - var err error - - _, _, err = i.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&bounds)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) MoveFocus(reason COREWEBVIEW2_MOVE_FOCUS_REASON) error { - var err error - - _, _, err = i.vtbl.MoveFocus.Call( - uintptr(unsafe.Pointer(i)), - uintptr(reason), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) AddAcceleratorKeyPressed(eventHandler *ICoreWebView2AcceleratorKeyPressedEventHandler, token *_EventRegistrationToken) error { - var err error - _, _, err = i.vtbl.AddAcceleratorKeyPressed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(eventHandler)), - uintptr(unsafe.Pointer(&token)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) PutIsVisible(isVisible bool) error { - var err error - - _, _, err = i.vtbl.PutIsVisible.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isVisible)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) GetICoreWebView2Controller2() *ICoreWebView2Controller2 { - - var result *ICoreWebView2Controller2 - - iidICoreWebView2Controller2 := NewGUID("{c979903e-d4ca-4228-92eb-47ee3fa96eab}") - i.vtbl.QueryInterface.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(iidICoreWebView2Controller2)), - uintptr(unsafe.Pointer(&result))) - - return result -} - -func (i *ICoreWebView2Controller) NotifyParentWindowPositionChanged() error { - var err error - _, _, err = i.vtbl.NotifyParentWindowPositionChanged.Call( - uintptr(unsafe.Pointer(i)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) PutZoomFactor(zoomFactor float64) error { - var err error - _, _, err = i.vtbl.PutZoomFactor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(math.Float64bits(zoomFactor)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) GetZoomFactor() (float64, error) { - var err error - var zoomFactorUint64 uint64 - _, _, err = i.vtbl.GetZoomFactor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&zoomFactorUint64)), - ) - if err != windows.ERROR_SUCCESS { - return 0.0, err - } - return math.Float64frombits(zoomFactorUint64), nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go deleted file mode 100644 index eff315a91..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2Controller2Vtbl 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 - GetDefaultBackgroundColor ComProc - PutDefaultBackgroundColor ComProc -} - -type ICoreWebView2Controller2 struct { - vtbl *_ICoreWebView2Controller2Vtbl -} - -func (i *ICoreWebView2Controller2) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2Controller2) GetDefaultBackgroundColor() (*COREWEBVIEW2_COLOR, error) { - var err error - var backgroundColor *COREWEBVIEW2_COLOR - _, _, err = i.vtbl.GetDefaultBackgroundColor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&backgroundColor)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return backgroundColor, nil -} - -func (i *ICoreWebView2Controller2) PutDefaultBackgroundColor(backgroundColor COREWEBVIEW2_COLOR) error { - var err error - - // Cast to a uint32 as that's what the call is expecting - col := *(*uint32)(unsafe.Pointer(&backgroundColor)) - - _, _, err = i.vtbl.PutDefaultBackgroundColor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(col), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go deleted file mode 100644 index c0e4d13b7..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2CreateCoreWebView2ControllerCompletedHandler struct { - vtbl *_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl - impl _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl -} - -func (i *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownQueryInterface(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownAddRef(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownRelease(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerInvoke(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler, errorCode uintptr, createdController *ICoreWebView2Controller) uintptr { - return this.impl.CreateCoreWebView2ControllerCompleted(errorCode, createdController) -} - -type _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl interface { - _IUnknownImpl - CreateCoreWebView2ControllerCompleted(errorCode uintptr, createdController *ICoreWebView2Controller) uintptr -} - -var _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerFn = _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerInvoke), -} - -func newICoreWebView2CreateCoreWebView2ControllerCompletedHandler(impl _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl) *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler { - return &iCoreWebView2CreateCoreWebView2ControllerCompletedHandler{ - vtbl: &_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go deleted file mode 100644 index 0c9eacb46..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go +++ /dev/null @@ -1,78 +0,0 @@ -//go:build windows - -package edge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2HttpHeadersCollectionIteratorVtbl struct { - _IUnknownVtbl - GetCurrentHeader ComProc - GetHasCurrentHeader ComProc - MoveNext ComProc -} - -type ICoreWebView2HttpHeadersCollectionIterator struct { - vtbl *_ICoreWebView2HttpHeadersCollectionIteratorVtbl -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) HasCurrentHeader() (bool, error) { - var hasHeader int32 - res, _, err := i.vtbl.GetHasCurrentHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&hasHeader)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - if windows.Handle(res) != windows.S_OK { - return false, syscall.Errno(res) - } - return hasHeader != 0, nil -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) GetCurrentHeader() (string, string, error) { - // Create *uint16 to hold result - var _name *uint16 - var _value *uint16 - res, _, err := i.vtbl.GetCurrentHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&_name)), - uintptr(unsafe.Pointer(&_value)), - ) - if err != windows.ERROR_SUCCESS { - return "", "", err - } - if windows.Handle(res) != windows.S_OK { - return "", "", syscall.Errno(res) - } - // Get result and cleanup - name := windows.UTF16PtrToString(_name) - windows.CoTaskMemFree(unsafe.Pointer(_name)) - value := windows.UTF16PtrToString(_value) - windows.CoTaskMemFree(unsafe.Pointer(_value)) - return name, value, nil -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) MoveNext() (bool, error) { - var next int32 - res, _, err := i.vtbl.MoveNext.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&next)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - if windows.Handle(res) != windows.S_OK { - return false, syscall.Errno(res) - } - return next != 0, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go deleted file mode 100644 index 5a147b299..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go +++ /dev/null @@ -1,101 +0,0 @@ -//go:build windows - -package edge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -const ( - ERROR_ELEMENT_NOT_FOUND syscall.Errno = 0x80070490 -) - -type _ICoreWebView2HttpRequestHeadersVtbl struct { - _IUnknownVtbl - GetHeader ComProc - GetHeaders ComProc - Contains ComProc - SetHeader ComProc - RemoveHeader ComProc - GetIterator ComProc -} - -type ICoreWebView2HttpRequestHeaders struct { - vtbl *_ICoreWebView2HttpRequestHeadersVtbl -} - -func (i *ICoreWebView2HttpRequestHeaders) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} - -// GetHeader returns the value of the specified header. If the header is not found -// ERROR_ELEMENT_NOT_FOUND is returned as error. -func (i *ICoreWebView2HttpRequestHeaders) GetHeader(name string) (string, error) { - _name, err := windows.UTF16PtrFromString(name) - if err != nil { - return "", nil - } - - var _value *uint16 - res, _, err := i.vtbl.GetHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(&_value)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } - if windows.Handle(res) != windows.S_OK { - return "", syscall.Errno(res) - } - - value := windows.UTF16PtrToString(_value) - windows.CoTaskMemFree(unsafe.Pointer(_value)) - return value, nil -} - -// SetHeader sets the specified header to the value. -func (i *ICoreWebView2HttpRequestHeaders) SetHeader(name, value string) error { - _name, err := windows.UTF16PtrFromString(name) - if err != nil { - return nil - } - - _value, err := windows.UTF16PtrFromString(value) - if err != nil { - return nil - } - - res, _, err := i.vtbl.SetHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(_value)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - if windows.Handle(res) != windows.S_OK { - return syscall.Errno(res) - } - return nil -} - -// GetIterator returns an iterator over the collection of request headers. Make sure to call -// Release on the returned Object after finished using it. -func (i *ICoreWebView2HttpRequestHeaders) GetIterator() (*ICoreWebView2HttpHeadersCollectionIterator, error) { - var headers *ICoreWebView2HttpHeadersCollectionIterator - res, _, err := i.vtbl.GetIterator.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&headers)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - if windows.Handle(res) != windows.S_OK { - return nil, syscall.Errno(res) - } - return headers, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go deleted file mode 100644 index c3998e0a2..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2NavigationCompletedEventArgsVtbl struct { - _IUnknownVtbl - GetIsSuccess ComProc - GetWebErrorStatus ComProc - GetNavigationId ComProc -} - -type ICoreWebView2NavigationCompletedEventArgs struct { - vtbl *_ICoreWebView2NavigationCompletedEventArgsVtbl -} - -func (i *ICoreWebView2NavigationCompletedEventArgs) AddRef() uintptr { - return i.AddRef() -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go deleted file mode 100644 index 456da5074..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2NavigationCompletedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type ICoreWebView2NavigationCompletedEventHandler struct { - vtbl *_ICoreWebView2NavigationCompletedEventHandlerVtbl - impl _ICoreWebView2NavigationCompletedEventHandlerImpl -} - -func (i *ICoreWebView2NavigationCompletedEventHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2NavigationCompletedEventHandlerIUnknownQueryInterface(this *ICoreWebView2NavigationCompletedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2NavigationCompletedEventHandlerIUnknownAddRef(this *ICoreWebView2NavigationCompletedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2NavigationCompletedEventHandlerIUnknownRelease(this *ICoreWebView2NavigationCompletedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2NavigationCompletedEventHandlerInvoke(this *ICoreWebView2NavigationCompletedEventHandler, sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr { - return this.impl.NavigationCompleted(sender, args) -} - -type _ICoreWebView2NavigationCompletedEventHandlerImpl interface { - _IUnknownImpl - NavigationCompleted(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr -} - -var _ICoreWebView2NavigationCompletedEventHandlerFn = _ICoreWebView2NavigationCompletedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerInvoke), -} - -func newICoreWebView2NavigationCompletedEventHandler(impl _ICoreWebView2NavigationCompletedEventHandlerImpl) *ICoreWebView2NavigationCompletedEventHandler { - return &ICoreWebView2NavigationCompletedEventHandler{ - vtbl: &_ICoreWebView2NavigationCompletedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go deleted file mode 100644 index b6d3cda1b..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build windows - -package edge - -import ( - "fmt" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2ProcessFailedEventArgsVtbl struct { - _IUnknownVtbl - GetProcessFailedKind ComProc -} - -type ICoreWebView2ProcessFailedEventArgs struct { - vtbl *_ICoreWebView2ProcessFailedEventArgsVtbl -} - -func (i *ICoreWebView2ProcessFailedEventArgs) GetProcessFailedKind() (COREWEBVIEW2_PROCESS_FAILED_KIND, error) { - kind := COREWEBVIEW2_PROCESS_FAILED_KIND(0xffffffff) - hr, _, err := i.vtbl.GetProcessFailedKind.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&kind)), - ) - - if windows.Handle(hr) != windows.S_OK { - return 0, syscall.Errno(hr) - } - - if kind == 0xffffffff { - if err == nil { - err = fmt.Errorf("unknown error") - } - return 0, err - } - - return kind, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go deleted file mode 100644 index fc8c7369c..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2ProcessFailedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type ICoreWebView2ProcessFailedEventHandler struct { - vtbl *_ICoreWebView2ProcessFailedEventHandlerVtbl - impl _ICoreWebView2ProcessFailedEventHandlerImpl -} - -func (i *ICoreWebView2ProcessFailedEventHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2ProcessFailedEventHandlerIUnknownQueryInterface(this *ICoreWebView2ProcessFailedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2ProcessFailedEventHandlerIUnknownAddRef(this *ICoreWebView2ProcessFailedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2ProcessFailedEventHandlerIUnknownRelease(this *ICoreWebView2ProcessFailedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2ProcessFailedEventHandlerInvoke(this *ICoreWebView2ProcessFailedEventHandler, sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr { - return this.impl.ProcessFailed(sender, args) -} - -type _ICoreWebView2ProcessFailedEventHandlerImpl interface { - _IUnknownImpl - ProcessFailed(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr -} - -var _ICoreWebView2ProcessFailedEventHandlerFn = _ICoreWebView2ProcessFailedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2ProcessFailedEventHandlerInvoke), -} - -func newICoreWebView2ProcessFailedEventHandler(impl _ICoreWebView2ProcessFailedEventHandlerImpl) *ICoreWebView2ProcessFailedEventHandler { - return &ICoreWebView2ProcessFailedEventHandler{ - vtbl: &_ICoreWebView2ProcessFailedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go deleted file mode 100644 index a4ba613d2..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go +++ /dev/null @@ -1,271 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -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 ICoreWebView2Settings struct { - vtbl *_ICoreWebView2SettingsVtbl -} - -func (i *ICoreWebView2Settings) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2Settings) GetIsScriptEnabled() (bool, error) { - var err error - var isScriptEnabled bool - _, _, err = i.vtbl.GetIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isScriptEnabled, nil -} - -func (i *ICoreWebView2Settings) PutIsScriptEnabled(isScriptEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsWebMessageEnabled() (bool, error) { - var err error - var isWebMessageEnabled bool - _, _, err = i.vtbl.GetIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isWebMessageEnabled, nil -} - -func (i *ICoreWebView2Settings) PutIsWebMessageEnabled(isWebMessageEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreDefaultScriptDialogsEnabled() (bool, error) { - var err error - var areDefaultScriptDialogsEnabled bool - _, _, err = i.vtbl.GetAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDefaultScriptDialogsEnabled, nil -} - -func (i *ICoreWebView2Settings) PutAreDefaultScriptDialogsEnabled(areDefaultScriptDialogsEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsStatusBarEnabled() (bool, error) { - var err error - var isStatusBarEnabled bool - _, _, err = i.vtbl.GetIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isStatusBarEnabled, nil -} - -func (i *ICoreWebView2Settings) PutIsStatusBarEnabled(isStatusBarEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreDevToolsEnabled() (bool, error) { - var err error - var areDevToolsEnabled bool - _, _, err = i.vtbl.GetAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDevToolsEnabled, nil -} - -func (i *ICoreWebView2Settings) PutAreDevToolsEnabled(areDevToolsEnabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreDefaultContextMenusEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebView2Settings) PutAreDefaultContextMenusEnabled(enabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreHostObjectsAllowed() (bool, error) { - var err error - var allowed bool - _, _, err = i.vtbl.GetAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowed)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return allowed, nil -} - -func (i *ICoreWebView2Settings) PutAreHostObjectsAllowed(allowed bool) error { - var err error - - _, _, err = i.vtbl.PutAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(allowed)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsZoomControlEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebView2Settings) PutIsZoomControlEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsBuiltInErrorPageEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebView2Settings) PutIsBuiltInErrorPageEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go deleted file mode 100644 index fe7f2cfa2..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go +++ /dev/null @@ -1,102 +0,0 @@ -//go:build windows - -package edge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2WebResourceRequestVtbl struct { - _IUnknownVtbl - GetUri ComProc - PutUri ComProc - GetMethod ComProc - PutMethod ComProc - GetContent ComProc - PutContent ComProc - GetHeaders ComProc -} - -type ICoreWebView2WebResourceRequest struct { - vtbl *_ICoreWebView2WebResourceRequestVtbl -} - -func (i *ICoreWebView2WebResourceRequest) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2WebResourceRequest) GetMethod() (string, error) { - // Create *uint16 to hold result - var _method *uint16 - res, _, err := i.vtbl.GetMethod.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&_method)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } - if windows.Handle(res) != windows.S_OK { - return "", syscall.Errno(res) - } - // Get result and cleanup - uri := windows.UTF16PtrToString(_method) - windows.CoTaskMemFree(unsafe.Pointer(_method)) - return uri, nil -} - -func (i *ICoreWebView2WebResourceRequest) GetUri() (string, error) { - var err error - // Create *uint16 to hold result - var _uri *uint16 - _, _, err = i.vtbl.GetUri.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&_uri)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } // Get result and cleanup - uri := windows.UTF16PtrToString(_uri) - windows.CoTaskMemFree(unsafe.Pointer(_uri)) - return uri, nil -} - -// GetContent returns the body of the request. Returns nil if there's no body. Make sure to call -// Release on the returned IStream after finished using it. -func (i *ICoreWebView2WebResourceRequest) GetContent() (*IStream, error) { - var stream *IStream - res, _, err := i.vtbl.GetContent.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&stream)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - if windows.Handle(res) != windows.S_OK { - return nil, syscall.Errno(res) - } - return stream, nil -} - -// GetHeaders returns the mutable HTTP request headers. Make sure to call -// Release on the returned Object after finished using it. -func (i *ICoreWebView2WebResourceRequest) GetHeaders() (*ICoreWebView2HttpRequestHeaders, error) { - var headers *ICoreWebView2HttpRequestHeaders - res, _, err := i.vtbl.GetHeaders.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&headers)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - if windows.Handle(res) != windows.S_OK { - return nil, syscall.Errno(res) - } - return headers, nil -} - -func (i *ICoreWebView2WebResourceRequest) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go deleted file mode 100644 index 614594e87..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go +++ /dev/null @@ -1,52 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2WebResourceRequestedEventArgsVtbl struct { - _IUnknownVtbl - GetRequest ComProc - GetResponse ComProc - PutResponse ComProc - GetDeferral ComProc - GetResourceContext ComProc -} - -type ICoreWebView2WebResourceRequestedEventArgs struct { - vtbl *_ICoreWebView2WebResourceRequestedEventArgsVtbl -} - -func (i *ICoreWebView2WebResourceRequestedEventArgs) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2WebResourceRequestedEventArgs) PutResponse(response *ICoreWebView2WebResourceResponse) error { - var err error - - _, _, err = i.vtbl.PutResponse.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(response)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2WebResourceRequestedEventArgs) GetRequest() (*ICoreWebView2WebResourceRequest, error) { - var err error - var request *ICoreWebView2WebResourceRequest - _, _, err = i.vtbl.GetRequest.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&request)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return request, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go deleted file mode 100644 index d0860c3be..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2WebResourceRequestedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2WebResourceRequestedEventHandler struct { - vtbl *_ICoreWebView2WebResourceRequestedEventHandlerVtbl - impl _ICoreWebView2WebResourceRequestedEventHandlerImpl -} - -func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownQueryInterface(this *iCoreWebView2WebResourceRequestedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownAddRef(this *iCoreWebView2WebResourceRequestedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownRelease(this *iCoreWebView2WebResourceRequestedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2WebResourceRequestedEventHandlerInvoke(this *iCoreWebView2WebResourceRequestedEventHandler, sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr { - return this.impl.WebResourceRequested(sender, args) -} - -type _ICoreWebView2WebResourceRequestedEventHandlerImpl interface { - _IUnknownImpl - WebResourceRequested(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr -} - -var _ICoreWebView2WebResourceRequestedEventHandlerFn = _ICoreWebView2WebResourceRequestedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerInvoke), -} - -func newICoreWebView2WebResourceRequestedEventHandler(impl _ICoreWebView2WebResourceRequestedEventHandlerImpl) *iCoreWebView2WebResourceRequestedEventHandler { - return &iCoreWebView2WebResourceRequestedEventHandler{ - vtbl: &_ICoreWebView2WebResourceRequestedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go deleted file mode 100644 index dd02e6089..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build windows - -package edge - -import "unsafe" - -type _ICoreWebView2WebResourceResponseVtbl struct { - _IUnknownVtbl - GetContent ComProc - PutContent ComProc - GetHeaders ComProc - GetStatusCode ComProc - PutStatusCode ComProc - GetReasonPhrase ComProc - PutReasonPhrase ComProc -} - -type ICoreWebView2WebResourceResponse struct { - vtbl *_ICoreWebView2WebResourceResponseVtbl -} - -func (i *ICoreWebView2WebResourceResponse) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2WebResourceResponse) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go deleted file mode 100644 index 85a4f71fa..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build windows - -package edge - -type iCoreWebView2_2Vtbl struct { - iCoreWebView2Vtbl - AddWebResourceResponseReceived ComProc - RemoveWebResourceResponseReceived ComProc - NavigateWithWebResourceRequest ComProc - AddDomContentLoaded ComProc - RemoveDomContentLoaded ComProc - GetCookieManager ComProc - GetEnvironment ComProc -} - -type ICoreWebView2_2 struct { - vtbl *iCoreWebView2_2Vtbl -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go deleted file mode 100644 index 58424bd6a..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type iCoreWebView2_3Vtbl struct { - iCoreWebView2_2Vtbl - TrySuspend ComProc - Resume ComProc - GetIsSuspended ComProc - SetVirtualHostNameToFolderMapping ComProc - ClearVirtualHostNameToFolderMapping ComProc -} - -type ICoreWebView2_3 struct { - vtbl *iCoreWebView2_3Vtbl -} - -func (i *ICoreWebView2_3) SetVirtualHostNameToFolderMapping(hostName, folderPath string, accessKind COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND) error { - _hostName, err := windows.UTF16PtrFromString(hostName) - if err != nil { - return err - } - - _folderPath, err := windows.UTF16PtrFromString(folderPath) - if err != nil { - return err - } - - _, _, err = i.vtbl.SetVirtualHostNameToFolderMapping.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_hostName)), - uintptr(unsafe.Pointer(_folderPath)), - uintptr(accessKind), - ) - if err != windows.ERROR_SUCCESS { - return err - } - - return nil -} - -func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 { - var result *ICoreWebView2_3 - - iidICoreWebView2_3 := NewGUID("{A0D6DF20-3B92-416D-AA0C-437A9C727857}") - _, _, _ = i.vtbl.QueryInterface.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(iidICoreWebView2_3)), - uintptr(unsafe.Pointer(&result))) - - return result -} - -func (e *Chromium) GetICoreWebView2_3() *ICoreWebView2_3 { - return e.webview.GetICoreWebView2_3() -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go deleted file mode 100644 index 6c6b16d74..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go +++ /dev/null @@ -1,397 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -// ICoreWebviewSettings is the merged settings class - -type _ICoreWebViewSettingsVtbl 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 - GetUserAgent ComProc // ICoreWebView2Settings2: SDK 1.0.864.35 - PutUserAgent ComProc - GetAreBrowserAcceleratorKeysEnabled ComProc // ICoreWebView2Settings3: SDK 1.0.864.35 - PutAreBrowserAcceleratorKeysEnabled ComProc - GetIsPasswordAutosaveEnabled ComProc // ICoreWebView2Settings4: SDK 1.0.902.49 - PutIsPasswordAutosaveEnabled ComProc - GetIsGeneralAutofillEnabled ComProc - PutIsGeneralAutofillEnabled ComProc - GetIsPinchZoomEnabled ComProc // ICoreWebView2Settings5: SDK 1.0.902.49 - PutIsPinchZoomEnabled ComProc - GetIsSwipeNavigationEnabled ComProc // ICoreWebView2Settings6: SDK 1.0.992.28 - PutIsSwipeNavigationEnabled ComProc -} - -type ICoreWebViewSettings struct { - vtbl *_ICoreWebViewSettingsVtbl -} - -func (i *ICoreWebViewSettings) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebViewSettings) GetIsScriptEnabled() (bool, error) { - var err error - var isScriptEnabled bool - _, _, err = i.vtbl.GetIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isScriptEnabled, nil -} - -func (i *ICoreWebViewSettings) PutIsScriptEnabled(isScriptEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsWebMessageEnabled() (bool, error) { - var err error - var isWebMessageEnabled bool - _, _, err = i.vtbl.GetIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isWebMessageEnabled, nil -} - -func (i *ICoreWebViewSettings) PutIsWebMessageEnabled(isWebMessageEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreDefaultScriptDialogsEnabled() (bool, error) { - var err error - var areDefaultScriptDialogsEnabled bool - _, _, err = i.vtbl.GetAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDefaultScriptDialogsEnabled, nil -} - -func (i *ICoreWebViewSettings) PutAreDefaultScriptDialogsEnabled(areDefaultScriptDialogsEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsStatusBarEnabled() (bool, error) { - var err error - var isStatusBarEnabled bool - _, _, err = i.vtbl.GetIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isStatusBarEnabled, nil -} - -func (i *ICoreWebViewSettings) PutIsStatusBarEnabled(isStatusBarEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreDevToolsEnabled() (bool, error) { - var err error - var areDevToolsEnabled bool - _, _, err = i.vtbl.GetAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDevToolsEnabled, nil -} - -func (i *ICoreWebViewSettings) PutAreDevToolsEnabled(areDevToolsEnabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreDefaultContextMenusEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutAreDefaultContextMenusEnabled(enabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreHostObjectsAllowed() (bool, error) { - var err error - var allowed bool - _, _, err = i.vtbl.GetAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowed)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return allowed, nil -} - -func (i *ICoreWebViewSettings) PutAreHostObjectsAllowed(allowed bool) error { - var err error - - _, _, err = i.vtbl.PutAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(allowed)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsZoomControlEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsZoomControlEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsBuiltInErrorPageEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsBuiltInErrorPageEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetUserAgent() (string, error) { - var err error - // Create *uint16 to hold result - var _userAgent *uint16 - _, _, err = i.vtbl.GetUserAgent.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_userAgent)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } // Get result and cleanup - userAgent := windows.UTF16PtrToString(_userAgent) - windows.CoTaskMemFree(unsafe.Pointer(_userAgent)) - return userAgent, nil -} - -func (i *ICoreWebViewSettings) PutUserAgent(userAgent string) error { - var err error - // Convert string 'userAgent' to *uint16 - _userAgent, err := windows.UTF16PtrFromString(userAgent) - if err != nil { - return err - } - - _, _, err = i.vtbl.PutUserAgent.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_userAgent)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreBrowserAcceleratorKeysEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetAreBrowserAcceleratorKeysEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutAreBrowserAcceleratorKeysEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutAreBrowserAcceleratorKeysEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsPinchZoomEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsPinchZoomEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsPinchZoomEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsPinchZoomEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsSwipeNavigationEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsSwipeNavigationEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsSwipeNavigationEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsSwipeNavigationEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go deleted file mode 100644 index 9e29ca4f0..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go +++ /dev/null @@ -1,54 +0,0 @@ -//go:build windows - -package edge - -import ( - "io" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _IStreamVtbl struct { - _IUnknownVtbl - Read ComProc - Write ComProc -} - -type IStream struct { - vtbl *_IStreamVtbl -} - -func (i *IStream) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} - -func (i *IStream) Read(p []byte) (int, error) { - bufLen := len(p) - if bufLen == 0 { - return 0, nil - } - - var n int - res, _, err := i.vtbl.Read.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&p[0])), - uintptr(bufLen), - uintptr(unsafe.Pointer(&n)), - ) - if err != windows.ERROR_SUCCESS { - return 0, err - } - - switch windows.Handle(res) { - case windows.S_OK: - // The buffer has been completely filled - return n, nil - case windows.S_FALSE: - // The buffer has been filled with less than len data and the stream is EOF - return n, io.EOF - default: - return 0, syscall.Errno(res) - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go deleted file mode 100644 index 376891bb1..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go +++ /dev/null @@ -1,419 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "errors" - "log" - "os" - "path/filepath" - "strings" - "sync/atomic" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "golang.org/x/sys/windows" -) - -type Rect = w32.Rect - -type Chromium struct { - hwnd uintptr - controller *ICoreWebView2Controller - webview *ICoreWebView2 - inited uintptr - envCompleted *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler - controllerCompleted *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler - webMessageReceived *iCoreWebView2WebMessageReceivedEventHandler - permissionRequested *iCoreWebView2PermissionRequestedEventHandler - webResourceRequested *iCoreWebView2WebResourceRequestedEventHandler - acceleratorKeyPressed *ICoreWebView2AcceleratorKeyPressedEventHandler - navigationCompleted *ICoreWebView2NavigationCompletedEventHandler - processFailed *ICoreWebView2ProcessFailedEventHandler - - environment *ICoreWebView2Environment - - padding Rect - - // Settings - Debug bool - DataPath string - BrowserPath string - AdditionalBrowserArgs []string - - // permissions - permissions map[CoreWebView2PermissionKind]CoreWebView2PermissionState - globalPermission *CoreWebView2PermissionState - - // Callbacks - MessageCallback func(string) - WebResourceRequestedCallback func(request *ICoreWebView2WebResourceRequest, args *ICoreWebView2WebResourceRequestedEventArgs) - NavigationCompletedCallback func(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) - ProcessFailedCallback func(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) - AcceleratorKeyCallback func(uint) bool -} - -func NewChromium() *Chromium { - e := &Chromium{} - /* - All these handlers are passed to native code through syscalls with 'uintptr(unsafe.Pointer(handler))' and we know - that a pointer to those will be kept in the native code. Furthermore these handlers als contain pointer to other Go - structs like the vtable. - This violates the unsafe.Pointer rule '(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.' because - theres no guarantee that Go doesn't move these objects. - AFAIK currently the Go runtime doesn't move HEAP objects, so we should be safe with these handlers. But they don't - guarantee it, because in the future Go might use a compacting GC. - There's a proposal to add a runtime.Pin function, to prevent moving pinned objects, which would allow to easily fix - this issue by just pinning the handlers. The https://go-review.googlesource.com/c/go/+/367296/ should land in Go 1.19. - */ - e.envCompleted = newICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler(e) - e.controllerCompleted = newICoreWebView2CreateCoreWebView2ControllerCompletedHandler(e) - e.webMessageReceived = newICoreWebView2WebMessageReceivedEventHandler(e) - e.permissionRequested = newICoreWebView2PermissionRequestedEventHandler(e) - e.webResourceRequested = newICoreWebView2WebResourceRequestedEventHandler(e) - e.acceleratorKeyPressed = newICoreWebView2AcceleratorKeyPressedEventHandler(e) - e.navigationCompleted = newICoreWebView2NavigationCompletedEventHandler(e) - e.processFailed = newICoreWebView2ProcessFailedEventHandler(e) - e.permissions = make(map[CoreWebView2PermissionKind]CoreWebView2PermissionState) - - return e -} - -func (e *Chromium) Embed(hwnd uintptr) bool { - e.hwnd = hwnd - - dataPath := e.DataPath - if dataPath == "" { - currentExePath := make([]uint16, windows.MAX_PATH) - _, err := windows.GetModuleFileName(windows.Handle(0), ¤tExePath[0], windows.MAX_PATH) - if err != nil { - // What to do here? - return false - } - currentExeName := filepath.Base(windows.UTF16ToString(currentExePath)) - dataPath = filepath.Join(os.Getenv("AppData"), currentExeName) - } - - if e.BrowserPath != "" { - if _, err := os.Stat(e.BrowserPath); errors.Is(err, os.ErrNotExist) { - log.Printf("Browser path %s does not exist", e.BrowserPath) - return false - } - } - - browserArgs := strings.Join(e.AdditionalBrowserArgs, " ") - if err := createCoreWebView2EnvironmentWithOptions(e.BrowserPath, dataPath, e.envCompleted, browserArgs); err != nil { - log.Printf("Error calling Webview2Loader: %v", err) - return false - } - - var msg w32.Msg - for { - if atomic.LoadUintptr(&e.inited) != 0 { - break - } - r, _, _ := w32.User32GetMessageW.Call( - uintptr(unsafe.Pointer(&msg)), - 0, - 0, - 0, - ) - if r == 0 { - break - } - w32.User32TranslateMessage.Call(uintptr(unsafe.Pointer(&msg))) - w32.User32DispatchMessageW.Call(uintptr(unsafe.Pointer(&msg))) - } - e.Init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}") - return true -} - -func (e *Chromium) SetPadding(padding Rect) { - if e.padding.Top == padding.Top && e.padding.Bottom == padding.Bottom && - e.padding.Left == padding.Left && e.padding.Right == padding.Right { - - return - } - - e.padding = padding - e.Resize() -} - -func (e *Chromium) Resize() { - if e.hwnd == 0 { - return - } - - var bounds w32.Rect - w32.User32GetClientRect.Call(e.hwnd, uintptr(unsafe.Pointer(&bounds))) - - bounds.Top += e.padding.Top - bounds.Bottom -= e.padding.Bottom - bounds.Left += e.padding.Left - bounds.Right -= e.padding.Right - - e.SetSize(bounds) -} - -func (e *Chromium) Navigate(url string) { - e.webview.vtbl.Navigate.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(url))), - ) -} - -func (e *Chromium) Init(script string) { - e.webview.vtbl.AddScriptToExecuteOnDocumentCreated.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(script))), - 0, - ) -} - -func (e *Chromium) Eval(script string) { - - _script, err := windows.UTF16PtrFromString(script) - if err != nil { - log.Fatal(err) - } - - e.webview.vtbl.ExecuteScript.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(_script)), - 0, - ) -} - -func (e *Chromium) Show() error { - return e.controller.PutIsVisible(true) -} - -func (e *Chromium) Hide() error { - return e.controller.PutIsVisible(false) -} - -func (e *Chromium) QueryInterface(_, _ uintptr) uintptr { - return 0 -} - -func (e *Chromium) AddRef() uintptr { - return 1 -} - -func (e *Chromium) Release() uintptr { - return 1 -} - -func (e *Chromium) EnvironmentCompleted(res uintptr, env *ICoreWebView2Environment) uintptr { - if int32(res) < 0 { - log.Fatalf("Creating environment failed with %08x: %s", res, syscall.Errno(res)) - } - env.vtbl.AddRef.Call(uintptr(unsafe.Pointer(env))) - e.environment = env - - env.vtbl.CreateCoreWebView2Controller.Call( - uintptr(unsafe.Pointer(env)), - e.hwnd, - uintptr(unsafe.Pointer(e.controllerCompleted)), - ) - return 0 -} - -func (e *Chromium) CreateCoreWebView2ControllerCompleted(res uintptr, controller *ICoreWebView2Controller) uintptr { - if int32(res) < 0 { - log.Fatalf("Creating controller failed with %08x: %s", res, syscall.Errno(res)) - } - controller.vtbl.AddRef.Call(uintptr(unsafe.Pointer(controller))) - e.controller = controller - - var token _EventRegistrationToken - controller.vtbl.GetCoreWebView2.Call( - uintptr(unsafe.Pointer(controller)), - uintptr(unsafe.Pointer(&e.webview)), - ) - e.webview.vtbl.AddRef.Call( - uintptr(unsafe.Pointer(e.webview)), - ) - e.webview.vtbl.AddWebMessageReceived.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.webMessageReceived)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddPermissionRequested.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.permissionRequested)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddWebResourceRequested.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.webResourceRequested)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddNavigationCompleted.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.navigationCompleted)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddProcessFailed.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.processFailed)), - uintptr(unsafe.Pointer(&token)), - ) - - e.controller.AddAcceleratorKeyPressed(e.acceleratorKeyPressed, &token) - - atomic.StoreUintptr(&e.inited, 1) - - return 0 -} - -func (e *Chromium) MessageReceived(sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr { - var message *uint16 - args.vtbl.TryGetWebMessageAsString.Call( - uintptr(unsafe.Pointer(args)), - uintptr(unsafe.Pointer(&message)), - ) - if e.MessageCallback != nil { - e.MessageCallback(w32.Utf16PtrToString(message)) - } - sender.vtbl.PostWebMessageAsString.Call( - uintptr(unsafe.Pointer(sender)), - uintptr(unsafe.Pointer(message)), - ) - windows.CoTaskMemFree(unsafe.Pointer(message)) - return 0 -} - -func (e *Chromium) SetPermission(kind CoreWebView2PermissionKind, state CoreWebView2PermissionState) { - e.permissions[kind] = state -} - -func (e *Chromium) SetGlobalPermission(state CoreWebView2PermissionState) { - e.globalPermission = &state -} - -func (e *Chromium) PermissionRequested(_ *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr { - var kind CoreWebView2PermissionKind - args.vtbl.GetPermissionKind.Call( - uintptr(unsafe.Pointer(args)), - uintptr(kind), - ) - var result CoreWebView2PermissionState - if e.globalPermission != nil { - result = *e.globalPermission - } else { - var ok bool - result, ok = e.permissions[kind] - if !ok { - result = CoreWebView2PermissionStateDefault - } - } - args.vtbl.PutState.Call( - uintptr(unsafe.Pointer(args)), - uintptr(result), - ) - return 0 -} - -func (e *Chromium) WebResourceRequested(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr { - req, err := args.GetRequest() - if err != nil { - log.Fatal(err) - } - defer req.Release() - - if e.WebResourceRequestedCallback != nil { - e.WebResourceRequestedCallback(req, args) - } - return 0 -} - -func (e *Chromium) AddWebResourceRequestedFilter(filter string, ctx COREWEBVIEW2_WEB_RESOURCE_CONTEXT) { - err := e.webview.AddWebResourceRequestedFilter(filter, ctx) - if err != nil { - log.Fatal(err) - } -} - -func (e *Chromium) Environment() *ICoreWebView2Environment { - return e.environment -} - -// AcceleratorKeyPressed is called when an accelerator key is pressed. -// If the AcceleratorKeyCallback method has been set, it will defer handling of the keypress -// to the callback. That callback returns a bool indicating if the event was handled. -func (e *Chromium) AcceleratorKeyPressed(sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr { - if e.AcceleratorKeyCallback == nil { - return 0 - } - eventKind, _ := args.GetKeyEventKind() - if eventKind == COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN || - eventKind == COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN { - virtualKey, _ := args.GetVirtualKey() - status, _ := args.GetPhysicalKeyStatus() - if !status.WasKeyDown { - args.PutHandled(e.AcceleratorKeyCallback(virtualKey)) - return 0 - } - } - args.PutHandled(false) - return 0 -} - -func (e *Chromium) GetSettings() (*ICoreWebViewSettings, error) { - return e.webview.GetSettings() -} - -func (e *Chromium) GetController() *ICoreWebView2Controller { - return e.controller -} - -func boolToInt(input bool) int { - if input { - return 1 - } - return 0 -} - -func (e *Chromium) NavigationCompleted(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr { - if e.NavigationCompletedCallback != nil { - e.NavigationCompletedCallback(sender, args) - } - return 0 -} - -func (e *Chromium) ProcessFailed(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr { - if e.ProcessFailedCallback != nil { - e.ProcessFailedCallback(sender, args) - } - return 0 -} - -func (e *Chromium) NotifyParentWindowPositionChanged() error { - //It looks like the wndproc function is called before the controller initialization is complete. - //Because of this the controller is nil - if e.controller == nil { - return nil - } - return e.controller.NotifyParentWindowPositionChanged() -} - -func (e *Chromium) Focus() { - err := e.controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC) - if err != nil { - log.Fatal(err) - } -} - -func (e *Chromium) PutZoomFactor(zoomFactor float64) { - err := e.controller.PutZoomFactor(zoomFactor) - if err != nil { - log.Fatal(err) - } -} - -func (e *Chromium) OpenDevToolsWindow() { - e.webview.OpenDevToolsWindow() -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go deleted file mode 100644 index 00f6f42fb..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "unsafe" -) - -func (e *Chromium) SetSize(bounds w32.Rect) { - if e.controller == nil { - return - } - - e.controller.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(e.controller)), - uintptr(bounds.Left), - uintptr(bounds.Top), - uintptr(bounds.Right), - uintptr(bounds.Bottom), - ) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go deleted file mode 100644 index 858b93f17..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "unsafe" -) - -func (e *Chromium) SetSize(bounds w32.Rect) { - if e.controller == nil { - return - } - - e.controller.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(e.controller)), - uintptr(unsafe.Pointer(&bounds)), - ) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go deleted file mode 100644 index b237792e4..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" -) - -func (e *Chromium) SetSize(bounds w32.Rect) { - if e.controller == nil { - return - } - - words := (*[2]uintptr)(unsafe.Pointer(&bounds)) - e.controller.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(e.controller)), - words[0], - words[1], - ) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go deleted file mode 100644 index 6f1afbd87..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go +++ /dev/null @@ -1,503 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "fmt" - "log" - "runtime" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - - "golang.org/x/sys/windows" -) - -func init() { - runtime.LockOSThread() - - r, _, _ := w32.Ole32CoInitializeEx.Call(0, 2) - if int(r) < 0 { - log.Printf("Warning: CoInitializeEx call failed: E=%08x", r) - } -} - -type _EventRegistrationToken struct { - value int64 -} - -type CoreWebView2PermissionKind uint32 - -const ( - CoreWebView2PermissionKindUnknownPermission CoreWebView2PermissionKind = iota - CoreWebView2PermissionKindMicrophone - CoreWebView2PermissionKindCamera - CoreWebView2PermissionKindGeolocation - CoreWebView2PermissionKindNotifications - CoreWebView2PermissionKindOtherSensors - CoreWebView2PermissionKindClipboardRead -) - -type CoreWebView2PermissionState uint32 - -const ( - CoreWebView2PermissionStateDefault CoreWebView2PermissionState = iota - CoreWebView2PermissionStateAllow - CoreWebView2PermissionStateDeny -) - -// ComProc stores a COM procedure. -type ComProc uintptr - -// NewComProc creates a new COM proc from a Go function. -func NewComProc(fn interface{}) ComProc { - return ComProc(windows.NewCallback(fn)) -} - -// Call calls a COM procedure. -// -//go:uintptrescapes -func (p ComProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { - // The magic uintptrescapes comment is needed to prevent moving uintptr(unsafe.Pointer(p)) so calls to .Call() also - // satisfy the unsafe.Pointer rule "(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall." - // Otherwise it might be that pointers get moved, especially pointer onto the Go stack which might grow dynamically. - // See https://pkg.go.dev/unsafe#Pointer and https://github.com/golang/go/issues/34474 - switch len(a) { - case 0: - return syscall.Syscall(uintptr(p), 0, 0, 0, 0) - case 1: - return syscall.Syscall(uintptr(p), 1, a[0], 0, 0) - case 2: - return syscall.Syscall(uintptr(p), 2, a[0], a[1], 0) - case 3: - return syscall.Syscall(uintptr(p), 3, a[0], a[1], a[2]) - case 4: - return syscall.Syscall6(uintptr(p), 4, a[0], a[1], a[2], a[3], 0, 0) - case 5: - return syscall.Syscall6(uintptr(p), 5, a[0], a[1], a[2], a[3], a[4], 0) - case 6: - return syscall.Syscall6(uintptr(p), 6, a[0], a[1], a[2], a[3], a[4], a[5]) - case 7: - return syscall.Syscall9(uintptr(p), 7, a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) - case 8: - return syscall.Syscall9(uintptr(p), 8, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) - case 9: - return syscall.Syscall9(uintptr(p), 9, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) - case 10: - return syscall.Syscall12(uintptr(p), 10, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) - case 11: - return syscall.Syscall12(uintptr(p), 11, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) - case 12: - return syscall.Syscall12(uintptr(p), 12, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) - case 13: - return syscall.Syscall15(uintptr(p), 13, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) - case 14: - return syscall.Syscall15(uintptr(p), 14, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) - case 15: - return syscall.Syscall15(uintptr(p), 15, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) - default: - panic("too many arguments") - } -} - -// IUnknown - -type _IUnknownVtbl struct { - QueryInterface ComProc - AddRef ComProc - Release ComProc -} - -func (i *_IUnknownVtbl) CallRelease(this unsafe.Pointer) error { - _, _, err := i.Release.Call( - uintptr(this), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -type _IUnknownImpl interface { - QueryInterface(refiid, object uintptr) uintptr - AddRef() uintptr - Release() uintptr -} - -// ICoreWebView2 - -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 ICoreWebView2 struct { - vtbl *iCoreWebView2Vtbl -} - -func (i *ICoreWebView2) GetSettings() (*ICoreWebViewSettings, error) { - var err error - var settings *ICoreWebViewSettings - _, _, err = i.vtbl.GetSettings.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&settings)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return settings, nil -} - -// ICoreWebView2Environment - -type iCoreWebView2EnvironmentVtbl struct { - _IUnknownVtbl - CreateCoreWebView2Controller ComProc - CreateWebResourceResponse ComProc - GetBrowserVersionString ComProc - AddNewBrowserVersionAvailable ComProc - RemoveNewBrowserVersionAvailable ComProc -} - -type ICoreWebView2Environment struct { - vtbl *iCoreWebView2EnvironmentVtbl -} - -// CreateWebResourceResponse creates a new ICoreWebView2WebResourceResponse, it must be released after finishing using it. -func (e *ICoreWebView2Environment) CreateWebResourceResponse(content []byte, statusCode int, reasonPhrase string, headers string) (*ICoreWebView2WebResourceResponse, error) { - var err error - var stream uintptr - - if len(content) > 0 { - // Create stream for response - stream, err = w32.SHCreateMemStream(content) - if err != nil { - return nil, err - } - - // Release the IStream after we are finished, CreateWebResourceResponse Call will increase the reference - // count on IStream and therefore it won't be freed until the reference count of the response is 0. - defer (*IStream)(unsafe.Pointer(stream)).Release() - } - - // Convert string 'uri' to *uint16 - _reason, err := windows.UTF16PtrFromString(reasonPhrase) - if err != nil { - return nil, err - } - // Convert string 'uri' to *uint16 - _headers, err := windows.UTF16PtrFromString(headers) - if err != nil { - return nil, err - } - var response *ICoreWebView2WebResourceResponse - hr, _, err := e.vtbl.CreateWebResourceResponse.Call( - uintptr(unsafe.Pointer(e)), - stream, - uintptr(statusCode), - uintptr(unsafe.Pointer(_reason)), - uintptr(unsafe.Pointer(_headers)), - uintptr(unsafe.Pointer(&response)), - ) - if windows.Handle(hr) != windows.S_OK { - return nil, syscall.Errno(hr) - } - - if response == nil { - if err == nil { - err = fmt.Errorf("unknown error") - } - return nil, err - } - return response, nil - -} - -// ICoreWebView2WebMessageReceivedEventArgs - -type iCoreWebView2WebMessageReceivedEventArgsVtbl struct { - _IUnknownVtbl - GetSource ComProc - GetWebMessageAsJSON ComProc - TryGetWebMessageAsString ComProc -} - -type iCoreWebView2WebMessageReceivedEventArgs struct { - vtbl *iCoreWebView2WebMessageReceivedEventArgsVtbl -} - -// ICoreWebView2PermissionRequestedEventArgs - -type iCoreWebView2PermissionRequestedEventArgsVtbl struct { - _IUnknownVtbl - GetURI ComProc - GetPermissionKind ComProc - GetIsUserInitiated ComProc - GetState ComProc - PutState ComProc - GetDeferral ComProc -} - -type iCoreWebView2PermissionRequestedEventArgs struct { - vtbl *iCoreWebView2PermissionRequestedEventArgsVtbl -} - -// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl interface { - _IUnknownImpl - EnvironmentCompleted(res uintptr, env *ICoreWebView2Environment) uintptr -} - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler struct { - vtbl *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl - impl iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownQueryInterface(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownAddRef(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownRelease(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, res uintptr, env *ICoreWebView2Environment) uintptr { - return this.impl.EnvironmentCompleted(res, env) -} - -var iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerFn = iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke), -} - -func newICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler(impl iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl) *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler { - return &iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler{ - vtbl: &iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerFn, - impl: impl, - } -} - -// ICoreWebView2WebMessageReceivedEventHandler - -type iCoreWebView2WebMessageReceivedEventHandlerImpl interface { - _IUnknownImpl - MessageReceived(sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr -} - -type iCoreWebView2WebMessageReceivedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2WebMessageReceivedEventHandler struct { - vtbl *iCoreWebView2WebMessageReceivedEventHandlerVtbl - impl iCoreWebView2WebMessageReceivedEventHandlerImpl -} - -func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownQueryInterface(this *iCoreWebView2WebMessageReceivedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownAddRef(this *iCoreWebView2WebMessageReceivedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownRelease(this *iCoreWebView2WebMessageReceivedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2WebMessageReceivedEventHandlerInvoke(this *iCoreWebView2WebMessageReceivedEventHandler, sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr { - return this.impl.MessageReceived(sender, args) -} - -var iCoreWebView2WebMessageReceivedEventHandlerFn = iCoreWebView2WebMessageReceivedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerInvoke), -} - -func newICoreWebView2WebMessageReceivedEventHandler(impl iCoreWebView2WebMessageReceivedEventHandlerImpl) *iCoreWebView2WebMessageReceivedEventHandler { - return &iCoreWebView2WebMessageReceivedEventHandler{ - vtbl: &iCoreWebView2WebMessageReceivedEventHandlerFn, - impl: impl, - } -} - -// ICoreWebView2PermissionRequestedEventHandler - -type iCoreWebView2PermissionRequestedEventHandlerImpl interface { - _IUnknownImpl - PermissionRequested(sender *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr -} - -type iCoreWebView2PermissionRequestedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2PermissionRequestedEventHandler struct { - vtbl *iCoreWebView2PermissionRequestedEventHandlerVtbl - impl iCoreWebView2PermissionRequestedEventHandlerImpl -} - -func _ICoreWebView2PermissionRequestedEventHandlerIUnknownQueryInterface(this *iCoreWebView2PermissionRequestedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2PermissionRequestedEventHandlerIUnknownAddRef(this *iCoreWebView2PermissionRequestedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2PermissionRequestedEventHandlerIUnknownRelease(this *iCoreWebView2PermissionRequestedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2PermissionRequestedEventHandlerInvoke(this *iCoreWebView2PermissionRequestedEventHandler, sender *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr { - return this.impl.PermissionRequested(sender, args) -} - -var iCoreWebView2PermissionRequestedEventHandlerFn = iCoreWebView2PermissionRequestedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerInvoke), -} - -func newICoreWebView2PermissionRequestedEventHandler(impl iCoreWebView2PermissionRequestedEventHandlerImpl) *iCoreWebView2PermissionRequestedEventHandler { - return &iCoreWebView2PermissionRequestedEventHandler{ - vtbl: &iCoreWebView2PermissionRequestedEventHandlerFn, - impl: impl, - } -} - -func (i *ICoreWebView2) AddWebResourceRequestedFilter(uri string, resourceContext COREWEBVIEW2_WEB_RESOURCE_CONTEXT) error { - var err error - // Convert string 'uri' to *uint16 - _uri, err := windows.UTF16PtrFromString(uri) - if err != nil { - return err - } - _, _, err = i.vtbl.AddWebResourceRequestedFilter.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), - uintptr(resourceContext), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} -func (i *ICoreWebView2) AddNavigationCompleted(eventHandler *ICoreWebView2NavigationCompletedEventHandler, token *_EventRegistrationToken) error { - var err error - _, _, err = i.vtbl.AddNavigationCompleted.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(eventHandler)), - uintptr(unsafe.Pointer(&token)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2) AddProcessFailed(eventHandler *ICoreWebView2ProcessFailedEventHandler, token *_EventRegistrationToken) error { - var err error - _, _, err = i.vtbl.AddProcessFailed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(eventHandler)), - uintptr(unsafe.Pointer(&token)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2) OpenDevToolsWindow() error { - var err error - _, _, err = i.vtbl.OpenDevToolsWindow.Call( - uintptr(unsafe.Pointer(i)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go deleted file mode 100644 index a3b7374ca..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build windows && !native_webview2loader - -package edge - -import ( - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" -) - -func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error { - e := &environmentCreatedHandler{environmentCompletedHandle} - return webviewloader.CreateCoreWebView2EnvironmentWithOptions( - e, - webviewloader.WithBrowserExecutableFolder(browserExecutableFolder), - webviewloader.WithUserDataFolder(userDataFolder), - webviewloader.WithAdditionalBrowserArguments(additionalBrowserArgs), - ) -} - -type environmentCreatedHandler struct { - originalHandler *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler -} - -func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode webviewloader.HRESULT, createdEnvironment *webviewloader.ICoreWebView2Environment) webviewloader.HRESULT { - env := (*ICoreWebView2Environment)(unsafe.Pointer(createdEnvironment)) - res := r.originalHandler.impl.EnvironmentCompleted(uintptr(errorCode), env) - return webviewloader.HRESULT(res) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go deleted file mode 100644 index 9b4f02bfd..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build windows && native_webview2loader - -package edge - -import ( - "fmt" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" - - "golang.org/x/sys/windows" -) - -func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error { - browserPathPtr, err := windows.UTF16PtrFromString(browserExecutableFolder) - if err != nil { - return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", browserExecutableFolder, err) - } - - userPathPtr, err := windows.UTF16PtrFromString(userDataFolder) - if err != nil { - return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", userDataFolder, err) - } - - hr, err := webviewloader.CreateCoreWebView2EnvironmentWithOptions( - browserPathPtr, - userPathPtr, - uintptr(unsafe.Pointer(environmentCompletedHandle)), - additionalBrowserArgs, - ) - - if hr != 0 { - if err == nil || err == windows.ERROR_SUCCESS { - err = syscall.Errno(hr) - } - return err - } - - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go deleted file mode 100644 index 007e60586..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go +++ /dev/null @@ -1,225 +0,0 @@ -//go:build windows - -package edge - -// This code has been adapted from: https://github.com/go-ole/go-ole - -/* - -The MIT License (MIT) - -Copyright © 2013-2017 Yasuhiro Matsumoto, - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the “Software”), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -const hextable = "0123456789ABCDEF" -const emptyGUID = "{00000000-0000-0000-0000-000000000000}" - -// GUID is Windows API specific GUID type. -// -// This exists to match Windows GUID type for direct passing for COM. -// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx. -type GUID struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]byte -} - -// NewGUID converts the given string into a globally unique identifier that is -// compliant with the Windows API. -// -// The supplied string may be in any of these formats: -// -// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} -// -// The conversion of the supplied string is not case-sensitive. -func NewGUID(guid string) *GUID { - d := []byte(guid) - var d1, d2, d3, d4a, d4b []byte - - switch len(d) { - case 38: - if d[0] != '{' || d[37] != '}' { - return nil - } - d = d[1:37] - fallthrough - case 36: - if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' { - return nil - } - d1 = d[0:8] - d2 = d[9:13] - d3 = d[14:18] - d4a = d[19:23] - d4b = d[24:36] - case 32: - d1 = d[0:8] - d2 = d[8:12] - d3 = d[12:16] - d4a = d[16:20] - d4b = d[20:32] - default: - return nil - } - - var g GUID - var ok1, ok2, ok3, ok4 bool - g.Data1, ok1 = decodeHexUint32(d1) - g.Data2, ok2 = decodeHexUint16(d2) - g.Data3, ok3 = decodeHexUint16(d3) - g.Data4, ok4 = decodeHexByte64(d4a, d4b) - if ok1 && ok2 && ok3 && ok4 { - return &g - } - return nil -} - -func decodeHexUint32(src []byte) (value uint32, ok bool) { - var b1, b2, b3, b4 byte - var ok1, ok2, ok3, ok4 bool - b1, ok1 = decodeHexByte(src[0], src[1]) - b2, ok2 = decodeHexByte(src[2], src[3]) - b3, ok3 = decodeHexByte(src[4], src[5]) - b4, ok4 = decodeHexByte(src[6], src[7]) - value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4) - ok = ok1 && ok2 && ok3 && ok4 - return -} - -func decodeHexUint16(src []byte) (value uint16, ok bool) { - var b1, b2 byte - var ok1, ok2 bool - b1, ok1 = decodeHexByte(src[0], src[1]) - b2, ok2 = decodeHexByte(src[2], src[3]) - value = (uint16(b1) << 8) | uint16(b2) - ok = ok1 && ok2 - return -} - -func decodeHexByte64(s1 []byte, s2 []byte) (value [8]byte, ok bool) { - var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool - value[0], ok1 = decodeHexByte(s1[0], s1[1]) - value[1], ok2 = decodeHexByte(s1[2], s1[3]) - value[2], ok3 = decodeHexByte(s2[0], s2[1]) - value[3], ok4 = decodeHexByte(s2[2], s2[3]) - value[4], ok5 = decodeHexByte(s2[4], s2[5]) - value[5], ok6 = decodeHexByte(s2[6], s2[7]) - value[6], ok7 = decodeHexByte(s2[8], s2[9]) - value[7], ok8 = decodeHexByte(s2[10], s2[11]) - ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8 - return -} - -func decodeHexByte(c1, c2 byte) (value byte, ok bool) { - var n1, n2 byte - var ok1, ok2 bool - n1, ok1 = decodeHexChar(c1) - n2, ok2 = decodeHexChar(c2) - value = (n1 << 4) | n2 - ok = ok1 && ok2 - return -} - -func decodeHexChar(c byte) (byte, bool) { - switch { - case '0' <= c && c <= '9': - return c - '0', true - case 'a' <= c && c <= 'f': - return c - 'a' + 10, true - case 'A' <= c && c <= 'F': - return c - 'A' + 10, true - } - - return 0, false -} - -// String converts the GUID to string form. It will adhere to this pattern: -// -// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} -// -// If the GUID is nil, the string representation of an empty GUID is returned: -// -// {00000000-0000-0000-0000-000000000000} -func (guid *GUID) String() string { - if guid == nil { - return emptyGUID - } - - var c [38]byte - c[0] = '{' - putUint32Hex(c[1:9], guid.Data1) - c[9] = '-' - putUint16Hex(c[10:14], guid.Data2) - c[14] = '-' - putUint16Hex(c[15:19], guid.Data3) - c[19] = '-' - putByteHex(c[20:24], guid.Data4[0:2]) - c[24] = '-' - putByteHex(c[25:37], guid.Data4[2:8]) - c[37] = '}' - return string(c[:]) -} - -func putUint32Hex(b []byte, v uint32) { - b[0] = hextable[byte(v>>24)>>4] - b[1] = hextable[byte(v>>24)&0x0f] - b[2] = hextable[byte(v>>16)>>4] - b[3] = hextable[byte(v>>16)&0x0f] - b[4] = hextable[byte(v>>8)>>4] - b[5] = hextable[byte(v>>8)&0x0f] - b[6] = hextable[byte(v)>>4] - b[7] = hextable[byte(v)&0x0f] -} - -func putUint16Hex(b []byte, v uint16) { - b[0] = hextable[byte(v>>8)>>4] - b[1] = hextable[byte(v>>8)&0x0f] - b[2] = hextable[byte(v)>>4] - b[3] = hextable[byte(v)&0x0f] -} - -func putByteHex(dst, src []byte) { - for i := 0; i < len(src); i++ { - dst[i*2] = hextable[src[i]>>4] - dst[i*2+1] = hextable[src[i]&0x0f] - } -} - -// IsEqualGUID compares two GUID. -// -// Not constant time comparison. -func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool { - return guid1.Data1 == guid2.Data1 && - guid1.Data2 == guid2.Data2 && - guid1.Data3 == guid2.Data3 && - guid1.Data4[0] == guid2.Data4[0] && - guid1.Data4[1] == guid2.Data4[1] && - guid1.Data4[2] == guid2.Data4[2] && - guid1.Data4[3] == guid2.Data4[3] && - guid1.Data4[4] == guid2.Data4[4] && - guid1.Data4[5] == guid2.Data4[5] && - guid1.Data4[6] == guid2.Data4[6] && - guid1.Data4[7] == guid2.Data4[7] -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE deleted file mode 100644 index af1894c87..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -ISC License (ISC) - -Copyright (c) 2020 John Chadwick -Copyright (c) 2022 Wails Project Developers - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md deleted file mode 100644 index f3e020ec4..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Webviewloader - -Webviewloader is a port of [OpenWebView2Loader](https://github.com/jchv/OpenWebView2Loader) to Go. - -It is intended to be feature-complete with the original WebView2Loader distributed with -the WebView2 NuGet package, but some features are intentionally not implemented. - -## Status - -- [x] CompareBrowserVersions -- [x] CreateCoreWebView2Environment -- [x] CreateCoreWebView2EnvironmentWithOptions -- [x] GetAvailableCoreWebView2BrowserVersionString - -## Not implemented features - -- Registry Overrides of Parameters -- Env Variable Overrides of Parameters -- Does not incorporate `GetCurrentPackageInfo` to search for an installed runtime diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/arm64/WebView2Loader.dll b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/arm64/WebView2Loader.dll deleted file mode 100644 index cd1c694b8..000000000 Binary files a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/arm64/WebView2Loader.dll and /dev/null differ diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go deleted file mode 100644 index 892189a4a..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go +++ /dev/null @@ -1,176 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "fmt" - "os" - "path/filepath" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge" - "golang.org/x/sys/windows" -) - -func init() { - fmt.Println("DEB | Using go webview2loader") - preventEnvAndRegistryOverrides() -} - -type webView2RunTimeType int32 - -const ( - webView2RunTimeTypeInstalled webView2RunTimeType = 0x00 - webView2RunTimeTypeRedistributable webView2RunTimeType = 0x01 -) - -// CreateCoreWebView2Environment creates an evergreen WebView2 Environment using the installed WebView2 Runtime version. -// -// This is equivalent to running CreateCoreWebView2EnvironmentWithOptions without any options. -// For more information, see CreateCoreWebView2EnvironmentWithOptions. -func CreateCoreWebView2Environment(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error { - return CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler) -} - -// CreateCoreWebView2EnvironmentWithOptions creates an environment with a custom version of WebView2 Runtime, -// user data folder, and with or without additional options. -// -// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?#createcorewebview2environmentwithoptions -func CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, opts ...option) error { - var params environmentOptions - for _, opt := range opts { - opt(¶ms) - } - - var err error - var dllPath string - var runtimeType webView2RunTimeType - if browserExecutableFolder := params.browserExecutableFolder; browserExecutableFolder != "" { - runtimeType = webView2RunTimeTypeRedistributable - dllPath, err = findEmbeddedClientDll(browserExecutableFolder) - } else { - runtimeType = webView2RunTimeTypeInstalled - dllPath, _, err = findInstalledClientDll(params.preferCanary) - } - - if err != nil { - return err - } - - return createWebViewEnvironmentWithClientDll(dllPath, runtimeType, params.userDataFolder, - ¶ms, environmentCompletedHandler) -} - -func createWebViewEnvironmentWithClientDll(lpLibFileName string, runtimeType webView2RunTimeType, userDataFolder string, - envOptions *environmentOptions, envCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error { - - if !filepath.IsAbs(lpLibFileName) { - return fmt.Errorf("lpLibFileName must be absolute") - } - - dll, err := windows.LoadDLL(lpLibFileName) - if err != nil { - return fmt.Errorf("Loading DLL failed: %w", err) - } - - defer func() { - canUnloadProc, err := dll.FindProc("DllCanUnloadNow") - if err != nil { - return - } - - if r1, _, _ := canUnloadProc.Call(); r1 != windows.NO_ERROR { - return - } - - dll.Release() - }() - - createProc, err := dll.FindProc("CreateWebViewEnvironmentWithOptionsInternal") - if err != nil { - return fmt.Errorf("Unable to find CreateWebViewEnvironmentWithOptionsInternal entrypoint: %w", err) - } - - userDataPtr, err := windows.UTF16PtrFromString(userDataFolder) - if err != nil { - return err - } - - envOptionsCom := combridge.New2[iCoreWebView2EnvironmentOptions, iCoreWebView2EnvironmentOptions2]( - envOptions, envOptions) - - defer envOptionsCom.Close() - - envCompletedHandler = &environmentCreatedHandler{envCompletedHandler} - envCompletedCom := combridge.New[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](envCompletedHandler) - defer envCompletedCom.Close() - - preventEnvAndRegistryOverrides() - - const unknown = 1 - hr, _, err := createProc.Call( - uintptr(unknown), - uintptr(runtimeType), - uintptr(unsafe.Pointer(userDataPtr)), - uintptr(envOptionsCom.Ref()), - uintptr(envCompletedCom.Ref())) - - if hr != 0 { - if err == nil || err == windows.ERROR_SUCCESS { - err = syscall.Errno(hr) - } - return err - } - - return nil -} - -type environmentCreatedHandler struct { - originalHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler -} - -func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT { - // The OpenWebview2Loader has some retry logic and retries once, didn't encounter any case when this would have been - // needed during the development: https://github.com/jchv/OpenWebView2Loader/blob/master/Source/WebView2Loader.cpp#L202 - - if createdEnvironment != nil { - // May or may not be necessary, but the official WebView2Loader seems to do it. - iidICoreWebView2Environment := windows.GUID{ - Data1: 0xb96d755e, - Data2: 0x0319, - Data3: 0x4e92, - Data4: [8]byte{0xa2, 0x96, 0x23, 0x43, 0x6f, 0x46, 0xa1, 0xfc}, - } - - if err := createdEnvironment.QueryInterface(&iidICoreWebView2Environment, &createdEnvironment); err != nil { - createdEnvironment = nil - errNo, ok := err.(syscall.Errno) - if !ok { - errNo = syscall.Errno(windows.E_FAIL) - } - errorCode = HRESULT(errNo) - } - } - - r.originalHandler.EnvironmentCompleted(errorCode, createdEnvironment) - - if createdEnvironment != nil { - createdEnvironment.Release() - } - - return HRESULT(windows.S_OK) -} - -func preventEnvAndRegistryOverrides() { - // Setting these env variables to empty string also prevents registry overrides because webview2 - // checks for existence and not for empty value - os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "") - os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "") - os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0") - - // The following seems not be be required because those are only used by the webview2loader which - // in this case is implemented on our own. But nevertheless set them to empty to be consistent. - os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", "") - os.Setenv("WEBVIEW2_USER_DATA_FOLDER", "") -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go deleted file mode 100644 index 223c77e85..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge" -) - -// HRESULT -// -// See https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values -type HRESULT int32 - -// ICoreWebView2Environment Represents the WebView2 Environment -// -// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment -type ICoreWebView2Environment = combridge.IUnknownImpl - -// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler receives the WebView2Environment created using CreateCoreWebView2Environment. -type ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface { - // EnvironmentCompleted is invoked to receive the created WebView2Environment - // - // See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2createcorewebview2environmentcompletedhandler?#invoke - EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT -} - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface { - combridge.IUnknown - ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler -} - -func init() { - combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler]( - "{4e8a3389-c9d8-4bd2-b6b5-124fee6cc14d}", - _iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke, - ) -} - -func _iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this uintptr, errorCode HRESULT, env *combridge.IUnknownImpl) uintptr { - res := combridge.Resolve[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](this).EnvironmentCompleted(errorCode, env) - return uintptr(res) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go deleted file mode 100644 index 4bae6064a..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go +++ /dev/null @@ -1,276 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "unicode/utf16" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge" - "golang.org/x/sys/windows" -) - -// WithBrowserExecutableFolder to specify whether WebView2 controls use a fixed or installed version -// of the WebView2 Runtime that exists on a user machine. -// -// To use a fixed version of the WebView2 Runtime, -// pass the folder path that contains the fixed version of the WebView2 Runtime. -// BrowserExecutableFolder supports both relative (to the application's executable) and absolute files paths. -// To create WebView2 controls that use the installed version of the WebView2 Runtime that exists on user -// machines, pass a empty string to WithBrowserExecutableFolder. In this scenario, the API tries to find a -// compatible version of the WebView2 Runtime that is installed on the user machine (first at the machine level, -// and then per user) using the selected channel preference. The path of fixed version of the WebView2 Runtime -// should not contain \Edge\Application\. When such a path is used, the API fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED). -func WithBrowserExecutableFolder(folder string) option { - return func(wvep *environmentOptions) { - wvep.browserExecutableFolder = folder - } -} - -// WithUserDataFolder specifies to user data folder location for WebView2 -// -// You may specify the userDataFolder to change the default user data folder location for WebView2. -// The path is either an absolute file path or a relative file path that is interpreted as relative -// to the compiled code for the current process. -// Dhe default user data ({Executable File Name}.WebView2) folder is created in the same directory -// next to the compiled code for the app. WebView2 creation fails if the compiled code is running -// in a directory in which the process does not have permission to create a new directory. -// The app is responsible to clean up the associated user data folder when it is done. -func WithUserDataFolder(folder string) option { - return func(wvep *environmentOptions) { - wvep.userDataFolder = folder - } -} - -// WithAdditionalBrowserArguments changes the behavior of the WebView. -// -// The arguments are passed to the -// browser process as part of the command. For more information about -// using command-line switches with Chromium browser processes, navigate to -// [Run Chromium with Flags][ChromiumDevelopersHowTosRunWithFlags]. -// The value appended to a switch is appended to the browser process, for -// example, in `--edge-webview-switches=xxx` the value is `xxx`. If you -// specify a switch that is important to WebView functionality, it is -// ignored, for example, `--user-data-dir`. Specific features are disabled -// internally and blocked from being enabled. If a switch is specified -// multiple times, only the last instance is used. -// -// \> [!NOTE]\n\> A merge of the different values of the same switch is not attempted, -// except for disabled and enabled features. The features specified by -// `--enable-features` and `--disable-features` are merged with simple -// logic.\n\> * The features is the union of the specified features -// and built-in features. If a feature is disabled, it is removed from the -// enabled features list. -// -// If you specify command-line switches and use the -// `additionalBrowserArguments` parameter, the `--edge-webview-switches` -// value takes precedence and is processed last. If a switch fails to -// parse, the switch is ignored. The default state for the operation is -// to run the browser process with no extra flags. -// -// [ChromiumDevelopersHowTosRunWithFlags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags "Run Chromium with flags | The Chromium Projects" -func WithAdditionalBrowserArguments(args string) option { - return func(wvep *environmentOptions) { - wvep.additionalBrowserArguments = args - } -} - -// WithLanguage sets the default display language for WebView. -// -// It applies to browser UI such as -// context menu and dialogs. It also applies to the `accept-languages` HTTP -// header that WebView sends to websites. It is in the format of -// -// `language[-country]` where `language` is the 2-letter code from -// [ISO 639][ISO639LanguageCodesHtml] -// and `country` is the -// 2-letter code from -// [ISO 3166][ISOStandard72482Html]. -// -// [ISO639LanguageCodesHtml]: https://www.iso.org/iso-639-language-codes.html "ISO 639 | ISO" -// [ISOStandard72482Html]: https://www.iso.org/standard/72482.html "ISO 3166-1:2020 | ISO" -func WithLanguage(lang string) option { - return func(wvep *environmentOptions) { - wvep.language = lang - } -} - -// WithTargetCompatibleBrowserVersion secifies the version of the WebView2 Runtime binaries required to be -// compatible with your app. -// -// This defaults to the WebView2 Runtime version -// that corresponds with the version of the SDK the app is using. The -// format of this value is the same as the format of the -// `BrowserVersionString` property and other `BrowserVersion` values. Only -// the version part of the `BrowserVersion` value is respected. The channel -// suffix, if it exists, is ignored. The version of the WebView2 Runtime -// binaries actually used may be different from the specified -// `TargetCompatibleBrowserVersion`. The binaries are only guaranteed to be -// compatible. Verify the actual version on the `BrowserVersionString` -// property on the `ICoreWebView2Environment`. -func WithTargetCompatibleBrowserVersion(version string) option { - return func(wvep *environmentOptions) { - wvep.targetCompatibleBrowserVersion = version - } -} - -// WithAllowSingleSignOnUsingOSPrimaryAccount is used to enable -// single sign on with Azure Active Directory (AAD) and personal Microsoft -// Account (MSA) resources inside WebView. All AAD accounts, connected to -// Windows and shared for all apps, are supported. For MSA, SSO is only enabled -// for the account associated for Windows account login, if any. -// Default is disabled. Universal Windows Platform apps must also declare -// `enterpriseCloudSSO` -// [Restricted capabilities][WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities] -// for the single sign on (SSO) to work. -// -// [WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]: /windows/uwp/packaging/app-capability-declarations\#restricted-capabilities "Restricted capabilities - App capability declarations | Microsoft Docs" -func WithAllowSingleSignOnUsingOSPrimaryAccount(allow bool) option { - return func(wvep *environmentOptions) { - wvep.allowSingleSignOnUsingOSPrimaryAccount = allow - } -} - -// WithExclusiveUserDataFolderAccess specifies that the WebView environment -// obtains exclusive access to the user data folder. -// -// If the user data folder is already being used by another WebView environment with a -// different value for `ExclusiveUserDataFolderAccess` property, the creation of a WebView2Controller -// using the environment object will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. -// When set as TRUE, no other WebView can be created from other processes using WebView2Environment -// objects with the same UserDataFolder. This prevents other processes from creating WebViews -// which share the same browser process instance, since sharing is performed among -// WebViews that have the same UserDataFolder. When another process tries to create a -// WebView2Controller from an WebView2Environment object created with the same user data folder, -// it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. -func WithExclusiveUserDataFolderAccess(exclusive bool) option { - return func(wvep *environmentOptions) { - wvep.exclusiveUserDataFolderAccess = exclusive - } -} - -type option func(*environmentOptions) - -var _ iCoreWebView2EnvironmentOptions = &environmentOptions{} -var _ iCoreWebView2EnvironmentOptions2 = &environmentOptions{} - -type environmentOptions struct { - browserExecutableFolder string - userDataFolder string - preferCanary bool - - additionalBrowserArguments string - language string - targetCompatibleBrowserVersion string - allowSingleSignOnUsingOSPrimaryAccount bool - exclusiveUserDataFolderAccess bool -} - -func (o *environmentOptions) AdditionalBrowserArguments() string { - return o.additionalBrowserArguments -} - -func (o *environmentOptions) Language() string { - return o.language -} - -func (o *environmentOptions) TargetCompatibleBrowserVersion() string { - v := o.targetCompatibleBrowserVersion - if v == "" { - v = kMinimumCompatibleVersion - } - return v -} - -func (o *environmentOptions) AllowSingleSignOnUsingOSPrimaryAccount() bool { - return o.allowSingleSignOnUsingOSPrimaryAccount -} - -func (o *environmentOptions) ExclusiveUserDataFolderAccess() bool { - return o.exclusiveUserDataFolderAccess -} - -type iCoreWebView2EnvironmentOptions interface { - combridge.IUnknown - - AdditionalBrowserArguments() string - Language() string - TargetCompatibleBrowserVersion() string - AllowSingleSignOnUsingOSPrimaryAccount() bool -} - -type iCoreWebView2EnvironmentOptions2 interface { - combridge.IUnknown - - ExclusiveUserDataFolderAccess() bool -} - -func init() { - combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions]( - "{2fde08a8-1e9a-4766-8c05-95a9ceb9d1c5}", - _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments, - _iCoreWebView2EnvironmentOptionsNOP, - _iCoreWebView2EnvironmentOptionsLanguage, - _iCoreWebView2EnvironmentOptionsNOP, - _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion, - _iCoreWebView2EnvironmentOptionsNOP, - _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount, - _iCoreWebView2EnvironmentOptionsNOP, - ) - - combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions2]( - "{ff85c98a-1ba7-4a6b-90c8-2b752c89e9e2}", - _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess, - _iCoreWebView2EnvironmentOptionsNOP, - ) -} -func _iCoreWebView2EnvironmentOptionsNOP(this uintptr) uintptr { - return uintptr(windows.S_FALSE) -} - -func _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments(this uintptr, value **uint16) uintptr { - v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AdditionalBrowserArguments() - *value = stringToOleString(v) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentOptionsLanguage(this uintptr, value **uint16) uintptr { - args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).Language() - *value = stringToOleString(args) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion(this uintptr, value **uint16) uintptr { - args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).TargetCompatibleBrowserVersion() - *value = stringToOleString(args) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount(this uintptr, value *int32) uintptr { - v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AllowSingleSignOnUsingOSPrimaryAccount() - *value = boolToInt(v) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess(this uintptr, value *int32) uintptr { - v := combridge.Resolve[iCoreWebView2EnvironmentOptions2](this).ExclusiveUserDataFolderAccess() - *value = boolToInt(v) - return uintptr(windows.S_OK) -} - -func stringToOleString(v string) *uint16 { - wstr := utf16.Encode([]rune(v + "\x00")) - lwstr := len(wstr) - ptr := (*uint16)(coTaskMemAlloc(2 * lwstr)) - - copy(unsafe.Slice(ptr, lwstr), wstr) - - return ptr -} - -func boolToInt(v bool) int32 { - if v { - return 1 - } - return 0 -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go deleted file mode 100644 index da9472ff1..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build windows - -package webviewloader - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - - "golang.org/x/sys/windows/registry" -) - -var ( - errNoClientDLLFound = errors.New("no webview2 found") -) - -func findEmbeddedBrowserVersion(filename string) (string, error) { - block, err := getFileVersionInfo(filename) - if err != nil { - return "", err - } - - info, err := verQueryValueString(block, "\\StringFileInfo\\040904B0\\ProductVersion") - if err != nil { - return "", err - } - - return info, nil -} - -func findEmbeddedClientDll(embeddedEdgeSubFolder string) (outClientPath string, err error) { - if !filepath.IsAbs(embeddedEdgeSubFolder) { - exe, err := os.Executable() - if err != nil { - return "", err - } - - embeddedEdgeSubFolder = filepath.Join(filepath.Dir(exe), embeddedEdgeSubFolder) - } - - return findClientDllInFolder(embeddedEdgeSubFolder) -} - -func findClientDllInFolder(folder string) (string, error) { - arch := "" - switch runtime.GOARCH { - case "arm64": - arch = "arm64" - case "amd64": - arch = "x64" - case "386": - arch = "x86" - default: - return "", fmt.Errorf("Unsupported architecture") - } - - dllPath := filepath.Join(folder, "EBWebView", arch, "EmbeddedBrowserWebView.dll") - if _, err := os.Stat(dllPath); err != nil { - return "", mapFindErr(err) - } - return dllPath, nil -} - -func mapFindErr(err error) error { - if errors.Is(err, registry.ErrNotExist) { - return errNoClientDLLFound - } - if errors.Is(err, os.ErrNotExist) { - return errNoClientDLLFound - } - return err -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go deleted file mode 100644 index 7ee171b2a..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go +++ /dev/null @@ -1,94 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "path/filepath" - - "golang.org/x/sys/windows/registry" -) - -const ( - kNumChannels = 4 - kInstallKeyPath = "Software\\Microsoft\\EdgeUpdate\\ClientState\\" - kMinimumCompatibleVersion = "86.0.616.0" -) - -var ( - kChannelName = [kNumChannels]string{ - "", "beta", "dev", "canary", // "internal" - } - - kChannelUuid = [kNumChannels]string{ - "{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}", - "{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}", - "{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}", - "{65C35B14-6C1D-4122-AC46-7148CC9D6497}", - //"{BE59E8FD-089A-411B-A3B0-051D9E417818}", - } - - minimumCompatibleVersion, _ = parseVersion(kMinimumCompatibleVersion) -) - -func findInstalledClientDll(preferCanary bool) (clientPath string, version *version, err error) { - for i := 0; i < kNumChannels; i++ { - channel := i - if preferCanary { - channel = (kNumChannels - 1) - i - } - - key := kInstallKeyPath + kChannelUuid[channel] - for _, checkSystem := range []bool{true, false} { - clientPath, version, err := findInstalledClientDllForChannel(key, checkSystem) - if err == errNoClientDLLFound { - continue - } - if err != nil { - return "", nil, err - } - - version.channel = kChannelName[channel] - return clientPath, version, nil - } - } - return "", nil, errNoClientDLLFound -} - -func findInstalledClientDllForChannel(subKey string, system bool) (clientPath string, clientVersion *version, err error) { - key := registry.LOCAL_MACHINE - if !system { - key = registry.CURRENT_USER - } - - regKey, err := registry.OpenKey(key, subKey, registry.READ|registry.WOW64_32KEY) - if err != nil { - return "", nil, mapFindErr(err) - } - defer regKey.Close() - - embeddedEdgeSubFolder, _, err := regKey.GetStringValue("EBWebView") - if err != nil { - return "", nil, mapFindErr(err) - } - - if embeddedEdgeSubFolder == "" { - return "", nil, errNoClientDLLFound - } - - versionString := filepath.Base(embeddedEdgeSubFolder) - version, err := parseVersion(versionString) - if err != nil { - return "", nil, errNoClientDLLFound - } - - if version.compare(minimumCompatibleVersion) < 0 { - return "", nil, errNoClientDLLFound - } - - dllPath, err := findEmbeddedClientDll(embeddedEdgeSubFolder) - if err != nil { - return "", nil, mapFindErr(err) - } - - return dllPath, &version, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go deleted file mode 100644 index 3e02fe985..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go +++ /dev/null @@ -1,173 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import ( - "errors" - "fmt" - "os" - "sync" - "unsafe" - - "github.com/jchv/go-winloader" - - "golang.org/x/sys/windows" -) - -func init() { - preventEnvAndRegistryOverrides(nil, nil, "") -} - -var ( - memOnce sync.Once - memModule winloader.Module - memCreate winloader.Proc - memCompareBrowserVersions winloader.Proc - memGetAvailableCoreWebView2BrowserVersionString winloader.Proc - memErr error -) - -const ( - // https://referencesource.microsoft.com/#system.web/Util/hresults.cs,20 - E_FILENOTFOUND = 0x80070002 -) - -// CompareBrowserVersions will compare the 2 given versions and return: -// -// Less than zero: v1 < v2 -// zero: v1 == v2 -// Greater than zero: v1 > v2 -func CompareBrowserVersions(v1 string, v2 string) (int, error) { - _v1, err := windows.UTF16PtrFromString(v1) - if err != nil { - return 0, err - } - _v2, err := windows.UTF16PtrFromString(v2) - if err != nil { - return 0, err - } - - err = loadFromMemory() - if err != nil { - return 0, err - } - - var result int32 - _, _, err = memCompareBrowserVersions.Call( - uint64(uintptr(unsafe.Pointer(_v1))), - uint64(uintptr(unsafe.Pointer(_v2))), - uint64(uintptr(unsafe.Pointer(&result)))) - - if err != windows.ERROR_SUCCESS { - return 0, err - } - return int(result), nil -} - -// GetAvailableCoreWebView2BrowserVersionString returns version of the webview2 runtime. -// If path is empty, it will try to find installed webview2 is the system. -// If there is no version installed, a blank string is returned. -func GetAvailableCoreWebView2BrowserVersionString(path string) (string, error) { - if path != "" { - // The default implementation fails if CGO and a fixed browser path is used. It's caused by the go-winloader - // which loads the native DLL from memory. - // Use the new GoWebView2Loader in this case, in the future we will make GoWebView2Loader - // feature-complete and remove the use of the native DLL and go-winloader. - version, err := goGetAvailableCoreWebView2BrowserVersionString(path) - if errors.Is(err, errNoClientDLLFound) { - // WebView2 is not found - return "", nil - } else if err != nil { - return "", err - } - - return version, nil - } - - err := loadFromMemory() - if err != nil { - return "", err - } - - var browserPath *uint16 = nil - if path != "" { - browserPath, err = windows.UTF16PtrFromString(path) - if err != nil { - return "", fmt.Errorf("error calling UTF16PtrFromString for %s: %v", path, err) - } - } - - preventEnvAndRegistryOverrides(browserPath, nil, "") - var result *uint16 - res, _, err := memGetAvailableCoreWebView2BrowserVersionString.Call( - uint64(uintptr(unsafe.Pointer(browserPath))), - uint64(uintptr(unsafe.Pointer(&result)))) - - if res != 0 { - if res == E_FILENOTFOUND { - // WebView2 is not installed - return "", nil - } - - return "", fmt.Errorf("Unable to call GetAvailableCoreWebView2BrowserVersionString (%x): %w", res, err) - } - - version := windows.UTF16PtrToString(result) - windows.CoTaskMemFree(unsafe.Pointer(result)) - return version, nil -} - -// CreateCoreWebView2EnvironmentWithOptions tries to load WebviewLoader2 and -// call the CreateCoreWebView2EnvironmentWithOptions routine. -func CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder *uint16, environmentCompletedHandle uintptr, additionalBrowserArgs string) (uintptr, error) { - err := loadFromMemory() - if err != nil { - return 0, err - } - - preventEnvAndRegistryOverrides(browserExecutableFolder, userDataFolder, additionalBrowserArgs) - res, _, _ := memCreate.Call( - uint64(uintptr(unsafe.Pointer(browserExecutableFolder))), - uint64(uintptr(unsafe.Pointer(userDataFolder))), - 0, - uint64(environmentCompletedHandle), - ) - return uintptr(res), nil -} - -func loadFromMemory() error { - var err error - // DLL is not available natively. Try loading embedded copy. - memOnce.Do(func() { - memModule, memErr = winloader.LoadFromMemory(WebView2Loader) - if memErr != nil { - err = fmt.Errorf("Unable to load WebView2Loader.dll from memory: %w", memErr) - return - } - memCreate = memModule.Proc("CreateCoreWebView2EnvironmentWithOptions") - memCompareBrowserVersions = memModule.Proc("CompareBrowserVersions") - memGetAvailableCoreWebView2BrowserVersionString = memModule.Proc("GetAvailableCoreWebView2BrowserVersionString") - }) - return err -} - -func preventEnvAndRegistryOverrides(browserFolder, userDataFolder *uint16, additionalBrowserArgs string) { - // Setting these env variables to empty string also prevents registry overrides because webview2loader - // checks for existence and not for empty value - os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "") - - // Set these overrides to the values or empty to prevent registry and external env overrides - os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", additionalBrowserArgs) - os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0") - os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", windows.UTF16PtrToString(browserFolder)) - os.Setenv("WEBVIEW2_USER_DATA_FOLDER", windows.UTF16PtrToString(userDataFolder)) -} - -func goGetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) { - clientPath, err := findEmbeddedClientDll(browserExecutableFolder) - if err != nil { - return "", err - } - - return findEmbeddedBrowserVersion(clientPath) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go deleted file mode 100644 index e4ff44ff3..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed x86/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go deleted file mode 100644 index 27423ae8a..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed x64/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go deleted file mode 100644 index bba6a88cb..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed arm64/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go deleted file mode 100644 index 24d0856a5..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go +++ /dev/null @@ -1,143 +0,0 @@ -//go:build windows - -package webviewloader - -import ( - "fmt" - "syscall" - "unicode/utf16" - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalAlloc = modkernel32.NewProc("GlobalAlloc") - procGlobalFree = modkernel32.NewProc("GlobalFree") - - modversion = windows.NewLazySystemDLL("version.dll") - procGetFileVersionInfoSize = modversion.NewProc("GetFileVersionInfoSizeW") - procGetFileVersionInfo = modversion.NewProc("GetFileVersionInfoW") - procVerQueryValue = modversion.NewProc("VerQueryValueW") - - modole32 = windows.NewLazySystemDLL("ole32.dll") - procCoTaskMemAlloc = modole32.NewProc("CoTaskMemAlloc") -) - -func getFileVersionInfo(path string) ([]byte, error) { - lptstrFilename, err := syscall.UTF16PtrFromString(path) - if err != nil { - return nil, err - } - - size, _, err := procGetFileVersionInfoSize.Call( - uintptr(unsafe.Pointer(lptstrFilename)), - 0, - ) - - err = maskErrorSuccess(err) - if size == 0 && err == nil { - err = fmt.Errorf("GetFileVersionInfoSize failed") - } - - if err != nil { - return nil, err - } - - data := make([]byte, size) - ret, _, err := procGetFileVersionInfo.Call( - uintptr(unsafe.Pointer(lptstrFilename)), - 0, - uintptr(size), - uintptr(unsafe.Pointer(&data[0])), - ) - - err = maskErrorSuccess(err) - if ret == 0 && err == nil { - err = fmt.Errorf("GetFileVersionInfo failed") - } - - if err != nil { - return nil, err - } - return data, nil -} - -func verQueryValueString(block []byte, subBlock string) (string, error) { - // Allocate memory from native side to make sure the block doesn't get moved - // because we get a pointer into that memory block from the native verQueryValue - // call back. - pBlock := globalAlloc(0, uint32(len(block))) - defer globalFree(unsafe.Pointer(pBlock)) - - // Copy the memory region into native side memory - copy(unsafe.Slice((*byte)(pBlock), len(block)), block) - - lpSubBlock, err := syscall.UTF16PtrFromString(subBlock) - if err != nil { - return "", err - } - - var lplpBuffer unsafe.Pointer - var puLen uint - ret, _, err := procVerQueryValue.Call( - uintptr(pBlock), - uintptr(unsafe.Pointer(lpSubBlock)), - uintptr(unsafe.Pointer(&lplpBuffer)), - uintptr(unsafe.Pointer(&puLen)), - ) - - err = maskErrorSuccess(err) - if ret == 0 && err == nil { - err = fmt.Errorf("VerQueryValue failed") - } - - if err != nil { - return "", err - } - - if puLen <= 1 { - return "", nil - } - puLen -= 1 // Remove Null-Terminator - - wchar := unsafe.Slice((*uint16)(lplpBuffer), puLen) - return string(utf16.Decode(wchar)), nil -} - -func globalAlloc(uFlags uint, dwBytes uint32) unsafe.Pointer { - ret, _, _ := procGlobalAlloc.Call( - uintptr(uFlags), - uintptr(dwBytes)) - - if ret == 0 { - panic("globalAlloc failed") - } - - return unsafe.Pointer(ret) -} - -func globalFree(data unsafe.Pointer) { - ret, _, _ := procGlobalFree.Call(uintptr(data)) - if ret != 0 { - panic("globalFree failed") - } -} - -func maskErrorSuccess(err error) error { - if err == windows.ERROR_SUCCESS { - return nil - } - return err -} - -func coTaskMemAlloc(size int) unsafe.Pointer { - ret, _, _ := procCoTaskMemAlloc.Call( - uintptr(size)) - - if ret == 0 { - panic("coTaskMemAlloc failed") - } - return unsafe.Pointer(ret) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go deleted file mode 100644 index cf278d950..000000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go +++ /dev/null @@ -1,147 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -// CompareBrowserVersions will compare the 2 given versions and return: -// -// -1 = v1 < v2 -// 0 = v1 == v2 -// 1 = v1 > v2 -func CompareBrowserVersions(v1 string, v2 string) (int, error) { - v, err := parseVersion(v1) - if err != nil { - return 0, fmt.Errorf("v1 invalid: %w", err) - } - - w, err := parseVersion(v2) - if err != nil { - return 0, fmt.Errorf("v2 invalid: %w", err) - } - - return v.compare(w), nil -} - -// GetAvailableCoreWebView2BrowserVersionString get the browser version info including channel name -// if it is the WebView2 Runtime. -// Channel names are Beta, Dev, and Canary. -func GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) { - if browserExecutableFolder != "" { - clientPath, err := findEmbeddedClientDll(browserExecutableFolder) - if errors.Is(err, errNoClientDLLFound) { - // WebView2 is not found - return "", nil - } else if err != nil { - return "", err - } - - return findEmbeddedBrowserVersion(clientPath) - } - - _, version, err := findInstalledClientDll(false) - if errors.Is(err, errNoClientDLLFound) { - return "", nil - } else if err != nil { - return "", err - } - - return version.String(), nil -} - -type version struct { - major int - minor int - patch int - build int - - channel string -} - -func (v version) String() string { - vv := fmt.Sprintf("%d.%d.%d.%d", v.major, v.minor, v.patch, v.build) - if v.channel != "" { - vv += " " + v.channel - } - - return vv -} - -func (v version) compare(o version) int { - if c := compareInt(v.major, o.major); c != 0 { - return c - } - if c := compareInt(v.minor, o.minor); c != 0 { - return c - } - if c := compareInt(v.patch, o.patch); c != 0 { - return c - } - return compareInt(v.build, o.build) -} - -func parseVersion(v string) (version, error) { - var p version - - // Split away channel information... - if i := strings.Index(v, " "); i > 0 { - p.channel = v[i+1:] - v = v[:i] - } - - vv := strings.Split(v, ".") - if len(vv) > 4 { - return p, fmt.Errorf("too many version parts") - } - - var err error - vv, p.major, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad major version: %w", err) - } - - vv, p.minor, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad minor version: %w", err) - } - - vv, p.patch, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad patch version: %w", err) - } - - _, p.build, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad build version: %w", err) - } - - return p, nil -} - -func parseInt(v []string) ([]string, int, error) { - if len(v) == 0 { - return nil, 0, nil - } - - p, err := strconv.ParseInt(v[0], 10, 32) - if err != nil { - return nil, 0, err - } - return v[1:], int(p), nil -} - -func compareInt(v1, v2 int) int { - if v1 == v2 { - return 0 - } - if v1 < v2 { - return -1 - } else { - return +1 - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x64/WebView2Loader.dll b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x64/WebView2Loader.dll deleted file mode 100644 index ab15cffb4..000000000 Binary files a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x64/WebView2Loader.dll and /dev/null differ diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x86/WebView2Loader.dll b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x86/WebView2Loader.dll deleted file mode 100644 index 8609d58ee..000000000 Binary files a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x86/WebView2Loader.dll and /dev/null differ diff --git a/v2/internal/frontend/desktop/windows/window.go b/v2/internal/frontend/desktop/windows/window.go index 43ec57c72..a513e875a 100644 --- a/v2/internal/frontend/desktop/windows/window.go +++ b/v2/internal/frontend/desktop/windows/window.go @@ -3,11 +3,10 @@ package windows import ( + "github.com/wailsapp/go-webview2/pkg/edge" "sync" "unsafe" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32" "github.com/wailsapp/wails/v2/internal/system/operatingsystem" diff --git a/v2/internal/system/system_windows.go b/v2/internal/system/system_windows.go index 1ef076cd8..40b8f0340 100644 --- a/v2/internal/system/system_windows.go +++ b/v2/internal/system/system_windows.go @@ -4,7 +4,7 @@ package system import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" + "github.com/wailsapp/go-webview2/webviewloader" "github.com/wailsapp/wails/v2/internal/system/operatingsystem" "github.com/wailsapp/wails/v2/internal/system/packagemanager" ) diff --git a/v2/internal/wv2installer/wv2installer.go b/v2/internal/wv2installer/wv2installer.go index ce754cee7..c89ad196f 100644 --- a/v2/internal/wv2installer/wv2installer.go +++ b/v2/internal/wv2installer/wv2installer.go @@ -5,7 +5,7 @@ package wv2installer import ( "fmt" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" + "github.com/wailsapp/go-webview2/webviewloader" "github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options/windows" ) diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 0ed111b6f..921521e85 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Now uses new `go-webview2` module. Added by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/2687). - Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) - Enable HiDPI option by default in windows nsis installer by @5aaee9 in [PR](https://github.com/wailsapp/wails/pull/2694)