package webkit /* #cgo pkg-config: webkitgtk-6.0 gtk4 #include #include #include // create_related_web_view creates a WebView with the related-view property set // This is the WebKitGTK 6.0 way to share session/cookies between views (for popups) // The related-view property is construct-only, so it must be set during g_object_new static inline WebKitWebView* create_related_web_view(WebKitWebView* parent) { return WEBKIT_WEB_VIEW(g_object_new( WEBKIT_TYPE_WEB_VIEW, "related-view", parent, NULL )); } */ import "C" import ( "fmt" "runtime" "unsafe" "github.com/bnema/dumber/internal/logging" webkit "github.com/diamondburned/gotk4-webkitgtk/pkg/webkit/v6" coreglib "github.com/diamondburned/gotk4/pkg/core/glib" "github.com/diamondburned/gotk4/pkg/glib/v2" "github.com/diamondburned/gotk4/pkg/gtk/v4" ) // NewBareRelatedWebView creates a bare gotk4 WebView with the related-view property set // This ensures the popup shares the same session/process context as the parent // The returned WebView is bare (no wrapper, no initialization) and must be initialized later // // Since gotk4-webkitgtk's wrapWebView() is internal and cannot be accessed, // we manually construct the WebView struct hierarchy using CGO. func NewBareRelatedWebView(parentView *webkit.WebView) *webkit.WebView { if parentView == nil { logging.Warn(fmt.Sprintf("[webkit] NewBareRelatedWebView: parent is nil, creating unrelated WebView")) return webkit.NewWebView() } // Get the native C pointer from the gotk4 WebView parentObj := glib.BaseObject(parentView) if parentObj == nil { logging.Error(fmt.Sprintf("[webkit] NewBareRelatedWebView: failed to get parent object, creating unrelated WebView")) return webkit.NewWebView() } parentNative := (*C.WebKitWebView)(unsafe.Pointer(parentObj.Native())) if parentNative == nil { logging.Error(fmt.Sprintf("[webkit] NewBareRelatedWebView: parent native pointer is nil, creating unrelated WebView")) return webkit.NewWebView() } logging.Debug(fmt.Sprintf("[webkit] Creating bare WebView with related-view property (parent=%p)", parentNative)) // Create related WebView using CGO helper with g_object_new logging.Debug(fmt.Sprintf("[webkit] Step 3: About to call C.create_related_web_view")) webViewNative := C.create_related_web_view(parentNative) logging.Debug(fmt.Sprintf("[webkit] Step 4: C.create_related_web_view returned: %p", webViewNative)) if webViewNative == nil { logging.Error(fmt.Sprintf("[webkit] NewBareRelatedWebView: C.create_related_web_view returned nil")) return nil } // Wrap the C object in a coreglib.Object // This takes ownership of the floating reference logging.Debug(fmt.Sprintf("[webkit] Step 5: About to call coreglib.Take")) obj := coreglib.Take(unsafe.Pointer(webViewNative)) logging.Debug(fmt.Sprintf("[webkit] Step 6: coreglib.Take succeeded, obj=%p", obj)) // Manually construct the WebView struct hierarchy // WebView -> WebViewBase -> gtk.Widget -> coreglib.InitiallyUnowned -> coreglib.Object // // Since we cannot call the internal wrapWebView() function, we must // manually construct the full struct hierarchy using the same pattern // that gotk4 uses internally. logging.Debug(fmt.Sprintf("[webkit] Step 7: About to create gtk.Widget base")) // Create the gtk.Widget base widget := gtk.Widget{ InitiallyUnowned: coreglib.InitiallyUnowned{ Object: obj, }, Object: obj, Accessible: gtk.Accessible{ Object: obj, }, Buildable: gtk.Buildable{ Object: obj, }, ConstraintTarget: gtk.ConstraintTarget{ Object: obj, }, } logging.Debug(fmt.Sprintf("[webkit] Step 8: Created gtk.Widget base")) // Create the WebViewBase logging.Debug(fmt.Sprintf("[webkit] Step 9: About to create WebViewBase")) webViewBase := webkit.WebViewBase{ Widget: widget, } logging.Debug(fmt.Sprintf("[webkit] Step 10: Created WebViewBase")) // Create the final WebView logging.Debug(fmt.Sprintf("[webkit] Step 11: About to create final WebView")) relatedView := &webkit.WebView{ WebViewBase: webViewBase, } logging.Debug(fmt.Sprintf("[webkit] Step 12: Created final WebView: %p", relatedView)) // Ensure parentView is kept alive until after the CGO call completes runtime.KeepAlive(parentView) logging.Debug(fmt.Sprintf("[webkit] Created bare related WebView (parent=%p)", parentNative)) return relatedView }