chore(deps): bump purego-cef to v0.14.1
v0.14.0 pinned the CEF API 15000 contract and fixed the struct ABI corruption that made BrowserSettings.BackgroundColor land on chrome_status_bubble (transparent windowless canvas). v0.14.1 restores the global function bindings dropped by that regeneration (DictionaryValueCreate, V8ContextGetCurrentContext, all *Create factories) and fixes global factory ownership so created objects are adopted without a leaked reference. This makes the white-canvas fix in this branch effective: the opaque white BrowserSettings.BackgroundColor now actually reaches libcef.
- commit
- 902c404508da47722a324d2f14b2a4cfc04a2812
- author
- brice · · 2026-07-21 19:07 UTC
- parent
- 1dc7dd4
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
75 files · +1836 -1983
M go.mod +1 -1
| @@ -6,7 +6,7 @@ require ( | |||
| 6 | 6 | github.com/a-h/templ v0.3.1020 | |
| 7 | 7 | github.com/andybalholm/brotli v1.2.2 | |
| 8 | 8 | github.com/bnema/purego v0.11.0-bnema.4 | |
| 9 | - | github.com/bnema/purego-cef v0.13.4 | |
| 9 | + | github.com/bnema/purego-cef v0.14.1 | |
| 10 | 10 | github.com/bnema/purego-cef2gtk v0.8.5 | |
| 11 | 11 | github.com/bnema/purego-pipewire v0.1.5 | |
| 12 | 12 | github.com/bnema/purego-sqlite v0.1.4 | |
| @@ -6,7 +6,7 @@ require ( | |||||
| 6 | github.com/a-h/templ v0.3.1020 | 6 | github.com/a-h/templ v0.3.1020 | ||
| 7 | github.com/andybalholm/brotli v1.2.2 | 7 | github.com/andybalholm/brotli v1.2.2 | ||
| 8 | github.com/bnema/purego v0.11.0-bnema.4 | 8 | github.com/bnema/purego v0.11.0-bnema.4 | ||
| 9 | - | github.com/bnema/purego-cef v0.13.4 | 9 | + | github.com/bnema/purego-cef v0.14.1 |
| 10 | github.com/bnema/purego-cef2gtk v0.8.5 | 10 | github.com/bnema/purego-cef2gtk v0.8.5 | ||
| 11 | github.com/bnema/purego-pipewire v0.1.5 | 11 | github.com/bnema/purego-pipewire v0.1.5 | ||
| 12 | github.com/bnema/purego-sqlite v0.1.4 | 12 | github.com/bnema/purego-sqlite v0.1.4 | ||
M go.sum +2 -2 generated file: collapsed
M vendor/github.com/bnema/purego-cef/cef/cef_browser_gen.go +15 -2 generated file: collapsed
M vendor/github.com/bnema/purego-cef/cef/cef_command_line_gen.go +15 -2 generated file: collapsed
A vendor/github.com/bnema/purego-cef/cef/cef_component_updater_gen.go +323 -0 generated file: collapsed
M vendor/github.com/bnema/purego-cef/cef/cef_cookie_gen.go +14 -1 generated file: collapsed
M vendor/github.com/bnema/purego-cef/cef/cef_drag_data_gen.go +14 -1 generated file: collapsed
M vendor/github.com/bnema/purego-cef/cef/cef_image_gen.go +14 -1 generated file: collapsed
M vendor/github.com/bnema/purego-cef/cef/cef_media_router_gen.go +24 -41
| @@ -103,6 +103,19 @@ func wrapMediaRouter(ptr unsafe.Pointer) MediaRouter { | |||
| 103 | 103 | return impl | |
| 104 | 104 | } | |
| 105 | 105 | ||
| 106 | + | // takeMediaRouter adopts a CEF MediaRouter pointer whose reference is already owned by | |
| 107 | + | // the caller (as returned by a global factory function). Unlike wrapMediaRouter it | |
| 108 | + | // does NOT call AddRef, because the C API already transferred one reference to us. | |
| 109 | + | func takeMediaRouter(ptr unsafe.Pointer) MediaRouter { | |
| 110 | + | if ptr == nil { | |
| 111 | + | return nil | |
| 112 | + | } | |
| 113 | + | r := (*capi.CEFMediaRouterT)(ptr) | |
| 114 | + | impl := &mediaRouterImpl{rawPtr: r} | |
| 115 | + | runtime.SetFinalizer(impl, (*mediaRouterImpl).Release) | |
| 116 | + | return impl | |
| 117 | + | } | |
| 118 | + | ||
| 106 | 119 | // MediaObserver Implemented by the client to observe MediaRouter events and registered via cef_media_router_t::AddObserver. The functions of this structure will be called on the browser process UI thread. | |
| 107 | 120 | type MediaObserver = portin.MediaObserver | |
| 108 | 121 | ||
| @@ -128,15 +141,9 @@ func mediaObserverOnSinksCEFCallback() uintptr { | |||
| 128 | 141 | if !ownerOK { | |
| 129 | 142 | return | |
| 130 | 143 | } | |
| 131 | - | var sinks []MediaSink | |
| 132 | - | if arg1 != 0 && arg0 > 0 { | |
| 133 | - | sinksPtrs := unsafe.Slice((*uintptr)(cefCallbackPointer(arg1)), int(arg0)) | |
| 134 | - | sinks = make([]MediaSink, int(arg0)) | |
| 135 | - | for i, ptr := range sinksPtrs { | |
| 136 | - | sinks[i] = wrapMediaSink(cefCallbackPointer(ptr)) | |
| 137 | - | } | |
| 138 | - | } | |
| 139 | - | impl.OnSinks(sinks) | |
| 144 | + | sinkscount := int(arg0) | |
| 145 | + | sinks := unsafe.Pointer(arg1) | |
| 146 | + | impl.OnSinks(sinkscount, sinks) | |
| 140 | 147 | }) | |
| 141 | 148 | } | |
| 142 | 149 | ||
| @@ -149,15 +156,9 @@ func mediaObserverOnRoutesCEFCallback() uintptr { | |||
| 149 | 156 | if !ownerOK { | |
| 150 | 157 | return | |
| 151 | 158 | } | |
| 152 | - | var routes []MediaRoute | |
| 153 | - | if arg1 != 0 && arg0 > 0 { | |
| 154 | - | routesPtrs := unsafe.Slice((*uintptr)(cefCallbackPointer(arg1)), int(arg0)) | |
| 155 | - | routes = make([]MediaRoute, int(arg0)) | |
| 156 | - | for i, ptr := range routesPtrs { | |
| 157 | - | routes[i] = wrapMediaRoute(cefCallbackPointer(ptr)) | |
| 158 | - | } | |
| 159 | - | } | |
| 160 | - | impl.OnRoutes(routes) | |
| 159 | + | routescount := int(arg0) | |
| 160 | + | routes := unsafe.Pointer(arg1) | |
| 161 | + | impl.OnRoutes(routescount, routes) | |
| 161 | 162 | }) | |
| 162 | 163 | } | |
| 163 | 164 | ||
| @@ -221,38 +222,20 @@ type mediaObserverImpl struct { | |||
| 221 | 222 | releaseOnce sync.Once | |
| 222 | 223 | } | |
| 223 | 224 | ||
| 224 | - | func (obj *mediaObserverImpl) OnSinks(sinks []MediaSink) { | |
| 225 | + | func (obj *mediaObserverImpl) OnSinks(sinkscount int, sinks unsafe.Pointer) { | |
| 225 | 226 | if obj == nil || obj.rawPtr == nil { | |
| 226 | 227 | return | |
| 227 | 228 | } | |
| 228 | 229 | rawPtr := obj.rawPtr | |
| 229 | - | var sinksRaw []uintptr | |
| 230 | - | var sinksPtr unsafe.Pointer | |
| 231 | - | if len(sinks) > 0 { | |
| 232 | - | sinksRaw = make([]uintptr, len(sinks)) | |
| 233 | - | for i, elem := range sinks { | |
| 234 | - | sinksRaw[i] = uintptr(extractRawPointer(elem)) | |
| 235 | - | } | |
| 236 | - | sinksPtr = unsafe.Pointer(&sinksRaw[0]) | |
| 237 | - | } | |
| 238 | - | rawPtr.CallOnSinks(uintptr(len(sinks)), uintptr(sinksPtr)) | |
| 230 | + | rawPtr.CallOnSinks(uintptr(sinkscount), uintptr(sinks)) | |
| 239 | 231 | } | |
| 240 | 232 | ||
| 241 | - | func (obj *mediaObserverImpl) OnRoutes(routes []MediaRoute) { | |
| 233 | + | func (obj *mediaObserverImpl) OnRoutes(routescount int, routes unsafe.Pointer) { | |
| 242 | 234 | if obj == nil || obj.rawPtr == nil { | |
| 243 | 235 | return | |
| 244 | 236 | } | |
| 245 | 237 | rawPtr := obj.rawPtr | |
| 246 | - | var routesRaw []uintptr | |
| 247 | - | var routesPtr unsafe.Pointer | |
| 248 | - | if len(routes) > 0 { | |
| 249 | - | routesRaw = make([]uintptr, len(routes)) | |
| 250 | - | for i, elem := range routes { | |
| 251 | - | routesRaw[i] = uintptr(extractRawPointer(elem)) | |
| 252 | - | } | |
| 253 | - | routesPtr = unsafe.Pointer(&routesRaw[0]) | |
| 254 | - | } | |
| 255 | - | rawPtr.CallOnRoutes(uintptr(len(routes)), uintptr(routesPtr)) | |
| 238 | + | rawPtr.CallOnRoutes(uintptr(routescount), uintptr(routes)) | |
| 256 | 239 | } | |
| 257 | 240 | ||
| 258 | 241 | func (obj *mediaObserverImpl) OnRouteStateChanged(route MediaRoute, state MediaRouteConnectionState) { | |
| @@ -784,5 +767,5 @@ func wrapMediaSource(ptr unsafe.Pointer) MediaSource { | |||
| 784 | 767 | // MediaRouterGetGlobal Returns the MediaRouter object associated with the global request context. If |callback| is non-NULL it will be executed asnychronously on the UI thread after the manager's storage has been initialized. Equivalent to calling cef_request_context_t::cef_request_context_get_global_context()- >get_media_router(). | |
| 785 | 768 | func MediaRouterGetGlobal(callback CompletionCallback) MediaRouter { | |
| 786 | 769 | ret := capi.CEFMediaRouterGetGlobal(extractOrWrapRawPointer(callback, func() any { return NewCompletionCallback(callback) })) | |
| 787 | - | return wrapMediaRouter(ret) | |
| 770 | + | return takeMediaRouter(ret) | |
| 788 | 771 | } | |
| @@ -103,6 +103,19 @@ func wrapMediaRouter(ptr unsafe.Pointer) MediaRouter { | |||||
| 103 | return impl | 103 | return impl | ||
| 104 | } | 104 | } | ||
| 105 | 105 | ||||
| 106 | + | // takeMediaRouter adopts a CEF MediaRouter pointer whose reference is already owned by | |||
| 107 | + | // the caller (as returned by a global factory function). Unlike wrapMediaRouter it | |||
| 108 | + | // does NOT call AddRef, because the C API already transferred one reference to us. | |||
| 109 | + | func takeMediaRouter(ptr unsafe.Pointer) MediaRouter { | |||
| 110 | + | if ptr == nil { | |||
| 111 | + | return nil | |||
| 112 | + | } | |||
| 113 | + | r := (*capi.CEFMediaRouterT)(ptr) | |||
| 114 | + | impl := &mediaRouterImpl{rawPtr: r} | |||
| 115 | + | runtime.SetFinalizer(impl, (*mediaRouterImpl).Release) | |||
| 116 | + | return impl | |||
| 117 | + | } | |||
| 118 | + | ||||
| 106 | // MediaObserver Implemented by the client to observe MediaRouter events and registered via cef_media_router_t::AddObserver. The functions of this structure will be called on the browser process UI thread. | 119 | // MediaObserver Implemented by the client to observe MediaRouter events and registered via cef_media_router_t::AddObserver. The functions of this structure will be called on the browser process UI thread. | ||
| 107 | type MediaObserver = portin.MediaObserver | 120 | type MediaObserver = portin.MediaObserver | ||
| 108 | 121 | ||||
| @@ -128,15 +141,9 @@ func mediaObserverOnSinksCEFCallback() uintptr { | |||||
| 128 | if !ownerOK { | 141 | if !ownerOK { | ||
| 129 | return | 142 | return | ||
| 130 | } | 143 | } | ||
| 131 | - | var sinks []MediaSink | 144 | + | sinkscount := int(arg0) |
| 132 | - | if arg1 != 0 && arg0 > 0 { | 145 | + | sinks := unsafe.Pointer(arg1) |
| 133 | - | sinksPtrs := unsafe.Slice((*uintptr)(cefCallbackPointer(arg1)), int(arg0)) | 146 | + | impl.OnSinks(sinkscount, sinks) |
| 134 | - | sinks = make([]MediaSink, int(arg0)) | |||
| 135 | - | for i, ptr := range sinksPtrs { | |||
| 136 | - | sinks[i] = wrapMediaSink(cefCallbackPointer(ptr)) | |||
| 137 | - | } | |||
| 138 | - | } | |||
| 139 | - | impl.OnSinks(sinks) | |||
| 140 | }) | 147 | }) | ||
| 141 | } | 148 | } | ||
| 142 | 149 | ||||
| @@ -149,15 +156,9 @@ func mediaObserverOnRoutesCEFCallback() uintptr { | |||||
| 149 | if !ownerOK { | 156 | if !ownerOK { | ||
| 150 | return | 157 | return | ||
| 151 | } | 158 | } | ||
| 152 | - | var routes []MediaRoute | 159 | + | routescount := int(arg0) |
| 153 | - | if arg1 != 0 && arg0 > 0 { | 160 | + | routes := unsafe.Pointer(arg1) |
| 154 | - | routesPtrs := unsafe.Slice((*uintptr)(cefCallbackPointer(arg1)), int(arg0)) | 161 | + | impl.OnRoutes(routescount, routes) |
| 155 | - | routes = make([]MediaRoute, int(arg0)) | |||
| 156 | - | for i, ptr := range routesPtrs { | |||
| 157 | - | routes[i] = wrapMediaRoute(cefCallbackPointer(ptr)) | |||
| 158 | - | } | |||
| 159 | - | } | |||
| 160 | - | impl.OnRoutes(routes) | |||
| 161 | }) | 162 | }) | ||
| 162 | } | 163 | } | ||
| 163 | 164 | ||||
| @@ -221,38 +222,20 @@ type mediaObserverImpl struct { | |||||
| 221 | releaseOnce sync.Once | 222 | releaseOnce sync.Once | ||
| 222 | } | 223 | } | ||
| 223 | 224 | ||||
| 224 | - | func (obj *mediaObserverImpl) OnSinks(sinks []MediaSink) { | 225 | + | func (obj *mediaObserverImpl) OnSinks(sinkscount int, sinks unsafe.Pointer) { |
| 225 | if obj == nil || obj.rawPtr == nil { | 226 | if obj == nil || obj.rawPtr == nil { | ||
| 226 | return | 227 | return | ||
| 227 | } | 228 | } | ||
| 228 | rawPtr := obj.rawPtr | 229 | rawPtr := obj.rawPtr | ||
| 229 | - | var sinksRaw []uintptr | 230 | + | rawPtr.CallOnSinks(uintptr(sinkscount), uintptr(sinks)) |
| 230 | - | var sinksPtr unsafe.Pointer | |||
| 231 | - | if len(sinks) > 0 { | |||
| 232 | - | sinksRaw = make([]uintptr, len(sinks)) | |||
| 233 | - | for i, elem := range sinks { | |||
| 234 | - | sinksRaw[i] = uintptr(extractRawPointer(elem)) | |||
| 235 | - | } | |||
| 236 | - | sinksPtr = unsafe.Pointer(&sinksRaw[0]) | |||
| 237 | - | } | |||
| 238 | - | rawPtr.CallOnSinks(uintptr(len(sinks)), uintptr(sinksPtr)) | |||
| 239 | } | 231 | } | ||
| 240 | 232 | ||||
| 241 | - | func (obj *mediaObserverImpl) OnRoutes(routes []MediaRoute) { | 233 | + | func (obj *mediaObserverImpl) OnRoutes(routescount int, routes unsafe.Pointer) { |
| 242 | if obj == nil || obj.rawPtr == nil { | 234 | if obj == nil || obj.rawPtr == nil { | ||
| 243 | return | 235 | return | ||
| 244 | } | 236 | } | ||
| 245 | rawPtr := obj.rawPtr | 237 | rawPtr := obj.rawPtr | ||
| 246 | - | var routesRaw []uintptr | 238 | + | rawPtr.CallOnRoutes(uintptr(routescount), uintptr(routes)) |
| 247 | - | var routesPtr unsafe.Pointer | |||
| 248 | - | if len(routes) > 0 { | |||
| 249 | - | routesRaw = make([]uintptr, len(routes)) | |||
| 250 | - | for i, elem := range routes { | |||
| 251 | - | routesRaw[i] = uintptr(extractRawPointer(elem)) | |||
| 252 | - | } | |||
| 253 | - | routesPtr = unsafe.Pointer(&routesRaw[0]) | |||
| 254 | - | } | |||
| 255 | - | rawPtr.CallOnRoutes(uintptr(len(routes)), uintptr(routesPtr)) | |||
| 256 | } | 239 | } | ||
| 257 | 240 | ||||
| 258 | func (obj *mediaObserverImpl) OnRouteStateChanged(route MediaRoute, state MediaRouteConnectionState) { | 241 | func (obj *mediaObserverImpl) OnRouteStateChanged(route MediaRoute, state MediaRouteConnectionState) { | ||
| @@ -784,5 +767,5 @@ func wrapMediaSource(ptr unsafe.Pointer) MediaSource { | |||||
| 784 | // MediaRouterGetGlobal Returns the MediaRouter object associated with the global request context. If |callback| is non-NULL it will be executed asnychronously on the UI thread after the manager's storage has been initialized. Equivalent to calling cef_request_context_t::cef_request_context_get_global_context()- >get_media_router(). | 767 | // MediaRouterGetGlobal Returns the MediaRouter object associated with the global request context. If |callback| is non-NULL it will be executed asnychronously on the UI thread after the manager's storage has been initialized. Equivalent to calling cef_request_context_t::cef_request_context_get_global_context()- >get_media_router(). | ||
| 785 | func MediaRouterGetGlobal(callback CompletionCallback) MediaRouter { | 768 | func MediaRouterGetGlobal(callback CompletionCallback) MediaRouter { | ||
| 786 | ret := capi.CEFMediaRouterGetGlobal(extractOrWrapRawPointer(callback, func() any { return NewCompletionCallback(callback) })) | 769 | ret := capi.CEFMediaRouterGetGlobal(extractOrWrapRawPointer(callback, func() any { return NewCompletionCallback(callback) })) | ||
| 787 | - | return wrapMediaRouter(ret) | 770 | + | return takeMediaRouter(ret) |
| 788 | } | 771 | } | ||