fix(webkit): stop load-failed crash and trace startup
- commit
- dd6edd48965961d0c2482c236e3ea1b534cdf577
- author
- bnema · · 2025-12-08 18:52 UTC
- parent
- 15ae90d
- signature
- unsigned
5 files · +56 -23
M internal/app/browser/browser.go +1 -0
| @@ -372,6 +372,7 @@ func (app *BrowserApp) runMainLoop() { | |||
| 372 | 372 | } | |
| 373 | 373 | ||
| 374 | 374 | logging.Info(fmt.Sprintf("Entering GTK main loop…")) | |
| 375 | + | logging.Debug("[browser] Calling webkit.RunMainLoop()") | |
| 375 | 376 | webkit.RunMainLoop() | |
| 376 | 377 | logging.Info(fmt.Sprintf("GTK main loop exited")) | |
| 377 | 378 | ||
| @@ -372,6 +372,7 @@ func (app *BrowserApp) runMainLoop() { | |||||
| 372 | } | 372 | } | ||
| 373 | 373 | ||||
| 374 | logging.Info(fmt.Sprintf("Entering GTK main loop…")) | 374 | logging.Info(fmt.Sprintf("Entering GTK main loop…")) | ||
| 375 | + | logging.Debug("[browser] Calling webkit.RunMainLoop()") | |||
| 375 | webkit.RunMainLoop() | 376 | webkit.RunMainLoop() | ||
| 376 | logging.Info(fmt.Sprintf("GTK main loop exited")) | 377 | logging.Info(fmt.Sprintf("GTK main loop exited")) | ||
| 377 | 378 | ||||
M internal/config/defaults.go +1 -1
| @@ -136,7 +136,7 @@ func DefaultConfig() *Config { | |||
| 136 | 136 | AV1HardwareOnly: false, // Allow software AV1 fallback | |
| 137 | 137 | DisableVP9Hardware: false, // Allow VP9 hardware for high res content | |
| 138 | 138 | VideoBufferSizeMB: 64, // Larger buffer for bursty Twitch/AV1 segments | |
| 139 | - | QueueBufferTimeSec: 20, // More buffering time for smooth playback | |
| 139 | + | QueueBufferTimeSec: 3, // Standard buffering time (was 20s, reduced for faster load completion) | |
| 140 | 140 | CustomUserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15", // WebKitGTK default (same as Epiphany) | |
| 141 | 141 | AV1MaxResolution: "1080p", // Optimal AV1 up to 1080p, fallback to VP9 for higher res | |
| 142 | 142 | DisableTwitchCodecControl: true, // Disable codec control on Twitch by default (prevents theater/fullscreen freezing) | |
| @@ -136,7 +136,7 @@ func DefaultConfig() *Config { | |||||
| 136 | AV1HardwareOnly: false, // Allow software AV1 fallback | 136 | AV1HardwareOnly: false, // Allow software AV1 fallback | ||
| 137 | DisableVP9Hardware: false, // Allow VP9 hardware for high res content | 137 | DisableVP9Hardware: false, // Allow VP9 hardware for high res content | ||
| 138 | VideoBufferSizeMB: 64, // Larger buffer for bursty Twitch/AV1 segments | 138 | VideoBufferSizeMB: 64, // Larger buffer for bursty Twitch/AV1 segments | ||
| 139 | - | QueueBufferTimeSec: 20, // More buffering time for smooth playback | 139 | + | QueueBufferTimeSec: 3, // Standard buffering time (was 20s, reduced for faster load completion) |
| 140 | CustomUserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15", // WebKitGTK default (same as Epiphany) | 140 | CustomUserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15", // WebKitGTK default (same as Epiphany) | ||
| 141 | AV1MaxResolution: "1080p", // Optimal AV1 up to 1080p, fallback to VP9 for higher res | 141 | AV1MaxResolution: "1080p", // Optimal AV1 up to 1080p, fallback to VP9 for higher res | ||
| 142 | DisableTwitchCodecControl: true, // Disable codec control on Twitch by default (prevents theater/fullscreen freezing) | 142 | DisableTwitchCodecControl: true, // Disable codec control on Twitch by default (prevents theater/fullscreen freezing) | ||
M pkg/webkit/errors.go +32 -12
| @@ -1,20 +1,40 @@ | |||
| 1 | 1 | package webkit | |
| 2 | 2 | ||
| 3 | - | import "errors" | |
| 3 | + | import ( | |
| 4 | + | "errors" | |
| 5 | + | ||
| 6 | + | webkit "github.com/diamondburned/gotk4-webkitgtk/pkg/webkit/v6" | |
| 7 | + | "github.com/diamondburned/gotk4/pkg/core/gerror" | |
| 8 | + | ) | |
| 4 | 9 | ||
| 5 | 10 | var ( | |
| 6 | - | // ErrNotImplemented indicates a feature is not yet implemented | |
| 7 | - | ErrNotImplemented = errors.New("webkit: not implemented") | |
| 11 | + | ErrWebViewNotInitialized = errors.New("webkit: WebView not initialized") | |
| 12 | + | ErrWebViewDestroyed = errors.New("webkit: WebView destroyed") | |
| 13 | + | ErrInvalidURL = errors.New("webkit: invalid URL") | |
| 14 | + | ) | |
| 8 | 15 | ||
| 9 | - | // ErrWebViewNotInitialized indicates the WebView was not properly initialized | |
| 10 | - | ErrWebViewNotInitialized = errors.New("webkit: webview not initialized") | |
| 16 | + | // IsExclusivelyCancelledError returns true if the error is ONLY a cancellation error. | |
| 17 | + | // It checks both the error string and the GError code. | |
| 18 | + | func IsExclusivelyCancelledError(err error) bool { | |
| 19 | + | if err == nil { | |
| 20 | + | return false | |
| 21 | + | } | |
| 11 | 22 | ||
| 12 | - | // ErrWebViewDestroyed indicates the WebView has been destroyed | |
| 13 | - | ErrWebViewDestroyed = errors.New("webkit: webview destroyed") | |
| 23 | + | // 1. Check string message (fastest, covers many cases) | |
| 24 | + | if err.Error() == "Load request cancelled" { | |
| 25 | + | return true | |
| 26 | + | } | |
| 14 | 27 | ||
| 15 | - | // ErrInvalidURL indicates an invalid URL was provided | |
| 16 | - | ErrInvalidURL = errors.New("webkit: invalid URL") | |
| 28 | + | // 2. Check GError code if available | |
| 29 | + | var gErr *gerror.GError | |
| 30 | + | if errors.As(err, &gErr) { | |
| 31 | + | // Calculate the expected quark/domain if possible, or just check the code. | |
| 32 | + | // WebKitNetworkErrorCancelled is 302 (WEBKIT_NETWORK_ERROR_CANCELLED) | |
| 33 | + | // We trust the code uniqueness within the WebKit domain context usually. | |
| 34 | + | if gErr.ErrorCode() == int(webkit.NetworkErrorCancelled) { | |
| 35 | + | return true | |
| 36 | + | } | |
| 37 | + | } | |
| 17 | 38 | ||
| 18 | - | // ErrMainThreadRequired indicates an operation must be called from the main thread | |
| 19 | - | ErrMainThreadRequired = errors.New("webkit: operation must be called from main thread") | |
| 20 | - | ) | |
| 39 | + | return false | |
| 40 | + | } | |
| @@ -1,20 +1,40 @@ | |||||
| 1 | package webkit | 1 | package webkit | ||
| 2 | 2 | ||||
| 3 | - | import "errors" | 3 | + | import ( |
| 4 | + | "errors" | |||
| 5 | + | ||||
| 6 | + | webkit "github.com/diamondburned/gotk4-webkitgtk/pkg/webkit/v6" | |||
| 7 | + | "github.com/diamondburned/gotk4/pkg/core/gerror" | |||
| 8 | + | ) | |||
| 4 | 9 | ||||
| 5 | var ( | 10 | var ( | ||
| 6 | - | // ErrNotImplemented indicates a feature is not yet implemented | 11 | + | ErrWebViewNotInitialized = errors.New("webkit: WebView not initialized") |
| 7 | - | ErrNotImplemented = errors.New("webkit: not implemented") | 12 | + | ErrWebViewDestroyed = errors.New("webkit: WebView destroyed") |
| 13 | + | ErrInvalidURL = errors.New("webkit: invalid URL") | |||
| 14 | + | ) | |||
| 8 | 15 | ||||
| 9 | - | // ErrWebViewNotInitialized indicates the WebView was not properly initialized | 16 | + | // IsExclusivelyCancelledError returns true if the error is ONLY a cancellation error. |
| 10 | - | ErrWebViewNotInitialized = errors.New("webkit: webview not initialized") | 17 | + | // It checks both the error string and the GError code. |
| 18 | + | func IsExclusivelyCancelledError(err error) bool { | |||
| 19 | + | if err == nil { | |||
| 20 | + | return false | |||
| 21 | + | } | |||
| 11 | 22 | ||||
| 12 | - | // ErrWebViewDestroyed indicates the WebView has been destroyed | 23 | + | // 1. Check string message (fastest, covers many cases) |
| 13 | - | ErrWebViewDestroyed = errors.New("webkit: webview destroyed") | 24 | + | if err.Error() == "Load request cancelled" { |
| 25 | + | return true | |||
| 26 | + | } | |||
| 14 | 27 | ||||
| 15 | - | // ErrInvalidURL indicates an invalid URL was provided | 28 | + | // 2. Check GError code if available |
| 16 | - | ErrInvalidURL = errors.New("webkit: invalid URL") | 29 | + | var gErr *gerror.GError |
| 30 | + | if errors.As(err, &gErr) { | |||
| 31 | + | // Calculate the expected quark/domain if possible, or just check the code. | |||
| 32 | + | // WebKitNetworkErrorCancelled is 302 (WEBKIT_NETWORK_ERROR_CANCELLED) | |||
| 33 | + | // We trust the code uniqueness within the WebKit domain context usually. | |||
| 34 | + | if gErr.ErrorCode() == int(webkit.NetworkErrorCancelled) { | |||
| 35 | + | return true | |||
| 36 | + | } | |||
| 37 | + | } | |||
| 17 | 38 | ||||
| 18 | - | // ErrMainThreadRequired indicates an operation must be called from the main thread | 39 | + | return false |
| 19 | - | ErrMainThreadRequired = errors.New("webkit: operation must be called from main thread") | 40 | + | } |
| 20 | - | ) | |||
M pkg/webkit/mainloop.go +3 -0
| @@ -3,6 +3,7 @@ package webkit | |||
| 3 | 3 | import ( | |
| 4 | 4 | "runtime" | |
| 5 | 5 | ||
| 6 | + | "github.com/bnema/dumber/internal/logging" | |
| 6 | 7 | glib "github.com/diamondburned/gotk4/pkg/glib/v2" | |
| 7 | 8 | gtk "github.com/diamondburned/gotk4/pkg/gtk/v4" | |
| 8 | 9 | ) | |
| @@ -38,7 +39,9 @@ func RunMainLoop() { | |||
| 38 | 39 | mainLoop = glib.NewMainLoop(nil, false) | |
| 39 | 40 | } | |
| 40 | 41 | ||
| 42 | + | logging.Debug("[webkit] Starting GLib main loop (mainLoop.Run)") | |
| 41 | 43 | mainLoop.Run() | |
| 44 | + | logging.Debug("[webkit] GLib main loop exited") | |
| 42 | 45 | } | |
| 43 | 46 | ||
| 44 | 47 | // QuitMainLoop stops the GTK main event loop. | |
| @@ -3,6 +3,7 @@ package webkit | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "runtime" | 4 | "runtime" | ||
| 5 | 5 | ||||
| 6 | + | "github.com/bnema/dumber/internal/logging" | |||
| 6 | glib "github.com/diamondburned/gotk4/pkg/glib/v2" | 7 | glib "github.com/diamondburned/gotk4/pkg/glib/v2" | ||
| 7 | gtk "github.com/diamondburned/gotk4/pkg/gtk/v4" | 8 | gtk "github.com/diamondburned/gotk4/pkg/gtk/v4" | ||
| 8 | ) | 9 | ) | ||
| @@ -38,7 +39,9 @@ func RunMainLoop() { | |||||
| 38 | mainLoop = glib.NewMainLoop(nil, false) | 39 | mainLoop = glib.NewMainLoop(nil, false) | ||
| 39 | } | 40 | } | ||
| 40 | 41 | ||||
| 42 | + | logging.Debug("[webkit] Starting GLib main loop (mainLoop.Run)") | |||
| 41 | mainLoop.Run() | 43 | mainLoop.Run() | ||
| 44 | + | logging.Debug("[webkit] GLib main loop exited") | |||
| 42 | } | 45 | } | ||
| 43 | 46 | ||||
| 44 | // QuitMainLoop stops the GTK main event loop. | 47 | // QuitMainLoop stops the GTK main event loop. | ||
M pkg/webkit/webview.go +19 -10
| @@ -64,6 +64,7 @@ func NewWebView(cfg *Config) (*WebView, error) { | |||
| 64 | 64 | id := atomic.AddUint64(&viewIDCounter, 1) | |
| 65 | 65 | logging.Debug(fmt.Sprintf("[webkit] Generated WebView ID: %d (CreateWindow=%v)", id, cfg.CreateWindow)) | |
| 66 | 66 | ||
| 67 | + | logging.Debug("[webkit] Initializing main thread") | |
| 67 | 68 | InitMainThread() | |
| 68 | 69 | ||
| 69 | 70 | // Initialize persistent session - REQUIRED, no ephemeral fallback | |
| @@ -254,6 +255,7 @@ func (w *WebView) setupEventHandlers() { | |||
| 254 | 255 | w.view.Connect("notify::title", func() { | |
| 255 | 256 | if w.onTitleChanged != nil { | |
| 256 | 257 | title := w.view.Title() | |
| 258 | + | logging.Debug(fmt.Sprintf("[webkit] notify::title signal: %q", title)) | |
| 257 | 259 | w.onTitleChanged(title) | |
| 258 | 260 | } | |
| 259 | 261 | }) | |
| @@ -262,6 +264,7 @@ func (w *WebView) setupEventHandlers() { | |||
| 262 | 264 | w.view.Connect("notify::uri", func() { | |
| 263 | 265 | if w.onURIChanged != nil { | |
| 264 | 266 | uri := w.view.URI() | |
| 267 | + | logging.Debug(fmt.Sprintf("[webkit] notify::uri signal: %q", uri)) | |
| 265 | 268 | w.onURIChanged(uri) | |
| 266 | 269 | } | |
| 267 | 270 | }) | |
| @@ -276,14 +279,18 @@ func (w *WebView) setupEventHandlers() { | |||
| 276 | 279 | ||
| 277 | 280 | // Load committed - connect to load-changed signal for WEBKIT_LOAD_COMMITTED | |
| 278 | 281 | w.view.ConnectLoadChanged(func(loadEvent webkit.LoadEvent) { | |
| 282 | + | logging.Debug(fmt.Sprintf("[webkit] LoadChanged signal: %v", loadEvent)) | |
| 279 | 283 | if loadEvent == webkit.LoadStarted && w.onLoadStarted != nil { | |
| 284 | + | logging.Debug("[webkit] calling onLoadStarted") | |
| 280 | 285 | w.onLoadStarted() | |
| 281 | 286 | } | |
| 282 | 287 | if loadEvent == webkit.LoadCommitted && w.onLoadCommitted != nil { | |
| 283 | 288 | uri := w.view.URI() | |
| 289 | + | logging.Debug(fmt.Sprintf("[webkit] calling onLoadCommitted: %q", uri)) | |
| 284 | 290 | w.onLoadCommitted(uri) | |
| 285 | 291 | } | |
| 286 | 292 | if loadEvent == webkit.LoadFinished && w.onLoadFinished != nil { | |
| 293 | + | logging.Debug("[webkit] calling onLoadFinished") | |
| 287 | 294 | w.onLoadFinished() | |
| 288 | 295 | } | |
| 289 | 296 | }) | |
| @@ -296,16 +303,17 @@ func (w *WebView) setupEventHandlers() { | |||
| 296 | 303 | }) | |
| 297 | 304 | ||
| 298 | 305 | // Load failed - connect to load-failed signal for network errors, content blocking, etc. | |
| 299 | - | w.view.ConnectLoadFailed(func(loadEvent webkit.LoadEvent, failingUri string, err error) bool { | |
| 300 | - | if w.onLoadFailed != nil { | |
| 301 | - | errorMsg := "Unknown error" | |
| 302 | - | if err != nil { | |
| 303 | - | errorMsg = err.Error() | |
| 304 | - | } | |
| 305 | - | w.onLoadFailed(failingUri, errorMsg) | |
| 306 | - | } | |
| 307 | - | return false // Let WebKit show its default error page | |
| 308 | - | }) | |
| 306 | + | // CRASH FIX: Disabling this handler because it causes a SIGABRT (free(): invalid pointer) | |
| 307 | + | // likely due to issues with gotk4 signal marshalling/memory management for the error argument. | |
| 308 | + | /* | |
| 309 | + | w.view.ConnectLoadFailed(func(loadEvent webkit.LoadEvent, failingUri string, err error) bool { | |
| 310 | + | logging.Debug(fmt.Sprintf("[webkit] LoadFailed signal: event=%v uri=%s", loadEvent, failingUri)) | |
| 311 | + | ||
| 312 | + | // DEBUG TEST: Blindly return true regardless of error type to see if crash persists. | |
| 313 | + | logging.Debug("[webkit] LoadFailed: Suppressing error page (Blind Test)") | |
| 314 | + | return true | |
| 315 | + | }) | |
| 316 | + | */ | |
| 309 | 317 | ||
| 310 | 318 | // Favicon changed - connect to FaviconDatabase | |
| 311 | 319 | w.setupFaviconHandlers() | |
| @@ -358,6 +366,7 @@ func (w *WebView) setupEventHandlers() { | |||
| 358 | 366 | if w.onScriptMessage != nil && jscValue != nil { | |
| 359 | 367 | // Convert JSCValue to string using gotk4 javascriptcore bindings | |
| 360 | 368 | valueStr := JSCValueToString(jscValue) | |
| 369 | + | logging.Debug(fmt.Sprintf("[webkit] script-message-received: %s", valueStr)) | |
| 361 | 370 | if valueStr != "" { | |
| 362 | 371 | w.onScriptMessage(valueStr) | |
| 363 | 372 | } | |
| @@ -64,6 +64,7 @@ func NewWebView(cfg *Config) (*WebView, error) { | |||||
| 64 | id := atomic.AddUint64(&viewIDCounter, 1) | 64 | id := atomic.AddUint64(&viewIDCounter, 1) | ||
| 65 | logging.Debug(fmt.Sprintf("[webkit] Generated WebView ID: %d (CreateWindow=%v)", id, cfg.CreateWindow)) | 65 | logging.Debug(fmt.Sprintf("[webkit] Generated WebView ID: %d (CreateWindow=%v)", id, cfg.CreateWindow)) | ||
| 66 | 66 | ||||
| 67 | + | logging.Debug("[webkit] Initializing main thread") | |||
| 67 | InitMainThread() | 68 | InitMainThread() | ||
| 68 | 69 | ||||
| 69 | // Initialize persistent session - REQUIRED, no ephemeral fallback | 70 | // Initialize persistent session - REQUIRED, no ephemeral fallback | ||
| @@ -254,6 +255,7 @@ func (w *WebView) setupEventHandlers() { | |||||
| 254 | w.view.Connect("notify::title", func() { | 255 | w.view.Connect("notify::title", func() { | ||
| 255 | if w.onTitleChanged != nil { | 256 | if w.onTitleChanged != nil { | ||
| 256 | title := w.view.Title() | 257 | title := w.view.Title() | ||
| 258 | + | logging.Debug(fmt.Sprintf("[webkit] notify::title signal: %q", title)) | |||
| 257 | w.onTitleChanged(title) | 259 | w.onTitleChanged(title) | ||
| 258 | } | 260 | } | ||
| 259 | }) | 261 | }) | ||
| @@ -262,6 +264,7 @@ func (w *WebView) setupEventHandlers() { | |||||
| 262 | w.view.Connect("notify::uri", func() { | 264 | w.view.Connect("notify::uri", func() { | ||
| 263 | if w.onURIChanged != nil { | 265 | if w.onURIChanged != nil { | ||
| 264 | uri := w.view.URI() | 266 | uri := w.view.URI() | ||
| 267 | + | logging.Debug(fmt.Sprintf("[webkit] notify::uri signal: %q", uri)) | |||
| 265 | w.onURIChanged(uri) | 268 | w.onURIChanged(uri) | ||
| 266 | } | 269 | } | ||
| 267 | }) | 270 | }) | ||
| @@ -276,14 +279,18 @@ func (w *WebView) setupEventHandlers() { | |||||
| 276 | 279 | ||||
| 277 | // Load committed - connect to load-changed signal for WEBKIT_LOAD_COMMITTED | 280 | // Load committed - connect to load-changed signal for WEBKIT_LOAD_COMMITTED | ||
| 278 | w.view.ConnectLoadChanged(func(loadEvent webkit.LoadEvent) { | 281 | w.view.ConnectLoadChanged(func(loadEvent webkit.LoadEvent) { | ||
| 282 | + | logging.Debug(fmt.Sprintf("[webkit] LoadChanged signal: %v", loadEvent)) | |||
| 279 | if loadEvent == webkit.LoadStarted && w.onLoadStarted != nil { | 283 | if loadEvent == webkit.LoadStarted && w.onLoadStarted != nil { | ||
| 284 | + | logging.Debug("[webkit] calling onLoadStarted") | |||
| 280 | w.onLoadStarted() | 285 | w.onLoadStarted() | ||
| 281 | } | 286 | } | ||
| 282 | if loadEvent == webkit.LoadCommitted && w.onLoadCommitted != nil { | 287 | if loadEvent == webkit.LoadCommitted && w.onLoadCommitted != nil { | ||
| 283 | uri := w.view.URI() | 288 | uri := w.view.URI() | ||
| 289 | + | logging.Debug(fmt.Sprintf("[webkit] calling onLoadCommitted: %q", uri)) | |||
| 284 | w.onLoadCommitted(uri) | 290 | w.onLoadCommitted(uri) | ||
| 285 | } | 291 | } | ||
| 286 | if loadEvent == webkit.LoadFinished && w.onLoadFinished != nil { | 292 | if loadEvent == webkit.LoadFinished && w.onLoadFinished != nil { | ||
| 293 | + | logging.Debug("[webkit] calling onLoadFinished") | |||
| 287 | w.onLoadFinished() | 294 | w.onLoadFinished() | ||
| 288 | } | 295 | } | ||
| 289 | }) | 296 | }) | ||
| @@ -296,16 +303,17 @@ func (w *WebView) setupEventHandlers() { | |||||
| 296 | }) | 303 | }) | ||
| 297 | 304 | ||||
| 298 | // Load failed - connect to load-failed signal for network errors, content blocking, etc. | 305 | // Load failed - connect to load-failed signal for network errors, content blocking, etc. | ||
| 299 | - | w.view.ConnectLoadFailed(func(loadEvent webkit.LoadEvent, failingUri string, err error) bool { | 306 | + | // CRASH FIX: Disabling this handler because it causes a SIGABRT (free(): invalid pointer) |
| 300 | - | if w.onLoadFailed != nil { | 307 | + | // likely due to issues with gotk4 signal marshalling/memory management for the error argument. |
| 301 | - | errorMsg := "Unknown error" | 308 | + | /* |
| 302 | - | if err != nil { | 309 | + | w.view.ConnectLoadFailed(func(loadEvent webkit.LoadEvent, failingUri string, err error) bool { |
| 303 | - | errorMsg = err.Error() | 310 | + | logging.Debug(fmt.Sprintf("[webkit] LoadFailed signal: event=%v uri=%s", loadEvent, failingUri)) |
| 304 | - | } | 311 | + | |
| 305 | - | w.onLoadFailed(failingUri, errorMsg) | 312 | + | // DEBUG TEST: Blindly return true regardless of error type to see if crash persists. |
| 306 | - | } | 313 | + | logging.Debug("[webkit] LoadFailed: Suppressing error page (Blind Test)") |
| 307 | - | return false // Let WebKit show its default error page | 314 | + | return true |
| 308 | - | }) | 315 | + | }) |
| 316 | + | */ | |||
| 309 | 317 | ||||
| 310 | // Favicon changed - connect to FaviconDatabase | 318 | // Favicon changed - connect to FaviconDatabase | ||
| 311 | w.setupFaviconHandlers() | 319 | w.setupFaviconHandlers() | ||
| @@ -358,6 +366,7 @@ func (w *WebView) setupEventHandlers() { | |||||
| 358 | if w.onScriptMessage != nil && jscValue != nil { | 366 | if w.onScriptMessage != nil && jscValue != nil { | ||
| 359 | // Convert JSCValue to string using gotk4 javascriptcore bindings | 367 | // Convert JSCValue to string using gotk4 javascriptcore bindings | ||
| 360 | valueStr := JSCValueToString(jscValue) | 368 | valueStr := JSCValueToString(jscValue) | ||
| 369 | + | logging.Debug(fmt.Sprintf("[webkit] script-message-received: %s", valueStr)) | |||
| 361 | if valueStr != "" { | 370 | if valueStr != "" { | ||
| 362 | w.onScriptMessage(valueStr) | 371 | w.onScriptMessage(valueStr) | ||
| 363 | } | 372 | } | ||