refactor(browser): defer content blocking initialization to main loop
Move setupContentBlocking from goroutine sleep pattern to explicit main loop execution via RunOnMainThread to ensure GTK is fully ready before loading content filters.
- commit
- 81a156ddaaa440fb981439cdb058b3379060bc8a
- author
- bnema · · 2025-12-06 20:52 UTC
- parent
- 3ba3877
- signature
- unsigned
2 files · +12 -9
M internal/app/browser/browser.go +8 -9
| @@ -281,15 +281,6 @@ func (app *BrowserApp) Run() { | |||
| 281 | 281 | // Register custom scheme resolver for "dumb://" URIs (will be applied after WebView creation) | |
| 282 | 282 | webkit.RegisterURIScheme("dumb", app.schemeHandler.Handle) | |
| 283 | 283 | ||
| 284 | - | // DEFERRED: Initialize content blocking AFTER window shows to speed up boot | |
| 285 | - | // Content filters load from cache quickly (~50ms) and apply to new navigations | |
| 286 | - | go func() { | |
| 287 | - | time.Sleep(100 * time.Millisecond) // Let window render first | |
| 288 | - | if err := app.setupContentBlocking(); err != nil { | |
| 289 | - | logging.Warn(fmt.Sprintf("Warning: failed to setup content blocking: %v", err)) | |
| 290 | - | } | |
| 291 | - | }() | |
| 292 | - | ||
| 293 | 284 | // Create and setup WebView (this also creates TabManager which creates more WebViews) | |
| 294 | 285 | if err := app.createWebView(); err != nil { | |
| 295 | 286 | logging.Warn(fmt.Sprintf("Warning: failed to create WebView: %v", err)) | |
| @@ -428,6 +419,14 @@ func (app *BrowserApp) setupSignalHandling() { | |||
| 428 | 419 | // runMainLoop starts the appropriate main loop based on WebKit availability | |
| 429 | 420 | func (app *BrowserApp) runMainLoop() { | |
| 430 | 421 | if webkit.IsNativeAvailable() { | |
| 422 | + | // Schedule content blocking initialization to run on the first main loop iteration | |
| 423 | + | // This ensures GTK is fully ready before we start loading filters | |
| 424 | + | webkit.RunOnMainThread(func() { | |
| 425 | + | if err := app.setupContentBlocking(); err != nil { | |
| 426 | + | logging.Warn(fmt.Sprintf("Warning: failed to setup content blocking: %v", err)) | |
| 427 | + | } | |
| 428 | + | }) | |
| 429 | + | ||
| 431 | 430 | logging.Info(fmt.Sprintf("Entering GTK main loop…")) | |
| 432 | 431 | webkit.RunMainLoop() | |
| 433 | 432 | logging.Info(fmt.Sprintf("GTK main loop exited")) | |
| @@ -281,15 +281,6 @@ func (app *BrowserApp) Run() { | |||||
| 281 | // Register custom scheme resolver for "dumb://" URIs (will be applied after WebView creation) | 281 | // Register custom scheme resolver for "dumb://" URIs (will be applied after WebView creation) | ||
| 282 | webkit.RegisterURIScheme("dumb", app.schemeHandler.Handle) | 282 | webkit.RegisterURIScheme("dumb", app.schemeHandler.Handle) | ||
| 283 | 283 | ||||
| 284 | - | // DEFERRED: Initialize content blocking AFTER window shows to speed up boot | |||
| 285 | - | // Content filters load from cache quickly (~50ms) and apply to new navigations | |||
| 286 | - | go func() { | |||
| 287 | - | time.Sleep(100 * time.Millisecond) // Let window render first | |||
| 288 | - | if err := app.setupContentBlocking(); err != nil { | |||
| 289 | - | logging.Warn(fmt.Sprintf("Warning: failed to setup content blocking: %v", err)) | |||
| 290 | - | } | |||
| 291 | - | }() | |||
| 292 | - | ||||
| 293 | // Create and setup WebView (this also creates TabManager which creates more WebViews) | 284 | // Create and setup WebView (this also creates TabManager which creates more WebViews) | ||
| 294 | if err := app.createWebView(); err != nil { | 285 | if err := app.createWebView(); err != nil { | ||
| 295 | logging.Warn(fmt.Sprintf("Warning: failed to create WebView: %v", err)) | 286 | logging.Warn(fmt.Sprintf("Warning: failed to create WebView: %v", err)) | ||
| @@ -428,6 +419,14 @@ func (app *BrowserApp) setupSignalHandling() { | |||||
| 428 | // runMainLoop starts the appropriate main loop based on WebKit availability | 419 | // runMainLoop starts the appropriate main loop based on WebKit availability | ||
| 429 | func (app *BrowserApp) runMainLoop() { | 420 | func (app *BrowserApp) runMainLoop() { | ||
| 430 | if webkit.IsNativeAvailable() { | 421 | if webkit.IsNativeAvailable() { | ||
| 422 | + | // Schedule content blocking initialization to run on the first main loop iteration | |||
| 423 | + | // This ensures GTK is fully ready before we start loading filters | |||
| 424 | + | webkit.RunOnMainThread(func() { | |||
| 425 | + | if err := app.setupContentBlocking(); err != nil { | |||
| 426 | + | logging.Warn(fmt.Sprintf("Warning: failed to setup content blocking: %v", err)) | |||
| 427 | + | } | |||
| 428 | + | }) | |||
| 429 | + | ||||
| 431 | logging.Info(fmt.Sprintf("Entering GTK main loop…")) | 430 | logging.Info(fmt.Sprintf("Entering GTK main loop…")) | ||
| 432 | webkit.RunMainLoop() | 431 | webkit.RunMainLoop() | ||
| 433 | logging.Info(fmt.Sprintf("GTK main loop exited")) | 432 | logging.Info(fmt.Sprintf("GTK main loop exited")) | ||
M internal/app/browser/workspace_pane_ops.go +4 -0
| @@ -971,6 +971,10 @@ func (wm *WorkspaceManager) cleanupPane(node *paneNode, generation uint) { | |||
| 971 | 971 | ||
| 972 | 972 | if node.pane != nil { | |
| 973 | 973 | pane := node.pane | |
| 974 | + | // Unregister from filtering BEFORE cleanup to prevent stale pointer callbacks | |
| 975 | + | if pane.webView != nil { | |
| 976 | + | wm.app.UnregisterWebViewFromFiltering(pane.webView) | |
| 977 | + | } | |
| 974 | 978 | pane.Cleanup() | |
| 975 | 979 | pane.CleanupFromWorkspace(wm) | |
| 976 | 980 | if pane.webView != nil { | |
| @@ -971,6 +971,10 @@ func (wm *WorkspaceManager) cleanupPane(node *paneNode, generation uint) { | |||||
| 971 | 971 | ||||
| 972 | if node.pane != nil { | 972 | if node.pane != nil { | ||
| 973 | pane := node.pane | 973 | pane := node.pane | ||
| 974 | + | // Unregister from filtering BEFORE cleanup to prevent stale pointer callbacks | |||
| 975 | + | if pane.webView != nil { | |||
| 976 | + | wm.app.UnregisterWebViewFromFiltering(pane.webView) | |||
| 977 | + | } | |||
| 974 | pane.Cleanup() | 978 | pane.Cleanup() | ||
| 975 | pane.CleanupFromWorkspace(wm) | 979 | pane.CleanupFromWorkspace(wm) | ||
| 976 | if pane.webView != nil { | 980 | if pane.webView != nil { | ||