fix(webkit): use default WebContext to prevent dumb:// scheme mismatch
- commit
- 3ef6fdfb408bea07421d1ca05fc74621b509c7b2
- author
- brice · · 2025-12-28 17:20 UTC
- committer
- brice · · 2025-12-29 17:28 UTC
- parent
- 95e4a50
- signature
- unsigned
2 files · +27 -21
M internal/infrastructure/webkit/context.go +11 -20
| @@ -74,30 +74,21 @@ func NewWebKitContextWithOptions(ctx context.Context, opts port.WebKitContextOpt | |||
| 74 | 74 | return nil, fmt.Errorf("failed to init network session: %w", err) | |
| 75 | 75 | } | |
| 76 | 76 | ||
| 77 | - | // Create WebContext - with memory pressure settings if configured | |
| 77 | + | // WebViews in this codebase are created via WebKit's default WebContext. | |
| 78 | + | // If we create a separate WebContext here and only register our custom | |
| 79 | + | // dumb:// scheme on it, internal pages will break with "The URL can't be shown". | |
| 80 | + | // | |
| 81 | + | // Additionally, WebKit's "memory-pressure-settings" is a construct-only property, | |
| 82 | + | // so setting it after `webkit.NewWebContext()` triggers a GLib critical and has no effect. | |
| 83 | + | // Until we can reliably construct a WebContext with memory-pressure-settings AND ensure | |
| 84 | + | // all WebViews use that context, we intentionally stick to the default WebContext. | |
| 78 | 85 | if opts.IsWebProcessMemoryConfigured() { | |
| 79 | - | applier := NewMemoryPressureApplier() | |
| 80 | - | settings, err := applier.ApplyWebProcessSettings(ctx, opts.WebProcessMemory) | |
| 81 | - | if err != nil { | |
| 82 | - | log.Warn().Err(err).Msg("failed to prepare web process memory pressure settings") | |
| 83 | - | } | |
| 84 | - | if settings != nil { | |
| 85 | - | wkCtx.webContext = createWebContextWithMemorySettings(settings.(*webkit.MemoryPressureSettings)) | |
| 86 | - | if wkCtx.webContext != nil { | |
| 87 | - | log.Debug().Msg("created WebContext with memory pressure settings") | |
| 88 | - | } | |
| 89 | - | } | |
| 86 | + | log.Warn().Msg("web process memory pressure settings requested but not applied (construct-only WebContext property; would break dumb:// scheme registration)") | |
| 90 | 87 | } | |
| 91 | 88 | ||
| 92 | - | // Fall back to default WebContext if not created above | |
| 93 | - | if wkCtx.webContext == nil { | |
| 94 | - | wkCtx.webContext = webkit.WebContextGetDefault() | |
| 95 | - | if wkCtx.webContext == nil { | |
| 96 | - | wkCtx.webContext = webkit.NewWebContext() | |
| 97 | - | } | |
| 98 | - | } | |
| 89 | + | wkCtx.webContext = webkit.WebContextGetDefault() | |
| 99 | 90 | if wkCtx.webContext == nil { | |
| 100 | - | return nil, fmt.Errorf("failed to get or create WebContext") | |
| 91 | + | return nil, fmt.Errorf("failed to get default WebContext") | |
| 101 | 92 | } | |
| 102 | 93 | ||
| 103 | 94 | // Set cache model for browser-style caching | |
| @@ -74,30 +74,21 @@ func NewWebKitContextWithOptions(ctx context.Context, opts port.WebKitContextOpt | |||||
| 74 | return nil, fmt.Errorf("failed to init network session: %w", err) | 74 | return nil, fmt.Errorf("failed to init network session: %w", err) | ||
| 75 | } | 75 | } | ||
| 76 | 76 | ||||
| 77 | - | // Create WebContext - with memory pressure settings if configured | 77 | + | // WebViews in this codebase are created via WebKit's default WebContext. |
| 78 | + | // If we create a separate WebContext here and only register our custom | |||
| 79 | + | // dumb:// scheme on it, internal pages will break with "The URL can't be shown". | |||
| 80 | + | // | |||
| 81 | + | // Additionally, WebKit's "memory-pressure-settings" is a construct-only property, | |||
| 82 | + | // so setting it after `webkit.NewWebContext()` triggers a GLib critical and has no effect. | |||
| 83 | + | // Until we can reliably construct a WebContext with memory-pressure-settings AND ensure | |||
| 84 | + | // all WebViews use that context, we intentionally stick to the default WebContext. | |||
| 78 | if opts.IsWebProcessMemoryConfigured() { | 85 | if opts.IsWebProcessMemoryConfigured() { | ||
| 79 | - | applier := NewMemoryPressureApplier() | 86 | + | log.Warn().Msg("web process memory pressure settings requested but not applied (construct-only WebContext property; would break dumb:// scheme registration)") |
| 80 | - | settings, err := applier.ApplyWebProcessSettings(ctx, opts.WebProcessMemory) | |||
| 81 | - | if err != nil { | |||
| 82 | - | log.Warn().Err(err).Msg("failed to prepare web process memory pressure settings") | |||
| 83 | - | } | |||
| 84 | - | if settings != nil { | |||
| 85 | - | wkCtx.webContext = createWebContextWithMemorySettings(settings.(*webkit.MemoryPressureSettings)) | |||
| 86 | - | if wkCtx.webContext != nil { | |||
| 87 | - | log.Debug().Msg("created WebContext with memory pressure settings") | |||
| 88 | - | } | |||
| 89 | - | } | |||
| 90 | } | 87 | } | ||
| 91 | 88 | ||||
| 92 | - | // Fall back to default WebContext if not created above | 89 | + | wkCtx.webContext = webkit.WebContextGetDefault() |
| 93 | - | if wkCtx.webContext == nil { | |||
| 94 | - | wkCtx.webContext = webkit.WebContextGetDefault() | |||
| 95 | - | if wkCtx.webContext == nil { | |||
| 96 | - | wkCtx.webContext = webkit.NewWebContext() | |||
| 97 | - | } | |||
| 98 | - | } | |||
| 99 | if wkCtx.webContext == nil { | 90 | if wkCtx.webContext == nil { | ||
| 100 | - | return nil, fmt.Errorf("failed to get or create WebContext") | 91 | + | return nil, fmt.Errorf("failed to get default WebContext") |
| 101 | } | 92 | } | ||
| 102 | 93 | ||||
| 103 | // Set cache model for browser-style caching | 94 | // Set cache model for browser-style caching | ||
M internal/infrastructure/webkit/webview.go +16 -1
| @@ -248,12 +248,27 @@ func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsMan | |||
| 248 | 248 | return nil, fmt.Errorf("webkit context not initialized") | |
| 249 | 249 | } | |
| 250 | 250 | ||
| 251 | - | // Use NetworkSession-aware constructor for persistent cookie storage | |
| 251 | + | // Use NetworkSession-aware constructor for persistent cookie/storage. | |
| 252 | 252 | inner := webkit.NewWebViewWithNetworkSession(wkCtx.NetworkSession()) | |
| 253 | 253 | if inner == nil { | |
| 254 | 254 | return nil, fmt.Errorf("failed to create webkit webview with network session") | |
| 255 | 255 | } | |
| 256 | 256 | ||
| 257 | + | // Sanity check: our internal dumb:// scheme must be registered on the same WebContext | |
| 258 | + | // that the WebView is actually using. | |
| 259 | + | if expectedCtx := wkCtx.Context(); expectedCtx != nil { | |
| 260 | + | if actualCtx := inner.GetContext(); actualCtx != nil { | |
| 261 | + | expectedPtr := expectedCtx.GoPointer() | |
| 262 | + | actualPtr := actualCtx.GoPointer() | |
| 263 | + | if expectedPtr != 0 && actualPtr != 0 && expectedPtr != actualPtr { | |
| 264 | + | log.Warn(). | |
| 265 | + | Uint64("expected_web_context", uint64(expectedPtr)). | |
| 266 | + | Uint64("actual_web_context", uint64(actualPtr)). | |
| 267 | + | Msg("webview WebContext mismatch; internal dumb:// pages may fail") | |
| 268 | + | } | |
| 269 | + | } | |
| 270 | + | } | |
| 271 | + | ||
| 257 | 272 | // Set background color IMMEDIATELY after creation, before any other operations. | |
| 258 | 273 | // This prevents white flash by ensuring WebKit's renderer starts with correct color. | |
| 259 | 274 | if bgColor != nil { | |
| @@ -248,12 +248,27 @@ func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsMan | |||||
| 248 | return nil, fmt.Errorf("webkit context not initialized") | 248 | return nil, fmt.Errorf("webkit context not initialized") | ||
| 249 | } | 249 | } | ||
| 250 | 250 | ||||
| 251 | - | // Use NetworkSession-aware constructor for persistent cookie storage | 251 | + | // Use NetworkSession-aware constructor for persistent cookie/storage. |
| 252 | inner := webkit.NewWebViewWithNetworkSession(wkCtx.NetworkSession()) | 252 | inner := webkit.NewWebViewWithNetworkSession(wkCtx.NetworkSession()) | ||
| 253 | if inner == nil { | 253 | if inner == nil { | ||
| 254 | return nil, fmt.Errorf("failed to create webkit webview with network session") | 254 | return nil, fmt.Errorf("failed to create webkit webview with network session") | ||
| 255 | } | 255 | } | ||
| 256 | 256 | ||||
| 257 | + | // Sanity check: our internal dumb:// scheme must be registered on the same WebContext | |||
| 258 | + | // that the WebView is actually using. | |||
| 259 | + | if expectedCtx := wkCtx.Context(); expectedCtx != nil { | |||
| 260 | + | if actualCtx := inner.GetContext(); actualCtx != nil { | |||
| 261 | + | expectedPtr := expectedCtx.GoPointer() | |||
| 262 | + | actualPtr := actualCtx.GoPointer() | |||
| 263 | + | if expectedPtr != 0 && actualPtr != 0 && expectedPtr != actualPtr { | |||
| 264 | + | log.Warn(). | |||
| 265 | + | Uint64("expected_web_context", uint64(expectedPtr)). | |||
| 266 | + | Uint64("actual_web_context", uint64(actualPtr)). | |||
| 267 | + | Msg("webview WebContext mismatch; internal dumb:// pages may fail") | |||
| 268 | + | } | |||
| 269 | + | } | |||
| 270 | + | } | |||
| 271 | + | ||||
| 257 | // Set background color IMMEDIATELY after creation, before any other operations. | 272 | // Set background color IMMEDIATELY after creation, before any other operations. | ||
| 258 | // This prevents white flash by ensuring WebKit's renderer starts with correct color. | 273 | // This prevents white flash by ensuring WebKit's renderer starts with correct color. | ||
| 259 | if bgColor != nil { | 274 | if bgColor != nil { | ||