refactor: complete engine abstraction (M5+M6) — decouple UI from webkit
Port layer: - Add RunJavaScript, SetBackgroundColor, Favicon, Generation to port.WebView - Add OnLinkMiddleClick, OnEnterFullscreen, OnLeaveFullscreen, OnAudioStateChanged to WebViewCallbacks - Add RefreshScripts(ctx, wv) error to ContentInjector - Add NativeWidgetProvider optional interface for GTK widget embedding - Add MemoryPressureConfig, MemoryPressureApplier (moved from deleted webkit_context.go) - Remove Engine.Init() (no-op — construction is initialization) - Delete port/webkit_context.go (absorbed into engine.go) Coordinator decoupling (0 webkit imports): - Use port.WebView methods directly instead of *webkit.WebView type assertions - Use port.NativeWidgetProvider for GTK widget embedding - Move fullscreen/audio/middle-click callbacks into WebViewCallbacks - Use injector.RefreshScripts replacing manual UCM pattern - Fix data races in ApplyWebUIThemeToAll and RefreshInjectedScriptsToAll (snapshot under lock) Favicon adapter decoupling (0 webkit imports): - Replace *webkit.FaviconDatabase with port.FaviconDatabase - Implement real GetFaviconAsync in webkit adapter (GIO async pattern) App.go consolidation: - Remove 5 redundant concrete webkit fields (pool, factory, injector, router, settings) - Keep single wkEngine escape hatch for webkit-specific operations - Use engine.Close() for proper shutdown Config cleanup: - Remove old Rendering, Performance, Privacy, Runtime sections from Config struct - Delete RenderingConfig, PrivacyConfig, RuntimeConfig structs - Redirect all consumers to cfg.Engine / cfg.Engine.WebKit - Add PerformanceConfigFromEngine helper for profile resolution Webkit infrastructure: - Store engine context for proper lifecycle management - Replace panic in messageRouterAdapter with logged warning - Fix performance profile reading from zeroed cfg.Performance to cfg.Engine - Add webkit-local context_options.go (unexported types)
- commit
- c068e175212f2afb684a96123a6ac43ff9f0ff17
- author
- brice · · 2026-03-16 21:58 UTC
- parent
- 3432396
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
42 files · +1119 -1149
M .mockery.yaml +0 -1
| @@ -20,7 +20,6 @@ packages: | |||
| 20 | 20 | WebViewFactory: {} | |
| 21 | 21 | WebViewPool: {} | |
| 22 | 22 | MemoryPressureApplier: {} | |
| 23 | - | WebKitContextProvider: {} | |
| 24 | 23 | HardwareSurveyor: {} | |
| 25 | 24 | ColorSchemeDetector: {} | |
| 26 | 25 | ColorSchemeResolver: {} | |
| @@ -20,7 +20,6 @@ packages: | |||||
| 20 | WebViewFactory: {} | 20 | WebViewFactory: {} | ||
| 21 | WebViewPool: {} | 21 | WebViewPool: {} | ||
| 22 | MemoryPressureApplier: {} | 22 | MemoryPressureApplier: {} | ||
| 23 | - | WebKitContextProvider: {} | |||
| 24 | HardwareSurveyor: {} | 23 | HardwareSurveyor: {} | ||
| 25 | ColorSchemeDetector: {} | 24 | ColorSchemeDetector: {} | ||
| 26 | ColorSchemeResolver: {} | 25 | ColorSchemeResolver: {} | ||
M cmd/dumber/main.go +8 -4
| @@ -22,6 +22,7 @@ import ( | |||
| 22 | 22 | "github.com/bnema/dumber/internal/infrastructure/config" | |
| 23 | 23 | "github.com/bnema/dumber/internal/infrastructure/deps" | |
| 24 | 24 | "github.com/bnema/dumber/internal/infrastructure/favicon" | |
| 25 | + | "github.com/bnema/dumber/internal/infrastructure/filtering" | |
| 25 | 26 | "github.com/bnema/dumber/internal/infrastructure/idle" | |
| 26 | 27 | "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite" | |
| 27 | 28 | "github.com/bnema/dumber/internal/infrastructure/updater" | |
| @@ -213,7 +214,7 @@ func buildAndConfigureApp( | |||
| 213 | 214 | } | |
| 214 | 215 | ||
| 215 | 216 | func initStartupContext(cfg *config.Config) context.Context { | |
| 216 | - | deps.ApplyPrefixEnv(cfg.Runtime.Prefix) | |
| 217 | + | deps.ApplyPrefixEnv(cfg.Engine.WebKit.Prefix) | |
| 217 | 218 | bootstrapLogger := logging.NewFromConfigValuesWithTimeFormat( | |
| 218 | 219 | cfg.Logging.Level, | |
| 219 | 220 | cfg.Logging.Format, | |
| @@ -468,7 +469,7 @@ func createUseCases(repos *repositories, cfg *config.Config) *useCases { | |||
| 468 | 469 | xdgDirs, _ := config.GetXDGDirs() | |
| 469 | 470 | stateDir, _ := config.GetStateDir() | |
| 470 | 471 | defaultZoom := cfg.DefaultWebpageZoom | |
| 471 | - | zoomCache := cache.NewLRU[string, *entity.ZoomLevel](cfg.Performance.ZoomCacheSize) | |
| 472 | + | zoomCache := cache.NewLRU[string, *entity.ZoomLevel](cfg.Engine.ZoomCacheSize) | |
| 472 | 473 | ||
| 473 | 474 | buildInfo := build.Info{ | |
| 474 | 475 | Version: version, | |
| @@ -515,7 +516,10 @@ func buildUIDependencies( | |||
| 515 | 516 | startupCrashReports []string, | |
| 516 | 517 | ) *ui.Dependencies { | |
| 517 | 518 | // Type-assert to *webkit.Engine to access FilterManager (not yet on port.Engine). | |
| 518 | - | wkEngine := engine.(*webkit.Engine) | |
| 519 | + | var filterManager *filtering.Manager | |
| 520 | + | if wkEngine, ok := engine.(*webkit.Engine); ok { | |
| 521 | + | filterManager = wkEngine.InternalFilterManager() | |
| 522 | + | } | |
| 519 | 523 | ||
| 520 | 524 | return &ui.Dependencies{ | |
| 521 | 525 | Ctx: ctx, | |
| @@ -528,7 +532,7 @@ func buildUIDependencies( | |||
| 528 | 532 | AdwaitaDetector: adwaitaDetector, | |
| 529 | 533 | XDG: xdg.New(), | |
| 530 | 534 | Engine: engine, | |
| 531 | - | FilterManager: wkEngine.InternalFilterManager(), | |
| 535 | + | FilterManager: filterManager, | |
| 532 | 536 | HistoryRepo: repos.history, | |
| 533 | 537 | FavoriteRepo: repos.favorite, | |
| 534 | 538 | ZoomRepo: repos.zoom, | |
| @@ -22,6 +22,7 @@ import ( | |||||
| 22 | "github.com/bnema/dumber/internal/infrastructure/config" | 22 | "github.com/bnema/dumber/internal/infrastructure/config" | ||
| 23 | "github.com/bnema/dumber/internal/infrastructure/deps" | 23 | "github.com/bnema/dumber/internal/infrastructure/deps" | ||
| 24 | "github.com/bnema/dumber/internal/infrastructure/favicon" | 24 | "github.com/bnema/dumber/internal/infrastructure/favicon" | ||
| 25 | + | "github.com/bnema/dumber/internal/infrastructure/filtering" | |||
| 25 | "github.com/bnema/dumber/internal/infrastructure/idle" | 26 | "github.com/bnema/dumber/internal/infrastructure/idle" | ||
| 26 | "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite" | 27 | "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite" | ||
| 27 | "github.com/bnema/dumber/internal/infrastructure/updater" | 28 | "github.com/bnema/dumber/internal/infrastructure/updater" | ||
| @@ -213,7 +214,7 @@ func buildAndConfigureApp( | |||||
| 213 | } | 214 | } | ||
| 214 | 215 | ||||
| 215 | func initStartupContext(cfg *config.Config) context.Context { | 216 | func initStartupContext(cfg *config.Config) context.Context { | ||
| 216 | - | deps.ApplyPrefixEnv(cfg.Runtime.Prefix) | 217 | + | deps.ApplyPrefixEnv(cfg.Engine.WebKit.Prefix) |
| 217 | bootstrapLogger := logging.NewFromConfigValuesWithTimeFormat( | 218 | bootstrapLogger := logging.NewFromConfigValuesWithTimeFormat( | ||
| 218 | cfg.Logging.Level, | 219 | cfg.Logging.Level, | ||
| 219 | cfg.Logging.Format, | 220 | cfg.Logging.Format, | ||
| @@ -468,7 +469,7 @@ func createUseCases(repos *repositories, cfg *config.Config) *useCases { | |||||
| 468 | xdgDirs, _ := config.GetXDGDirs() | 469 | xdgDirs, _ := config.GetXDGDirs() | ||
| 469 | stateDir, _ := config.GetStateDir() | 470 | stateDir, _ := config.GetStateDir() | ||
| 470 | defaultZoom := cfg.DefaultWebpageZoom | 471 | defaultZoom := cfg.DefaultWebpageZoom | ||
| 471 | - | zoomCache := cache.NewLRU[string, *entity.ZoomLevel](cfg.Performance.ZoomCacheSize) | 472 | + | zoomCache := cache.NewLRU[string, *entity.ZoomLevel](cfg.Engine.ZoomCacheSize) |
| 472 | 473 | ||||
| 473 | buildInfo := build.Info{ | 474 | buildInfo := build.Info{ | ||
| 474 | Version: version, | 475 | Version: version, | ||
| @@ -515,7 +516,10 @@ func buildUIDependencies( | |||||
| 515 | startupCrashReports []string, | 516 | startupCrashReports []string, | ||
| 516 | ) *ui.Dependencies { | 517 | ) *ui.Dependencies { | ||
| 517 | // Type-assert to *webkit.Engine to access FilterManager (not yet on port.Engine). | 518 | // Type-assert to *webkit.Engine to access FilterManager (not yet on port.Engine). | ||
| 518 | - | wkEngine := engine.(*webkit.Engine) | 519 | + | var filterManager *filtering.Manager |
| 520 | + | if wkEngine, ok := engine.(*webkit.Engine); ok { | |||
| 521 | + | filterManager = wkEngine.InternalFilterManager() | |||
| 522 | + | } | |||
| 519 | 523 | ||||
| 520 | return &ui.Dependencies{ | 524 | return &ui.Dependencies{ | ||
| 521 | Ctx: ctx, | 525 | Ctx: ctx, | ||
| @@ -528,7 +532,7 @@ func buildUIDependencies( | |||||
| 528 | AdwaitaDetector: adwaitaDetector, | 532 | AdwaitaDetector: adwaitaDetector, | ||
| 529 | XDG: xdg.New(), | 533 | XDG: xdg.New(), | ||
| 530 | Engine: engine, | 534 | Engine: engine, | ||
| 531 | - | FilterManager: wkEngine.InternalFilterManager(), | 535 | + | FilterManager: filterManager, |
| 532 | HistoryRepo: repos.history, | 536 | HistoryRepo: repos.history, | ||
| 533 | FavoriteRepo: repos.favorite, | 537 | FavoriteRepo: repos.favorite, | ||
| 534 | ZoomRepo: repos.zoom, | 538 | ZoomRepo: repos.zoom, | ||
M internal/application/port/content_injector.go +5 -0
| @@ -8,4 +8,9 @@ type ContentInjector interface { | |||
| 8 | 8 | // InjectThemeCSS injects CSS variables into the page for theming. | |
| 9 | 9 | // The css parameter should contain CSS custom property declarations. | |
| 10 | 10 | InjectThemeCSS(ctx context.Context, css string) error | |
| 11 | + | ||
| 12 | + | // RefreshScripts clears and re-injects user scripts for a single WebView. | |
| 13 | + | // Called when appearance settings change so future navigations pick up latest values. | |
| 14 | + | // Returns an error if the refresh could not be performed. | |
| 15 | + | RefreshScripts(ctx context.Context, wv WebView) error | |
| 11 | 16 | } | |
| @@ -8,4 +8,9 @@ type ContentInjector interface { | |||||
| 8 | // InjectThemeCSS injects CSS variables into the page for theming. | 8 | // InjectThemeCSS injects CSS variables into the page for theming. | ||
| 9 | // The css parameter should contain CSS custom property declarations. | 9 | // The css parameter should contain CSS custom property declarations. | ||
| 10 | InjectThemeCSS(ctx context.Context, css string) error | 10 | InjectThemeCSS(ctx context.Context, css string) error | ||
| 11 | + | ||||
| 12 | + | // RefreshScripts clears and re-injects user scripts for a single WebView. | |||
| 13 | + | // Called when appearance settings change so future navigations pick up latest values. | |||
| 14 | + | // Returns an error if the refresh could not be performed. | |||
| 15 | + | RefreshScripts(ctx context.Context, wv WebView) error | |||
| 11 | } | 16 | } | ||
M internal/application/port/engine.go +57 -4
| @@ -17,6 +17,53 @@ const ( | |||
| 17 | 17 | CookiePolicyNever CookiePolicy = "never" | |
| 18 | 18 | ) | |
| 19 | 19 | ||
| 20 | + | // MemoryPressureConfig holds memory pressure settings for an engine process. | |
| 21 | + | // This is a value type (no infrastructure dependencies) co-located with the | |
| 22 | + | // interfaces that use it (MemoryPressureApplier, EngineOptions). | |
| 23 | + | // Zero values mean "use engine defaults". | |
| 24 | + | type MemoryPressureConfig struct { | |
| 25 | + | // MemoryLimitMB sets the memory limit in megabytes. | |
| 26 | + | // 0 means unset (uses engine default). | |
| 27 | + | MemoryLimitMB int | |
| 28 | + | ||
| 29 | + | // PollIntervalSec sets the interval for memory usage checks. | |
| 30 | + | // 0 means unset (uses engine default: 30 seconds). | |
| 31 | + | PollIntervalSec float64 | |
| 32 | + | ||
| 33 | + | // ConservativeThreshold sets threshold for conservative memory release. | |
| 34 | + | // Must be in (0, 1). 0 means unset (uses engine default: 0.33). | |
| 35 | + | ConservativeThreshold float64 | |
| 36 | + | ||
| 37 | + | // StrictThreshold sets threshold for strict memory release. | |
| 38 | + | // Must be in (0, 1). 0 means unset (uses engine default: 0.5). | |
| 39 | + | StrictThreshold float64 | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | // IsConfigured returns true if any memory pressure setting is configured. | |
| 43 | + | func (c *MemoryPressureConfig) IsConfigured() bool { | |
| 44 | + | if c == nil { | |
| 45 | + | return false | |
| 46 | + | } | |
| 47 | + | return c.MemoryLimitMB > 0 || | |
| 48 | + | c.PollIntervalSec > 0 || | |
| 49 | + | c.ConservativeThreshold > 0 || | |
| 50 | + | c.StrictThreshold > 0 | |
| 51 | + | } | |
| 52 | + | ||
| 53 | + | // MemoryPressureApplier applies memory pressure settings to engine processes. | |
| 54 | + | // This interface abstracts engine-specific memory pressure configuration | |
| 55 | + | // to allow testing without engine dependencies. | |
| 56 | + | type MemoryPressureApplier interface { | |
| 57 | + | // ApplyNetworkProcessSettings applies memory pressure settings to the network process. | |
| 58 | + | // Must be called BEFORE creating any NetworkSession. | |
| 59 | + | ApplyNetworkProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) error | |
| 60 | + | ||
| 61 | + | // ApplyWebProcessSettings applies memory pressure settings to web processes. | |
| 62 | + | // Returns an opaque settings object that should be passed to context creation. | |
| 63 | + | // Returns nil if no settings are configured. | |
| 64 | + | ApplyWebProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) (any, error) | |
| 65 | + | } | |
| 66 | + | ||
| 20 | 67 | // EngineOptions configures engine initialization. | |
| 21 | 68 | type EngineOptions struct { | |
| 22 | 69 | // DataDir is the directory for persistent data (cookies, storage, etc.). | |
| @@ -41,11 +88,10 @@ type EngineOptions struct { | |||
| 41 | 88 | // Engine is the top-level interface for a browser engine implementation. | |
| 42 | 89 | // It provides access to all engine subsystems and manages the lifecycle | |
| 43 | 90 | // of the underlying browser context. | |
| 91 | + | // | |
| 92 | + | // Engines are fully initialized by their constructor (e.g., webkit.NewEngine). | |
| 93 | + | // There is no separate Init step. | |
| 44 | 94 | type Engine interface { | |
| 45 | - | // Init initializes the engine with the given options. | |
| 46 | - | // Must be called before any other methods. | |
| 47 | - | Init(ctx context.Context, opts EngineOptions) error | |
| 48 | - | ||
| 49 | 95 | // Factory returns the WebViewFactory for creating new WebView instances. | |
| 50 | 96 | Factory() WebViewFactory | |
| 51 | 97 | ||
| @@ -132,3 +178,10 @@ type ScriptRefresher interface { | |||
| 132 | 178 | // RefreshAll re-injects scripts into all provided WebView instances. | |
| 133 | 179 | RefreshAll(ctx context.Context, webviews []WebView) | |
| 134 | 180 | } | |
| 181 | + | ||
| 182 | + | // NativeWidgetProvider is an optional capability for WebViews that can provide | |
| 183 | + | // a native GTK widget pointer for embedding into the UI layout. | |
| 184 | + | type NativeWidgetProvider interface { | |
| 185 | + | // NativeWidget returns the underlying native widget pointer. | |
| 186 | + | NativeWidget() uintptr | |
| 187 | + | } | |
| @@ -17,6 +17,53 @@ const ( | |||||
| 17 | CookiePolicyNever CookiePolicy = "never" | 17 | CookiePolicyNever CookiePolicy = "never" | ||
| 18 | ) | 18 | ) | ||
| 19 | 19 | ||||
| 20 | + | // MemoryPressureConfig holds memory pressure settings for an engine process. | |||
| 21 | + | // This is a value type (no infrastructure dependencies) co-located with the | |||
| 22 | + | // interfaces that use it (MemoryPressureApplier, EngineOptions). | |||
| 23 | + | // Zero values mean "use engine defaults". | |||
| 24 | + | type MemoryPressureConfig struct { | |||
| 25 | + | // MemoryLimitMB sets the memory limit in megabytes. | |||
| 26 | + | // 0 means unset (uses engine default). | |||
| 27 | + | MemoryLimitMB int | |||
| 28 | + | ||||
| 29 | + | // PollIntervalSec sets the interval for memory usage checks. | |||
| 30 | + | // 0 means unset (uses engine default: 30 seconds). | |||
| 31 | + | PollIntervalSec float64 | |||
| 32 | + | ||||
| 33 | + | // ConservativeThreshold sets threshold for conservative memory release. | |||
| 34 | + | // Must be in (0, 1). 0 means unset (uses engine default: 0.33). | |||
| 35 | + | ConservativeThreshold float64 | |||
| 36 | + | ||||
| 37 | + | // StrictThreshold sets threshold for strict memory release. | |||
| 38 | + | // Must be in (0, 1). 0 means unset (uses engine default: 0.5). | |||
| 39 | + | StrictThreshold float64 | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | // IsConfigured returns true if any memory pressure setting is configured. | |||
| 43 | + | func (c *MemoryPressureConfig) IsConfigured() bool { | |||
| 44 | + | if c == nil { | |||
| 45 | + | return false | |||
| 46 | + | } | |||
| 47 | + | return c.MemoryLimitMB > 0 || | |||
| 48 | + | c.PollIntervalSec > 0 || | |||
| 49 | + | c.ConservativeThreshold > 0 || | |||
| 50 | + | c.StrictThreshold > 0 | |||
| 51 | + | } | |||
| 52 | + | ||||
| 53 | + | // MemoryPressureApplier applies memory pressure settings to engine processes. | |||
| 54 | + | // This interface abstracts engine-specific memory pressure configuration | |||
| 55 | + | // to allow testing without engine dependencies. | |||
| 56 | + | type MemoryPressureApplier interface { | |||
| 57 | + | // ApplyNetworkProcessSettings applies memory pressure settings to the network process. | |||
| 58 | + | // Must be called BEFORE creating any NetworkSession. | |||
| 59 | + | ApplyNetworkProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) error | |||
| 60 | + | ||||
| 61 | + | // ApplyWebProcessSettings applies memory pressure settings to web processes. | |||
| 62 | + | // Returns an opaque settings object that should be passed to context creation. | |||
| 63 | + | // Returns nil if no settings are configured. | |||
| 64 | + | ApplyWebProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) (any, error) | |||
| 65 | + | } | |||
| 66 | + | ||||
| 20 | // EngineOptions configures engine initialization. | 67 | // EngineOptions configures engine initialization. | ||
| 21 | type EngineOptions struct { | 68 | type EngineOptions struct { | ||
| 22 | // DataDir is the directory for persistent data (cookies, storage, etc.). | 69 | // DataDir is the directory for persistent data (cookies, storage, etc.). | ||
| @@ -41,11 +88,10 @@ type EngineOptions struct { | |||||
| 41 | // Engine is the top-level interface for a browser engine implementation. | 88 | // Engine is the top-level interface for a browser engine implementation. | ||
| 42 | // It provides access to all engine subsystems and manages the lifecycle | 89 | // It provides access to all engine subsystems and manages the lifecycle | ||
| 43 | // of the underlying browser context. | 90 | // of the underlying browser context. | ||
| 91 | + | // | |||
| 92 | + | // Engines are fully initialized by their constructor (e.g., webkit.NewEngine). | |||
| 93 | + | // There is no separate Init step. | |||
| 44 | type Engine interface { | 94 | type Engine interface { | ||
| 45 | - | // Init initializes the engine with the given options. | |||
| 46 | - | // Must be called before any other methods. | |||
| 47 | - | Init(ctx context.Context, opts EngineOptions) error | |||
| 48 | - | ||||
| 49 | // Factory returns the WebViewFactory for creating new WebView instances. | 95 | // Factory returns the WebViewFactory for creating new WebView instances. | ||
| 50 | Factory() WebViewFactory | 96 | Factory() WebViewFactory | ||
| 51 | 97 | ||||
| @@ -132,3 +178,10 @@ type ScriptRefresher interface { | |||||
| 132 | // RefreshAll re-injects scripts into all provided WebView instances. | 178 | // RefreshAll re-injects scripts into all provided WebView instances. | ||
| 133 | RefreshAll(ctx context.Context, webviews []WebView) | 179 | RefreshAll(ctx context.Context, webviews []WebView) | ||
| 134 | } | 180 | } | ||
| 181 | + | ||||
| 182 | + | // NativeWidgetProvider is an optional capability for WebViews that can provide | |||
| 183 | + | // a native GTK widget pointer for embedding into the UI layout. | |||
| 184 | + | type NativeWidgetProvider interface { | |||
| 185 | + | // NativeWidget returns the underlying native widget pointer. | |||
| 186 | + | NativeWidget() uintptr | |||
| 187 | + | } | |||
M internal/application/port/engine_context_test.go +12 -12
| @@ -81,27 +81,27 @@ func TestMemoryPressureConfig_IsConfigured(t *testing.T) { | |||
| 81 | 81 | } | |
| 82 | 82 | } | |
| 83 | 83 | ||
| 84 | - | func TestWebKitContextOptions_IsWebProcessMemoryConfigured(t *testing.T) { | |
| 84 | + | func TestEngineOptions_IsWebProcessMemoryConfigured(t *testing.T) { | |
| 85 | 85 | tests := []struct { | |
| 86 | 86 | name string | |
| 87 | - | opts port.WebKitContextOptions | |
| 87 | + | opts port.EngineOptions | |
| 88 | 88 | expected bool | |
| 89 | 89 | }{ | |
| 90 | 90 | { | |
| 91 | 91 | name: "nil WebProcessMemory", | |
| 92 | - | opts: port.WebKitContextOptions{}, | |
| 92 | + | opts: port.EngineOptions{}, | |
| 93 | 93 | expected: false, | |
| 94 | 94 | }, | |
| 95 | 95 | { | |
| 96 | 96 | name: "empty WebProcessMemory", | |
| 97 | - | opts: port.WebKitContextOptions{ | |
| 97 | + | opts: port.EngineOptions{ | |
| 98 | 98 | WebProcessMemory: &port.MemoryPressureConfig{}, | |
| 99 | 99 | }, | |
| 100 | 100 | expected: false, | |
| 101 | 101 | }, | |
| 102 | 102 | { | |
| 103 | 103 | name: "configured WebProcessMemory", | |
| 104 | - | opts: port.WebKitContextOptions{ | |
| 104 | + | opts: port.EngineOptions{ | |
| 105 | 105 | WebProcessMemory: &port.MemoryPressureConfig{ | |
| 106 | 106 | MemoryLimitMB: 1024, | |
| 107 | 107 | }, | |
| @@ -112,33 +112,33 @@ func TestWebKitContextOptions_IsWebProcessMemoryConfigured(t *testing.T) { | |||
| 112 | 112 | ||
| 113 | 113 | for _, tt := range tests { | |
| 114 | 114 | t.Run(tt.name, func(t *testing.T) { | |
| 115 | - | result := tt.opts.IsWebProcessMemoryConfigured() | |
| 115 | + | result := tt.opts.WebProcessMemory.IsConfigured() | |
| 116 | 116 | assert.Equal(t, tt.expected, result) | |
| 117 | 117 | }) | |
| 118 | 118 | } | |
| 119 | 119 | } | |
| 120 | 120 | ||
| 121 | - | func TestWebKitContextOptions_IsNetworkProcessMemoryConfigured(t *testing.T) { | |
| 121 | + | func TestEngineOptions_IsNetworkProcessMemoryConfigured(t *testing.T) { | |
| 122 | 122 | tests := []struct { | |
| 123 | 123 | name string | |
| 124 | - | opts port.WebKitContextOptions | |
| 124 | + | opts port.EngineOptions | |
| 125 | 125 | expected bool | |
| 126 | 126 | }{ | |
| 127 | 127 | { | |
| 128 | 128 | name: "nil NetworkProcessMemory", | |
| 129 | - | opts: port.WebKitContextOptions{}, | |
| 129 | + | opts: port.EngineOptions{}, | |
| 130 | 130 | expected: false, | |
| 131 | 131 | }, | |
| 132 | 132 | { | |
| 133 | 133 | name: "empty NetworkProcessMemory", | |
| 134 | - | opts: port.WebKitContextOptions{ | |
| 134 | + | opts: port.EngineOptions{ | |
| 135 | 135 | NetworkProcessMemory: &port.MemoryPressureConfig{}, | |
| 136 | 136 | }, | |
| 137 | 137 | expected: false, | |
| 138 | 138 | }, | |
| 139 | 139 | { | |
| 140 | 140 | name: "configured NetworkProcessMemory", | |
| 141 | - | opts: port.WebKitContextOptions{ | |
| 141 | + | opts: port.EngineOptions{ | |
| 142 | 142 | NetworkProcessMemory: &port.MemoryPressureConfig{ | |
| 143 | 143 | PollIntervalSec: 20.0, | |
| 144 | 144 | }, | |
| @@ -149,7 +149,7 @@ func TestWebKitContextOptions_IsNetworkProcessMemoryConfigured(t *testing.T) { | |||
| 149 | 149 | ||
| 150 | 150 | for _, tt := range tests { | |
| 151 | 151 | t.Run(tt.name, func(t *testing.T) { | |
| 152 | - | result := tt.opts.IsNetworkProcessMemoryConfigured() | |
| 152 | + | result := tt.opts.NetworkProcessMemory.IsConfigured() | |
| 153 | 153 | assert.Equal(t, tt.expected, result) | |
| 154 | 154 | }) | |
| 155 | 155 | } | |
| @@ -81,27 +81,27 @@ func TestMemoryPressureConfig_IsConfigured(t *testing.T) { | |||||
| 81 | } | 81 | } | ||
| 82 | } | 82 | } | ||
| 83 | 83 | ||||
| 84 | - | func TestWebKitContextOptions_IsWebProcessMemoryConfigured(t *testing.T) { | 84 | + | func TestEngineOptions_IsWebProcessMemoryConfigured(t *testing.T) { |
| 85 | tests := []struct { | 85 | tests := []struct { | ||
| 86 | name string | 86 | name string | ||
| 87 | - | opts port.WebKitContextOptions | 87 | + | opts port.EngineOptions |
| 88 | expected bool | 88 | expected bool | ||
| 89 | }{ | 89 | }{ | ||
| 90 | { | 90 | { | ||
| 91 | name: "nil WebProcessMemory", | 91 | name: "nil WebProcessMemory", | ||
| 92 | - | opts: port.WebKitContextOptions{}, | 92 | + | opts: port.EngineOptions{}, |
| 93 | expected: false, | 93 | expected: false, | ||
| 94 | }, | 94 | }, | ||
| 95 | { | 95 | { | ||
| 96 | name: "empty WebProcessMemory", | 96 | name: "empty WebProcessMemory", | ||
| 97 | - | opts: port.WebKitContextOptions{ | 97 | + | opts: port.EngineOptions{ |
| 98 | WebProcessMemory: &port.MemoryPressureConfig{}, | 98 | WebProcessMemory: &port.MemoryPressureConfig{}, | ||
| 99 | }, | 99 | }, | ||
| 100 | expected: false, | 100 | expected: false, | ||
| 101 | }, | 101 | }, | ||
| 102 | { | 102 | { | ||
| 103 | name: "configured WebProcessMemory", | 103 | name: "configured WebProcessMemory", | ||
| 104 | - | opts: port.WebKitContextOptions{ | 104 | + | opts: port.EngineOptions{ |
| 105 | WebProcessMemory: &port.MemoryPressureConfig{ | 105 | WebProcessMemory: &port.MemoryPressureConfig{ | ||
| 106 | MemoryLimitMB: 1024, | 106 | MemoryLimitMB: 1024, | ||
| 107 | }, | 107 | }, | ||
| @@ -112,33 +112,33 @@ func TestWebKitContextOptions_IsWebProcessMemoryConfigured(t *testing.T) { | |||||
| 112 | 112 | ||||
| 113 | for _, tt := range tests { | 113 | for _, tt := range tests { | ||
| 114 | t.Run(tt.name, func(t *testing.T) { | 114 | t.Run(tt.name, func(t *testing.T) { | ||
| 115 | - | result := tt.opts.IsWebProcessMemoryConfigured() | 115 | + | result := tt.opts.WebProcessMemory.IsConfigured() |
| 116 | assert.Equal(t, tt.expected, result) | 116 | assert.Equal(t, tt.expected, result) | ||
| 117 | }) | 117 | }) | ||
| 118 | } | 118 | } | ||
| 119 | } | 119 | } | ||
| 120 | 120 | ||||
| 121 | - | func TestWebKitContextOptions_IsNetworkProcessMemoryConfigured(t *testing.T) { | 121 | + | func TestEngineOptions_IsNetworkProcessMemoryConfigured(t *testing.T) { |
| 122 | tests := []struct { | 122 | tests := []struct { | ||
| 123 | name string | 123 | name string | ||
| 124 | - | opts port.WebKitContextOptions | 124 | + | opts port.EngineOptions |
| 125 | expected bool | 125 | expected bool | ||
| 126 | }{ | 126 | }{ | ||
| 127 | { | 127 | { | ||
| 128 | name: "nil NetworkProcessMemory", | 128 | name: "nil NetworkProcessMemory", | ||
| 129 | - | opts: port.WebKitContextOptions{}, | 129 | + | opts: port.EngineOptions{}, |
| 130 | expected: false, | 130 | expected: false, | ||
| 131 | }, | 131 | }, | ||
| 132 | { | 132 | { | ||
| 133 | name: "empty NetworkProcessMemory", | 133 | name: "empty NetworkProcessMemory", | ||
| 134 | - | opts: port.WebKitContextOptions{ | 134 | + | opts: port.EngineOptions{ |
| 135 | NetworkProcessMemory: &port.MemoryPressureConfig{}, | 135 | NetworkProcessMemory: &port.MemoryPressureConfig{}, | ||
| 136 | }, | 136 | }, | ||
| 137 | expected: false, | 137 | expected: false, | ||
| 138 | }, | 138 | }, | ||
| 139 | { | 139 | { | ||
| 140 | name: "configured NetworkProcessMemory", | 140 | name: "configured NetworkProcessMemory", | ||
| 141 | - | opts: port.WebKitContextOptions{ | 141 | + | opts: port.EngineOptions{ |
| 142 | NetworkProcessMemory: &port.MemoryPressureConfig{ | 142 | NetworkProcessMemory: &port.MemoryPressureConfig{ | ||
| 143 | PollIntervalSec: 20.0, | 143 | PollIntervalSec: 20.0, | ||
| 144 | }, | 144 | }, | ||
| @@ -149,7 +149,7 @@ func TestWebKitContextOptions_IsNetworkProcessMemoryConfigured(t *testing.T) { | |||||
| 149 | 149 | ||||
| 150 | for _, tt := range tests { | 150 | for _, tt := range tests { | ||
| 151 | t.Run(tt.name, func(t *testing.T) { | 151 | t.Run(tt.name, func(t *testing.T) { | ||
| 152 | - | result := tt.opts.IsNetworkProcessMemoryConfigured() | 152 | + | result := tt.opts.NetworkProcessMemory.IsConfigured() |
| 153 | assert.Equal(t, tt.expected, result) | 153 | assert.Equal(t, tt.expected, result) | ||
| 154 | }) | 154 | }) | ||
| 155 | } | 155 | } | ||
M internal/application/port/mocks/mocks.go +445 -474
| @@ -1188,6 +1188,63 @@ func (_c *MockContentInjector_InjectThemeCSS_Call) RunAndReturn(run func(ctx con | |||
| 1188 | 1188 | return _c | |
| 1189 | 1189 | } | |
| 1190 | 1190 | ||
| 1191 | + | // RefreshScripts provides a mock function for the type MockContentInjector | |
| 1192 | + | func (_mock *MockContentInjector) RefreshScripts(ctx context.Context, wv port.WebView) error { | |
| 1193 | + | ret := _mock.Called(ctx, wv) | |
| 1194 | + | ||
| 1195 | + | if len(ret) == 0 { | |
| 1196 | + | panic("no return value specified for RefreshScripts") | |
| 1197 | + | } | |
| 1198 | + | ||
| 1199 | + | var r0 error | |
| 1200 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, port.WebView) error); ok { | |
| 1201 | + | r0 = returnFunc(ctx, wv) | |
| 1202 | + | } else { | |
| 1203 | + | r0 = ret.Error(0) | |
| 1204 | + | } | |
| 1205 | + | return r0 | |
| 1206 | + | } | |
| 1207 | + | ||
| 1208 | + | // MockContentInjector_RefreshScripts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RefreshScripts' | |
| 1209 | + | type MockContentInjector_RefreshScripts_Call struct { | |
| 1210 | + | *mock.Call | |
| 1211 | + | } | |
| 1212 | + | ||
| 1213 | + | // RefreshScripts is a helper method to define mock.On call | |
| 1214 | + | // - ctx context.Context | |
| 1215 | + | // - wv port.WebView | |
| 1216 | + | func (_e *MockContentInjector_Expecter) RefreshScripts(ctx interface{}, wv interface{}) *MockContentInjector_RefreshScripts_Call { | |
| 1217 | + | return &MockContentInjector_RefreshScripts_Call{Call: _e.mock.On("RefreshScripts", ctx, wv)} | |
| 1218 | + | } | |
| 1219 | + | ||
| 1220 | + | func (_c *MockContentInjector_RefreshScripts_Call) Run(run func(ctx context.Context, wv port.WebView)) *MockContentInjector_RefreshScripts_Call { | |
| 1221 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1222 | + | var arg0 context.Context | |
| 1223 | + | if args[0] != nil { | |
| 1224 | + | arg0 = args[0].(context.Context) | |
| 1225 | + | } | |
| 1226 | + | var arg1 port.WebView | |
| 1227 | + | if args[1] != nil { | |
| 1228 | + | arg1 = args[1].(port.WebView) | |
| 1229 | + | } | |
| 1230 | + | run( | |
| 1231 | + | arg0, | |
| 1232 | + | arg1, | |
| 1233 | + | ) | |
| 1234 | + | }) | |
| 1235 | + | return _c | |
| 1236 | + | } | |
| 1237 | + | ||
| 1238 | + | func (_c *MockContentInjector_RefreshScripts_Call) Return(_a0 error) *MockContentInjector_RefreshScripts_Call { | |
| 1239 | + | _c.Call.Return(_a0) | |
| 1240 | + | return _c | |
| 1241 | + | } | |
| 1242 | + | ||
| 1243 | + | func (_c *MockContentInjector_RefreshScripts_Call) RunAndReturn(run func(ctx context.Context, wv port.WebView) error) *MockContentInjector_RefreshScripts_Call { | |
| 1244 | + | _c.Call.Return(run) | |
| 1245 | + | return _c | |
| 1246 | + | } | |
| 1247 | + | ||
| 1191 | 1248 | // NewMockDatabaseProvider creates a new instance of MockDatabaseProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 1192 | 1249 | // The first argument is typically a *testing.T value. | |
| 1193 | 1250 | func NewMockDatabaseProvider(t interface { | |
| @@ -1524,6 +1581,158 @@ func (_c *MockDownloadResponse_GetUri_Call) RunAndReturn(run func() string) *Moc | |||
| 1524 | 1581 | return _c | |
| 1525 | 1582 | } | |
| 1526 | 1583 | ||
| 1584 | + | // NewMockMemoryPressureApplier creates a new instance of MockMemoryPressureApplier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 1585 | + | // The first argument is typically a *testing.T value. | |
| 1586 | + | func NewMockMemoryPressureApplier(t interface { | |
| 1587 | + | mock.TestingT | |
| 1588 | + | Cleanup(func()) | |
| 1589 | + | }) *MockMemoryPressureApplier { | |
| 1590 | + | mock := &MockMemoryPressureApplier{} | |
| 1591 | + | mock.Mock.Test(t) | |
| 1592 | + | ||
| 1593 | + | t.Cleanup(func() { mock.AssertExpectations(t) }) | |
| 1594 | + | ||
| 1595 | + | return mock | |
| 1596 | + | } | |
| 1597 | + | ||
| 1598 | + | // MockMemoryPressureApplier is an autogenerated mock type for the MemoryPressureApplier type | |
| 1599 | + | type MockMemoryPressureApplier struct { | |
| 1600 | + | mock.Mock | |
| 1601 | + | } | |
| 1602 | + | ||
| 1603 | + | type MockMemoryPressureApplier_Expecter struct { | |
| 1604 | + | mock *mock.Mock | |
| 1605 | + | } | |
| 1606 | + | ||
| 1607 | + | func (_m *MockMemoryPressureApplier) EXPECT() *MockMemoryPressureApplier_Expecter { | |
| 1608 | + | return &MockMemoryPressureApplier_Expecter{mock: &_m.Mock} | |
| 1609 | + | } | |
| 1610 | + | ||
| 1611 | + | // ApplyNetworkProcessSettings provides a mock function for the type MockMemoryPressureApplier | |
| 1612 | + | func (_mock *MockMemoryPressureApplier) ApplyNetworkProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) error { | |
| 1613 | + | ret := _mock.Called(ctx, cfg) | |
| 1614 | + | ||
| 1615 | + | if len(ret) == 0 { | |
| 1616 | + | panic("no return value specified for ApplyNetworkProcessSettings") | |
| 1617 | + | } | |
| 1618 | + | ||
| 1619 | + | var r0 error | |
| 1620 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |
| 1621 | + | r0 = returnFunc(ctx, cfg) | |
| 1622 | + | } else { | |
| 1623 | + | r0 = ret.Error(0) | |
| 1624 | + | } | |
| 1625 | + | return r0 | |
| 1626 | + | } | |
| 1627 | + | ||
| 1628 | + | // MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyNetworkProcessSettings' | |
| 1629 | + | type MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call struct { | |
| 1630 | + | *mock.Call | |
| 1631 | + | } | |
| 1632 | + | ||
| 1633 | + | // ApplyNetworkProcessSettings is a helper method to define mock.On call | |
| 1634 | + | // - ctx context.Context | |
| 1635 | + | // - cfg *port.MemoryPressureConfig | |
| 1636 | + | func (_e *MockMemoryPressureApplier_Expecter) ApplyNetworkProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 1637 | + | return &MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call{Call: _e.mock.On("ApplyNetworkProcessSettings", ctx, cfg)} | |
| 1638 | + | } | |
| 1639 | + | ||
| 1640 | + | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 1641 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1642 | + | var arg0 context.Context | |
| 1643 | + | if args[0] != nil { | |
| 1644 | + | arg0 = args[0].(context.Context) | |
| 1645 | + | } | |
| 1646 | + | var arg1 *port.MemoryPressureConfig | |
| 1647 | + | if args[1] != nil { | |
| 1648 | + | arg1 = args[1].(*port.MemoryPressureConfig) | |
| 1649 | + | } | |
| 1650 | + | run( | |
| 1651 | + | arg0, | |
| 1652 | + | arg1, | |
| 1653 | + | ) | |
| 1654 | + | }) | |
| 1655 | + | return _c | |
| 1656 | + | } | |
| 1657 | + | ||
| 1658 | + | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Return(err error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 1659 | + | _c.Call.Return(err) | |
| 1660 | + | return _c | |
| 1661 | + | } | |
| 1662 | + | ||
| 1663 | + | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 1664 | + | _c.Call.Return(run) | |
| 1665 | + | return _c | |
| 1666 | + | } | |
| 1667 | + | ||
| 1668 | + | // ApplyWebProcessSettings provides a mock function for the type MockMemoryPressureApplier | |
| 1669 | + | func (_mock *MockMemoryPressureApplier) ApplyWebProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error) { | |
| 1670 | + | ret := _mock.Called(ctx, cfg) | |
| 1671 | + | ||
| 1672 | + | if len(ret) == 0 { | |
| 1673 | + | panic("no return value specified for ApplyWebProcessSettings") | |
| 1674 | + | } | |
| 1675 | + | ||
| 1676 | + | var r0 any | |
| 1677 | + | var r1 error | |
| 1678 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) (any, error)); ok { | |
| 1679 | + | return returnFunc(ctx, cfg) | |
| 1680 | + | } | |
| 1681 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) any); ok { | |
| 1682 | + | r0 = returnFunc(ctx, cfg) | |
| 1683 | + | } else { | |
| 1684 | + | if ret.Get(0) != nil { | |
| 1685 | + | r0 = ret.Get(0).(any) | |
| 1686 | + | } | |
| 1687 | + | } | |
| 1688 | + | if returnFunc, ok := ret.Get(1).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |
| 1689 | + | r1 = returnFunc(ctx, cfg) | |
| 1690 | + | } else { | |
| 1691 | + | r1 = ret.Error(1) | |
| 1692 | + | } | |
| 1693 | + | return r0, r1 | |
| 1694 | + | } | |
| 1695 | + | ||
| 1696 | + | // MockMemoryPressureApplier_ApplyWebProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyWebProcessSettings' | |
| 1697 | + | type MockMemoryPressureApplier_ApplyWebProcessSettings_Call struct { | |
| 1698 | + | *mock.Call | |
| 1699 | + | } | |
| 1700 | + | ||
| 1701 | + | // ApplyWebProcessSettings is a helper method to define mock.On call | |
| 1702 | + | // - ctx context.Context | |
| 1703 | + | // - cfg *port.MemoryPressureConfig | |
| 1704 | + | func (_e *MockMemoryPressureApplier_Expecter) ApplyWebProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 1705 | + | return &MockMemoryPressureApplier_ApplyWebProcessSettings_Call{Call: _e.mock.On("ApplyWebProcessSettings", ctx, cfg)} | |
| 1706 | + | } | |
| 1707 | + | ||
| 1708 | + | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 1709 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1710 | + | var arg0 context.Context | |
| 1711 | + | if args[0] != nil { | |
| 1712 | + | arg0 = args[0].(context.Context) | |
| 1713 | + | } | |
| 1714 | + | var arg1 *port.MemoryPressureConfig | |
| 1715 | + | if args[1] != nil { | |
| 1716 | + | arg1 = args[1].(*port.MemoryPressureConfig) | |
| 1717 | + | } | |
| 1718 | + | run( | |
| 1719 | + | arg0, | |
| 1720 | + | arg1, | |
| 1721 | + | ) | |
| 1722 | + | }) | |
| 1723 | + | return _c | |
| 1724 | + | } | |
| 1725 | + | ||
| 1726 | + | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Return(v any, err error) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 1727 | + | _c.Call.Return(v, err) | |
| 1728 | + | return _c | |
| 1729 | + | } | |
| 1730 | + | ||
| 1731 | + | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 1732 | + | _c.Call.Return(run) | |
| 1733 | + | return _c | |
| 1734 | + | } | |
| 1735 | + | ||
| 1527 | 1736 | // NewMockEngine creates a new instance of MockEngine. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 1528 | 1737 | // The first argument is typically a *testing.T value. | |
| 1529 | 1738 | func NewMockEngine(t interface { | |
| @@ -1779,63 +1988,6 @@ func (_c *MockEngine_FilterApplier_Call) RunAndReturn(run func() port.FilterAppl | |||
| 1779 | 1988 | return _c | |
| 1780 | 1989 | } | |
| 1781 | 1990 | ||
| 1782 | - | // Init provides a mock function for the type MockEngine | |
| 1783 | - | func (_mock *MockEngine) Init(ctx context.Context, opts port.EngineOptions) error { | |
| 1784 | - | ret := _mock.Called(ctx, opts) | |
| 1785 | - | ||
| 1786 | - | if len(ret) == 0 { | |
| 1787 | - | panic("no return value specified for Init") | |
| 1788 | - | } | |
| 1789 | - | ||
| 1790 | - | var r0 error | |
| 1791 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, port.EngineOptions) error); ok { | |
| 1792 | - | r0 = returnFunc(ctx, opts) | |
| 1793 | - | } else { | |
| 1794 | - | r0 = ret.Error(0) | |
| 1795 | - | } | |
| 1796 | - | return r0 | |
| 1797 | - | } | |
| 1798 | - | ||
| 1799 | - | // MockEngine_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' | |
| 1800 | - | type MockEngine_Init_Call struct { | |
| 1801 | - | *mock.Call | |
| 1802 | - | } | |
| 1803 | - | ||
| 1804 | - | // Init is a helper method to define mock.On call | |
| 1805 | - | // - ctx context.Context | |
| 1806 | - | // - opts port.EngineOptions | |
| 1807 | - | func (_e *MockEngine_Expecter) Init(ctx interface{}, opts interface{}) *MockEngine_Init_Call { | |
| 1808 | - | return &MockEngine_Init_Call{Call: _e.mock.On("Init", ctx, opts)} | |
| 1809 | - | } | |
| 1810 | - | ||
| 1811 | - | func (_c *MockEngine_Init_Call) Run(run func(ctx context.Context, opts port.EngineOptions)) *MockEngine_Init_Call { | |
| 1812 | - | _c.Call.Run(func(args mock.Arguments) { | |
| 1813 | - | var arg0 context.Context | |
| 1814 | - | if args[0] != nil { | |
| 1815 | - | arg0 = args[0].(context.Context) | |
| 1816 | - | } | |
| 1817 | - | var arg1 port.EngineOptions | |
| 1818 | - | if args[1] != nil { | |
| 1819 | - | arg1 = args[1].(port.EngineOptions) | |
| 1820 | - | } | |
| 1821 | - | run( | |
| 1822 | - | arg0, | |
| 1823 | - | arg1, | |
| 1824 | - | ) | |
| 1825 | - | }) | |
| 1826 | - | return _c | |
| 1827 | - | } | |
| 1828 | - | ||
| 1829 | - | func (_c *MockEngine_Init_Call) Return(err error) *MockEngine_Init_Call { | |
| 1830 | - | _c.Call.Return(err) | |
| 1831 | - | return _c | |
| 1832 | - | } | |
| 1833 | - | ||
| 1834 | - | func (_c *MockEngine_Init_Call) RunAndReturn(run func(ctx context.Context, opts port.EngineOptions) error) *MockEngine_Init_Call { | |
| 1835 | - | _c.Call.Return(run) | |
| 1836 | - | return _c | |
| 1837 | - | } | |
| 1838 | - | ||
| 1839 | 1991 | // InternalSchemePath provides a mock function for the type MockEngine | |
| 1840 | 1992 | func (_mock *MockEngine) InternalSchemePath() string { | |
| 1841 | 1993 | ret := _mock.Called() | |
| @@ -4339,13 +4491,13 @@ func (_c *MockFocusedInputProvider_SetFocusedInput_Call) RunAndReturn(run func(t | |||
| 4339 | 4491 | return _c | |
| 4340 | 4492 | } | |
| 4341 | 4493 | ||
| 4342 | - | // NewMockMemoryPressureApplier creates a new instance of MockMemoryPressureApplier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 4494 | + | // NewMockWebView creates a new instance of MockWebView. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 4343 | 4495 | // The first argument is typically a *testing.T value. | |
| 4344 | - | func NewMockMemoryPressureApplier(t interface { | |
| 4496 | + | func NewMockWebView(t interface { | |
| 4345 | 4497 | mock.TestingT | |
| 4346 | 4498 | Cleanup(func()) | |
| 4347 | - | }) *MockMemoryPressureApplier { | |
| 4348 | - | mock := &MockMemoryPressureApplier{} | |
| 4499 | + | }) *MockWebView { | |
| 4500 | + | mock := &MockWebView{} | |
| 4349 | 4501 | mock.Mock.Test(t) | |
| 4350 | 4502 | ||
| 4351 | 4503 | t.Cleanup(func() { mock.AssertExpectations(t) }) | |
| @@ -4353,588 +4505,270 @@ func NewMockMemoryPressureApplier(t interface { | |||
| 4353 | 4505 | return mock | |
| 4354 | 4506 | } | |
| 4355 | 4507 | ||
| 4356 | - | // MockMemoryPressureApplier is an autogenerated mock type for the MemoryPressureApplier type | |
| 4357 | - | type MockMemoryPressureApplier struct { | |
| 4508 | + | // MockWebView is an autogenerated mock type for the WebView type | |
| 4509 | + | type MockWebView struct { | |
| 4358 | 4510 | mock.Mock | |
| 4359 | 4511 | } | |
| 4360 | 4512 | ||
| 4361 | - | type MockMemoryPressureApplier_Expecter struct { | |
| 4513 | + | type MockWebView_Expecter struct { | |
| 4362 | 4514 | mock *mock.Mock | |
| 4363 | 4515 | } | |
| 4364 | 4516 | ||
| 4365 | - | func (_m *MockMemoryPressureApplier) EXPECT() *MockMemoryPressureApplier_Expecter { | |
| 4366 | - | return &MockMemoryPressureApplier_Expecter{mock: &_m.Mock} | |
| 4517 | + | func (_m *MockWebView) EXPECT() *MockWebView_Expecter { | |
| 4518 | + | return &MockWebView_Expecter{mock: &_m.Mock} | |
| 4367 | 4519 | } | |
| 4368 | 4520 | ||
| 4369 | - | // ApplyNetworkProcessSettings provides a mock function for the type MockMemoryPressureApplier | |
| 4370 | - | func (_mock *MockMemoryPressureApplier) ApplyNetworkProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) error { | |
| 4371 | - | ret := _mock.Called(ctx, cfg) | |
| 4521 | + | // CanGoBack provides a mock function for the type MockWebView | |
| 4522 | + | func (_mock *MockWebView) CanGoBack() bool { | |
| 4523 | + | ret := _mock.Called() | |
| 4372 | 4524 | ||
| 4373 | 4525 | if len(ret) == 0 { | |
| 4374 | - | panic("no return value specified for ApplyNetworkProcessSettings") | |
| 4375 | - | } | |
| 4376 | - | ||
| 4377 | - | var r0 error | |
| 4378 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |
| 4379 | - | r0 = returnFunc(ctx, cfg) | |
| 4380 | - | } else { | |
| 4381 | - | r0 = ret.Error(0) | |
| 4382 | - | } | |
| 4383 | - | return r0 | |
| 4384 | - | } | |
| 4385 | - | ||
| 4386 | - | // MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyNetworkProcessSettings' | |
| 4387 | - | type MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call struct { | |
| 4388 | - | *mock.Call | |
| 4389 | - | } | |
| 4390 | - | ||
| 4391 | - | // ApplyNetworkProcessSettings is a helper method to define mock.On call | |
| 4392 | - | // - ctx context.Context | |
| 4393 | - | // - cfg *port.MemoryPressureConfig | |
| 4394 | - | func (_e *MockMemoryPressureApplier_Expecter) ApplyNetworkProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 4395 | - | return &MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call{Call: _e.mock.On("ApplyNetworkProcessSettings", ctx, cfg)} | |
| 4396 | - | } | |
| 4397 | - | ||
| 4398 | - | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 4399 | - | _c.Call.Run(func(args mock.Arguments) { | |
| 4400 | - | var arg0 context.Context | |
| 4401 | - | if args[0] != nil { | |
| 4402 | - | arg0 = args[0].(context.Context) | |
| 4403 | - | } | |
| 4404 | - | var arg1 *port.MemoryPressureConfig | |
| 4405 | - | if args[1] != nil { | |
| 4406 | - | arg1 = args[1].(*port.MemoryPressureConfig) | |
| 4407 | - | } | |
| 4408 | - | run( | |
| 4409 | - | arg0, | |
| 4410 | - | arg1, | |
| 4411 | - | ) | |
| 4412 | - | }) | |
| 4413 | - | return _c | |
| 4414 | - | } | |
| 4415 | - | ||
| 4416 | - | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Return(err error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 4417 | - | _c.Call.Return(err) | |
| 4418 | - | return _c | |
| 4419 | - | } | |
| 4420 | - | ||
| 4421 | - | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |
| 4422 | - | _c.Call.Return(run) | |
| 4423 | - | return _c | |
| 4424 | - | } | |
| 4425 | - | ||
| 4426 | - | // ApplyWebProcessSettings provides a mock function for the type MockMemoryPressureApplier | |
| 4427 | - | func (_mock *MockMemoryPressureApplier) ApplyWebProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error) { | |
| 4428 | - | ret := _mock.Called(ctx, cfg) | |
| 4429 | - | ||
| 4430 | - | if len(ret) == 0 { | |
| 4431 | - | panic("no return value specified for ApplyWebProcessSettings") | |
| 4432 | - | } | |
| 4433 | - | ||
| 4434 | - | var r0 any | |
| 4435 | - | var r1 error | |
| 4436 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) (any, error)); ok { | |
| 4437 | - | return returnFunc(ctx, cfg) | |
| 4438 | - | } | |
| 4439 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) any); ok { | |
| 4440 | - | r0 = returnFunc(ctx, cfg) | |
| 4441 | - | } else { | |
| 4442 | - | if ret.Get(0) != nil { | |
| 4443 | - | r0 = ret.Get(0).(any) | |
| 4444 | - | } | |
| 4445 | - | } | |
| 4446 | - | if returnFunc, ok := ret.Get(1).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |
| 4447 | - | r1 = returnFunc(ctx, cfg) | |
| 4448 | - | } else { | |
| 4449 | - | r1 = ret.Error(1) | |
| 4450 | - | } | |
| 4451 | - | return r0, r1 | |
| 4452 | - | } | |
| 4453 | - | ||
| 4454 | - | // MockMemoryPressureApplier_ApplyWebProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyWebProcessSettings' | |
| 4455 | - | type MockMemoryPressureApplier_ApplyWebProcessSettings_Call struct { | |
| 4456 | - | *mock.Call | |
| 4457 | - | } | |
| 4458 | - | ||
| 4459 | - | // ApplyWebProcessSettings is a helper method to define mock.On call | |
| 4460 | - | // - ctx context.Context | |
| 4461 | - | // - cfg *port.MemoryPressureConfig | |
| 4462 | - | func (_e *MockMemoryPressureApplier_Expecter) ApplyWebProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 4463 | - | return &MockMemoryPressureApplier_ApplyWebProcessSettings_Call{Call: _e.mock.On("ApplyWebProcessSettings", ctx, cfg)} | |
| 4464 | - | } | |
| 4465 | - | ||
| 4466 | - | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 4467 | - | _c.Call.Run(func(args mock.Arguments) { | |
| 4468 | - | var arg0 context.Context | |
| 4469 | - | if args[0] != nil { | |
| 4470 | - | arg0 = args[0].(context.Context) | |
| 4471 | - | } | |
| 4472 | - | var arg1 *port.MemoryPressureConfig | |
| 4473 | - | if args[1] != nil { | |
| 4474 | - | arg1 = args[1].(*port.MemoryPressureConfig) | |
| 4475 | - | } | |
| 4476 | - | run( | |
| 4477 | - | arg0, | |
| 4478 | - | arg1, | |
| 4479 | - | ) | |
| 4480 | - | }) | |
| 4481 | - | return _c | |
| 4482 | - | } | |
| 4483 | - | ||
| 4484 | - | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Return(v any, err error) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 4485 | - | _c.Call.Return(v, err) | |
| 4486 | - | return _c | |
| 4487 | - | } | |
| 4488 | - | ||
| 4489 | - | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |
| 4490 | - | _c.Call.Return(run) | |
| 4491 | - | return _c | |
| 4492 | - | } | |
| 4493 | - | ||
| 4494 | - | // NewMockWebKitContextProvider creates a new instance of MockWebKitContextProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 4495 | - | // The first argument is typically a *testing.T value. | |
| 4496 | - | func NewMockWebKitContextProvider(t interface { | |
| 4497 | - | mock.TestingT | |
| 4498 | - | Cleanup(func()) | |
| 4499 | - | }) *MockWebKitContextProvider { | |
| 4500 | - | mock := &MockWebKitContextProvider{} | |
| 4501 | - | mock.Mock.Test(t) | |
| 4502 | - | ||
| 4503 | - | t.Cleanup(func() { mock.AssertExpectations(t) }) | |
| 4504 | - | ||
| 4505 | - | return mock | |
| 4506 | - | } | |
| 4507 | - | ||
| 4508 | - | // MockWebKitContextProvider is an autogenerated mock type for the WebKitContextProvider type | |
| 4509 | - | type MockWebKitContextProvider struct { | |
| 4510 | - | mock.Mock | |
| 4511 | - | } | |
| 4512 | - | ||
| 4513 | - | type MockWebKitContextProvider_Expecter struct { | |
| 4514 | - | mock *mock.Mock | |
| 4515 | - | } | |
| 4516 | - | ||
| 4517 | - | func (_m *MockWebKitContextProvider) EXPECT() *MockWebKitContextProvider_Expecter { | |
| 4518 | - | return &MockWebKitContextProvider_Expecter{mock: &_m.Mock} | |
| 4519 | - | } | |
| 4520 | - | ||
| 4521 | - | // CacheDir provides a mock function for the type MockWebKitContextProvider | |
| 4522 | - | func (_mock *MockWebKitContextProvider) CacheDir() string { | |
| 4523 | - | ret := _mock.Called() | |
| 4524 | - | ||
| 4525 | - | if len(ret) == 0 { | |
| 4526 | - | panic("no return value specified for CacheDir") | |
| 4527 | - | } | |
| 4528 | - | ||
| 4529 | - | var r0 string | |
| 4530 | - | if returnFunc, ok := ret.Get(0).(func() string); ok { | |
| 4531 | - | r0 = returnFunc() | |
| 4532 | - | } else { | |
| 4533 | - | r0 = ret.Get(0).(string) | |
| 4534 | - | } | |
| 4535 | - | return r0 | |
| 4536 | - | } | |
| 4537 | - | ||
| 4538 | - | // MockWebKitContextProvider_CacheDir_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CacheDir' | |
| 4539 | - | type MockWebKitContextProvider_CacheDir_Call struct { | |
| 4540 | - | *mock.Call | |
| 4541 | - | } | |
| 4542 | - | ||
| 4543 | - | // CacheDir is a helper method to define mock.On call | |
| 4544 | - | func (_e *MockWebKitContextProvider_Expecter) CacheDir() *MockWebKitContextProvider_CacheDir_Call { | |
| 4545 | - | return &MockWebKitContextProvider_CacheDir_Call{Call: _e.mock.On("CacheDir")} | |
| 4546 | - | } | |
| 4547 | - | ||
| 4548 | - | func (_c *MockWebKitContextProvider_CacheDir_Call) Run(run func()) *MockWebKitContextProvider_CacheDir_Call { | |
| 4549 | - | _c.Call.Run(func(args mock.Arguments) { | |
| 4550 | - | run() | |
| 4551 | - | }) | |
| 4552 | - | return _c | |
| 4553 | - | } | |
| 4554 | - | ||
| 4555 | - | func (_c *MockWebKitContextProvider_CacheDir_Call) Return(s string) *MockWebKitContextProvider_CacheDir_Call { | |
| 4556 | - | _c.Call.Return(s) | |
| 4557 | - | return _c | |
| 4558 | - | } | |
| 4559 | - | ||
| 4560 | - | func (_c *MockWebKitContextProvider_CacheDir_Call) RunAndReturn(run func() string) *MockWebKitContextProvider_CacheDir_Call { | |
| 4561 | - | _c.Call.Return(run) | |
| 4562 | - | return _c | |
| 4563 | - | } | |
| 4564 | - | ||
| 4565 | - | // Close provides a mock function for the type MockWebKitContextProvider | |
| 4566 | - | func (_mock *MockWebKitContextProvider) Close() error { | |
| 4567 | - | ret := _mock.Called() | |
| 4568 | - | ||
| 4569 | - | if len(ret) == 0 { | |
| 4570 | - | panic("no return value specified for Close") | |
| 4526 | + | panic("no return value specified for CanGoBack") | |
| 4571 | 4527 | } | |
| 4572 | 4528 | ||
| 4573 | - | var r0 error | |
| 4574 | - | if returnFunc, ok := ret.Get(0).(func() error); ok { | |
| 4529 | + | var r0 bool | |
| 4530 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |
| 4575 | 4531 | r0 = returnFunc() | |
| 4576 | 4532 | } else { | |
| 4577 | - | r0 = ret.Error(0) | |
| 4533 | + | r0 = ret.Get(0).(bool) | |
| 4578 | 4534 | } | |
| 4579 | 4535 | return r0 | |
| 4580 | 4536 | } | |
| 4581 | 4537 | ||
| 4582 | - | // MockWebKitContextProvider_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' | |
| 4583 | - | type MockWebKitContextProvider_Close_Call struct { | |
| 4538 | + | // MockWebView_CanGoBack_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoBack' | |
| 4539 | + | type MockWebView_CanGoBack_Call struct { | |
| 4584 | 4540 | *mock.Call | |
| 4585 | 4541 | } | |
| 4586 | 4542 | ||
| 4587 | - | // Close is a helper method to define mock.On call | |
| 4588 | - | func (_e *MockWebKitContextProvider_Expecter) Close() *MockWebKitContextProvider_Close_Call { | |
| 4589 | - | return &MockWebKitContextProvider_Close_Call{Call: _e.mock.On("Close")} | |
| 4543 | + | // CanGoBack is a helper method to define mock.On call | |
| 4544 | + | func (_e *MockWebView_Expecter) CanGoBack() *MockWebView_CanGoBack_Call { | |
| 4545 | + | return &MockWebView_CanGoBack_Call{Call: _e.mock.On("CanGoBack")} | |
| 4590 | 4546 | } | |
| 4591 | 4547 | ||
| 4592 | - | func (_c *MockWebKitContextProvider_Close_Call) Run(run func()) *MockWebKitContextProvider_Close_Call { | |
| 4548 | + | func (_c *MockWebView_CanGoBack_Call) Run(run func()) *MockWebView_CanGoBack_Call { | |
| 4593 | 4549 | _c.Call.Run(func(args mock.Arguments) { | |
| 4594 | 4550 | run() | |
| 4595 | 4551 | }) | |
| 4596 | 4552 | return _c | |
| 4597 | 4553 | } | |
| 4598 | 4554 | ||
| 4599 | - | func (_c *MockWebKitContextProvider_Close_Call) Return(err error) *MockWebKitContextProvider_Close_Call { | |
| 4600 | - | _c.Call.Return(err) | |
| 4555 | + | func (_c *MockWebView_CanGoBack_Call) Return(b bool) *MockWebView_CanGoBack_Call { | |
| 4556 | + | _c.Call.Return(b) | |
| 4601 | 4557 | return _c | |
| 4602 | 4558 | } | |
| 4603 | 4559 | ||
| 4604 | - | func (_c *MockWebKitContextProvider_Close_Call) RunAndReturn(run func() error) *MockWebKitContextProvider_Close_Call { | |
| 4560 | + | func (_c *MockWebView_CanGoBack_Call) RunAndReturn(run func() bool) *MockWebView_CanGoBack_Call { | |
| 4605 | 4561 | _c.Call.Return(run) | |
| 4606 | 4562 | return _c | |
| 4607 | 4563 | } | |
| 4608 | 4564 | ||
| 4609 | - | // DataDir provides a mock function for the type MockWebKitContextProvider | |
| 4610 | - | func (_mock *MockWebKitContextProvider) DataDir() string { | |
| 4565 | + | // CanGoForward provides a mock function for the type MockWebView | |
| 4566 | + | func (_mock *MockWebView) CanGoForward() bool { | |
| 4611 | 4567 | ret := _mock.Called() | |
| 4612 | 4568 | ||
| 4613 | 4569 | if len(ret) == 0 { | |
| 4614 | - | panic("no return value specified for DataDir") | |
| 4570 | + | panic("no return value specified for CanGoForward") | |
| 4615 | 4571 | } | |
| 4616 | 4572 | ||
| 4617 | - | var r0 string | |
| 4618 | - | if returnFunc, ok := ret.Get(0).(func() string); ok { | |
| 4573 | + | var r0 bool | |
| 4574 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |
| 4619 | 4575 | r0 = returnFunc() | |
| 4620 | 4576 | } else { | |
| 4621 | - | r0 = ret.Get(0).(string) | |
| 4577 | + | r0 = ret.Get(0).(bool) | |
| 4622 | 4578 | } | |
| 4623 | 4579 | return r0 | |
| 4624 | 4580 | } | |
| 4625 | 4581 | ||
| 4626 | - | // MockWebKitContextProvider_DataDir_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DataDir' | |
| 4627 | - | type MockWebKitContextProvider_DataDir_Call struct { | |
| 4582 | + | // MockWebView_CanGoForward_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoForward' | |
| 4583 | + | type MockWebView_CanGoForward_Call struct { | |
| 4628 | 4584 | *mock.Call | |
| 4629 | 4585 | } | |
| 4630 | 4586 | ||
| 4631 | - | // DataDir is a helper method to define mock.On call | |
| 4632 | - | func (_e *MockWebKitContextProvider_Expecter) DataDir() *MockWebKitContextProvider_DataDir_Call { | |
| 4633 | - | return &MockWebKitContextProvider_DataDir_Call{Call: _e.mock.On("DataDir")} | |
| 4587 | + | // CanGoForward is a helper method to define mock.On call | |
| 4588 | + | func (_e *MockWebView_Expecter) CanGoForward() *MockWebView_CanGoForward_Call { | |
| 4589 | + | return &MockWebView_CanGoForward_Call{Call: _e.mock.On("CanGoForward")} | |
| 4634 | 4590 | } | |
| 4635 | 4591 | ||
| 4636 | - | func (_c *MockWebKitContextProvider_DataDir_Call) Run(run func()) *MockWebKitContextProvider_DataDir_Call { | |
| 4592 | + | func (_c *MockWebView_CanGoForward_Call) Run(run func()) *MockWebView_CanGoForward_Call { | |
| 4637 | 4593 | _c.Call.Run(func(args mock.Arguments) { | |
| 4638 | 4594 | run() | |
| 4639 | 4595 | }) | |
| 4640 | 4596 | return _c | |
| 4641 | 4597 | } | |
| 4642 | 4598 | ||
| 4643 | - | func (_c *MockWebKitContextProvider_DataDir_Call) Return(s string) *MockWebKitContextProvider_DataDir_Call { | |
| 4644 | - | _c.Call.Return(s) | |
| 4645 | - | return _c | |
| 4646 | - | } | |
| 4647 | - | ||
| 4648 | - | func (_c *MockWebKitContextProvider_DataDir_Call) RunAndReturn(run func() string) *MockWebKitContextProvider_DataDir_Call { | |
| 4649 | - | _c.Call.Return(run) | |
| 4650 | - | return _c | |
| 4651 | - | } | |
| 4652 | - | ||
| 4653 | - | // Initialize provides a mock function for the type MockWebKitContextProvider | |
| 4654 | - | func (_mock *MockWebKitContextProvider) Initialize(ctx context.Context, opts port.WebKitContextOptions) error { | |
| 4655 | - | ret := _mock.Called(ctx, opts) | |
| 4656 | - | ||
| 4657 | - | if len(ret) == 0 { | |
| 4658 | - | panic("no return value specified for Initialize") | |
| 4659 | - | } | |
| 4660 | - | ||
| 4661 | - | var r0 error | |
| 4662 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, port.WebKitContextOptions) error); ok { | |
| 4663 | - | r0 = returnFunc(ctx, opts) | |
| 4664 | - | } else { | |
| 4665 | - | r0 = ret.Error(0) | |
| 4666 | - | } | |
| 4667 | - | return r0 | |
| 4668 | - | } | |
| 4669 | - | ||
| 4670 | - | // MockWebKitContextProvider_Initialize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Initialize' | |
| 4671 | - | type MockWebKitContextProvider_Initialize_Call struct { | |
| 4672 | - | *mock.Call | |
| 4673 | - | } | |
| 4674 | - | ||
| 4675 | - | // Initialize is a helper method to define mock.On call | |
| 4676 | - | // - ctx context.Context | |
| 4677 | - | // - opts port.WebKitContextOptions | |
| 4678 | - | func (_e *MockWebKitContextProvider_Expecter) Initialize(ctx interface{}, opts interface{}) *MockWebKitContextProvider_Initialize_Call { | |
| 4679 | - | return &MockWebKitContextProvider_Initialize_Call{Call: _e.mock.On("Initialize", ctx, opts)} | |
| 4680 | - | } | |
| 4681 | - | ||
| 4682 | - | func (_c *MockWebKitContextProvider_Initialize_Call) Run(run func(ctx context.Context, opts port.WebKitContextOptions)) *MockWebKitContextProvider_Initialize_Call { | |
| 4683 | - | _c.Call.Run(func(args mock.Arguments) { | |
| 4684 | - | var arg0 context.Context | |
| 4685 | - | if args[0] != nil { | |
| 4686 | - | arg0 = args[0].(context.Context) | |
| 4687 | - | } | |
| 4688 | - | var arg1 port.WebKitContextOptions | |
| 4689 | - | if args[1] != nil { | |
| 4690 | - | arg1 = args[1].(port.WebKitContextOptions) | |
| 4691 | - | } | |
| 4692 | - | run( | |
| 4693 | - | arg0, | |
| 4694 | - | arg1, | |
| 4695 | - | ) | |
| 4696 | - | }) | |
| 4697 | - | return _c | |
| 4698 | - | } | |
| 4699 | - | ||
| 4700 | - | func (_c *MockWebKitContextProvider_Initialize_Call) Return(err error) *MockWebKitContextProvider_Initialize_Call { | |
| 4701 | - | _c.Call.Return(err) | |
| 4599 | + | func (_c *MockWebView_CanGoForward_Call) Return(b bool) *MockWebView_CanGoForward_Call { | |
| 4600 | + | _c.Call.Return(b) | |
| 4702 | 4601 | return _c | |
| 4703 | 4602 | } | |
| 4704 | 4603 | ||
| 4705 | - | func (_c *MockWebKitContextProvider_Initialize_Call) RunAndReturn(run func(ctx context.Context, opts port.WebKitContextOptions) error) *MockWebKitContextProvider_Initialize_Call { | |
| 4604 | + | func (_c *MockWebView_CanGoForward_Call) RunAndReturn(run func() bool) *MockWebView_CanGoForward_Call { | |
| 4706 | 4605 | _c.Call.Return(run) | |
| 4707 | 4606 | return _c | |
| 4708 | 4607 | } | |
| 4709 | 4608 | ||
| 4710 | - | // PrefetchDNS provides a mock function for the type MockWebKitContextProvider | |
| 4711 | - | func (_mock *MockWebKitContextProvider) PrefetchDNS(hostname string) { | |
| 4712 | - | _mock.Called(hostname) | |
| 4609 | + | // Destroy provides a mock function for the type MockWebView | |
| 4610 | + | func (_mock *MockWebView) Destroy() { | |
| 4611 | + | _mock.Called() | |
| 4713 | 4612 | return | |
| 4714 | 4613 | } | |
| 4715 | 4614 | ||
| 4716 | - | // MockWebKitContextProvider_PrefetchDNS_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrefetchDNS' | |
| 4717 | - | type MockWebKitContextProvider_PrefetchDNS_Call struct { | |
| 4615 | + | // MockWebView_Destroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Destroy' | |
| 4616 | + | type MockWebView_Destroy_Call struct { | |
| 4718 | 4617 | *mock.Call | |
| 4719 | 4618 | } | |
| 4720 | 4619 | ||
| 4721 | - | // PrefetchDNS is a helper method to define mock.On call | |
| 4722 | - | // - hostname string | |
| 4723 | - | func (_e *MockWebKitContextProvider_Expecter) PrefetchDNS(hostname interface{}) *MockWebKitContextProvider_PrefetchDNS_Call { | |
| 4724 | - | return &MockWebKitContextProvider_PrefetchDNS_Call{Call: _e.mock.On("PrefetchDNS", hostname)} | |
| 4620 | + | // Destroy is a helper method to define mock.On call | |
| 4621 | + | func (_e *MockWebView_Expecter) Destroy() *MockWebView_Destroy_Call { | |
| 4622 | + | return &MockWebView_Destroy_Call{Call: _e.mock.On("Destroy")} | |
| 4725 | 4623 | } | |
| 4726 | 4624 | ||
| 4727 | - | func (_c *MockWebKitContextProvider_PrefetchDNS_Call) Run(run func(hostname string)) *MockWebKitContextProvider_PrefetchDNS_Call { | |
| 4625 | + | func (_c *MockWebView_Destroy_Call) Run(run func()) *MockWebView_Destroy_Call { | |
| 4728 | 4626 | _c.Call.Run(func(args mock.Arguments) { | |
| 4729 | - | var arg0 string | |
| 4730 | - | if args[0] != nil { | |
| 4731 | - | arg0 = args[0].(string) | |
| 4732 | - | } | |
| 4733 | - | run( | |
| 4734 | - | arg0, | |
| 4735 | - | ) | |
| 4627 | + | run() | |
| 4736 | 4628 | }) | |
| 4737 | 4629 | return _c | |
| 4738 | 4630 | } | |
| 4739 | 4631 | ||
| 4740 | - | func (_c *MockWebKitContextProvider_PrefetchDNS_Call) Return() *MockWebKitContextProvider_PrefetchDNS_Call { | |
| 4632 | + | func (_c *MockWebView_Destroy_Call) Return() *MockWebView_Destroy_Call { | |
| 4741 | 4633 | _c.Call.Return() | |
| 4742 | 4634 | return _c | |
| 4743 | 4635 | } | |
| 4744 | 4636 | ||
| 4745 | - | func (_c *MockWebKitContextProvider_PrefetchDNS_Call) RunAndReturn(run func(hostname string)) *MockWebKitContextProvider_PrefetchDNS_Call { | |
| 4637 | + | func (_c *MockWebView_Destroy_Call) RunAndReturn(run func()) *MockWebView_Destroy_Call { | |
| 4746 | 4638 | _c.Run(run) | |
| 4747 | 4639 | return _c | |
| 4748 | 4640 | } | |
| 4749 | 4641 | ||
| 4750 | - | // NewMockWebView creates a new instance of MockWebView. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |
| 4751 | - | // The first argument is typically a *testing.T value. | |
| 4752 | - | func NewMockWebView(t interface { | |
| 4753 | - | mock.TestingT | |
| 4754 | - | Cleanup(func()) | |
| 4755 | - | }) *MockWebView { | |
| 4756 | - | mock := &MockWebView{} | |
| 4757 | - | mock.Mock.Test(t) | |
| 4758 | - | ||
| 4759 | - | t.Cleanup(func() { mock.AssertExpectations(t) }) | |
| 4760 | - | ||
| 4761 | - | return mock | |
| 4762 | - | } | |
| 4763 | - | ||
| 4764 | - | // MockWebView is an autogenerated mock type for the WebView type | |
| 4765 | - | type MockWebView struct { | |
| 4766 | - | mock.Mock | |
| 4767 | - | } | |
| 4768 | - | ||
| 4769 | - | type MockWebView_Expecter struct { | |
| 4770 | - | mock *mock.Mock | |
| 4771 | - | } | |
| 4772 | - | ||
| 4773 | - | func (_m *MockWebView) EXPECT() *MockWebView_Expecter { | |
| 4774 | - | return &MockWebView_Expecter{mock: &_m.Mock} | |
| 4775 | - | } | |
| 4776 | - | ||
| 4777 | - | // CanGoBack provides a mock function for the type MockWebView | |
| 4778 | - | func (_mock *MockWebView) CanGoBack() bool { | |
| 4642 | + | // EstimatedProgress provides a mock function for the type MockWebView | |
| 4643 | + | func (_mock *MockWebView) EstimatedProgress() float64 { | |
| 4779 | 4644 | ret := _mock.Called() | |
| 4780 | 4645 | ||
| 4781 | 4646 | if len(ret) == 0 { | |
| 4782 | - | panic("no return value specified for CanGoBack") | |
| 4647 | + | panic("no return value specified for EstimatedProgress") | |
| 4783 | 4648 | } | |
| 4784 | 4649 | ||
| 4785 | - | var r0 bool | |
| 4786 | - | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |
| 4650 | + | var r0 float64 | |
| 4651 | + | if returnFunc, ok := ret.Get(0).(func() float64); ok { | |
| 4787 | 4652 | r0 = returnFunc() | |
| 4788 | 4653 | } else { | |
| 4789 | - | r0 = ret.Get(0).(bool) | |
| 4654 | + | r0 = ret.Get(0).(float64) | |
| 4790 | 4655 | } | |
| 4791 | 4656 | return r0 | |
| 4792 | 4657 | } | |
| 4793 | 4658 | ||
| 4794 | - | // MockWebView_CanGoBack_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoBack' | |
| 4795 | - | type MockWebView_CanGoBack_Call struct { | |
| 4659 | + | // MockWebView_EstimatedProgress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimatedProgress' | |
| 4660 | + | type MockWebView_EstimatedProgress_Call struct { | |
| 4796 | 4661 | *mock.Call | |
| 4797 | 4662 | } | |
| 4798 | 4663 | ||
| 4799 | - | // CanGoBack is a helper method to define mock.On call | |
| 4800 | - | func (_e *MockWebView_Expecter) CanGoBack() *MockWebView_CanGoBack_Call { | |
| 4801 | - | return &MockWebView_CanGoBack_Call{Call: _e.mock.On("CanGoBack")} | |
| 4664 | + | // EstimatedProgress is a helper method to define mock.On call | |
| 4665 | + | func (_e *MockWebView_Expecter) EstimatedProgress() *MockWebView_EstimatedProgress_Call { | |
| 4666 | + | return &MockWebView_EstimatedProgress_Call{Call: _e.mock.On("EstimatedProgress")} | |
| 4802 | 4667 | } | |
| 4803 | 4668 | ||
| 4804 | - | func (_c *MockWebView_CanGoBack_Call) Run(run func()) *MockWebView_CanGoBack_Call { | |
| 4669 | + | func (_c *MockWebView_EstimatedProgress_Call) Run(run func()) *MockWebView_EstimatedProgress_Call { | |
| 4805 | 4670 | _c.Call.Run(func(args mock.Arguments) { | |
| 4806 | 4671 | run() | |
| 4807 | 4672 | }) | |
| 4808 | 4673 | return _c | |
| 4809 | 4674 | } | |
| 4810 | 4675 | ||
| 4811 | - | func (_c *MockWebView_CanGoBack_Call) Return(b bool) *MockWebView_CanGoBack_Call { | |
| 4812 | - | _c.Call.Return(b) | |
| 4676 | + | func (_c *MockWebView_EstimatedProgress_Call) Return(f float64) *MockWebView_EstimatedProgress_Call { | |
| 4677 | + | _c.Call.Return(f) | |
| 4813 | 4678 | return _c | |
| 4814 | 4679 | } | |
| 4815 | 4680 | ||
| 4816 | - | func (_c *MockWebView_CanGoBack_Call) RunAndReturn(run func() bool) *MockWebView_CanGoBack_Call { | |
| 4681 | + | func (_c *MockWebView_EstimatedProgress_Call) RunAndReturn(run func() float64) *MockWebView_EstimatedProgress_Call { | |
| 4817 | 4682 | _c.Call.Return(run) | |
| 4818 | 4683 | return _c | |
| 4819 | 4684 | } | |
| 4820 | 4685 | ||
| 4821 | - | // CanGoForward provides a mock function for the type MockWebView | |
| 4822 | - | func (_mock *MockWebView) CanGoForward() bool { | |
| 4686 | + | // Favicon provides a mock function for the type MockWebView | |
| 4687 | + | func (_mock *MockWebView) Favicon() port.Texture { | |
| 4823 | 4688 | ret := _mock.Called() | |
| 4824 | 4689 | ||
| 4825 | 4690 | if len(ret) == 0 { | |
| 4826 | - | panic("no return value specified for CanGoForward") | |
| 4691 | + | panic("no return value specified for Favicon") | |
| 4827 | 4692 | } | |
| 4828 | 4693 | ||
| 4829 | - | var r0 bool | |
| 4830 | - | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |
| 4694 | + | var r0 port.Texture | |
| 4695 | + | if returnFunc, ok := ret.Get(0).(func() port.Texture); ok { | |
| 4831 | 4696 | r0 = returnFunc() | |
| 4832 | 4697 | } else { | |
| 4833 | - | r0 = ret.Get(0).(bool) | |
| 4698 | + | if ret.Get(0) != nil { | |
| 4699 | + | r0 = ret.Get(0).(port.Texture) | |
| 4700 | + | } | |
| 4834 | 4701 | } | |
| 4835 | 4702 | return r0 | |
| 4836 | 4703 | } | |
| 4837 | 4704 | ||
| 4838 | - | // MockWebView_CanGoForward_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoForward' | |
| 4839 | - | type MockWebView_CanGoForward_Call struct { | |
| 4705 | + | // MockWebView_Favicon_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Favicon' | |
| 4706 | + | type MockWebView_Favicon_Call struct { | |
| 4840 | 4707 | *mock.Call | |
| 4841 | 4708 | } | |
| 4842 | 4709 | ||
| 4843 | - | // CanGoForward is a helper method to define mock.On call | |
| 4844 | - | func (_e *MockWebView_Expecter) CanGoForward() *MockWebView_CanGoForward_Call { | |
| 4845 | - | return &MockWebView_CanGoForward_Call{Call: _e.mock.On("CanGoForward")} | |
| 4710 | + | // Favicon is a helper method to define mock.On call | |
| 4711 | + | func (_e *MockWebView_Expecter) Favicon() *MockWebView_Favicon_Call { | |
| 4712 | + | return &MockWebView_Favicon_Call{Call: _e.mock.On("Favicon")} | |
| 4846 | 4713 | } | |
| 4847 | 4714 | ||
| 4848 | - | func (_c *MockWebView_CanGoForward_Call) Run(run func()) *MockWebView_CanGoForward_Call { | |
| 4715 | + | func (_c *MockWebView_Favicon_Call) Run(run func()) *MockWebView_Favicon_Call { | |
| 4849 | 4716 | _c.Call.Run(func(args mock.Arguments) { | |
| 4850 | 4717 | run() | |
| 4851 | 4718 | }) | |
| 4852 | 4719 | return _c | |
| 4853 | 4720 | } | |
| 4854 | 4721 | ||
| 4855 | - | func (_c *MockWebView_CanGoForward_Call) Return(b bool) *MockWebView_CanGoForward_Call { | |
| 4856 | - | _c.Call.Return(b) | |
| 4722 | + | func (_c *MockWebView_Favicon_Call) Return(texture port.Texture) *MockWebView_Favicon_Call { | |
| 4723 | + | _c.Call.Return(texture) | |
| 4857 | 4724 | return _c | |
| 4858 | 4725 | } | |
| 4859 | 4726 | ||
| 4860 | - | func (_c *MockWebView_CanGoForward_Call) RunAndReturn(run func() bool) *MockWebView_CanGoForward_Call { | |
| 4727 | + | func (_c *MockWebView_Favicon_Call) RunAndReturn(run func() port.Texture) *MockWebView_Favicon_Call { | |
| 4861 | 4728 | _c.Call.Return(run) | |
| 4862 | 4729 | return _c | |
| 4863 | 4730 | } | |
| 4864 | 4731 | ||
| 4865 | - | // Destroy provides a mock function for the type MockWebView | |
| 4866 | - | func (_mock *MockWebView) Destroy() { | |
| 4867 | - | _mock.Called() | |
| 4868 | - | return | |
| 4869 | - | } | |
| 4870 | - | ||
| 4871 | - | // MockWebView_Destroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Destroy' | |
| 4872 | - | type MockWebView_Destroy_Call struct { | |
| 4873 | - | *mock.Call | |
| 4874 | - | } | |
| 4875 | - | ||
| 4876 | - | // Destroy is a helper method to define mock.On call | |
| 4877 | - | func (_e *MockWebView_Expecter) Destroy() *MockWebView_Destroy_Call { | |
| 4878 | - | return &MockWebView_Destroy_Call{Call: _e.mock.On("Destroy")} | |
| 4879 | - | } | |
| 4880 | - | ||
| 4881 | - | func (_c *MockWebView_Destroy_Call) Run(run func()) *MockWebView_Destroy_Call { | |
| 4882 | - | _c.Call.Run(func(args mock.Arguments) { | |
| 4883 | - | run() | |
| 4884 | - | }) | |
| 4885 | - | return _c | |
| 4886 | - | } | |
| 4887 | - | ||
| 4888 | - | func (_c *MockWebView_Destroy_Call) Return() *MockWebView_Destroy_Call { | |
| 4889 | - | _c.Call.Return() | |
| 4890 | - | return _c | |
| 4891 | - | } | |
| 4892 | - | ||
| 4893 | - | func (_c *MockWebView_Destroy_Call) RunAndReturn(run func()) *MockWebView_Destroy_Call { | |
| 4894 | - | _c.Run(run) | |
| 4895 | - | return _c | |
| 4896 | - | } | |
| 4897 | - | ||
| 4898 | - | // EstimatedProgress provides a mock function for the type MockWebView | |
| 4899 | - | func (_mock *MockWebView) EstimatedProgress() float64 { | |
| 4732 | + | // Generation provides a mock function for the type MockWebView | |
| 4733 | + | func (_mock *MockWebView) Generation() uint64 { | |
| 4900 | 4734 | ret := _mock.Called() | |
| 4901 | 4735 | ||
| 4902 | 4736 | if len(ret) == 0 { | |
| 4903 | - | panic("no return value specified for EstimatedProgress") | |
| 4737 | + | panic("no return value specified for Generation") | |
| 4904 | 4738 | } | |
| 4905 | 4739 | ||
| 4906 | - | var r0 float64 | |
| 4907 | - | if returnFunc, ok := ret.Get(0).(func() float64); ok { | |
| 4740 | + | var r0 uint64 | |
| 4741 | + | if returnFunc, ok := ret.Get(0).(func() uint64); ok { | |
| 4908 | 4742 | r0 = returnFunc() | |
| 4909 | 4743 | } else { | |
| 4910 | - | r0 = ret.Get(0).(float64) | |
| 4744 | + | r0 = ret.Get(0).(uint64) | |
| 4911 | 4745 | } | |
| 4912 | 4746 | return r0 | |
| 4913 | 4747 | } | |
| 4914 | 4748 | ||
| 4915 | - | // MockWebView_EstimatedProgress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimatedProgress' | |
| 4916 | - | type MockWebView_EstimatedProgress_Call struct { | |
| 4749 | + | // MockWebView_Generation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Generation' | |
| 4750 | + | type MockWebView_Generation_Call struct { | |
| 4917 | 4751 | *mock.Call | |
| 4918 | 4752 | } | |
| 4919 | 4753 | ||
| 4920 | - | // EstimatedProgress is a helper method to define mock.On call | |
| 4921 | - | func (_e *MockWebView_Expecter) EstimatedProgress() *MockWebView_EstimatedProgress_Call { | |
| 4922 | - | return &MockWebView_EstimatedProgress_Call{Call: _e.mock.On("EstimatedProgress")} | |
| 4754 | + | // Generation is a helper method to define mock.On call | |
| 4755 | + | func (_e *MockWebView_Expecter) Generation() *MockWebView_Generation_Call { | |
| 4756 | + | return &MockWebView_Generation_Call{Call: _e.mock.On("Generation")} | |
| 4923 | 4757 | } | |
| 4924 | 4758 | ||
| 4925 | - | func (_c *MockWebView_EstimatedProgress_Call) Run(run func()) *MockWebView_EstimatedProgress_Call { | |
| 4759 | + | func (_c *MockWebView_Generation_Call) Run(run func()) *MockWebView_Generation_Call { | |
| 4926 | 4760 | _c.Call.Run(func(args mock.Arguments) { | |
| 4927 | 4761 | run() | |
| 4928 | 4762 | }) | |
| 4929 | 4763 | return _c | |
| 4930 | 4764 | } | |
| 4931 | 4765 | ||
| 4932 | - | func (_c *MockWebView_EstimatedProgress_Call) Return(f float64) *MockWebView_EstimatedProgress_Call { | |
| 4933 | - | _c.Call.Return(f) | |
| 4766 | + | func (_c *MockWebView_Generation_Call) Return(v uint64) *MockWebView_Generation_Call { | |
| 4767 | + | _c.Call.Return(v) | |
| 4934 | 4768 | return _c | |
| 4935 | 4769 | } | |
| 4936 | 4770 | ||
| 4937 | - | func (_c *MockWebView_EstimatedProgress_Call) RunAndReturn(run func() float64) *MockWebView_EstimatedProgress_Call { | |
| 4771 | + | func (_c *MockWebView_Generation_Call) RunAndReturn(run func() uint64) *MockWebView_Generation_Call { | |
| 4938 | 4772 | _c.Call.Return(run) | |
| 4939 | 4773 | return _c | |
| 4940 | 4774 | } | |
| @@ -5573,6 +5407,143 @@ func (_c *MockWebView_ReloadBypassCache_Call) RunAndReturn(run func(ctx context. | |||
| 5573 | 5407 | return _c | |
| 5574 | 5408 | } | |
| 5575 | 5409 | ||
| 5410 | + | // ResetBackgroundToDefault provides a mock function for the type MockWebView | |
| 5411 | + | func (_mock *MockWebView) ResetBackgroundToDefault() { | |
| 5412 | + | _mock.Called() | |
| 5413 | + | return | |
| 5414 | + | } | |
| 5415 | + | ||
| 5416 | + | // MockWebView_ResetBackgroundToDefault_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetBackgroundToDefault' | |
| 5417 | + | type MockWebView_ResetBackgroundToDefault_Call struct { | |
| 5418 | + | *mock.Call | |
| 5419 | + | } | |
| 5420 | + | ||
| 5421 | + | // ResetBackgroundToDefault is a helper method to define mock.On call | |
| 5422 | + | func (_e *MockWebView_Expecter) ResetBackgroundToDefault() *MockWebView_ResetBackgroundToDefault_Call { | |
| 5423 | + | return &MockWebView_ResetBackgroundToDefault_Call{Call: _e.mock.On("ResetBackgroundToDefault")} | |
| 5424 | + | } | |
| 5425 | + | ||
| 5426 | + | func (_c *MockWebView_ResetBackgroundToDefault_Call) Run(run func()) *MockWebView_ResetBackgroundToDefault_Call { | |
| 5427 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 5428 | + | run() | |
| 5429 | + | }) | |
| 5430 | + | return _c | |
| 5431 | + | } | |
| 5432 | + | ||
| 5433 | + | func (_c *MockWebView_ResetBackgroundToDefault_Call) Return() *MockWebView_ResetBackgroundToDefault_Call { | |
| 5434 | + | _c.Call.Return() | |
| 5435 | + | return _c | |
| 5436 | + | } | |
| 5437 | + | ||
| 5438 | + | func (_c *MockWebView_ResetBackgroundToDefault_Call) RunAndReturn(run func()) *MockWebView_ResetBackgroundToDefault_Call { | |
| 5439 | + | _c.Run(run) | |
| 5440 | + | return _c | |
| 5441 | + | } | |
| 5442 | + | ||
| 5443 | + | // RunJavaScript provides a mock function for the type MockWebView | |
| 5444 | + | func (_mock *MockWebView) RunJavaScript(ctx context.Context, script string) { | |
| 5445 | + | _mock.Called(ctx, script) | |
| 5446 | + | return | |
| 5447 | + | } | |
| 5448 | + | ||
| 5449 | + | // MockWebView_RunJavaScript_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunJavaScript' | |
| 5450 | + | type MockWebView_RunJavaScript_Call struct { | |
| 5451 | + | *mock.Call | |
| 5452 | + | } | |
| 5453 | + | ||
| 5454 | + | // RunJavaScript is a helper method to define mock.On call | |
| 5455 | + | // - ctx context.Context | |
| 5456 | + | // - script string | |
| 5457 | + | func (_e *MockWebView_Expecter) RunJavaScript(ctx interface{}, script interface{}) *MockWebView_RunJavaScript_Call { | |
| 5458 | + | return &MockWebView_RunJavaScript_Call{Call: _e.mock.On("RunJavaScript", ctx, script)} | |
| 5459 | + | } | |
| 5460 | + | ||
| 5461 | + | func (_c *MockWebView_RunJavaScript_Call) Run(run func(ctx context.Context, script string)) *MockWebView_RunJavaScript_Call { | |
| 5462 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 5463 | + | var arg0 context.Context | |
| 5464 | + | if args[0] != nil { | |
| 5465 | + | arg0 = args[0].(context.Context) | |
| 5466 | + | } | |
| 5467 | + | var arg1 string | |
| 5468 | + | if args[1] != nil { | |
| 5469 | + | arg1 = args[1].(string) | |
| 5470 | + | } | |
| 5471 | + | run( | |
| 5472 | + | arg0, | |
| 5473 | + | arg1, | |
| 5474 | + | ) | |
| 5475 | + | }) | |
| 5476 | + | return _c | |
| 5477 | + | } | |
| 5478 | + | ||
| 5479 | + | func (_c *MockWebView_RunJavaScript_Call) Return() *MockWebView_RunJavaScript_Call { | |
| 5480 | + | _c.Call.Return() | |
| 5481 | + | return _c | |
| 5482 | + | } | |
| 5483 | + | ||
| 5484 | + | func (_c *MockWebView_RunJavaScript_Call) RunAndReturn(run func(ctx context.Context, script string)) *MockWebView_RunJavaScript_Call { | |
| 5485 | + | _c.Run(run) | |
| 5486 | + | return _c | |
| 5487 | + | } | |
| 5488 | + | ||
| 5489 | + | // SetBackgroundColor provides a mock function for the type MockWebView | |
| 5490 | + | func (_mock *MockWebView) SetBackgroundColor(r float64, g float64, b float64, a float64) { | |
| 5491 | + | _mock.Called(r, g, b, a) | |
| 5492 | + | return | |
| 5493 | + | } | |
| 5494 | + | ||
| 5495 | + | // MockWebView_SetBackgroundColor_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetBackgroundColor' | |
| 5496 | + | type MockWebView_SetBackgroundColor_Call struct { | |
| 5497 | + | *mock.Call | |
| 5498 | + | } | |
| 5499 | + | ||
| 5500 | + | // SetBackgroundColor is a helper method to define mock.On call | |
| 5501 | + | // - r float64 | |
| 5502 | + | // - g float64 | |
| 5503 | + | // - b float64 | |
| 5504 | + | // - a float64 | |
| 5505 | + | func (_e *MockWebView_Expecter) SetBackgroundColor(r interface{}, g interface{}, b interface{}, a interface{}) *MockWebView_SetBackgroundColor_Call { | |
| 5506 | + | return &MockWebView_SetBackgroundColor_Call{Call: _e.mock.On("SetBackgroundColor", r, g, b, a)} | |
| 5507 | + | } | |
| 5508 | + | ||
| 5509 | + | func (_c *MockWebView_SetBackgroundColor_Call) Run(run func(r float64, g float64, b float64, a float64)) *MockWebView_SetBackgroundColor_Call { | |
| 5510 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 5511 | + | var arg0 float64 | |
| 5512 | + | if args[0] != nil { | |
| 5513 | + | arg0 = args[0].(float64) | |
| 5514 | + | } | |
| 5515 | + | var arg1 float64 | |
| 5516 | + | if args[1] != nil { | |
| 5517 | + | arg1 = args[1].(float64) | |
| 5518 | + | } | |
| 5519 | + | var arg2 float64 | |
| 5520 | + | if args[2] != nil { | |
| 5521 | + | arg2 = args[2].(float64) | |
| 5522 | + | } | |
| 5523 | + | var arg3 float64 | |
| 5524 | + | if args[3] != nil { | |
| 5525 | + | arg3 = args[3].(float64) | |
| 5526 | + | } | |
| 5527 | + | run( | |
| 5528 | + | arg0, | |
| 5529 | + | arg1, | |
| 5530 | + | arg2, | |
| 5531 | + | arg3, | |
| 5532 | + | ) | |
| 5533 | + | }) | |
| 5534 | + | return _c | |
| 5535 | + | } | |
| 5536 | + | ||
| 5537 | + | func (_c *MockWebView_SetBackgroundColor_Call) Return() *MockWebView_SetBackgroundColor_Call { | |
| 5538 | + | _c.Call.Return() | |
| 5539 | + | return _c | |
| 5540 | + | } | |
| 5541 | + | ||
| 5542 | + | func (_c *MockWebView_SetBackgroundColor_Call) RunAndReturn(run func(r float64, g float64, b float64, a float64)) *MockWebView_SetBackgroundColor_Call { | |
| 5543 | + | _c.Run(run) | |
| 5544 | + | return _c | |
| 5545 | + | } | |
| 5546 | + | ||
| 5576 | 5547 | // SetCallbacks provides a mock function for the type MockWebView | |
| 5577 | 5548 | func (_mock *MockWebView) SetCallbacks(callbacks *port.WebViewCallbacks) { | |
| 5578 | 5549 | _mock.Called(callbacks) | |
| @@ -1188,6 +1188,63 @@ func (_c *MockContentInjector_InjectThemeCSS_Call) RunAndReturn(run func(ctx con | |||||
| 1188 | return _c | 1188 | return _c | ||
| 1189 | } | 1189 | } | ||
| 1190 | 1190 | ||||
| 1191 | + | // RefreshScripts provides a mock function for the type MockContentInjector | |||
| 1192 | + | func (_mock *MockContentInjector) RefreshScripts(ctx context.Context, wv port.WebView) error { | |||
| 1193 | + | ret := _mock.Called(ctx, wv) | |||
| 1194 | + | ||||
| 1195 | + | if len(ret) == 0 { | |||
| 1196 | + | panic("no return value specified for RefreshScripts") | |||
| 1197 | + | } | |||
| 1198 | + | ||||
| 1199 | + | var r0 error | |||
| 1200 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, port.WebView) error); ok { | |||
| 1201 | + | r0 = returnFunc(ctx, wv) | |||
| 1202 | + | } else { | |||
| 1203 | + | r0 = ret.Error(0) | |||
| 1204 | + | } | |||
| 1205 | + | return r0 | |||
| 1206 | + | } | |||
| 1207 | + | ||||
| 1208 | + | // MockContentInjector_RefreshScripts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RefreshScripts' | |||
| 1209 | + | type MockContentInjector_RefreshScripts_Call struct { | |||
| 1210 | + | *mock.Call | |||
| 1211 | + | } | |||
| 1212 | + | ||||
| 1213 | + | // RefreshScripts is a helper method to define mock.On call | |||
| 1214 | + | // - ctx context.Context | |||
| 1215 | + | // - wv port.WebView | |||
| 1216 | + | func (_e *MockContentInjector_Expecter) RefreshScripts(ctx interface{}, wv interface{}) *MockContentInjector_RefreshScripts_Call { | |||
| 1217 | + | return &MockContentInjector_RefreshScripts_Call{Call: _e.mock.On("RefreshScripts", ctx, wv)} | |||
| 1218 | + | } | |||
| 1219 | + | ||||
| 1220 | + | func (_c *MockContentInjector_RefreshScripts_Call) Run(run func(ctx context.Context, wv port.WebView)) *MockContentInjector_RefreshScripts_Call { | |||
| 1221 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1222 | + | var arg0 context.Context | |||
| 1223 | + | if args[0] != nil { | |||
| 1224 | + | arg0 = args[0].(context.Context) | |||
| 1225 | + | } | |||
| 1226 | + | var arg1 port.WebView | |||
| 1227 | + | if args[1] != nil { | |||
| 1228 | + | arg1 = args[1].(port.WebView) | |||
| 1229 | + | } | |||
| 1230 | + | run( | |||
| 1231 | + | arg0, | |||
| 1232 | + | arg1, | |||
| 1233 | + | ) | |||
| 1234 | + | }) | |||
| 1235 | + | return _c | |||
| 1236 | + | } | |||
| 1237 | + | ||||
| 1238 | + | func (_c *MockContentInjector_RefreshScripts_Call) Return(_a0 error) *MockContentInjector_RefreshScripts_Call { | |||
| 1239 | + | _c.Call.Return(_a0) | |||
| 1240 | + | return _c | |||
| 1241 | + | } | |||
| 1242 | + | ||||
| 1243 | + | func (_c *MockContentInjector_RefreshScripts_Call) RunAndReturn(run func(ctx context.Context, wv port.WebView) error) *MockContentInjector_RefreshScripts_Call { | |||
| 1244 | + | _c.Call.Return(run) | |||
| 1245 | + | return _c | |||
| 1246 | + | } | |||
| 1247 | + | ||||
| 1191 | // NewMockDatabaseProvider creates a new instance of MockDatabaseProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | 1248 | // NewMockDatabaseProvider creates a new instance of MockDatabaseProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | ||
| 1192 | // The first argument is typically a *testing.T value. | 1249 | // The first argument is typically a *testing.T value. | ||
| 1193 | func NewMockDatabaseProvider(t interface { | 1250 | func NewMockDatabaseProvider(t interface { | ||
| @@ -1524,6 +1581,158 @@ func (_c *MockDownloadResponse_GetUri_Call) RunAndReturn(run func() string) *Moc | |||||
| 1524 | return _c | 1581 | return _c | ||
| 1525 | } | 1582 | } | ||
| 1526 | 1583 | ||||
| 1584 | + | // NewMockMemoryPressureApplier creates a new instance of MockMemoryPressureApplier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |||
| 1585 | + | // The first argument is typically a *testing.T value. | |||
| 1586 | + | func NewMockMemoryPressureApplier(t interface { | |||
| 1587 | + | mock.TestingT | |||
| 1588 | + | Cleanup(func()) | |||
| 1589 | + | }) *MockMemoryPressureApplier { | |||
| 1590 | + | mock := &MockMemoryPressureApplier{} | |||
| 1591 | + | mock.Mock.Test(t) | |||
| 1592 | + | ||||
| 1593 | + | t.Cleanup(func() { mock.AssertExpectations(t) }) | |||
| 1594 | + | ||||
| 1595 | + | return mock | |||
| 1596 | + | } | |||
| 1597 | + | ||||
| 1598 | + | // MockMemoryPressureApplier is an autogenerated mock type for the MemoryPressureApplier type | |||
| 1599 | + | type MockMemoryPressureApplier struct { | |||
| 1600 | + | mock.Mock | |||
| 1601 | + | } | |||
| 1602 | + | ||||
| 1603 | + | type MockMemoryPressureApplier_Expecter struct { | |||
| 1604 | + | mock *mock.Mock | |||
| 1605 | + | } | |||
| 1606 | + | ||||
| 1607 | + | func (_m *MockMemoryPressureApplier) EXPECT() *MockMemoryPressureApplier_Expecter { | |||
| 1608 | + | return &MockMemoryPressureApplier_Expecter{mock: &_m.Mock} | |||
| 1609 | + | } | |||
| 1610 | + | ||||
| 1611 | + | // ApplyNetworkProcessSettings provides a mock function for the type MockMemoryPressureApplier | |||
| 1612 | + | func (_mock *MockMemoryPressureApplier) ApplyNetworkProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) error { | |||
| 1613 | + | ret := _mock.Called(ctx, cfg) | |||
| 1614 | + | ||||
| 1615 | + | if len(ret) == 0 { | |||
| 1616 | + | panic("no return value specified for ApplyNetworkProcessSettings") | |||
| 1617 | + | } | |||
| 1618 | + | ||||
| 1619 | + | var r0 error | |||
| 1620 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |||
| 1621 | + | r0 = returnFunc(ctx, cfg) | |||
| 1622 | + | } else { | |||
| 1623 | + | r0 = ret.Error(0) | |||
| 1624 | + | } | |||
| 1625 | + | return r0 | |||
| 1626 | + | } | |||
| 1627 | + | ||||
| 1628 | + | // MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyNetworkProcessSettings' | |||
| 1629 | + | type MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call struct { | |||
| 1630 | + | *mock.Call | |||
| 1631 | + | } | |||
| 1632 | + | ||||
| 1633 | + | // ApplyNetworkProcessSettings is a helper method to define mock.On call | |||
| 1634 | + | // - ctx context.Context | |||
| 1635 | + | // - cfg *port.MemoryPressureConfig | |||
| 1636 | + | func (_e *MockMemoryPressureApplier_Expecter) ApplyNetworkProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 1637 | + | return &MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call{Call: _e.mock.On("ApplyNetworkProcessSettings", ctx, cfg)} | |||
| 1638 | + | } | |||
| 1639 | + | ||||
| 1640 | + | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 1641 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1642 | + | var arg0 context.Context | |||
| 1643 | + | if args[0] != nil { | |||
| 1644 | + | arg0 = args[0].(context.Context) | |||
| 1645 | + | } | |||
| 1646 | + | var arg1 *port.MemoryPressureConfig | |||
| 1647 | + | if args[1] != nil { | |||
| 1648 | + | arg1 = args[1].(*port.MemoryPressureConfig) | |||
| 1649 | + | } | |||
| 1650 | + | run( | |||
| 1651 | + | arg0, | |||
| 1652 | + | arg1, | |||
| 1653 | + | ) | |||
| 1654 | + | }) | |||
| 1655 | + | return _c | |||
| 1656 | + | } | |||
| 1657 | + | ||||
| 1658 | + | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Return(err error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 1659 | + | _c.Call.Return(err) | |||
| 1660 | + | return _c | |||
| 1661 | + | } | |||
| 1662 | + | ||||
| 1663 | + | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 1664 | + | _c.Call.Return(run) | |||
| 1665 | + | return _c | |||
| 1666 | + | } | |||
| 1667 | + | ||||
| 1668 | + | // ApplyWebProcessSettings provides a mock function for the type MockMemoryPressureApplier | |||
| 1669 | + | func (_mock *MockMemoryPressureApplier) ApplyWebProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error) { | |||
| 1670 | + | ret := _mock.Called(ctx, cfg) | |||
| 1671 | + | ||||
| 1672 | + | if len(ret) == 0 { | |||
| 1673 | + | panic("no return value specified for ApplyWebProcessSettings") | |||
| 1674 | + | } | |||
| 1675 | + | ||||
| 1676 | + | var r0 any | |||
| 1677 | + | var r1 error | |||
| 1678 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) (any, error)); ok { | |||
| 1679 | + | return returnFunc(ctx, cfg) | |||
| 1680 | + | } | |||
| 1681 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) any); ok { | |||
| 1682 | + | r0 = returnFunc(ctx, cfg) | |||
| 1683 | + | } else { | |||
| 1684 | + | if ret.Get(0) != nil { | |||
| 1685 | + | r0 = ret.Get(0).(any) | |||
| 1686 | + | } | |||
| 1687 | + | } | |||
| 1688 | + | if returnFunc, ok := ret.Get(1).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |||
| 1689 | + | r1 = returnFunc(ctx, cfg) | |||
| 1690 | + | } else { | |||
| 1691 | + | r1 = ret.Error(1) | |||
| 1692 | + | } | |||
| 1693 | + | return r0, r1 | |||
| 1694 | + | } | |||
| 1695 | + | ||||
| 1696 | + | // MockMemoryPressureApplier_ApplyWebProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyWebProcessSettings' | |||
| 1697 | + | type MockMemoryPressureApplier_ApplyWebProcessSettings_Call struct { | |||
| 1698 | + | *mock.Call | |||
| 1699 | + | } | |||
| 1700 | + | ||||
| 1701 | + | // ApplyWebProcessSettings is a helper method to define mock.On call | |||
| 1702 | + | // - ctx context.Context | |||
| 1703 | + | // - cfg *port.MemoryPressureConfig | |||
| 1704 | + | func (_e *MockMemoryPressureApplier_Expecter) ApplyWebProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 1705 | + | return &MockMemoryPressureApplier_ApplyWebProcessSettings_Call{Call: _e.mock.On("ApplyWebProcessSettings", ctx, cfg)} | |||
| 1706 | + | } | |||
| 1707 | + | ||||
| 1708 | + | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 1709 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1710 | + | var arg0 context.Context | |||
| 1711 | + | if args[0] != nil { | |||
| 1712 | + | arg0 = args[0].(context.Context) | |||
| 1713 | + | } | |||
| 1714 | + | var arg1 *port.MemoryPressureConfig | |||
| 1715 | + | if args[1] != nil { | |||
| 1716 | + | arg1 = args[1].(*port.MemoryPressureConfig) | |||
| 1717 | + | } | |||
| 1718 | + | run( | |||
| 1719 | + | arg0, | |||
| 1720 | + | arg1, | |||
| 1721 | + | ) | |||
| 1722 | + | }) | |||
| 1723 | + | return _c | |||
| 1724 | + | } | |||
| 1725 | + | ||||
| 1726 | + | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Return(v any, err error) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 1727 | + | _c.Call.Return(v, err) | |||
| 1728 | + | return _c | |||
| 1729 | + | } | |||
| 1730 | + | ||||
| 1731 | + | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 1732 | + | _c.Call.Return(run) | |||
| 1733 | + | return _c | |||
| 1734 | + | } | |||
| 1735 | + | ||||
| 1527 | // NewMockEngine creates a new instance of MockEngine. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | 1736 | // NewMockEngine creates a new instance of MockEngine. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | ||
| 1528 | // The first argument is typically a *testing.T value. | 1737 | // The first argument is typically a *testing.T value. | ||
| 1529 | func NewMockEngine(t interface { | 1738 | func NewMockEngine(t interface { | ||
| @@ -1779,63 +1988,6 @@ func (_c *MockEngine_FilterApplier_Call) RunAndReturn(run func() port.FilterAppl | |||||
| 1779 | return _c | 1988 | return _c | ||
| 1780 | } | 1989 | } | ||
| 1781 | 1990 | ||||
| 1782 | - | // Init provides a mock function for the type MockEngine | |||
| 1783 | - | func (_mock *MockEngine) Init(ctx context.Context, opts port.EngineOptions) error { | |||
| 1784 | - | ret := _mock.Called(ctx, opts) | |||
| 1785 | - | ||||
| 1786 | - | if len(ret) == 0 { | |||
| 1787 | - | panic("no return value specified for Init") | |||
| 1788 | - | } | |||
| 1789 | - | ||||
| 1790 | - | var r0 error | |||
| 1791 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, port.EngineOptions) error); ok { | |||
| 1792 | - | r0 = returnFunc(ctx, opts) | |||
| 1793 | - | } else { | |||
| 1794 | - | r0 = ret.Error(0) | |||
| 1795 | - | } | |||
| 1796 | - | return r0 | |||
| 1797 | - | } | |||
| 1798 | - | ||||
| 1799 | - | // MockEngine_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' | |||
| 1800 | - | type MockEngine_Init_Call struct { | |||
| 1801 | - | *mock.Call | |||
| 1802 | - | } | |||
| 1803 | - | ||||
| 1804 | - | // Init is a helper method to define mock.On call | |||
| 1805 | - | // - ctx context.Context | |||
| 1806 | - | // - opts port.EngineOptions | |||
| 1807 | - | func (_e *MockEngine_Expecter) Init(ctx interface{}, opts interface{}) *MockEngine_Init_Call { | |||
| 1808 | - | return &MockEngine_Init_Call{Call: _e.mock.On("Init", ctx, opts)} | |||
| 1809 | - | } | |||
| 1810 | - | ||||
| 1811 | - | func (_c *MockEngine_Init_Call) Run(run func(ctx context.Context, opts port.EngineOptions)) *MockEngine_Init_Call { | |||
| 1812 | - | _c.Call.Run(func(args mock.Arguments) { | |||
| 1813 | - | var arg0 context.Context | |||
| 1814 | - | if args[0] != nil { | |||
| 1815 | - | arg0 = args[0].(context.Context) | |||
| 1816 | - | } | |||
| 1817 | - | var arg1 port.EngineOptions | |||
| 1818 | - | if args[1] != nil { | |||
| 1819 | - | arg1 = args[1].(port.EngineOptions) | |||
| 1820 | - | } | |||
| 1821 | - | run( | |||
| 1822 | - | arg0, | |||
| 1823 | - | arg1, | |||
| 1824 | - | ) | |||
| 1825 | - | }) | |||
| 1826 | - | return _c | |||
| 1827 | - | } | |||
| 1828 | - | ||||
| 1829 | - | func (_c *MockEngine_Init_Call) Return(err error) *MockEngine_Init_Call { | |||
| 1830 | - | _c.Call.Return(err) | |||
| 1831 | - | return _c | |||
| 1832 | - | } | |||
| 1833 | - | ||||
| 1834 | - | func (_c *MockEngine_Init_Call) RunAndReturn(run func(ctx context.Context, opts port.EngineOptions) error) *MockEngine_Init_Call { | |||
| 1835 | - | _c.Call.Return(run) | |||
| 1836 | - | return _c | |||
| 1837 | - | } | |||
| 1838 | - | ||||
| 1839 | // InternalSchemePath provides a mock function for the type MockEngine | 1991 | // InternalSchemePath provides a mock function for the type MockEngine | ||
| 1840 | func (_mock *MockEngine) InternalSchemePath() string { | 1992 | func (_mock *MockEngine) InternalSchemePath() string { | ||
| 1841 | ret := _mock.Called() | 1993 | ret := _mock.Called() | ||
| @@ -4339,13 +4491,13 @@ func (_c *MockFocusedInputProvider_SetFocusedInput_Call) RunAndReturn(run func(t | |||||
| 4339 | return _c | 4491 | return _c | ||
| 4340 | } | 4492 | } | ||
| 4341 | 4493 | ||||
| 4342 | - | // NewMockMemoryPressureApplier creates a new instance of MockMemoryPressureApplier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | 4494 | + | // NewMockWebView creates a new instance of MockWebView. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. |
| 4343 | // The first argument is typically a *testing.T value. | 4495 | // The first argument is typically a *testing.T value. | ||
| 4344 | - | func NewMockMemoryPressureApplier(t interface { | 4496 | + | func NewMockWebView(t interface { |
| 4345 | mock.TestingT | 4497 | mock.TestingT | ||
| 4346 | Cleanup(func()) | 4498 | Cleanup(func()) | ||
| 4347 | - | }) *MockMemoryPressureApplier { | 4499 | + | }) *MockWebView { |
| 4348 | - | mock := &MockMemoryPressureApplier{} | 4500 | + | mock := &MockWebView{} |
| 4349 | mock.Mock.Test(t) | 4501 | mock.Mock.Test(t) | ||
| 4350 | 4502 | ||||
| 4351 | t.Cleanup(func() { mock.AssertExpectations(t) }) | 4503 | t.Cleanup(func() { mock.AssertExpectations(t) }) | ||
| @@ -4353,588 +4505,270 @@ func NewMockMemoryPressureApplier(t interface { | |||||
| 4353 | return mock | 4505 | return mock | ||
| 4354 | } | 4506 | } | ||
| 4355 | 4507 | ||||
| 4356 | - | // MockMemoryPressureApplier is an autogenerated mock type for the MemoryPressureApplier type | 4508 | + | // MockWebView is an autogenerated mock type for the WebView type |
| 4357 | - | type MockMemoryPressureApplier struct { | 4509 | + | type MockWebView struct { |
| 4358 | mock.Mock | 4510 | mock.Mock | ||
| 4359 | } | 4511 | } | ||
| 4360 | 4512 | ||||
| 4361 | - | type MockMemoryPressureApplier_Expecter struct { | 4513 | + | type MockWebView_Expecter struct { |
| 4362 | mock *mock.Mock | 4514 | mock *mock.Mock | ||
| 4363 | } | 4515 | } | ||
| 4364 | 4516 | ||||
| 4365 | - | func (_m *MockMemoryPressureApplier) EXPECT() *MockMemoryPressureApplier_Expecter { | 4517 | + | func (_m *MockWebView) EXPECT() *MockWebView_Expecter { |
| 4366 | - | return &MockMemoryPressureApplier_Expecter{mock: &_m.Mock} | 4518 | + | return &MockWebView_Expecter{mock: &_m.Mock} |
| 4367 | } | 4519 | } | ||
| 4368 | 4520 | ||||
| 4369 | - | // ApplyNetworkProcessSettings provides a mock function for the type MockMemoryPressureApplier | 4521 | + | // CanGoBack provides a mock function for the type MockWebView |
| 4370 | - | func (_mock *MockMemoryPressureApplier) ApplyNetworkProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) error { | 4522 | + | func (_mock *MockWebView) CanGoBack() bool { |
| 4371 | - | ret := _mock.Called(ctx, cfg) | 4523 | + | ret := _mock.Called() |
| 4372 | 4524 | ||||
| 4373 | if len(ret) == 0 { | 4525 | if len(ret) == 0 { | ||
| 4374 | - | panic("no return value specified for ApplyNetworkProcessSettings") | 4526 | + | panic("no return value specified for CanGoBack") |
| 4375 | - | } | |||
| 4376 | - | ||||
| 4377 | - | var r0 error | |||
| 4378 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |||
| 4379 | - | r0 = returnFunc(ctx, cfg) | |||
| 4380 | - | } else { | |||
| 4381 | - | r0 = ret.Error(0) | |||
| 4382 | - | } | |||
| 4383 | - | return r0 | |||
| 4384 | - | } | |||
| 4385 | - | ||||
| 4386 | - | // MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyNetworkProcessSettings' | |||
| 4387 | - | type MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call struct { | |||
| 4388 | - | *mock.Call | |||
| 4389 | - | } | |||
| 4390 | - | ||||
| 4391 | - | // ApplyNetworkProcessSettings is a helper method to define mock.On call | |||
| 4392 | - | // - ctx context.Context | |||
| 4393 | - | // - cfg *port.MemoryPressureConfig | |||
| 4394 | - | func (_e *MockMemoryPressureApplier_Expecter) ApplyNetworkProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 4395 | - | return &MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call{Call: _e.mock.On("ApplyNetworkProcessSettings", ctx, cfg)} | |||
| 4396 | - | } | |||
| 4397 | - | ||||
| 4398 | - | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 4399 | - | _c.Call.Run(func(args mock.Arguments) { | |||
| 4400 | - | var arg0 context.Context | |||
| 4401 | - | if args[0] != nil { | |||
| 4402 | - | arg0 = args[0].(context.Context) | |||
| 4403 | - | } | |||
| 4404 | - | var arg1 *port.MemoryPressureConfig | |||
| 4405 | - | if args[1] != nil { | |||
| 4406 | - | arg1 = args[1].(*port.MemoryPressureConfig) | |||
| 4407 | - | } | |||
| 4408 | - | run( | |||
| 4409 | - | arg0, | |||
| 4410 | - | arg1, | |||
| 4411 | - | ) | |||
| 4412 | - | }) | |||
| 4413 | - | return _c | |||
| 4414 | - | } | |||
| 4415 | - | ||||
| 4416 | - | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) Return(err error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 4417 | - | _c.Call.Return(err) | |||
| 4418 | - | return _c | |||
| 4419 | - | } | |||
| 4420 | - | ||||
| 4421 | - | func (_c *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) error) *MockMemoryPressureApplier_ApplyNetworkProcessSettings_Call { | |||
| 4422 | - | _c.Call.Return(run) | |||
| 4423 | - | return _c | |||
| 4424 | - | } | |||
| 4425 | - | ||||
| 4426 | - | // ApplyWebProcessSettings provides a mock function for the type MockMemoryPressureApplier | |||
| 4427 | - | func (_mock *MockMemoryPressureApplier) ApplyWebProcessSettings(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error) { | |||
| 4428 | - | ret := _mock.Called(ctx, cfg) | |||
| 4429 | - | ||||
| 4430 | - | if len(ret) == 0 { | |||
| 4431 | - | panic("no return value specified for ApplyWebProcessSettings") | |||
| 4432 | - | } | |||
| 4433 | - | ||||
| 4434 | - | var r0 any | |||
| 4435 | - | var r1 error | |||
| 4436 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) (any, error)); ok { | |||
| 4437 | - | return returnFunc(ctx, cfg) | |||
| 4438 | - | } | |||
| 4439 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, *port.MemoryPressureConfig) any); ok { | |||
| 4440 | - | r0 = returnFunc(ctx, cfg) | |||
| 4441 | - | } else { | |||
| 4442 | - | if ret.Get(0) != nil { | |||
| 4443 | - | r0 = ret.Get(0).(any) | |||
| 4444 | - | } | |||
| 4445 | - | } | |||
| 4446 | - | if returnFunc, ok := ret.Get(1).(func(context.Context, *port.MemoryPressureConfig) error); ok { | |||
| 4447 | - | r1 = returnFunc(ctx, cfg) | |||
| 4448 | - | } else { | |||
| 4449 | - | r1 = ret.Error(1) | |||
| 4450 | - | } | |||
| 4451 | - | return r0, r1 | |||
| 4452 | - | } | |||
| 4453 | - | ||||
| 4454 | - | // MockMemoryPressureApplier_ApplyWebProcessSettings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyWebProcessSettings' | |||
| 4455 | - | type MockMemoryPressureApplier_ApplyWebProcessSettings_Call struct { | |||
| 4456 | - | *mock.Call | |||
| 4457 | - | } | |||
| 4458 | - | ||||
| 4459 | - | // ApplyWebProcessSettings is a helper method to define mock.On call | |||
| 4460 | - | // - ctx context.Context | |||
| 4461 | - | // - cfg *port.MemoryPressureConfig | |||
| 4462 | - | func (_e *MockMemoryPressureApplier_Expecter) ApplyWebProcessSettings(ctx interface{}, cfg interface{}) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 4463 | - | return &MockMemoryPressureApplier_ApplyWebProcessSettings_Call{Call: _e.mock.On("ApplyWebProcessSettings", ctx, cfg)} | |||
| 4464 | - | } | |||
| 4465 | - | ||||
| 4466 | - | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Run(run func(ctx context.Context, cfg *port.MemoryPressureConfig)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 4467 | - | _c.Call.Run(func(args mock.Arguments) { | |||
| 4468 | - | var arg0 context.Context | |||
| 4469 | - | if args[0] != nil { | |||
| 4470 | - | arg0 = args[0].(context.Context) | |||
| 4471 | - | } | |||
| 4472 | - | var arg1 *port.MemoryPressureConfig | |||
| 4473 | - | if args[1] != nil { | |||
| 4474 | - | arg1 = args[1].(*port.MemoryPressureConfig) | |||
| 4475 | - | } | |||
| 4476 | - | run( | |||
| 4477 | - | arg0, | |||
| 4478 | - | arg1, | |||
| 4479 | - | ) | |||
| 4480 | - | }) | |||
| 4481 | - | return _c | |||
| 4482 | - | } | |||
| 4483 | - | ||||
| 4484 | - | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) Return(v any, err error) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 4485 | - | _c.Call.Return(v, err) | |||
| 4486 | - | return _c | |||
| 4487 | - | } | |||
| 4488 | - | ||||
| 4489 | - | func (_c *MockMemoryPressureApplier_ApplyWebProcessSettings_Call) RunAndReturn(run func(ctx context.Context, cfg *port.MemoryPressureConfig) (any, error)) *MockMemoryPressureApplier_ApplyWebProcessSettings_Call { | |||
| 4490 | - | _c.Call.Return(run) | |||
| 4491 | - | return _c | |||
| 4492 | - | } | |||
| 4493 | - | ||||
| 4494 | - | // NewMockWebKitContextProvider creates a new instance of MockWebKitContextProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | |||
| 4495 | - | // The first argument is typically a *testing.T value. | |||
| 4496 | - | func NewMockWebKitContextProvider(t interface { | |||
| 4497 | - | mock.TestingT | |||
| 4498 | - | Cleanup(func()) | |||
| 4499 | - | }) *MockWebKitContextProvider { | |||
| 4500 | - | mock := &MockWebKitContextProvider{} | |||
| 4501 | - | mock.Mock.Test(t) | |||
| 4502 | - | ||||
| 4503 | - | t.Cleanup(func() { mock.AssertExpectations(t) }) | |||
| 4504 | - | ||||
| 4505 | - | return mock | |||
| 4506 | - | } | |||
| 4507 | - | ||||
| 4508 | - | // MockWebKitContextProvider is an autogenerated mock type for the WebKitContextProvider type | |||
| 4509 | - | type MockWebKitContextProvider struct { | |||
| 4510 | - | mock.Mock | |||
| 4511 | - | } | |||
| 4512 | - | ||||
| 4513 | - | type MockWebKitContextProvider_Expecter struct { | |||
| 4514 | - | mock *mock.Mock | |||
| 4515 | - | } | |||
| 4516 | - | ||||
| 4517 | - | func (_m *MockWebKitContextProvider) EXPECT() *MockWebKitContextProvider_Expecter { | |||
| 4518 | - | return &MockWebKitContextProvider_Expecter{mock: &_m.Mock} | |||
| 4519 | - | } | |||
| 4520 | - | ||||
| 4521 | - | // CacheDir provides a mock function for the type MockWebKitContextProvider | |||
| 4522 | - | func (_mock *MockWebKitContextProvider) CacheDir() string { | |||
| 4523 | - | ret := _mock.Called() | |||
| 4524 | - | ||||
| 4525 | - | if len(ret) == 0 { | |||
| 4526 | - | panic("no return value specified for CacheDir") | |||
| 4527 | - | } | |||
| 4528 | - | ||||
| 4529 | - | var r0 string | |||
| 4530 | - | if returnFunc, ok := ret.Get(0).(func() string); ok { | |||
| 4531 | - | r0 = returnFunc() | |||
| 4532 | - | } else { | |||
| 4533 | - | r0 = ret.Get(0).(string) | |||
| 4534 | - | } | |||
| 4535 | - | return r0 | |||
| 4536 | - | } | |||
| 4537 | - | ||||
| 4538 | - | // MockWebKitContextProvider_CacheDir_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CacheDir' | |||
| 4539 | - | type MockWebKitContextProvider_CacheDir_Call struct { | |||
| 4540 | - | *mock.Call | |||
| 4541 | - | } | |||
| 4542 | - | ||||
| 4543 | - | // CacheDir is a helper method to define mock.On call | |||
| 4544 | - | func (_e *MockWebKitContextProvider_Expecter) CacheDir() *MockWebKitContextProvider_CacheDir_Call { | |||
| 4545 | - | return &MockWebKitContextProvider_CacheDir_Call{Call: _e.mock.On("CacheDir")} | |||
| 4546 | - | } | |||
| 4547 | - | ||||
| 4548 | - | func (_c *MockWebKitContextProvider_CacheDir_Call) Run(run func()) *MockWebKitContextProvider_CacheDir_Call { | |||
| 4549 | - | _c.Call.Run(func(args mock.Arguments) { | |||
| 4550 | - | run() | |||
| 4551 | - | }) | |||
| 4552 | - | return _c | |||
| 4553 | - | } | |||
| 4554 | - | ||||
| 4555 | - | func (_c *MockWebKitContextProvider_CacheDir_Call) Return(s string) *MockWebKitContextProvider_CacheDir_Call { | |||
| 4556 | - | _c.Call.Return(s) | |||
| 4557 | - | return _c | |||
| 4558 | - | } | |||
| 4559 | - | ||||
| 4560 | - | func (_c *MockWebKitContextProvider_CacheDir_Call) RunAndReturn(run func() string) *MockWebKitContextProvider_CacheDir_Call { | |||
| 4561 | - | _c.Call.Return(run) | |||
| 4562 | - | return _c | |||
| 4563 | - | } | |||
| 4564 | - | ||||
| 4565 | - | // Close provides a mock function for the type MockWebKitContextProvider | |||
| 4566 | - | func (_mock *MockWebKitContextProvider) Close() error { | |||
| 4567 | - | ret := _mock.Called() | |||
| 4568 | - | ||||
| 4569 | - | if len(ret) == 0 { | |||
| 4570 | - | panic("no return value specified for Close") | |||
| 4571 | } | 4527 | } | ||
| 4572 | 4528 | ||||
| 4573 | - | var r0 error | 4529 | + | var r0 bool |
| 4574 | - | if returnFunc, ok := ret.Get(0).(func() error); ok { | 4530 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { |
| 4575 | r0 = returnFunc() | 4531 | r0 = returnFunc() | ||
| 4576 | } else { | 4532 | } else { | ||
| 4577 | - | r0 = ret.Error(0) | 4533 | + | r0 = ret.Get(0).(bool) |
| 4578 | } | 4534 | } | ||
| 4579 | return r0 | 4535 | return r0 | ||
| 4580 | } | 4536 | } | ||
| 4581 | 4537 | ||||
| 4582 | - | // MockWebKitContextProvider_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' | 4538 | + | // MockWebView_CanGoBack_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoBack' |
| 4583 | - | type MockWebKitContextProvider_Close_Call struct { | 4539 | + | type MockWebView_CanGoBack_Call struct { |
| 4584 | *mock.Call | 4540 | *mock.Call | ||
| 4585 | } | 4541 | } | ||
| 4586 | 4542 | ||||
| 4587 | - | // Close is a helper method to define mock.On call | 4543 | + | // CanGoBack is a helper method to define mock.On call |
| 4588 | - | func (_e *MockWebKitContextProvider_Expecter) Close() *MockWebKitContextProvider_Close_Call { | 4544 | + | func (_e *MockWebView_Expecter) CanGoBack() *MockWebView_CanGoBack_Call { |
| 4589 | - | return &MockWebKitContextProvider_Close_Call{Call: _e.mock.On("Close")} | 4545 | + | return &MockWebView_CanGoBack_Call{Call: _e.mock.On("CanGoBack")} |
| 4590 | } | 4546 | } | ||
| 4591 | 4547 | ||||
| 4592 | - | func (_c *MockWebKitContextProvider_Close_Call) Run(run func()) *MockWebKitContextProvider_Close_Call { | 4548 | + | func (_c *MockWebView_CanGoBack_Call) Run(run func()) *MockWebView_CanGoBack_Call { |
| 4593 | _c.Call.Run(func(args mock.Arguments) { | 4549 | _c.Call.Run(func(args mock.Arguments) { | ||
| 4594 | run() | 4550 | run() | ||
| 4595 | }) | 4551 | }) | ||
| 4596 | return _c | 4552 | return _c | ||
| 4597 | } | 4553 | } | ||
| 4598 | 4554 | ||||
| 4599 | - | func (_c *MockWebKitContextProvider_Close_Call) Return(err error) *MockWebKitContextProvider_Close_Call { | 4555 | + | func (_c *MockWebView_CanGoBack_Call) Return(b bool) *MockWebView_CanGoBack_Call { |
| 4600 | - | _c.Call.Return(err) | 4556 | + | _c.Call.Return(b) |
| 4601 | return _c | 4557 | return _c | ||
| 4602 | } | 4558 | } | ||
| 4603 | 4559 | ||||
| 4604 | - | func (_c *MockWebKitContextProvider_Close_Call) RunAndReturn(run func() error) *MockWebKitContextProvider_Close_Call { | 4560 | + | func (_c *MockWebView_CanGoBack_Call) RunAndReturn(run func() bool) *MockWebView_CanGoBack_Call { |
| 4605 | _c.Call.Return(run) | 4561 | _c.Call.Return(run) | ||
| 4606 | return _c | 4562 | return _c | ||
| 4607 | } | 4563 | } | ||
| 4608 | 4564 | ||||
| 4609 | - | // DataDir provides a mock function for the type MockWebKitContextProvider | 4565 | + | // CanGoForward provides a mock function for the type MockWebView |
| 4610 | - | func (_mock *MockWebKitContextProvider) DataDir() string { | 4566 | + | func (_mock *MockWebView) CanGoForward() bool { |
| 4611 | ret := _mock.Called() | 4567 | ret := _mock.Called() | ||
| 4612 | 4568 | ||||
| 4613 | if len(ret) == 0 { | 4569 | if len(ret) == 0 { | ||
| 4614 | - | panic("no return value specified for DataDir") | 4570 | + | panic("no return value specified for CanGoForward") |
| 4615 | } | 4571 | } | ||
| 4616 | 4572 | ||||
| 4617 | - | var r0 string | 4573 | + | var r0 bool |
| 4618 | - | if returnFunc, ok := ret.Get(0).(func() string); ok { | 4574 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { |
| 4619 | r0 = returnFunc() | 4575 | r0 = returnFunc() | ||
| 4620 | } else { | 4576 | } else { | ||
| 4621 | - | r0 = ret.Get(0).(string) | 4577 | + | r0 = ret.Get(0).(bool) |
| 4622 | } | 4578 | } | ||
| 4623 | return r0 | 4579 | return r0 | ||
| 4624 | } | 4580 | } | ||
| 4625 | 4581 | ||||
| 4626 | - | // MockWebKitContextProvider_DataDir_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DataDir' | 4582 | + | // MockWebView_CanGoForward_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoForward' |
| 4627 | - | type MockWebKitContextProvider_DataDir_Call struct { | 4583 | + | type MockWebView_CanGoForward_Call struct { |
| 4628 | *mock.Call | 4584 | *mock.Call | ||
| 4629 | } | 4585 | } | ||
| 4630 | 4586 | ||||
| 4631 | - | // DataDir is a helper method to define mock.On call | 4587 | + | // CanGoForward is a helper method to define mock.On call |
| 4632 | - | func (_e *MockWebKitContextProvider_Expecter) DataDir() *MockWebKitContextProvider_DataDir_Call { | 4588 | + | func (_e *MockWebView_Expecter) CanGoForward() *MockWebView_CanGoForward_Call { |
| 4633 | - | return &MockWebKitContextProvider_DataDir_Call{Call: _e.mock.On("DataDir")} | 4589 | + | return &MockWebView_CanGoForward_Call{Call: _e.mock.On("CanGoForward")} |
| 4634 | } | 4590 | } | ||
| 4635 | 4591 | ||||
| 4636 | - | func (_c *MockWebKitContextProvider_DataDir_Call) Run(run func()) *MockWebKitContextProvider_DataDir_Call { | 4592 | + | func (_c *MockWebView_CanGoForward_Call) Run(run func()) *MockWebView_CanGoForward_Call { |
| 4637 | _c.Call.Run(func(args mock.Arguments) { | 4593 | _c.Call.Run(func(args mock.Arguments) { | ||
| 4638 | run() | 4594 | run() | ||
| 4639 | }) | 4595 | }) | ||
| 4640 | return _c | 4596 | return _c | ||
| 4641 | } | 4597 | } | ||
| 4642 | 4598 | ||||
| 4643 | - | func (_c *MockWebKitContextProvider_DataDir_Call) Return(s string) *MockWebKitContextProvider_DataDir_Call { | 4599 | + | func (_c *MockWebView_CanGoForward_Call) Return(b bool) *MockWebView_CanGoForward_Call { |
| 4644 | - | _c.Call.Return(s) | 4600 | + | _c.Call.Return(b) |
| 4645 | - | return _c | |||
| 4646 | - | } | |||
| 4647 | - | ||||
| 4648 | - | func (_c *MockWebKitContextProvider_DataDir_Call) RunAndReturn(run func() string) *MockWebKitContextProvider_DataDir_Call { | |||
| 4649 | - | _c.Call.Return(run) | |||
| 4650 | - | return _c | |||
| 4651 | - | } | |||
| 4652 | - | ||||
| 4653 | - | // Initialize provides a mock function for the type MockWebKitContextProvider | |||
| 4654 | - | func (_mock *MockWebKitContextProvider) Initialize(ctx context.Context, opts port.WebKitContextOptions) error { | |||
| 4655 | - | ret := _mock.Called(ctx, opts) | |||
| 4656 | - | ||||
| 4657 | - | if len(ret) == 0 { | |||
| 4658 | - | panic("no return value specified for Initialize") | |||
| 4659 | - | } | |||
| 4660 | - | ||||
| 4661 | - | var r0 error | |||
| 4662 | - | if returnFunc, ok := ret.Get(0).(func(context.Context, port.WebKitContextOptions) error); ok { | |||
| 4663 | - | r0 = returnFunc(ctx, opts) | |||
| 4664 | - | } else { | |||
| 4665 | - | r0 = ret.Error(0) | |||
| 4666 | - | } | |||
| 4667 | - | return r0 | |||
| 4668 | - | } | |||
| 4669 | - | ||||
| 4670 | - | // MockWebKitContextProvider_Initialize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Initialize' | |||
| 4671 | - | type MockWebKitContextProvider_Initialize_Call struct { | |||
| 4672 | - | *mock.Call | |||
| 4673 | - | } | |||
| 4674 | - | ||||
| 4675 | - | // Initialize is a helper method to define mock.On call | |||
| 4676 | - | // - ctx context.Context | |||
| 4677 | - | // - opts port.WebKitContextOptions | |||
| 4678 | - | func (_e *MockWebKitContextProvider_Expecter) Initialize(ctx interface{}, opts interface{}) *MockWebKitContextProvider_Initialize_Call { | |||
| 4679 | - | return &MockWebKitContextProvider_Initialize_Call{Call: _e.mock.On("Initialize", ctx, opts)} | |||
| 4680 | - | } | |||
| 4681 | - | ||||
| 4682 | - | func (_c *MockWebKitContextProvider_Initialize_Call) Run(run func(ctx context.Context, opts port.WebKitContextOptions)) *MockWebKitContextProvider_Initialize_Call { | |||
| 4683 | - | _c.Call.Run(func(args mock.Arguments) { | |||
| 4684 | - | var arg0 context.Context | |||
| 4685 | - | if args[0] != nil { | |||
| 4686 | - | arg0 = args[0].(context.Context) | |||
| 4687 | - | } | |||
| 4688 | - | var arg1 port.WebKitContextOptions | |||
| 4689 | - | if args[1] != nil { | |||
| 4690 | - | arg1 = args[1].(port.WebKitContextOptions) | |||
| 4691 | - | } | |||
| 4692 | - | run( | |||
| 4693 | - | arg0, | |||
| 4694 | - | arg1, | |||
| 4695 | - | ) | |||
| 4696 | - | }) | |||
| 4697 | - | return _c | |||
| 4698 | - | } | |||
| 4699 | - | ||||
| 4700 | - | func (_c *MockWebKitContextProvider_Initialize_Call) Return(err error) *MockWebKitContextProvider_Initialize_Call { | |||
| 4701 | - | _c.Call.Return(err) | |||
| 4702 | return _c | 4601 | return _c | ||
| 4703 | } | 4602 | } | ||
| 4704 | 4603 | ||||
| 4705 | - | func (_c *MockWebKitContextProvider_Initialize_Call) RunAndReturn(run func(ctx context.Context, opts port.WebKitContextOptions) error) *MockWebKitContextProvider_Initialize_Call { | 4604 | + | func (_c *MockWebView_CanGoForward_Call) RunAndReturn(run func() bool) *MockWebView_CanGoForward_Call { |
| 4706 | _c.Call.Return(run) | 4605 | _c.Call.Return(run) | ||
| 4707 | return _c | 4606 | return _c | ||
| 4708 | } | 4607 | } | ||
| 4709 | 4608 | ||||
| 4710 | - | // PrefetchDNS provides a mock function for the type MockWebKitContextProvider | 4609 | + | // Destroy provides a mock function for the type MockWebView |
| 4711 | - | func (_mock *MockWebKitContextProvider) PrefetchDNS(hostname string) { | 4610 | + | func (_mock *MockWebView) Destroy() { |
| 4712 | - | _mock.Called(hostname) | 4611 | + | _mock.Called() |
| 4713 | return | 4612 | return | ||
| 4714 | } | 4613 | } | ||
| 4715 | 4614 | ||||
| 4716 | - | // MockWebKitContextProvider_PrefetchDNS_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PrefetchDNS' | 4615 | + | // MockWebView_Destroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Destroy' |
| 4717 | - | type MockWebKitContextProvider_PrefetchDNS_Call struct { | 4616 | + | type MockWebView_Destroy_Call struct { |
| 4718 | *mock.Call | 4617 | *mock.Call | ||
| 4719 | } | 4618 | } | ||
| 4720 | 4619 | ||||
| 4721 | - | // PrefetchDNS is a helper method to define mock.On call | 4620 | + | // Destroy is a helper method to define mock.On call |
| 4722 | - | // - hostname string | 4621 | + | func (_e *MockWebView_Expecter) Destroy() *MockWebView_Destroy_Call { |
| 4723 | - | func (_e *MockWebKitContextProvider_Expecter) PrefetchDNS(hostname interface{}) *MockWebKitContextProvider_PrefetchDNS_Call { | 4622 | + | return &MockWebView_Destroy_Call{Call: _e.mock.On("Destroy")} |
| 4724 | - | return &MockWebKitContextProvider_PrefetchDNS_Call{Call: _e.mock.On("PrefetchDNS", hostname)} | |||
| 4725 | } | 4623 | } | ||
| 4726 | 4624 | ||||
| 4727 | - | func (_c *MockWebKitContextProvider_PrefetchDNS_Call) Run(run func(hostname string)) *MockWebKitContextProvider_PrefetchDNS_Call { | 4625 | + | func (_c *MockWebView_Destroy_Call) Run(run func()) *MockWebView_Destroy_Call { |
| 4728 | _c.Call.Run(func(args mock.Arguments) { | 4626 | _c.Call.Run(func(args mock.Arguments) { | ||
| 4729 | - | var arg0 string | 4627 | + | run() |
| 4730 | - | if args[0] != nil { | |||
| 4731 | - | arg0 = args[0].(string) | |||
| 4732 | - | } | |||
| 4733 | - | run( | |||
| 4734 | - | arg0, | |||
| 4735 | - | ) | |||
| 4736 | }) | 4628 | }) | ||
| 4737 | return _c | 4629 | return _c | ||
| 4738 | } | 4630 | } | ||
| 4739 | 4631 | ||||
| 4740 | - | func (_c *MockWebKitContextProvider_PrefetchDNS_Call) Return() *MockWebKitContextProvider_PrefetchDNS_Call { | 4632 | + | func (_c *MockWebView_Destroy_Call) Return() *MockWebView_Destroy_Call { |
| 4741 | _c.Call.Return() | 4633 | _c.Call.Return() | ||
| 4742 | return _c | 4634 | return _c | ||
| 4743 | } | 4635 | } | ||
| 4744 | 4636 | ||||
| 4745 | - | func (_c *MockWebKitContextProvider_PrefetchDNS_Call) RunAndReturn(run func(hostname string)) *MockWebKitContextProvider_PrefetchDNS_Call { | 4637 | + | func (_c *MockWebView_Destroy_Call) RunAndReturn(run func()) *MockWebView_Destroy_Call { |
| 4746 | _c.Run(run) | 4638 | _c.Run(run) | ||
| 4747 | return _c | 4639 | return _c | ||
| 4748 | } | 4640 | } | ||
| 4749 | 4641 | ||||
| 4750 | - | // NewMockWebView creates a new instance of MockWebView. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. | 4642 | + | // EstimatedProgress provides a mock function for the type MockWebView |
| 4751 | - | // The first argument is typically a *testing.T value. | 4643 | + | func (_mock *MockWebView) EstimatedProgress() float64 { |
| 4752 | - | func NewMockWebView(t interface { | |||
| 4753 | - | mock.TestingT | |||
| 4754 | - | Cleanup(func()) | |||
| 4755 | - | }) *MockWebView { | |||
| 4756 | - | mock := &MockWebView{} | |||
| 4757 | - | mock.Mock.Test(t) | |||
| 4758 | - | ||||
| 4759 | - | t.Cleanup(func() { mock.AssertExpectations(t) }) | |||
| 4760 | - | ||||
| 4761 | - | return mock | |||
| 4762 | - | } | |||
| 4763 | - | ||||
| 4764 | - | // MockWebView is an autogenerated mock type for the WebView type | |||
| 4765 | - | type MockWebView struct { | |||
| 4766 | - | mock.Mock | |||
| 4767 | - | } | |||
| 4768 | - | ||||
| 4769 | - | type MockWebView_Expecter struct { | |||
| 4770 | - | mock *mock.Mock | |||
| 4771 | - | } | |||
| 4772 | - | ||||
| 4773 | - | func (_m *MockWebView) EXPECT() *MockWebView_Expecter { | |||
| 4774 | - | return &MockWebView_Expecter{mock: &_m.Mock} | |||
| 4775 | - | } | |||
| 4776 | - | ||||
| 4777 | - | // CanGoBack provides a mock function for the type MockWebView | |||
| 4778 | - | func (_mock *MockWebView) CanGoBack() bool { | |||
| 4779 | ret := _mock.Called() | 4644 | ret := _mock.Called() | ||
| 4780 | 4645 | ||||
| 4781 | if len(ret) == 0 { | 4646 | if len(ret) == 0 { | ||
| 4782 | - | panic("no return value specified for CanGoBack") | 4647 | + | panic("no return value specified for EstimatedProgress") |
| 4783 | } | 4648 | } | ||
| 4784 | 4649 | ||||
| 4785 | - | var r0 bool | 4650 | + | var r0 float64 |
| 4786 | - | if returnFunc, ok := ret.Get(0).(func() bool); ok { | 4651 | + | if returnFunc, ok := ret.Get(0).(func() float64); ok { |
| 4787 | r0 = returnFunc() | 4652 | r0 = returnFunc() | ||
| 4788 | } else { | 4653 | } else { | ||
| 4789 | - | r0 = ret.Get(0).(bool) | 4654 | + | r0 = ret.Get(0).(float64) |
| 4790 | } | 4655 | } | ||
| 4791 | return r0 | 4656 | return r0 | ||
| 4792 | } | 4657 | } | ||
| 4793 | 4658 | ||||
| 4794 | - | // MockWebView_CanGoBack_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoBack' | 4659 | + | // MockWebView_EstimatedProgress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimatedProgress' |
| 4795 | - | type MockWebView_CanGoBack_Call struct { | 4660 | + | type MockWebView_EstimatedProgress_Call struct { |
| 4796 | *mock.Call | 4661 | *mock.Call | ||
| 4797 | } | 4662 | } | ||
| 4798 | 4663 | ||||
| 4799 | - | // CanGoBack is a helper method to define mock.On call | 4664 | + | // EstimatedProgress is a helper method to define mock.On call |
| 4800 | - | func (_e *MockWebView_Expecter) CanGoBack() *MockWebView_CanGoBack_Call { | 4665 | + | func (_e *MockWebView_Expecter) EstimatedProgress() *MockWebView_EstimatedProgress_Call { |
| 4801 | - | return &MockWebView_CanGoBack_Call{Call: _e.mock.On("CanGoBack")} | 4666 | + | return &MockWebView_EstimatedProgress_Call{Call: _e.mock.On("EstimatedProgress")} |
| 4802 | } | 4667 | } | ||
| 4803 | 4668 | ||||
| 4804 | - | func (_c *MockWebView_CanGoBack_Call) Run(run func()) *MockWebView_CanGoBack_Call { | 4669 | + | func (_c *MockWebView_EstimatedProgress_Call) Run(run func()) *MockWebView_EstimatedProgress_Call { |
| 4805 | _c.Call.Run(func(args mock.Arguments) { | 4670 | _c.Call.Run(func(args mock.Arguments) { | ||
| 4806 | run() | 4671 | run() | ||
| 4807 | }) | 4672 | }) | ||
| 4808 | return _c | 4673 | return _c | ||
| 4809 | } | 4674 | } | ||
| 4810 | 4675 | ||||
| 4811 | - | func (_c *MockWebView_CanGoBack_Call) Return(b bool) *MockWebView_CanGoBack_Call { | 4676 | + | func (_c *MockWebView_EstimatedProgress_Call) Return(f float64) *MockWebView_EstimatedProgress_Call { |
| 4812 | - | _c.Call.Return(b) | 4677 | + | _c.Call.Return(f) |
| 4813 | return _c | 4678 | return _c | ||
| 4814 | } | 4679 | } | ||
| 4815 | 4680 | ||||
| 4816 | - | func (_c *MockWebView_CanGoBack_Call) RunAndReturn(run func() bool) *MockWebView_CanGoBack_Call { | 4681 | + | func (_c *MockWebView_EstimatedProgress_Call) RunAndReturn(run func() float64) *MockWebView_EstimatedProgress_Call { |
| 4817 | _c.Call.Return(run) | 4682 | _c.Call.Return(run) | ||
| 4818 | return _c | 4683 | return _c | ||
| 4819 | } | 4684 | } | ||
| 4820 | 4685 | ||||
| 4821 | - | // CanGoForward provides a mock function for the type MockWebView | 4686 | + | // Favicon provides a mock function for the type MockWebView |
| 4822 | - | func (_mock *MockWebView) CanGoForward() bool { | 4687 | + | func (_mock *MockWebView) Favicon() port.Texture { |
| 4823 | ret := _mock.Called() | 4688 | ret := _mock.Called() | ||
| 4824 | 4689 | ||||
| 4825 | if len(ret) == 0 { | 4690 | if len(ret) == 0 { | ||
| 4826 | - | panic("no return value specified for CanGoForward") | 4691 | + | panic("no return value specified for Favicon") |
| 4827 | } | 4692 | } | ||
| 4828 | 4693 | ||||
| 4829 | - | var r0 bool | 4694 | + | var r0 port.Texture |
| 4830 | - | if returnFunc, ok := ret.Get(0).(func() bool); ok { | 4695 | + | if returnFunc, ok := ret.Get(0).(func() port.Texture); ok { |
| 4831 | r0 = returnFunc() | 4696 | r0 = returnFunc() | ||
| 4832 | } else { | 4697 | } else { | ||
| 4833 | - | r0 = ret.Get(0).(bool) | 4698 | + | if ret.Get(0) != nil { |
| 4699 | + | r0 = ret.Get(0).(port.Texture) | |||
| 4700 | + | } | |||
| 4834 | } | 4701 | } | ||
| 4835 | return r0 | 4702 | return r0 | ||
| 4836 | } | 4703 | } | ||
| 4837 | 4704 | ||||
| 4838 | - | // MockWebView_CanGoForward_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CanGoForward' | 4705 | + | // MockWebView_Favicon_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Favicon' |
| 4839 | - | type MockWebView_CanGoForward_Call struct { | 4706 | + | type MockWebView_Favicon_Call struct { |
| 4840 | *mock.Call | 4707 | *mock.Call | ||
| 4841 | } | 4708 | } | ||
| 4842 | 4709 | ||||
| 4843 | - | // CanGoForward is a helper method to define mock.On call | 4710 | + | // Favicon is a helper method to define mock.On call |
| 4844 | - | func (_e *MockWebView_Expecter) CanGoForward() *MockWebView_CanGoForward_Call { | 4711 | + | func (_e *MockWebView_Expecter) Favicon() *MockWebView_Favicon_Call { |
| 4845 | - | return &MockWebView_CanGoForward_Call{Call: _e.mock.On("CanGoForward")} | 4712 | + | return &MockWebView_Favicon_Call{Call: _e.mock.On("Favicon")} |
| 4846 | } | 4713 | } | ||
| 4847 | 4714 | ||||
| 4848 | - | func (_c *MockWebView_CanGoForward_Call) Run(run func()) *MockWebView_CanGoForward_Call { | 4715 | + | func (_c *MockWebView_Favicon_Call) Run(run func()) *MockWebView_Favicon_Call { |
| 4849 | _c.Call.Run(func(args mock.Arguments) { | 4716 | _c.Call.Run(func(args mock.Arguments) { | ||
| 4850 | run() | 4717 | run() | ||
| 4851 | }) | 4718 | }) | ||
| 4852 | return _c | 4719 | return _c | ||
| 4853 | } | 4720 | } | ||
| 4854 | 4721 | ||||
| 4855 | - | func (_c *MockWebView_CanGoForward_Call) Return(b bool) *MockWebView_CanGoForward_Call { | 4722 | + | func (_c *MockWebView_Favicon_Call) Return(texture port.Texture) *MockWebView_Favicon_Call { |
| 4856 | - | _c.Call.Return(b) | 4723 | + | _c.Call.Return(texture) |
| 4857 | return _c | 4724 | return _c | ||
| 4858 | } | 4725 | } | ||
| 4859 | 4726 | ||||
| 4860 | - | func (_c *MockWebView_CanGoForward_Call) RunAndReturn(run func() bool) *MockWebView_CanGoForward_Call { | 4727 | + | func (_c *MockWebView_Favicon_Call) RunAndReturn(run func() port.Texture) *MockWebView_Favicon_Call { |
| 4861 | _c.Call.Return(run) | 4728 | _c.Call.Return(run) | ||
| 4862 | return _c | 4729 | return _c | ||
| 4863 | } | 4730 | } | ||
| 4864 | 4731 | ||||
| 4865 | - | // Destroy provides a mock function for the type MockWebView | 4732 | + | // Generation provides a mock function for the type MockWebView |
| 4866 | - | func (_mock *MockWebView) Destroy() { | 4733 | + | func (_mock *MockWebView) Generation() uint64 { |
| 4867 | - | _mock.Called() | |||
| 4868 | - | return | |||
| 4869 | - | } | |||
| 4870 | - | ||||
| 4871 | - | // MockWebView_Destroy_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Destroy' | |||
| 4872 | - | type MockWebView_Destroy_Call struct { | |||
| 4873 | - | *mock.Call | |||
| 4874 | - | } | |||
| 4875 | - | ||||
| 4876 | - | // Destroy is a helper method to define mock.On call | |||
| 4877 | - | func (_e *MockWebView_Expecter) Destroy() *MockWebView_Destroy_Call { | |||
| 4878 | - | return &MockWebView_Destroy_Call{Call: _e.mock.On("Destroy")} | |||
| 4879 | - | } | |||
| 4880 | - | ||||
| 4881 | - | func (_c *MockWebView_Destroy_Call) Run(run func()) *MockWebView_Destroy_Call { | |||
| 4882 | - | _c.Call.Run(func(args mock.Arguments) { | |||
| 4883 | - | run() | |||
| 4884 | - | }) | |||
| 4885 | - | return _c | |||
| 4886 | - | } | |||
| 4887 | - | ||||
| 4888 | - | func (_c *MockWebView_Destroy_Call) Return() *MockWebView_Destroy_Call { | |||
| 4889 | - | _c.Call.Return() | |||
| 4890 | - | return _c | |||
| 4891 | - | } | |||
| 4892 | - | ||||
| 4893 | - | func (_c *MockWebView_Destroy_Call) RunAndReturn(run func()) *MockWebView_Destroy_Call { | |||
| 4894 | - | _c.Run(run) | |||
| 4895 | - | return _c | |||
| 4896 | - | } | |||
| 4897 | - | ||||
| 4898 | - | // EstimatedProgress provides a mock function for the type MockWebView | |||
| 4899 | - | func (_mock *MockWebView) EstimatedProgress() float64 { | |||
| 4900 | ret := _mock.Called() | 4734 | ret := _mock.Called() | ||
| 4901 | 4735 | ||||
| 4902 | if len(ret) == 0 { | 4736 | if len(ret) == 0 { | ||
| 4903 | - | panic("no return value specified for EstimatedProgress") | 4737 | + | panic("no return value specified for Generation") |
| 4904 | } | 4738 | } | ||
| 4905 | 4739 | ||||
| 4906 | - | var r0 float64 | 4740 | + | var r0 uint64 |
| 4907 | - | if returnFunc, ok := ret.Get(0).(func() float64); ok { | 4741 | + | if returnFunc, ok := ret.Get(0).(func() uint64); ok { |
| 4908 | r0 = returnFunc() | 4742 | r0 = returnFunc() | ||
| 4909 | } else { | 4743 | } else { | ||
| 4910 | - | r0 = ret.Get(0).(float64) | 4744 | + | r0 = ret.Get(0).(uint64) |
| 4911 | } | 4745 | } | ||
| 4912 | return r0 | 4746 | return r0 | ||
| 4913 | } | 4747 | } | ||
| 4914 | 4748 | ||||
| 4915 | - | // MockWebView_EstimatedProgress_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EstimatedProgress' | 4749 | + | // MockWebView_Generation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Generation' |
| 4916 | - | type MockWebView_EstimatedProgress_Call struct { | 4750 | + | type MockWebView_Generation_Call struct { |
| 4917 | *mock.Call | 4751 | *mock.Call | ||
| 4918 | } | 4752 | } | ||
| 4919 | 4753 | ||||
| 4920 | - | // EstimatedProgress is a helper method to define mock.On call | 4754 | + | // Generation is a helper method to define mock.On call |
| 4921 | - | func (_e *MockWebView_Expecter) EstimatedProgress() *MockWebView_EstimatedProgress_Call { | 4755 | + | func (_e *MockWebView_Expecter) Generation() *MockWebView_Generation_Call { |
| 4922 | - | return &MockWebView_EstimatedProgress_Call{Call: _e.mock.On("EstimatedProgress")} | 4756 | + | return &MockWebView_Generation_Call{Call: _e.mock.On("Generation")} |
| 4923 | } | 4757 | } | ||
| 4924 | 4758 | ||||
| 4925 | - | func (_c *MockWebView_EstimatedProgress_Call) Run(run func()) *MockWebView_EstimatedProgress_Call { | 4759 | + | func (_c *MockWebView_Generation_Call) Run(run func()) *MockWebView_Generation_Call { |
| 4926 | _c.Call.Run(func(args mock.Arguments) { | 4760 | _c.Call.Run(func(args mock.Arguments) { | ||
| 4927 | run() | 4761 | run() | ||
| 4928 | }) | 4762 | }) | ||
| 4929 | return _c | 4763 | return _c | ||
| 4930 | } | 4764 | } | ||
| 4931 | 4765 | ||||
| 4932 | - | func (_c *MockWebView_EstimatedProgress_Call) Return(f float64) *MockWebView_EstimatedProgress_Call { | 4766 | + | func (_c *MockWebView_Generation_Call) Return(v uint64) *MockWebView_Generation_Call { |
| 4933 | - | _c.Call.Return(f) | 4767 | + | _c.Call.Return(v) |
| 4934 | return _c | 4768 | return _c | ||
| 4935 | } | 4769 | } | ||
| 4936 | 4770 | ||||
| 4937 | - | func (_c *MockWebView_EstimatedProgress_Call) RunAndReturn(run func() float64) *MockWebView_EstimatedProgress_Call { | 4771 | + | func (_c *MockWebView_Generation_Call) RunAndReturn(run func() uint64) *MockWebView_Generation_Call { |
| 4938 | _c.Call.Return(run) | 4772 | _c.Call.Return(run) | ||
| 4939 | return _c | 4773 | return _c | ||
| 4940 | } | 4774 | } | ||
| @@ -5573,6 +5407,143 @@ func (_c *MockWebView_ReloadBypassCache_Call) RunAndReturn(run func(ctx context. | |||||
| 5573 | return _c | 5407 | return _c | ||
| 5574 | } | 5408 | } | ||
| 5575 | 5409 | ||||
| 5410 | + | // ResetBackgroundToDefault provides a mock function for the type MockWebView | |||
| 5411 | + | func (_mock *MockWebView) ResetBackgroundToDefault() { | |||
| 5412 | + | _mock.Called() | |||
| 5413 | + | return | |||
| 5414 | + | } | |||
| 5415 | + | ||||
| 5416 | + | // MockWebView_ResetBackgroundToDefault_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetBackgroundToDefault' | |||
| 5417 | + | type MockWebView_ResetBackgroundToDefault_Call struct { | |||
| 5418 | + | *mock.Call | |||
| 5419 | + | } | |||
| 5420 | + | ||||
| 5421 | + | // ResetBackgroundToDefault is a helper method to define mock.On call | |||
| 5422 | + | func (_e *MockWebView_Expecter) ResetBackgroundToDefault() *MockWebView_ResetBackgroundToDefault_Call { | |||
| 5423 | + | return &MockWebView_ResetBackgroundToDefault_Call{Call: _e.mock.On("ResetBackgroundToDefault")} | |||
| 5424 | + | } | |||
| 5425 | + | ||||
| 5426 | + | func (_c *MockWebView_ResetBackgroundToDefault_Call) Run(run func()) *MockWebView_ResetBackgroundToDefault_Call { | |||
| 5427 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 5428 | + | run() | |||
| 5429 | + | }) | |||
| 5430 | + | return _c | |||
| 5431 | + | } | |||
| 5432 | + | ||||
| 5433 | + | func (_c *MockWebView_ResetBackgroundToDefault_Call) Return() *MockWebView_ResetBackgroundToDefault_Call { | |||
| 5434 | + | _c.Call.Return() | |||
| 5435 | + | return _c | |||
| 5436 | + | } | |||
| 5437 | + | ||||
| 5438 | + | func (_c *MockWebView_ResetBackgroundToDefault_Call) RunAndReturn(run func()) *MockWebView_ResetBackgroundToDefault_Call { | |||
| 5439 | + | _c.Run(run) | |||
| 5440 | + | return _c | |||
| 5441 | + | } | |||
| 5442 | + | ||||
| 5443 | + | // RunJavaScript provides a mock function for the type MockWebView | |||
| 5444 | + | func (_mock *MockWebView) RunJavaScript(ctx context.Context, script string) { | |||
| 5445 | + | _mock.Called(ctx, script) | |||
| 5446 | + | return | |||
| 5447 | + | } | |||
| 5448 | + | ||||
| 5449 | + | // MockWebView_RunJavaScript_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RunJavaScript' | |||
| 5450 | + | type MockWebView_RunJavaScript_Call struct { | |||
| 5451 | + | *mock.Call | |||
| 5452 | + | } | |||
| 5453 | + | ||||
| 5454 | + | // RunJavaScript is a helper method to define mock.On call | |||
| 5455 | + | // - ctx context.Context | |||
| 5456 | + | // - script string | |||
| 5457 | + | func (_e *MockWebView_Expecter) RunJavaScript(ctx interface{}, script interface{}) *MockWebView_RunJavaScript_Call { | |||
| 5458 | + | return &MockWebView_RunJavaScript_Call{Call: _e.mock.On("RunJavaScript", ctx, script)} | |||
| 5459 | + | } | |||
| 5460 | + | ||||
| 5461 | + | func (_c *MockWebView_RunJavaScript_Call) Run(run func(ctx context.Context, script string)) *MockWebView_RunJavaScript_Call { | |||
| 5462 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 5463 | + | var arg0 context.Context | |||
| 5464 | + | if args[0] != nil { | |||
| 5465 | + | arg0 = args[0].(context.Context) | |||
| 5466 | + | } | |||
| 5467 | + | var arg1 string | |||
| 5468 | + | if args[1] != nil { | |||
| 5469 | + | arg1 = args[1].(string) | |||
| 5470 | + | } | |||
| 5471 | + | run( | |||
| 5472 | + | arg0, | |||
| 5473 | + | arg1, | |||
| 5474 | + | ) | |||
| 5475 | + | }) | |||
| 5476 | + | return _c | |||
| 5477 | + | } | |||
| 5478 | + | ||||
| 5479 | + | func (_c *MockWebView_RunJavaScript_Call) Return() *MockWebView_RunJavaScript_Call { | |||
| 5480 | + | _c.Call.Return() | |||
| 5481 | + | return _c | |||
| 5482 | + | } | |||
| 5483 | + | ||||
| 5484 | + | func (_c *MockWebView_RunJavaScript_Call) RunAndReturn(run func(ctx context.Context, script string)) *MockWebView_RunJavaScript_Call { | |||
| 5485 | + | _c.Run(run) | |||
| 5486 | + | return _c | |||
| 5487 | + | } | |||
| 5488 | + | ||||
| 5489 | + | // SetBackgroundColor provides a mock function for the type MockWebView | |||
| 5490 | + | func (_mock *MockWebView) SetBackgroundColor(r float64, g float64, b float64, a float64) { | |||
| 5491 | + | _mock.Called(r, g, b, a) | |||
| 5492 | + | return | |||
| 5493 | + | } | |||
| 5494 | + | ||||
| 5495 | + | // MockWebView_SetBackgroundColor_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetBackgroundColor' | |||
| 5496 | + | type MockWebView_SetBackgroundColor_Call struct { | |||
| 5497 | + | *mock.Call | |||
| 5498 | + | } | |||
| 5499 | + | ||||
| 5500 | + | // SetBackgroundColor is a helper method to define mock.On call | |||
| 5501 | + | // - r float64 | |||
| 5502 | + | // - g float64 | |||
| 5503 | + | // - b float64 | |||
| 5504 | + | // - a float64 | |||
| 5505 | + | func (_e *MockWebView_Expecter) SetBackgroundColor(r interface{}, g interface{}, b interface{}, a interface{}) *MockWebView_SetBackgroundColor_Call { | |||
| 5506 | + | return &MockWebView_SetBackgroundColor_Call{Call: _e.mock.On("SetBackgroundColor", r, g, b, a)} | |||
| 5507 | + | } | |||
| 5508 | + | ||||
| 5509 | + | func (_c *MockWebView_SetBackgroundColor_Call) Run(run func(r float64, g float64, b float64, a float64)) *MockWebView_SetBackgroundColor_Call { | |||
| 5510 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 5511 | + | var arg0 float64 | |||
| 5512 | + | if args[0] != nil { | |||
| 5513 | + | arg0 = args[0].(float64) | |||
| 5514 | + | } | |||
| 5515 | + | var arg1 float64 | |||
| 5516 | + | if args[1] != nil { | |||
| 5517 | + | arg1 = args[1].(float64) | |||
| 5518 | + | } | |||
| 5519 | + | var arg2 float64 | |||
| 5520 | + | if args[2] != nil { | |||
| 5521 | + | arg2 = args[2].(float64) | |||
| 5522 | + | } | |||
| 5523 | + | var arg3 float64 | |||
| 5524 | + | if args[3] != nil { | |||
| 5525 | + | arg3 = args[3].(float64) | |||
| 5526 | + | } | |||
| 5527 | + | run( | |||
| 5528 | + | arg0, | |||
| 5529 | + | arg1, | |||
| 5530 | + | arg2, | |||
| 5531 | + | arg3, | |||
| 5532 | + | ) | |||
| 5533 | + | }) | |||
| 5534 | + | return _c | |||
| 5535 | + | } | |||
| 5536 | + | ||||
| 5537 | + | func (_c *MockWebView_SetBackgroundColor_Call) Return() *MockWebView_SetBackgroundColor_Call { | |||
| 5538 | + | _c.Call.Return() | |||
| 5539 | + | return _c | |||
| 5540 | + | } | |||
| 5541 | + | ||||
| 5542 | + | func (_c *MockWebView_SetBackgroundColor_Call) RunAndReturn(run func(r float64, g float64, b float64, a float64)) *MockWebView_SetBackgroundColor_Call { | |||
| 5543 | + | _c.Run(run) | |||
| 5544 | + | return _c | |||
| 5545 | + | } | |||
| 5546 | + | ||||
| 5576 | // SetCallbacks provides a mock function for the type MockWebView | 5547 | // SetCallbacks provides a mock function for the type MockWebView | ||
| 5577 | func (_mock *MockWebView) SetCallbacks(callbacks *port.WebViewCallbacks) { | 5548 | func (_mock *MockWebView) SetCallbacks(callbacks *port.WebViewCallbacks) { | ||
| 5578 | _mock.Called(callbacks) | 5549 | _mock.Called(callbacks) | ||
D internal/application/port/webkit_context.go +0 -119
| @@ -1,119 +0,0 @@ | |||
| 1 | - | // Package port defines interfaces for external dependencies. | |
| 2 | - | package port | |
| 3 | - | ||
| 4 | - | import "context" | |
| 5 | - | ||
| 6 | - | // WebKitCookiePolicy controls cookie acceptance behavior for NetworkSession. | |
| 7 | - | type WebKitCookiePolicy string | |
| 8 | - | ||
| 9 | - | const ( | |
| 10 | - | WebKitCookiePolicyAlways WebKitCookiePolicy = "always" | |
| 11 | - | WebKitCookiePolicyNoThirdParty WebKitCookiePolicy = "no_third_party" | |
| 12 | - | WebKitCookiePolicyNever WebKitCookiePolicy = "never" | |
| 13 | - | ) | |
| 14 | - | ||
| 15 | - | // MemoryPressureConfig holds memory pressure settings for a WebKit process. | |
| 16 | - | // Zero values mean "use WebKit defaults". | |
| 17 | - | type MemoryPressureConfig struct { | |
| 18 | - | // MemoryLimitMB sets the memory limit in megabytes. | |
| 19 | - | // 0 means unset (uses WebKit default: system RAM capped at 3GB). | |
| 20 | - | MemoryLimitMB int | |
| 21 | - | ||
| 22 | - | // PollIntervalSec sets the interval for memory usage checks. | |
| 23 | - | // 0 means unset (uses WebKit default: 30 seconds). | |
| 24 | - | PollIntervalSec float64 | |
| 25 | - | ||
| 26 | - | // ConservativeThreshold sets threshold for conservative memory release. | |
| 27 | - | // Must be in (0, 1). 0 means unset (uses WebKit default: 0.33). | |
| 28 | - | ConservativeThreshold float64 | |
| 29 | - | ||
| 30 | - | // StrictThreshold sets threshold for strict memory release. | |
| 31 | - | // Must be in (0, 1). 0 means unset (uses WebKit default: 0.5). | |
| 32 | - | StrictThreshold float64 | |
| 33 | - | } | |
| 34 | - | ||
| 35 | - | // IsConfigured returns true if any memory pressure setting is configured. | |
| 36 | - | func (c *MemoryPressureConfig) IsConfigured() bool { | |
| 37 | - | if c == nil { | |
| 38 | - | return false | |
| 39 | - | } | |
| 40 | - | return c.MemoryLimitMB > 0 || | |
| 41 | - | c.PollIntervalSec > 0 || | |
| 42 | - | c.ConservativeThreshold > 0 || | |
| 43 | - | c.StrictThreshold > 0 | |
| 44 | - | } | |
| 45 | - | ||
| 46 | - | // WebKitContextOptions configures WebKitContext creation. | |
| 47 | - | type WebKitContextOptions struct { | |
| 48 | - | // DataDir is the directory for persistent data (cookies, storage, etc.). | |
| 49 | - | DataDir string | |
| 50 | - | ||
| 51 | - | // CacheDir is the directory for cache data. | |
| 52 | - | CacheDir string | |
| 53 | - | ||
| 54 | - | // CookiePolicy controls cookie acceptance behavior. | |
| 55 | - | // Empty value means runtime defaults are used. | |
| 56 | - | CookiePolicy WebKitCookiePolicy | |
| 57 | - | ||
| 58 | - | // ITPEnabled controls Intelligent Tracking Prevention for NetworkSession. | |
| 59 | - | // False means ITP remains disabled unless enabled explicitly. | |
| 60 | - | ITPEnabled bool | |
| 61 | - | ||
| 62 | - | // WebProcessMemory configures memory pressure for web processes. | |
| 63 | - | // nil means use WebKit defaults. | |
| 64 | - | WebProcessMemory *MemoryPressureConfig | |
| 65 | - | ||
| 66 | - | // NetworkProcessMemory configures memory pressure for the network process. | |
| 67 | - | // nil means use WebKit defaults. | |
| 68 | - | NetworkProcessMemory *MemoryPressureConfig | |
| 69 | - | } | |
| 70 | - | ||
| 71 | - | // IsWebProcessMemoryConfigured returns true if web process memory settings are configured. | |
| 72 | - | func (o *WebKitContextOptions) IsWebProcessMemoryConfigured() bool { | |
| 73 | - | if o == nil { | |
| 74 | - | return false | |
| 75 | - | } | |
| 76 | - | return o.WebProcessMemory.IsConfigured() | |
| 77 | - | } | |
| 78 | - | ||
| 79 | - | // IsNetworkProcessMemoryConfigured returns true if network process memory settings are configured. | |
| 80 | - | func (o *WebKitContextOptions) IsNetworkProcessMemoryConfigured() bool { | |
| 81 | - | if o == nil { | |
| 82 | - | return false | |
| 83 | - | } | |
| 84 | - | return o.NetworkProcessMemory.IsConfigured() | |
| 85 | - | } | |
| 86 | - | ||
| 87 | - | // MemoryPressureApplier applies memory pressure settings to WebKit processes. | |
| 88 | - | // This interface abstracts the WebKit-specific memory pressure configuration | |
| 89 | - | // to allow testing without WebKit dependencies. | |
| 90 | - | type MemoryPressureApplier interface { | |
| 91 | - | // ApplyNetworkProcessSettings applies memory pressure settings to the network process. | |
| 92 | - | // Must be called BEFORE creating any NetworkSession. | |
| 93 | - | ApplyNetworkProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) error | |
| 94 | - | ||
| 95 | - | // ApplyWebProcessSettings applies memory pressure settings to web processes. | |
| 96 | - | // Returns an opaque settings object that should be passed to WebContext creation. | |
| 97 | - | // Returns nil if no settings are configured. | |
| 98 | - | ApplyWebProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) (any, error) | |
| 99 | - | } | |
| 100 | - | ||
| 101 | - | // WebKitContextProvider creates and manages WebKit contexts. | |
| 102 | - | // This interface abstracts WebKit context creation for testability. | |
| 103 | - | type WebKitContextProvider interface { | |
| 104 | - | // Initialize sets up the WebKit context with the given options. | |
| 105 | - | // Must be called before any other methods. | |
| 106 | - | Initialize(ctx context.Context, opts WebKitContextOptions) error | |
| 107 | - | ||
| 108 | - | // DataDir returns the data directory path. | |
| 109 | - | DataDir() string | |
| 110 | - | ||
| 111 | - | // CacheDir returns the cache directory path. | |
| 112 | - | CacheDir() string | |
| 113 | - | ||
| 114 | - | // PrefetchDNS prefetches DNS for the given hostname. | |
| 115 | - | PrefetchDNS(hostname string) | |
| 116 | - | ||
| 117 | - | // Close releases resources held by the context. | |
| 118 | - | Close() error | |
| 119 | - | } | |
| @@ -1,119 +0,0 @@ | |||||
| 1 | - | // Package port defines interfaces for external dependencies. | |||
| 2 | - | package port | |||
| 3 | - | ||||
| 4 | - | import "context" | |||
| 5 | - | ||||
| 6 | - | // WebKitCookiePolicy controls cookie acceptance behavior for NetworkSession. | |||
| 7 | - | type WebKitCookiePolicy string | |||
| 8 | - | ||||
| 9 | - | const ( | |||
| 10 | - | WebKitCookiePolicyAlways WebKitCookiePolicy = "always" | |||
| 11 | - | WebKitCookiePolicyNoThirdParty WebKitCookiePolicy = "no_third_party" | |||
| 12 | - | WebKitCookiePolicyNever WebKitCookiePolicy = "never" | |||
| 13 | - | ) | |||
| 14 | - | ||||
| 15 | - | // MemoryPressureConfig holds memory pressure settings for a WebKit process. | |||
| 16 | - | // Zero values mean "use WebKit defaults". | |||
| 17 | - | type MemoryPressureConfig struct { | |||
| 18 | - | // MemoryLimitMB sets the memory limit in megabytes. | |||
| 19 | - | // 0 means unset (uses WebKit default: system RAM capped at 3GB). | |||
| 20 | - | MemoryLimitMB int | |||
| 21 | - | ||||
| 22 | - | // PollIntervalSec sets the interval for memory usage checks. | |||
| 23 | - | // 0 means unset (uses WebKit default: 30 seconds). | |||
| 24 | - | PollIntervalSec float64 | |||
| 25 | - | ||||
| 26 | - | // ConservativeThreshold sets threshold for conservative memory release. | |||
| 27 | - | // Must be in (0, 1). 0 means unset (uses WebKit default: 0.33). | |||
| 28 | - | ConservativeThreshold float64 | |||
| 29 | - | ||||
| 30 | - | // StrictThreshold sets threshold for strict memory release. | |||
| 31 | - | // Must be in (0, 1). 0 means unset (uses WebKit default: 0.5). | |||
| 32 | - | StrictThreshold float64 | |||
| 33 | - | } | |||
| 34 | - | ||||
| 35 | - | // IsConfigured returns true if any memory pressure setting is configured. | |||
| 36 | - | func (c *MemoryPressureConfig) IsConfigured() bool { | |||
| 37 | - | if c == nil { | |||
| 38 | - | return false | |||
| 39 | - | } | |||
| 40 | - | return c.MemoryLimitMB > 0 || | |||
| 41 | - | c.PollIntervalSec > 0 || | |||
| 42 | - | c.ConservativeThreshold > 0 || | |||
| 43 | - | c.StrictThreshold > 0 | |||
| 44 | - | } | |||
| 45 | - | ||||
| 46 | - | // WebKitContextOptions configures WebKitContext creation. | |||
| 47 | - | type WebKitContextOptions struct { | |||
| 48 | - | // DataDir is the directory for persistent data (cookies, storage, etc.). | |||
| 49 | - | DataDir string | |||
| 50 | - | ||||
| 51 | - | // CacheDir is the directory for cache data. | |||
| 52 | - | CacheDir string | |||
| 53 | - | ||||
| 54 | - | // CookiePolicy controls cookie acceptance behavior. | |||
| 55 | - | // Empty value means runtime defaults are used. | |||
| 56 | - | CookiePolicy WebKitCookiePolicy | |||
| 57 | - | ||||
| 58 | - | // ITPEnabled controls Intelligent Tracking Prevention for NetworkSession. | |||
| 59 | - | // False means ITP remains disabled unless enabled explicitly. | |||
| 60 | - | ITPEnabled bool | |||
| 61 | - | ||||
| 62 | - | // WebProcessMemory configures memory pressure for web processes. | |||
| 63 | - | // nil means use WebKit defaults. | |||
| 64 | - | WebProcessMemory *MemoryPressureConfig | |||
| 65 | - | ||||
| 66 | - | // NetworkProcessMemory configures memory pressure for the network process. | |||
| 67 | - | // nil means use WebKit defaults. | |||
| 68 | - | NetworkProcessMemory *MemoryPressureConfig | |||
| 69 | - | } | |||
| 70 | - | ||||
| 71 | - | // IsWebProcessMemoryConfigured returns true if web process memory settings are configured. | |||
| 72 | - | func (o *WebKitContextOptions) IsWebProcessMemoryConfigured() bool { | |||
| 73 | - | if o == nil { | |||
| 74 | - | return false | |||
| 75 | - | } | |||
| 76 | - | return o.WebProcessMemory.IsConfigured() | |||
| 77 | - | } | |||
| 78 | - | ||||
| 79 | - | // IsNetworkProcessMemoryConfigured returns true if network process memory settings are configured. | |||
| 80 | - | func (o *WebKitContextOptions) IsNetworkProcessMemoryConfigured() bool { | |||
| 81 | - | if o == nil { | |||
| 82 | - | return false | |||
| 83 | - | } | |||
| 84 | - | return o.NetworkProcessMemory.IsConfigured() | |||
| 85 | - | } | |||
| 86 | - | ||||
| 87 | - | // MemoryPressureApplier applies memory pressure settings to WebKit processes. | |||
| 88 | - | // This interface abstracts the WebKit-specific memory pressure configuration | |||
| 89 | - | // to allow testing without WebKit dependencies. | |||
| 90 | - | type MemoryPressureApplier interface { | |||
| 91 | - | // ApplyNetworkProcessSettings applies memory pressure settings to the network process. | |||
| 92 | - | // Must be called BEFORE creating any NetworkSession. | |||
| 93 | - | ApplyNetworkProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) error | |||
| 94 | - | ||||
| 95 | - | // ApplyWebProcessSettings applies memory pressure settings to web processes. | |||
| 96 | - | // Returns an opaque settings object that should be passed to WebContext creation. | |||
| 97 | - | // Returns nil if no settings are configured. | |||
| 98 | - | ApplyWebProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) (any, error) | |||
| 99 | - | } | |||
| 100 | - | ||||
| 101 | - | // WebKitContextProvider creates and manages WebKit contexts. | |||
| 102 | - | // This interface abstracts WebKit context creation for testability. | |||
| 103 | - | type WebKitContextProvider interface { | |||
| 104 | - | // Initialize sets up the WebKit context with the given options. | |||
| 105 | - | // Must be called before any other methods. | |||
| 106 | - | Initialize(ctx context.Context, opts WebKitContextOptions) error | |||
| 107 | - | ||||
| 108 | - | // DataDir returns the data directory path. | |||
| 109 | - | DataDir() string | |||
| 110 | - | ||||
| 111 | - | // CacheDir returns the cache directory path. | |||
| 112 | - | CacheDir() string | |||
| 113 | - | ||||
| 114 | - | // PrefetchDNS prefetches DNS for the given hostname. | |||
| 115 | - | PrefetchDNS(hostname string) | |||
| 116 | - | ||||
| 117 | - | // Close releases resources held by the context. | |||
| 118 | - | Close() error | |||
| 119 | - | } | |||
M internal/application/port/webview.go +35 -0
| @@ -109,6 +109,21 @@ type WebViewCallbacks struct { | |||
| 109 | 109 | // Return true to indicate the request was handled. Call allow()/deny() to respond. | |
| 110 | 110 | // The permission types are passed as strings ("microphone", "camera", "display", etc.). | |
| 111 | 111 | OnPermissionRequest func(origin string, permTypes []string, allow, deny func()) bool | |
| 112 | + | ||
| 113 | + | // OnLinkMiddleClick is called when a link is middle-clicked. | |
| 114 | + | // Return true if handled (blocks default navigation). | |
| 115 | + | OnLinkMiddleClick func(uri string) bool | |
| 116 | + | ||
| 117 | + | // OnEnterFullscreen is called when the WebView requests fullscreen mode. | |
| 118 | + | // Return true to prevent fullscreen. | |
| 119 | + | OnEnterFullscreen func() bool | |
| 120 | + | ||
| 121 | + | // OnLeaveFullscreen is called when the WebView exits fullscreen mode. | |
| 122 | + | // Return true to prevent leaving fullscreen. | |
| 123 | + | OnLeaveFullscreen func() bool | |
| 124 | + | ||
| 125 | + | // OnAudioStateChanged is called when audio playback starts or stops. | |
| 126 | + | OnAudioStateChanged func(playing bool) | |
| 112 | 127 | } | |
| 113 | 128 | ||
| 114 | 129 | // FindOptions configures search behavior. | |
| @@ -210,6 +225,26 @@ type WebView interface { | |||
| 210 | 225 | // Pass nil to clear all callbacks. | |
| 211 | 226 | SetCallbacks(callbacks *WebViewCallbacks) | |
| 212 | 227 | ||
| 228 | + | // --- Appearance --- | |
| 229 | + | ||
| 230 | + | // RunJavaScript executes a script in the main world. Fire-and-forget. | |
| 231 | + | RunJavaScript(ctx context.Context, script string) | |
| 232 | + | ||
| 233 | + | // SetBackgroundColor sets the background color shown before content paints (0.0-1.0 RGBA). | |
| 234 | + | SetBackgroundColor(r, g, b, a float64) | |
| 235 | + | ||
| 236 | + | // ResetBackgroundToDefault resets the background to white (browser default). | |
| 237 | + | ResetBackgroundToDefault() | |
| 238 | + | ||
| 239 | + | // --- Favicon --- | |
| 240 | + | ||
| 241 | + | // Favicon returns the current page favicon, or nil if unavailable. | |
| 242 | + | Favicon() Texture | |
| 243 | + | ||
| 244 | + | // Generation returns a monotonic counter incremented on pool reuse. | |
| 245 | + | // Used to detect stale callbacks after a WebView is recycled. | |
| 246 | + | Generation() uint64 | |
| 247 | + | ||
| 213 | 248 | // --- Media/Fullscreen State --- | |
| 214 | 249 | ||
| 215 | 250 | // IsFullscreen returns true if the WebView is currently in fullscreen mode. | |
| @@ -109,6 +109,21 @@ type WebViewCallbacks struct { | |||||
| 109 | // Return true to indicate the request was handled. Call allow()/deny() to respond. | 109 | // Return true to indicate the request was handled. Call allow()/deny() to respond. | ||
| 110 | // The permission types are passed as strings ("microphone", "camera", "display", etc.). | 110 | // The permission types are passed as strings ("microphone", "camera", "display", etc.). | ||
| 111 | OnPermissionRequest func(origin string, permTypes []string, allow, deny func()) bool | 111 | OnPermissionRequest func(origin string, permTypes []string, allow, deny func()) bool | ||
| 112 | + | ||||
| 113 | + | // OnLinkMiddleClick is called when a link is middle-clicked. | |||
| 114 | + | // Return true if handled (blocks default navigation). | |||
| 115 | + | OnLinkMiddleClick func(uri string) bool | |||
| 116 | + | ||||
| 117 | + | // OnEnterFullscreen is called when the WebView requests fullscreen mode. | |||
| 118 | + | // Return true to prevent fullscreen. | |||
| 119 | + | OnEnterFullscreen func() bool | |||
| 120 | + | ||||
| 121 | + | // OnLeaveFullscreen is called when the WebView exits fullscreen mode. | |||
| 122 | + | // Return true to prevent leaving fullscreen. | |||
| 123 | + | OnLeaveFullscreen func() bool | |||
| 124 | + | ||||
| 125 | + | // OnAudioStateChanged is called when audio playback starts or stops. | |||
| 126 | + | OnAudioStateChanged func(playing bool) | |||
| 112 | } | 127 | } | ||
| 113 | 128 | ||||
| 114 | // FindOptions configures search behavior. | 129 | // FindOptions configures search behavior. | ||
| @@ -210,6 +225,26 @@ type WebView interface { | |||||
| 210 | // Pass nil to clear all callbacks. | 225 | // Pass nil to clear all callbacks. | ||
| 211 | SetCallbacks(callbacks *WebViewCallbacks) | 226 | SetCallbacks(callbacks *WebViewCallbacks) | ||
| 212 | 227 | ||||
| 228 | + | // --- Appearance --- | |||
| 229 | + | ||||
| 230 | + | // RunJavaScript executes a script in the main world. Fire-and-forget. | |||
| 231 | + | RunJavaScript(ctx context.Context, script string) | |||
| 232 | + | ||||
| 233 | + | // SetBackgroundColor sets the background color shown before content paints (0.0-1.0 RGBA). | |||
| 234 | + | SetBackgroundColor(r, g, b, a float64) | |||
| 235 | + | ||||
| 236 | + | // ResetBackgroundToDefault resets the background to white (browser default). | |||
| 237 | + | ResetBackgroundToDefault() | |||
| 238 | + | ||||
| 239 | + | // --- Favicon --- | |||
| 240 | + | ||||
| 241 | + | // Favicon returns the current page favicon, or nil if unavailable. | |||
| 242 | + | Favicon() Texture | |||
| 243 | + | ||||
| 244 | + | // Generation returns a monotonic counter incremented on pool reuse. | |||
| 245 | + | // Used to detect stale callbacks after a WebView is recycled. | |||
| 246 | + | Generation() uint64 | |||
| 247 | + | ||||
| 213 | // --- Media/Fullscreen State --- | 248 | // --- Media/Fullscreen State --- | ||
| 214 | 249 | ||||
| 215 | // IsFullscreen returns true if the WebView is currently in fullscreen mode. | 250 | // IsFullscreen returns true if the WebView is currently in fullscreen mode. | ||
M internal/bootstrap/gui.go +1 -1
| @@ -199,7 +199,7 @@ func CheckRuntimeRequirements(ctx context.Context, cfg *config.Config) error { | |||
| 199 | 199 | probe := deps.NewPkgConfigProbe() | |
| 200 | 200 | checkRuntimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe) | |
| 201 | 201 | runtimeOut, err := checkRuntimeUC.Execute(ctx, usecase.CheckRuntimeDependenciesInput{ | |
| 202 | - | Prefix: cfg.Runtime.Prefix, | |
| 202 | + | Prefix: cfg.Engine.WebKit.Prefix, | |
| 203 | 203 | }) | |
| 204 | 204 | if err != nil { | |
| 205 | 205 | return fmt.Errorf("runtime check execution failed: %w", err) | |
| @@ -199,7 +199,7 @@ func CheckRuntimeRequirements(ctx context.Context, cfg *config.Config) error { | |||||
| 199 | probe := deps.NewPkgConfigProbe() | 199 | probe := deps.NewPkgConfigProbe() | ||
| 200 | checkRuntimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe) | 200 | checkRuntimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe) | ||
| 201 | runtimeOut, err := checkRuntimeUC.Execute(ctx, usecase.CheckRuntimeDependenciesInput{ | 201 | runtimeOut, err := checkRuntimeUC.Execute(ctx, usecase.CheckRuntimeDependenciesInput{ | ||
| 202 | - | Prefix: cfg.Runtime.Prefix, | 202 | + | Prefix: cfg.Engine.WebKit.Prefix, |
| 203 | }) | 203 | }) | ||
| 204 | if err != nil { | 204 | if err != nil { | ||
| 205 | return fmt.Errorf("runtime check execution failed: %w", err) | 205 | return fmt.Errorf("runtime check execution failed: %w", err) | ||
M internal/cli/cmd/doctor.go +1 -1
| @@ -59,7 +59,7 @@ func runDoctor(_ *cobra.Command, _ []string) error { | |||
| 59 | 59 | probe := deps.NewPkgConfigProbe() | |
| 60 | 60 | runtimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe) | |
| 61 | 61 | runtimeOut, err := runtimeUC.Execute(app.Ctx(), usecase.CheckRuntimeDependenciesInput{ | |
| 62 | - | Prefix: app.Config.Runtime.Prefix, | |
| 62 | + | Prefix: app.Config.Engine.WebKit.Prefix, | |
| 63 | 63 | }) | |
| 64 | 64 | if err != nil { | |
| 65 | 65 | return err | |
| @@ -59,7 +59,7 @@ func runDoctor(_ *cobra.Command, _ []string) error { | |||||
| 59 | probe := deps.NewPkgConfigProbe() | 59 | probe := deps.NewPkgConfigProbe() | ||
| 60 | runtimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe) | 60 | runtimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe) | ||
| 61 | runtimeOut, err := runtimeUC.Execute(app.Ctx(), usecase.CheckRuntimeDependenciesInput{ | 61 | runtimeOut, err := runtimeUC.Execute(app.Ctx(), usecase.CheckRuntimeDependenciesInput{ | ||
| 62 | - | Prefix: app.Config.Runtime.Prefix, | 62 | + | Prefix: app.Config.Engine.WebKit.Prefix, |
| 63 | }) | 63 | }) | ||
| 64 | if err != nil { | 64 | if err != nil { | ||
| 65 | return err | 65 | return err | ||
M internal/infrastructure/config/defaults.go +3 -7
| @@ -149,17 +149,13 @@ func DefaultConfig() *Config { | |||
| 149 | 149 | ZoomCacheSize: defaultZoomCacheSize, | |
| 150 | 150 | CookiePolicy: CookiePolicyNoThirdParty, | |
| 151 | 151 | WebKit: WebKitEngineConfig{ | |
| 152 | - | ITPEnabled: true, | |
| 152 | + | ITPEnabled: true, | |
| 153 | 153 | SkiaCPUPaintingThreads: defaultSkiaCPUPaintingThreads, | |
| 154 | 154 | SkiaGPUPaintingThreads: defaultSkiaGPUPaintingThreads, | |
| 155 | - | GSKRenderer: GSKRendererAuto, | |
| 156 | - | GLRenderingMode: GLRenderingModeAuto, | |
| 155 | + | GSKRenderer: GSKRendererAuto, | |
| 156 | + | GLRenderingMode: GLRenderingModeAuto, | |
| 157 | 157 | }, | |
| 158 | 158 | }, | |
| 159 | - | // Rendering, Privacy, Runtime, Performance: zeroed out. | |
| 160 | - | // These sections have been migrated to [engine]/[engine.webkit]. | |
| 161 | - | // Keeping zero-value structs so the Config type remains backward-compatible | |
| 162 | - | // for unmarshalling old config files during migration. | |
| 163 | 159 | DefaultWebpageZoom: 1.2, // 120% default zoom for better readability | |
| 164 | 160 | DefaultUIScale: defaultUIScale, // 1.0 = 100%, 2.0 = 200% | |
| 165 | 161 | Workspace: WorkspaceConfig{ | |
| @@ -149,17 +149,13 @@ func DefaultConfig() *Config { | |||||
| 149 | ZoomCacheSize: defaultZoomCacheSize, | 149 | ZoomCacheSize: defaultZoomCacheSize, | ||
| 150 | CookiePolicy: CookiePolicyNoThirdParty, | 150 | CookiePolicy: CookiePolicyNoThirdParty, | ||
| 151 | WebKit: WebKitEngineConfig{ | 151 | WebKit: WebKitEngineConfig{ | ||
| 152 | - | ITPEnabled: true, | 152 | + | ITPEnabled: true, |
| 153 | SkiaCPUPaintingThreads: defaultSkiaCPUPaintingThreads, | 153 | SkiaCPUPaintingThreads: defaultSkiaCPUPaintingThreads, | ||
| 154 | SkiaGPUPaintingThreads: defaultSkiaGPUPaintingThreads, | 154 | SkiaGPUPaintingThreads: defaultSkiaGPUPaintingThreads, | ||
| 155 | - | GSKRenderer: GSKRendererAuto, | 155 | + | GSKRenderer: GSKRendererAuto, |
| 156 | - | GLRenderingMode: GLRenderingModeAuto, | 156 | + | GLRenderingMode: GLRenderingModeAuto, |
| 157 | }, | 157 | }, | ||
| 158 | }, | 158 | }, | ||
| 159 | - | // Rendering, Privacy, Runtime, Performance: zeroed out. | |||
| 160 | - | // These sections have been migrated to [engine]/[engine.webkit]. | |||
| 161 | - | // Keeping zero-value structs so the Config type remains backward-compatible | |||
| 162 | - | // for unmarshalling old config files during migration. | |||
| 163 | DefaultWebpageZoom: 1.2, // 120% default zoom for better readability | 159 | DefaultWebpageZoom: 1.2, // 120% default zoom for better readability | ||
| 164 | DefaultUIScale: defaultUIScale, // 1.0 = 100%, 2.0 = 200% | 160 | DefaultUIScale: defaultUIScale, // 1.0 = 100%, 2.0 = 200% | ||
| 165 | Workspace: WorkspaceConfig{ | 161 | Workspace: WorkspaceConfig{ | ||
M internal/infrastructure/config/defaults_test.go +2 -4
| @@ -18,8 +18,6 @@ func TestDefaultConfig_CoreDefaults(t *testing.T) { | |||
| 18 | 18 | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Engine.CookiePolicy) | |
| 19 | 19 | assert.True(t, cfg.Engine.WebKit.ITPEnabled) | |
| 20 | 20 | ||
| 21 | - | // Old sections should be zero-valued | |
| 22 | - | assert.Empty(t, string(cfg.Performance.Profile)) | |
| 23 | - | assert.Empty(t, string(cfg.Privacy.CookiePolicy)) | |
| 24 | - | assert.Empty(t, string(cfg.Rendering.Mode)) | |
| 21 | + | // Old sections (Rendering, Privacy, Performance, Runtime) have been removed from Config. | |
| 22 | + | // Their values now live under cfg.Engine / cfg.Engine.WebKit (validated above). | |
| 25 | 23 | } | |
| @@ -18,8 +18,6 @@ func TestDefaultConfig_CoreDefaults(t *testing.T) { | |||||
| 18 | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Engine.CookiePolicy) | 18 | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Engine.CookiePolicy) | ||
| 19 | assert.True(t, cfg.Engine.WebKit.ITPEnabled) | 19 | assert.True(t, cfg.Engine.WebKit.ITPEnabled) | ||
| 20 | 20 | ||||
| 21 | - | // Old sections should be zero-valued | 21 | + | // Old sections (Rendering, Privacy, Performance, Runtime) have been removed from Config. |
| 22 | - | assert.Empty(t, string(cfg.Performance.Profile)) | 22 | + | // Their values now live under cfg.Engine / cfg.Engine.WebKit (validated above). |
| 23 | - | assert.Empty(t, string(cfg.Privacy.CookiePolicy)) | |||
| 24 | - | assert.Empty(t, string(cfg.Rendering.Mode)) | |||
| 25 | } | 23 | } | ||
M internal/infrastructure/config/engine.go +24 -0
| @@ -56,3 +56,27 @@ type WebKitEngineConfig struct { | |||
| 56 | 56 | NetworkProcessMemoryConservativeThreshold float64 `mapstructure:"network_process_memory_conservative_threshold" toml:"network_process_memory_conservative_threshold" yaml:"network_process_memory_conservative_threshold"` //nolint:lll // struct tags exceed lll limit | |
| 57 | 57 | NetworkProcessMemoryStrictThreshold float64 `mapstructure:"network_process_memory_strict_threshold" toml:"network_process_memory_strict_threshold" yaml:"network_process_memory_strict_threshold"` //nolint:lll // struct tags exceed lll limit | |
| 58 | 58 | } | |
| 59 | + | ||
| 60 | + | // PerformanceConfigFromEngine constructs a PerformanceConfig from the | |
| 61 | + | // new [engine] config section, for use with ResolvePerformanceProfile. | |
| 62 | + | func PerformanceConfigFromEngine(e *EngineConfig) PerformanceConfig { | |
| 63 | + | if e == nil { | |
| 64 | + | return PerformanceConfig{} | |
| 65 | + | } | |
| 66 | + | return PerformanceConfig{ | |
| 67 | + | Profile: e.Profile, | |
| 68 | + | ZoomCacheSize: e.ZoomCacheSize, | |
| 69 | + | WebViewPoolPrewarmCount: e.PoolPrewarmCount, | |
| 70 | + | SkiaCPUPaintingThreads: e.WebKit.SkiaCPUPaintingThreads, | |
| 71 | + | SkiaGPUPaintingThreads: e.WebKit.SkiaGPUPaintingThreads, | |
| 72 | + | SkiaEnableCPURendering: e.WebKit.SkiaEnableCPURendering, | |
| 73 | + | WebProcessMemoryLimitMB: e.WebKit.WebProcessMemoryLimitMB, | |
| 74 | + | WebProcessMemoryPollIntervalSec: e.WebKit.WebProcessMemoryPollIntervalSec, | |
| 75 | + | WebProcessMemoryConservativeThreshold: e.WebKit.WebProcessMemoryConservativeThreshold, | |
| 76 | + | WebProcessMemoryStrictThreshold: e.WebKit.WebProcessMemoryStrictThreshold, | |
| 77 | + | NetworkProcessMemoryLimitMB: e.WebKit.NetworkProcessMemoryLimitMB, | |
| 78 | + | NetworkProcessMemoryPollIntervalSec: e.WebKit.NetworkProcessMemoryPollIntervalSec, | |
| 79 | + | NetworkProcessMemoryConservativeThreshold: e.WebKit.NetworkProcessMemoryConservativeThreshold, | |
| 80 | + | NetworkProcessMemoryStrictThreshold: e.WebKit.NetworkProcessMemoryStrictThreshold, | |
| 81 | + | } | |
| 82 | + | } | |
| @@ -56,3 +56,27 @@ type WebKitEngineConfig struct { | |||||
| 56 | NetworkProcessMemoryConservativeThreshold float64 `mapstructure:"network_process_memory_conservative_threshold" toml:"network_process_memory_conservative_threshold" yaml:"network_process_memory_conservative_threshold"` //nolint:lll // struct tags exceed lll limit | 56 | NetworkProcessMemoryConservativeThreshold float64 `mapstructure:"network_process_memory_conservative_threshold" toml:"network_process_memory_conservative_threshold" yaml:"network_process_memory_conservative_threshold"` //nolint:lll // struct tags exceed lll limit | ||
| 57 | NetworkProcessMemoryStrictThreshold float64 `mapstructure:"network_process_memory_strict_threshold" toml:"network_process_memory_strict_threshold" yaml:"network_process_memory_strict_threshold"` //nolint:lll // struct tags exceed lll limit | 57 | NetworkProcessMemoryStrictThreshold float64 `mapstructure:"network_process_memory_strict_threshold" toml:"network_process_memory_strict_threshold" yaml:"network_process_memory_strict_threshold"` //nolint:lll // struct tags exceed lll limit | ||
| 58 | } | 58 | } | ||
| 59 | + | ||||
| 60 | + | // PerformanceConfigFromEngine constructs a PerformanceConfig from the | |||
| 61 | + | // new [engine] config section, for use with ResolvePerformanceProfile. | |||
| 62 | + | func PerformanceConfigFromEngine(e *EngineConfig) PerformanceConfig { | |||
| 63 | + | if e == nil { | |||
| 64 | + | return PerformanceConfig{} | |||
| 65 | + | } | |||
| 66 | + | return PerformanceConfig{ | |||
| 67 | + | Profile: e.Profile, | |||
| 68 | + | ZoomCacheSize: e.ZoomCacheSize, | |||
| 69 | + | WebViewPoolPrewarmCount: e.PoolPrewarmCount, | |||
| 70 | + | SkiaCPUPaintingThreads: e.WebKit.SkiaCPUPaintingThreads, | |||
| 71 | + | SkiaGPUPaintingThreads: e.WebKit.SkiaGPUPaintingThreads, | |||
| 72 | + | SkiaEnableCPURendering: e.WebKit.SkiaEnableCPURendering, | |||
| 73 | + | WebProcessMemoryLimitMB: e.WebKit.WebProcessMemoryLimitMB, | |||
| 74 | + | WebProcessMemoryPollIntervalSec: e.WebKit.WebProcessMemoryPollIntervalSec, | |||
| 75 | + | WebProcessMemoryConservativeThreshold: e.WebKit.WebProcessMemoryConservativeThreshold, | |||
| 76 | + | WebProcessMemoryStrictThreshold: e.WebKit.WebProcessMemoryStrictThreshold, | |||
| 77 | + | NetworkProcessMemoryLimitMB: e.WebKit.NetworkProcessMemoryLimitMB, | |||
| 78 | + | NetworkProcessMemoryPollIntervalSec: e.WebKit.NetworkProcessMemoryPollIntervalSec, | |||
| 79 | + | NetworkProcessMemoryConservativeThreshold: e.WebKit.NetworkProcessMemoryConservativeThreshold, | |||
| 80 | + | NetworkProcessMemoryStrictThreshold: e.WebKit.NetworkProcessMemoryStrictThreshold, | |||
| 81 | + | } | |||
| 82 | + | } | |||
M internal/infrastructure/config/loader.go +32 -45
| @@ -204,52 +204,54 @@ func ensureDatabasePath(config *Config) error { | |||
| 204 | 204 | } | |
| 205 | 205 | ||
| 206 | 206 | func normalizeConfig(config *Config) { | |
| 207 | - | normalizeRendering(config) | |
| 208 | - | normalizePrivacy(config) | |
| 209 | 207 | normalizeAppearance(config) | |
| 210 | 208 | normalizeMedia(config) | |
| 211 | - | ||
| 212 | - | config.Runtime.Prefix = strings.TrimSpace(config.Runtime.Prefix) | |
| 213 | - | normalizePerformanceProfile(config) | |
| 209 | + | normalizeEngineConfig(config) | |
| 214 | 210 | } | |
| 215 | 211 | ||
| 216 | - | func normalizeRendering(config *Config) { | |
| 217 | - | switch strings.ToLower(string(config.Rendering.Mode)) { | |
| 218 | - | case "", string(RenderingModeAuto): | |
| 219 | - | config.Rendering.Mode = RenderingModeAuto | |
| 220 | - | case string(RenderingModeGPU): | |
| 221 | - | config.Rendering.Mode = RenderingModeGPU | |
| 222 | - | case string(RenderingModeCPU): | |
| 223 | - | config.Rendering.Mode = RenderingModeCPU | |
| 224 | - | default: | |
| 225 | - | config.Rendering.Mode = RenderingModeAuto | |
| 226 | - | } | |
| 227 | - | ||
| 228 | - | switch strings.ToLower(string(config.Rendering.GSKRenderer)) { | |
| 212 | + | func normalizeEngineConfig(config *Config) { | |
| 213 | + | // Normalize GSK renderer (engine.webkit) | |
| 214 | + | switch strings.ToLower(string(config.Engine.WebKit.GSKRenderer)) { | |
| 229 | 215 | case "", string(GSKRendererAuto): | |
| 230 | - | config.Rendering.GSKRenderer = GSKRendererAuto | |
| 216 | + | config.Engine.WebKit.GSKRenderer = GSKRendererAuto | |
| 231 | 217 | case string(GSKRendererOpenGL): | |
| 232 | - | config.Rendering.GSKRenderer = GSKRendererOpenGL | |
| 218 | + | config.Engine.WebKit.GSKRenderer = GSKRendererOpenGL | |
| 233 | 219 | case string(GSKRendererVulkan): | |
| 234 | - | config.Rendering.GSKRenderer = GSKRendererVulkan | |
| 220 | + | config.Engine.WebKit.GSKRenderer = GSKRendererVulkan | |
| 235 | 221 | case string(GSKRendererCairo): | |
| 236 | - | config.Rendering.GSKRenderer = GSKRendererCairo | |
| 222 | + | config.Engine.WebKit.GSKRenderer = GSKRendererCairo | |
| 237 | 223 | default: | |
| 238 | - | config.Rendering.GSKRenderer = GSKRendererAuto | |
| 224 | + | config.Engine.WebKit.GSKRenderer = GSKRendererAuto | |
| 239 | 225 | } | |
| 240 | - | } | |
| 241 | 226 | ||
| 242 | - | func normalizePrivacy(config *Config) { | |
| 243 | - | switch strings.ToLower(string(config.Privacy.CookiePolicy)) { | |
| 227 | + | // Normalize cookie policy (engine) | |
| 228 | + | switch strings.ToLower(string(config.Engine.CookiePolicy)) { | |
| 244 | 229 | case "", string(CookiePolicyNoThirdParty): | |
| 245 | - | config.Privacy.CookiePolicy = CookiePolicyNoThirdParty | |
| 230 | + | config.Engine.CookiePolicy = CookiePolicyNoThirdParty | |
| 246 | 231 | case string(CookiePolicyAlways): | |
| 247 | - | config.Privacy.CookiePolicy = CookiePolicyAlways | |
| 232 | + | config.Engine.CookiePolicy = CookiePolicyAlways | |
| 248 | 233 | case string(CookiePolicyNever): | |
| 249 | - | config.Privacy.CookiePolicy = CookiePolicyNever | |
| 234 | + | config.Engine.CookiePolicy = CookiePolicyNever | |
| 250 | 235 | default: | |
| 251 | - | config.Privacy.CookiePolicy = CookiePolicyNoThirdParty | |
| 236 | + | config.Engine.CookiePolicy = CookiePolicyNoThirdParty | |
| 252 | 237 | } | |
| 238 | + | ||
| 239 | + | // Normalize performance profile (engine) | |
| 240 | + | switch strings.ToLower(string(config.Engine.Profile)) { | |
| 241 | + | case "", string(ProfileDefault): | |
| 242 | + | config.Engine.Profile = ProfileDefault | |
| 243 | + | case string(ProfileLite): | |
| 244 | + | config.Engine.Profile = ProfileLite | |
| 245 | + | case string(ProfileMax): | |
| 246 | + | config.Engine.Profile = ProfileMax | |
| 247 | + | case string(ProfileCustom): | |
| 248 | + | config.Engine.Profile = ProfileCustom | |
| 249 | + | default: | |
| 250 | + | config.Engine.Profile = ProfileDefault | |
| 251 | + | } | |
| 252 | + | ||
| 253 | + | // Trim runtime prefix (engine.webkit) | |
| 254 | + | config.Engine.WebKit.Prefix = strings.TrimSpace(config.Engine.WebKit.Prefix) | |
| 253 | 255 | } | |
| 254 | 256 | ||
| 255 | 257 | func normalizeAppearance(config *Config) { | |
| @@ -291,21 +293,6 @@ func normalizeMedia(config *Config) { | |||
| 291 | 293 | } | |
| 292 | 294 | } | |
| 293 | 295 | ||
| 294 | - | func normalizePerformanceProfile(config *Config) { | |
| 295 | - | switch strings.ToLower(string(config.Performance.Profile)) { | |
| 296 | - | case "", string(ProfileDefault): | |
| 297 | - | config.Performance.Profile = ProfileDefault | |
| 298 | - | case string(ProfileLite): | |
| 299 | - | config.Performance.Profile = ProfileLite | |
| 300 | - | case string(ProfileMax): | |
| 301 | - | config.Performance.Profile = ProfileMax | |
| 302 | - | case string(ProfileCustom): | |
| 303 | - | config.Performance.Profile = ProfileCustom | |
| 304 | - | default: | |
| 305 | - | config.Performance.Profile = ProfileDefault | |
| 306 | - | } | |
| 307 | - | } | |
| 308 | - | ||
| 309 | 296 | // Get returns the current configuration (thread-safe). | |
| 310 | 297 | func (m *Manager) Get() *Config { | |
| 311 | 298 | m.mu.RLock() | |
| @@ -204,52 +204,54 @@ func ensureDatabasePath(config *Config) error { | |||||
| 204 | } | 204 | } | ||
| 205 | 205 | ||||
| 206 | func normalizeConfig(config *Config) { | 206 | func normalizeConfig(config *Config) { | ||
| 207 | - | normalizeRendering(config) | |||
| 208 | - | normalizePrivacy(config) | |||
| 209 | normalizeAppearance(config) | 207 | normalizeAppearance(config) | ||
| 210 | normalizeMedia(config) | 208 | normalizeMedia(config) | ||
| 211 | - | 209 | + | normalizeEngineConfig(config) | |
| 212 | - | config.Runtime.Prefix = strings.TrimSpace(config.Runtime.Prefix) | |||
| 213 | - | normalizePerformanceProfile(config) | |||
| 214 | } | 210 | } | ||
| 215 | 211 | ||||
| 216 | - | func normalizeRendering(config *Config) { | 212 | + | func normalizeEngineConfig(config *Config) { |
| 217 | - | switch strings.ToLower(string(config.Rendering.Mode)) { | 213 | + | // Normalize GSK renderer (engine.webkit) |
| 218 | - | case "", string(RenderingModeAuto): | 214 | + | switch strings.ToLower(string(config.Engine.WebKit.GSKRenderer)) { |
| 219 | - | config.Rendering.Mode = RenderingModeAuto | |||
| 220 | - | case string(RenderingModeGPU): | |||
| 221 | - | config.Rendering.Mode = RenderingModeGPU | |||
| 222 | - | case string(RenderingModeCPU): | |||
| 223 | - | config.Rendering.Mode = RenderingModeCPU | |||
| 224 | - | default: | |||
| 225 | - | config.Rendering.Mode = RenderingModeAuto | |||
| 226 | - | } | |||
| 227 | - | ||||
| 228 | - | switch strings.ToLower(string(config.Rendering.GSKRenderer)) { | |||
| 229 | case "", string(GSKRendererAuto): | 215 | case "", string(GSKRendererAuto): | ||
| 230 | - | config.Rendering.GSKRenderer = GSKRendererAuto | 216 | + | config.Engine.WebKit.GSKRenderer = GSKRendererAuto |
| 231 | case string(GSKRendererOpenGL): | 217 | case string(GSKRendererOpenGL): | ||
| 232 | - | config.Rendering.GSKRenderer = GSKRendererOpenGL | 218 | + | config.Engine.WebKit.GSKRenderer = GSKRendererOpenGL |
| 233 | case string(GSKRendererVulkan): | 219 | case string(GSKRendererVulkan): | ||
| 234 | - | config.Rendering.GSKRenderer = GSKRendererVulkan | 220 | + | config.Engine.WebKit.GSKRenderer = GSKRendererVulkan |
| 235 | case string(GSKRendererCairo): | 221 | case string(GSKRendererCairo): | ||
| 236 | - | config.Rendering.GSKRenderer = GSKRendererCairo | 222 | + | config.Engine.WebKit.GSKRenderer = GSKRendererCairo |
| 237 | default: | 223 | default: | ||
| 238 | - | config.Rendering.GSKRenderer = GSKRendererAuto | 224 | + | config.Engine.WebKit.GSKRenderer = GSKRendererAuto |
| 239 | } | 225 | } | ||
| 240 | - | } | |||
| 241 | 226 | ||||
| 242 | - | func normalizePrivacy(config *Config) { | 227 | + | // Normalize cookie policy (engine) |
| 243 | - | switch strings.ToLower(string(config.Privacy.CookiePolicy)) { | 228 | + | switch strings.ToLower(string(config.Engine.CookiePolicy)) { |
| 244 | case "", string(CookiePolicyNoThirdParty): | 229 | case "", string(CookiePolicyNoThirdParty): | ||
| 245 | - | config.Privacy.CookiePolicy = CookiePolicyNoThirdParty | 230 | + | config.Engine.CookiePolicy = CookiePolicyNoThirdParty |
| 246 | case string(CookiePolicyAlways): | 231 | case string(CookiePolicyAlways): | ||
| 247 | - | config.Privacy.CookiePolicy = CookiePolicyAlways | 232 | + | config.Engine.CookiePolicy = CookiePolicyAlways |
| 248 | case string(CookiePolicyNever): | 233 | case string(CookiePolicyNever): | ||
| 249 | - | config.Privacy.CookiePolicy = CookiePolicyNever | 234 | + | config.Engine.CookiePolicy = CookiePolicyNever |
| 250 | default: | 235 | default: | ||
| 251 | - | config.Privacy.CookiePolicy = CookiePolicyNoThirdParty | 236 | + | config.Engine.CookiePolicy = CookiePolicyNoThirdParty |
| 252 | } | 237 | } | ||
| 238 | + | ||||
| 239 | + | // Normalize performance profile (engine) | |||
| 240 | + | switch strings.ToLower(string(config.Engine.Profile)) { | |||
| 241 | + | case "", string(ProfileDefault): | |||
| 242 | + | config.Engine.Profile = ProfileDefault | |||
| 243 | + | case string(ProfileLite): | |||
| 244 | + | config.Engine.Profile = ProfileLite | |||
| 245 | + | case string(ProfileMax): | |||
| 246 | + | config.Engine.Profile = ProfileMax | |||
| 247 | + | case string(ProfileCustom): | |||
| 248 | + | config.Engine.Profile = ProfileCustom | |||
| 249 | + | default: | |||
| 250 | + | config.Engine.Profile = ProfileDefault | |||
| 251 | + | } | |||
| 252 | + | ||||
| 253 | + | // Trim runtime prefix (engine.webkit) | |||
| 254 | + | config.Engine.WebKit.Prefix = strings.TrimSpace(config.Engine.WebKit.Prefix) | |||
| 253 | } | 255 | } | ||
| 254 | 256 | ||||
| 255 | func normalizeAppearance(config *Config) { | 257 | func normalizeAppearance(config *Config) { | ||
| @@ -291,21 +293,6 @@ func normalizeMedia(config *Config) { | |||||
| 291 | } | 293 | } | ||
| 292 | } | 294 | } | ||
| 293 | 295 | ||||
| 294 | - | func normalizePerformanceProfile(config *Config) { | |||
| 295 | - | switch strings.ToLower(string(config.Performance.Profile)) { | |||
| 296 | - | case "", string(ProfileDefault): | |||
| 297 | - | config.Performance.Profile = ProfileDefault | |||
| 298 | - | case string(ProfileLite): | |||
| 299 | - | config.Performance.Profile = ProfileLite | |||
| 300 | - | case string(ProfileMax): | |||
| 301 | - | config.Performance.Profile = ProfileMax | |||
| 302 | - | case string(ProfileCustom): | |||
| 303 | - | config.Performance.Profile = ProfileCustom | |||
| 304 | - | default: | |||
| 305 | - | config.Performance.Profile = ProfileDefault | |||
| 306 | - | } | |||
| 307 | - | } | |||
| 308 | - | ||||
| 309 | // Get returns the current configuration (thread-safe). | 296 | // Get returns the current configuration (thread-safe). | ||
| 310 | func (m *Manager) Get() *Config { | 297 | func (m *Manager) Get() *Config { | ||
| 311 | m.mu.RLock() | 298 | m.mu.RLock() | ||
M internal/infrastructure/config/loader_test.go +3 -3
| @@ -31,11 +31,11 @@ func TestSetEngineDefaults(t *testing.T) { | |||
| 31 | 31 | assert.Empty(t, mgr.viper.GetString("runtime.prefix")) | |
| 32 | 32 | } | |
| 33 | 33 | ||
| 34 | - | func TestNormalizeConfig_PrivacyCookiePolicy(t *testing.T) { | |
| 34 | + | func TestNormalizeConfig_EngineCookiePolicy(t *testing.T) { | |
| 35 | 35 | cfg := DefaultConfig() | |
| 36 | - | cfg.Privacy.CookiePolicy = CookiePolicy("INVALID") | |
| 36 | + | cfg.Engine.CookiePolicy = CookiePolicy("INVALID") | |
| 37 | 37 | ||
| 38 | 38 | normalizeConfig(cfg) | |
| 39 | 39 | ||
| 40 | - | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Privacy.CookiePolicy) | |
| 40 | + | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Engine.CookiePolicy) | |
| 41 | 41 | } | |
| @@ -31,11 +31,11 @@ func TestSetEngineDefaults(t *testing.T) { | |||||
| 31 | assert.Empty(t, mgr.viper.GetString("runtime.prefix")) | 31 | assert.Empty(t, mgr.viper.GetString("runtime.prefix")) | ||
| 32 | } | 32 | } | ||
| 33 | 33 | ||||
| 34 | - | func TestNormalizeConfig_PrivacyCookiePolicy(t *testing.T) { | 34 | + | func TestNormalizeConfig_EngineCookiePolicy(t *testing.T) { |
| 35 | cfg := DefaultConfig() | 35 | cfg := DefaultConfig() | ||
| 36 | - | cfg.Privacy.CookiePolicy = CookiePolicy("INVALID") | 36 | + | cfg.Engine.CookiePolicy = CookiePolicy("INVALID") |
| 37 | 37 | ||||
| 38 | normalizeConfig(cfg) | 38 | normalizeConfig(cfg) | ||
| 39 | 39 | ||||
| 40 | - | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Privacy.CookiePolicy) | 40 | + | assert.Equal(t, CookiePolicyNoThirdParty, cfg.Engine.CookiePolicy) |
| 41 | } | 41 | } | ||
M internal/infrastructure/config/schema.go +0 -78
| @@ -25,16 +25,8 @@ type Config struct { | |||
| 25 | 25 | Clipboard ClipboardConfig `mapstructure:"clipboard" yaml:"clipboard" toml:"clipboard"` | |
| 26 | 26 | // Omnibox controls the omnibox behavior (initial history display) | |
| 27 | 27 | Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"` | |
| 28 | - | // Rendering controls WebKit, GTK and compositor behavior. | |
| 29 | - | Rendering RenderingConfig `mapstructure:"rendering" yaml:"rendering" toml:"rendering"` | |
| 30 | - | // Privacy controls cookie acceptance and tracking prevention. | |
| 31 | - | Privacy PrivacyConfig `mapstructure:"privacy" yaml:"privacy" toml:"privacy"` | |
| 32 | 28 | // Media controls video playback and hardware acceleration | |
| 33 | 29 | Media MediaConfig `mapstructure:"media" yaml:"media" toml:"media"` | |
| 34 | - | // Runtime configures optional runtime overrides (e.g., /opt prefix for WebKitGTK/GTK). | |
| 35 | - | Runtime RuntimeConfig `mapstructure:"runtime" yaml:"runtime" toml:"runtime"` | |
| 36 | - | // Performance holds internal performance tuning options (not exposed in UI). | |
| 37 | - | Performance PerformanceConfig `mapstructure:"performance" yaml:"performance" toml:"performance"` | |
| 38 | 30 | // Update controls automatic update checking and downloading. | |
| 39 | 31 | Update UpdateConfig `mapstructure:"update" yaml:"update" toml:"update"` | |
| 40 | 32 | // Downloads configures file download behavior. | |
| @@ -43,15 +35,6 @@ type Config struct { | |||
| 43 | 35 | Engine EngineConfig `mapstructure:"engine" toml:"engine" yaml:"engine"` | |
| 44 | 36 | } | |
| 45 | 37 | ||
| 46 | - | // RenderingMode selects GPU vs CPU rendering. | |
| 47 | - | type RenderingMode string | |
| 48 | - | ||
| 49 | - | const ( | |
| 50 | - | RenderingModeAuto RenderingMode = "auto" | |
| 51 | - | RenderingModeGPU RenderingMode = "gpu" | |
| 52 | - | RenderingModeCPU RenderingMode = "cpu" | |
| 53 | - | ) | |
| 54 | - | ||
| 55 | 38 | // CookiePolicy controls cookie acceptance behavior. | |
| 56 | 39 | type CookiePolicy string | |
| 57 | 40 | ||
| @@ -74,60 +57,6 @@ const ( | |||
| 74 | 57 | GSKRendererCairo GSKRendererMode = "cairo" | |
| 75 | 58 | ) | |
| 76 | 59 | ||
| 77 | - | // RenderingConfig controls WebKit and GTK/GSK rendering behavior. | |
| 78 | - | type RenderingConfig struct { | |
| 79 | - | // Mode controls GPU/CPU rendering selection for WebKit (auto, gpu, cpu). | |
| 80 | - | Mode RenderingMode `mapstructure:"mode" yaml:"mode" toml:"mode"` | |
| 81 | - | ||
| 82 | - | // DisableDMABufRenderer disables DMA-BUF accelerated renderer. | |
| 83 | - | // Env: WEBKIT_DISABLE_DMABUF_RENDERER | |
| 84 | - | DisableDMABufRenderer bool `mapstructure:"disable_dmabuf_renderer" yaml:"disable_dmabuf_renderer" toml:"disable_dmabuf_renderer"` | |
| 85 | - | ||
| 86 | - | // ForceCompositingMode forces accelerated compositing. | |
| 87 | - | // Env: WEBKIT_FORCE_COMPOSITING_MODE | |
| 88 | - | ForceCompositingMode bool `mapstructure:"force_compositing_mode" yaml:"force_compositing_mode" toml:"force_compositing_mode"` | |
| 89 | - | ||
| 90 | - | // DisableCompositingMode disables accelerated compositing. | |
| 91 | - | // Env: WEBKIT_DISABLE_COMPOSITING_MODE | |
| 92 | - | DisableCompositingMode bool `mapstructure:"disable_compositing_mode" yaml:"disable_compositing_mode" toml:"disable_compositing_mode"` | |
| 93 | - | ||
| 94 | - | // GSKRenderer overrides GTK Scene Kit renderer selection. | |
| 95 | - | // Env: GSK_RENDERER | |
| 96 | - | GSKRenderer GSKRendererMode `mapstructure:"gsk_renderer" yaml:"gsk_renderer" toml:"gsk_renderer"` | |
| 97 | - | ||
| 98 | - | // DisableMipmaps disables mipmap generation. | |
| 99 | - | // Env: GSK_GPU_DISABLE=mipmap | |
| 100 | - | DisableMipmaps bool `mapstructure:"disable_mipmaps" yaml:"disable_mipmaps" toml:"disable_mipmaps"` | |
| 101 | - | ||
| 102 | - | // PreferGL forces OpenGL over GLES. | |
| 103 | - | // Env: GDK_DEBUG=gl-prefer-gl | |
| 104 | - | PreferGL bool `mapstructure:"prefer_gl" yaml:"prefer_gl" toml:"prefer_gl"` | |
| 105 | - | ||
| 106 | - | // DrawCompositingIndicators shows compositing layer borders and repaint counters. | |
| 107 | - | DrawCompositingIndicators bool `mapstructure:"draw_compositing_indicators" yaml:"draw_compositing_indicators" toml:"draw_compositing_indicators"` //nolint:lll // struct tags exceed lll limit | |
| 108 | - | ||
| 109 | - | // ShowFPS displays WebKit FPS counter. | |
| 110 | - | // Env: WEBKIT_SHOW_FPS | |
| 111 | - | ShowFPS bool `mapstructure:"show_fps" yaml:"show_fps" toml:"show_fps"` | |
| 112 | - | ||
| 113 | - | // SampleMemory enables memory sampling. | |
| 114 | - | // Env: WEBKIT_SAMPLE_MEMORY | |
| 115 | - | SampleMemory bool `mapstructure:"sample_memory" yaml:"sample_memory" toml:"sample_memory"` | |
| 116 | - | ||
| 117 | - | // DebugFrames enables frame timing debug output. | |
| 118 | - | // Env: GDK_DEBUG=frames | |
| 119 | - | DebugFrames bool `mapstructure:"debug_frames" yaml:"debug_frames" toml:"debug_frames"` | |
| 120 | - | } | |
| 121 | - | ||
| 122 | - | // PrivacyConfig controls cookie behavior and tracking prevention. | |
| 123 | - | type PrivacyConfig struct { | |
| 124 | - | // CookiePolicy controls cookie acceptance behavior. | |
| 125 | - | // Values: "always", "no_third_party", "never" | |
| 126 | - | CookiePolicy CookiePolicy `mapstructure:"cookie_policy" yaml:"cookie_policy" toml:"cookie_policy"` | |
| 127 | - | // ITPEnabled enables Intelligent Tracking Prevention. | |
| 128 | - | ITPEnabled bool `mapstructure:"itp_enabled" yaml:"itp_enabled" toml:"itp_enabled"` | |
| 129 | - | } | |
| 130 | - | ||
| 131 | 60 | // HardwareDecodingMode controls video hardware acceleration. | |
| 132 | 61 | type HardwareDecodingMode string | |
| 133 | 62 | ||
| @@ -196,13 +125,6 @@ type MediaConfig struct { | |||
| 196 | 125 | GStreamerDebugLevel int `mapstructure:"gstreamer_debug_level" yaml:"gstreamer_debug_level" toml:"gstreamer_debug_level"` | |
| 197 | 126 | } | |
| 198 | 127 | ||
| 199 | - | // RuntimeConfig holds optional runtime overrides. | |
| 200 | - | type RuntimeConfig struct { | |
| 201 | - | // Prefix points to a custom runtime prefix (e.g., /opt/webkitgtk). | |
| 202 | - | // This is used to influence pkg-config lookup and dynamic library loading. | |
| 203 | - | Prefix string `mapstructure:"prefix" yaml:"prefix" toml:"prefix"` | |
| 204 | - | } | |
| 205 | - | ||
| 206 | 128 | // DatabaseConfig holds database-related configuration. | |
| 207 | 129 | type DatabaseConfig struct { | |
| 208 | 130 | Path string `mapstructure:"path" yaml:"path" toml:"path"` | |
| @@ -25,16 +25,8 @@ type Config struct { | |||||
| 25 | Clipboard ClipboardConfig `mapstructure:"clipboard" yaml:"clipboard" toml:"clipboard"` | 25 | Clipboard ClipboardConfig `mapstructure:"clipboard" yaml:"clipboard" toml:"clipboard"` | ||
| 26 | // Omnibox controls the omnibox behavior (initial history display) | 26 | // Omnibox controls the omnibox behavior (initial history display) | ||
| 27 | Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"` | 27 | Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"` | ||
| 28 | - | // Rendering controls WebKit, GTK and compositor behavior. | |||
| 29 | - | Rendering RenderingConfig `mapstructure:"rendering" yaml:"rendering" toml:"rendering"` | |||
| 30 | - | // Privacy controls cookie acceptance and tracking prevention. | |||
| 31 | - | Privacy PrivacyConfig `mapstructure:"privacy" yaml:"privacy" toml:"privacy"` | |||
| 32 | // Media controls video playback and hardware acceleration | 28 | // Media controls video playback and hardware acceleration | ||
| 33 | Media MediaConfig `mapstructure:"media" yaml:"media" toml:"media"` | 29 | Media MediaConfig `mapstructure:"media" yaml:"media" toml:"media"` | ||
| 34 | - | // Runtime configures optional runtime overrides (e.g., /opt prefix for WebKitGTK/GTK). | |||
| 35 | - | Runtime RuntimeConfig `mapstructure:"runtime" yaml:"runtime" toml:"runtime"` | |||
| 36 | - | // Performance holds internal performance tuning options (not exposed in UI). | |||
| 37 | - | Performance PerformanceConfig `mapstructure:"performance" yaml:"performance" toml:"performance"` | |||
| 38 | // Update controls automatic update checking and downloading. | 30 | // Update controls automatic update checking and downloading. | ||
| 39 | Update UpdateConfig `mapstructure:"update" yaml:"update" toml:"update"` | 31 | Update UpdateConfig `mapstructure:"update" yaml:"update" toml:"update"` | ||
| 40 | // Downloads configures file download behavior. | 32 | // Downloads configures file download behavior. | ||
| @@ -43,15 +35,6 @@ type Config struct { | |||||
| 43 | Engine EngineConfig `mapstructure:"engine" toml:"engine" yaml:"engine"` | 35 | Engine EngineConfig `mapstructure:"engine" toml:"engine" yaml:"engine"` | ||
| 44 | } | 36 | } | ||
| 45 | 37 | ||||
| 46 | - | // RenderingMode selects GPU vs CPU rendering. | |||
| 47 | - | type RenderingMode string | |||
| 48 | - | ||||
| 49 | - | const ( | |||
| 50 | - | RenderingModeAuto RenderingMode = "auto" | |||
| 51 | - | RenderingModeGPU RenderingMode = "gpu" | |||
| 52 | - | RenderingModeCPU RenderingMode = "cpu" | |||
| 53 | - | ) | |||
| 54 | - | ||||
| 55 | // CookiePolicy controls cookie acceptance behavior. | 38 | // CookiePolicy controls cookie acceptance behavior. | ||
| 56 | type CookiePolicy string | 39 | type CookiePolicy string | ||
| 57 | 40 | ||||
| @@ -74,60 +57,6 @@ const ( | |||||
| 74 | GSKRendererCairo GSKRendererMode = "cairo" | 57 | GSKRendererCairo GSKRendererMode = "cairo" | ||
| 75 | ) | 58 | ) | ||
| 76 | 59 | ||||
| 77 | - | // RenderingConfig controls WebKit and GTK/GSK rendering behavior. | |||
| 78 | - | type RenderingConfig struct { | |||
| 79 | - | // Mode controls GPU/CPU rendering selection for WebKit (auto, gpu, cpu). | |||
| 80 | - | Mode RenderingMode `mapstructure:"mode" yaml:"mode" toml:"mode"` | |||
| 81 | - | ||||
| 82 | - | // DisableDMABufRenderer disables DMA-BUF accelerated renderer. | |||
| 83 | - | // Env: WEBKIT_DISABLE_DMABUF_RENDERER | |||
| 84 | - | DisableDMABufRenderer bool `mapstructure:"disable_dmabuf_renderer" yaml:"disable_dmabuf_renderer" toml:"disable_dmabuf_renderer"` | |||
| 85 | - | ||||
| 86 | - | // ForceCompositingMode forces accelerated compositing. | |||
| 87 | - | // Env: WEBKIT_FORCE_COMPOSITING_MODE | |||
| 88 | - | ForceCompositingMode bool `mapstructure:"force_compositing_mode" yaml:"force_compositing_mode" toml:"force_compositing_mode"` | |||
| 89 | - | ||||
| 90 | - | // DisableCompositingMode disables accelerated compositing. | |||
| 91 | - | // Env: WEBKIT_DISABLE_COMPOSITING_MODE | |||
| 92 | - | DisableCompositingMode bool `mapstructure:"disable_compositing_mode" yaml:"disable_compositing_mode" toml:"disable_compositing_mode"` | |||
| 93 | - | ||||
| 94 | - | // GSKRenderer overrides GTK Scene Kit renderer selection. | |||
| 95 | - | // Env: GSK_RENDERER | |||
| 96 | - | GSKRenderer GSKRendererMode `mapstructure:"gsk_renderer" yaml:"gsk_renderer" toml:"gsk_renderer"` | |||
| 97 | - | ||||
| 98 | - | // DisableMipmaps disables mipmap generation. | |||
| 99 | - | // Env: GSK_GPU_DISABLE=mipmap | |||
| 100 | - | DisableMipmaps bool `mapstructure:"disable_mipmaps" yaml:"disable_mipmaps" toml:"disable_mipmaps"` | |||
| 101 | - | ||||
| 102 | - | // PreferGL forces OpenGL over GLES. | |||
| 103 | - | // Env: GDK_DEBUG=gl-prefer-gl | |||
| 104 | - | PreferGL bool `mapstructure:"prefer_gl" yaml:"prefer_gl" toml:"prefer_gl"` | |||
| 105 | - | ||||
| 106 | - | // DrawCompositingIndicators shows compositing layer borders and repaint counters. | |||
| 107 | - | DrawCompositingIndicators bool `mapstructure:"draw_compositing_indicators" yaml:"draw_compositing_indicators" toml:"draw_compositing_indicators"` //nolint:lll // struct tags exceed lll limit | |||
| 108 | - | ||||
| 109 | - | // ShowFPS displays WebKit FPS counter. | |||
| 110 | - | // Env: WEBKIT_SHOW_FPS | |||
| 111 | - | ShowFPS bool `mapstructure:"show_fps" yaml:"show_fps" toml:"show_fps"` | |||
| 112 | - | ||||
| 113 | - | // SampleMemory enables memory sampling. | |||
| 114 | - | // Env: WEBKIT_SAMPLE_MEMORY | |||
| 115 | - | SampleMemory bool `mapstructure:"sample_memory" yaml:"sample_memory" toml:"sample_memory"` | |||
| 116 | - | ||||
| 117 | - | // DebugFrames enables frame timing debug output. | |||
| 118 | - | // Env: GDK_DEBUG=frames | |||
| 119 | - | DebugFrames bool `mapstructure:"debug_frames" yaml:"debug_frames" toml:"debug_frames"` | |||
| 120 | - | } | |||
| 121 | - | ||||
| 122 | - | // PrivacyConfig controls cookie behavior and tracking prevention. | |||
| 123 | - | type PrivacyConfig struct { | |||
| 124 | - | // CookiePolicy controls cookie acceptance behavior. | |||
| 125 | - | // Values: "always", "no_third_party", "never" | |||
| 126 | - | CookiePolicy CookiePolicy `mapstructure:"cookie_policy" yaml:"cookie_policy" toml:"cookie_policy"` | |||
| 127 | - | // ITPEnabled enables Intelligent Tracking Prevention. | |||
| 128 | - | ITPEnabled bool `mapstructure:"itp_enabled" yaml:"itp_enabled" toml:"itp_enabled"` | |||
| 129 | - | } | |||
| 130 | - | ||||
| 131 | // HardwareDecodingMode controls video hardware acceleration. | 60 | // HardwareDecodingMode controls video hardware acceleration. | ||
| 132 | type HardwareDecodingMode string | 61 | type HardwareDecodingMode string | ||
| 133 | 62 | ||||
| @@ -196,13 +125,6 @@ type MediaConfig struct { | |||||
| 196 | GStreamerDebugLevel int `mapstructure:"gstreamer_debug_level" yaml:"gstreamer_debug_level" toml:"gstreamer_debug_level"` | 125 | GStreamerDebugLevel int `mapstructure:"gstreamer_debug_level" yaml:"gstreamer_debug_level" toml:"gstreamer_debug_level"` | ||
| 197 | } | 126 | } | ||
| 198 | 127 | ||||
| 199 | - | // RuntimeConfig holds optional runtime overrides. | |||
| 200 | - | type RuntimeConfig struct { | |||
| 201 | - | // Prefix points to a custom runtime prefix (e.g., /opt/webkitgtk). | |||
| 202 | - | // This is used to influence pkg-config lookup and dynamic library loading. | |||
| 203 | - | Prefix string `mapstructure:"prefix" yaml:"prefix" toml:"prefix"` | |||
| 204 | - | } | |||
| 205 | - | ||||
| 206 | // DatabaseConfig holds database-related configuration. | 128 | // DatabaseConfig holds database-related configuration. | ||
| 207 | type DatabaseConfig struct { | 129 | type DatabaseConfig struct { | ||
| 208 | Path string `mapstructure:"path" yaml:"path" toml:"path"` | 130 | Path string `mapstructure:"path" yaml:"path" toml:"path"` | ||
M internal/infrastructure/config/schema_provider.go +51 -59
| @@ -712,81 +712,73 @@ func (*SchemaProvider) getClipboardKeys(defaults *Config) []entity.ConfigKeyInfo | |||
| 712 | 712 | func (*SchemaProvider) getRenderingKeys(defaults *Config) []entity.ConfigKeyInfo { | |
| 713 | 713 | return []entity.ConfigKeyInfo{ | |
| 714 | 714 | { | |
| 715 | - | Key: "rendering.mode", | |
| 715 | + | Key: "engine.webkit.gsk_renderer", | |
| 716 | 716 | Type: "string", | |
| 717 | - | Default: string(defaults.Rendering.Mode), | |
| 718 | - | Description: "GPU/CPU rendering selection for WebKit", | |
| 719 | - | Values: []string{"auto", "gpu", "cpu"}, | |
| 720 | - | Section: SectionRendering, | |
| 721 | - | }, | |
| 722 | - | { | |
| 723 | - | Key: "rendering.gsk_renderer", | |
| 724 | - | Type: "string", | |
| 725 | - | Default: string(defaults.Rendering.GSKRenderer), | |
| 717 | + | Default: string(defaults.Engine.WebKit.GSKRenderer), | |
| 726 | 718 | Description: "GTK Scene Kit renderer selection", | |
| 727 | 719 | Values: []string{"auto", "opengl", "vulkan", "cairo"}, | |
| 728 | 720 | Section: SectionRendering, | |
| 729 | 721 | }, | |
| 730 | 722 | { | |
| 731 | - | Key: "rendering.disable_dmabuf_renderer", | |
| 723 | + | Key: "engine.webkit.disable_dmabuf_renderer", | |
| 732 | 724 | Type: "bool", | |
| 733 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DisableDMABufRenderer), | |
| 725 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DisableDMABufRenderer), | |
| 734 | 726 | Description: "Disable DMA-BUF accelerated renderer", | |
| 735 | 727 | Section: SectionRendering, | |
| 736 | 728 | }, | |
| 737 | 729 | { | |
| 738 | - | Key: "rendering.force_compositing_mode", | |
| 730 | + | Key: "engine.webkit.force_compositing_mode", | |
| 739 | 731 | Type: "bool", | |
| 740 | - | Default: fmt.Sprintf("%t", defaults.Rendering.ForceCompositingMode), | |
| 732 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.ForceCompositingMode), | |
| 741 | 733 | Description: "Force accelerated compositing", | |
| 742 | 734 | Section: SectionRendering, | |
| 743 | 735 | }, | |
| 744 | 736 | { | |
| 745 | - | Key: "rendering.disable_compositing_mode", | |
| 737 | + | Key: "engine.webkit.disable_compositing_mode", | |
| 746 | 738 | Type: "bool", | |
| 747 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DisableCompositingMode), | |
| 739 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DisableCompositingMode), | |
| 748 | 740 | Description: "Disable accelerated compositing", | |
| 749 | 741 | Section: SectionRendering, | |
| 750 | 742 | }, | |
| 751 | 743 | { | |
| 752 | - | Key: "rendering.disable_mipmaps", | |
| 744 | + | Key: "engine.webkit.disable_mipmaps", | |
| 753 | 745 | Type: "bool", | |
| 754 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DisableMipmaps), | |
| 746 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DisableMipmaps), | |
| 755 | 747 | Description: "Disable mipmap generation", | |
| 756 | 748 | Section: SectionRendering, | |
| 757 | 749 | }, | |
| 758 | 750 | { | |
| 759 | - | Key: "rendering.prefer_gl", | |
| 751 | + | Key: "engine.webkit.prefer_gl", | |
| 760 | 752 | Type: "bool", | |
| 761 | - | Default: fmt.Sprintf("%t", defaults.Rendering.PreferGL), | |
| 753 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.PreferGL), | |
| 762 | 754 | Description: "Force OpenGL over GLES", | |
| 763 | 755 | Section: SectionRendering, | |
| 764 | 756 | }, | |
| 765 | 757 | { | |
| 766 | - | Key: "rendering.draw_compositing_indicators", | |
| 758 | + | Key: "engine.webkit.draw_compositing_indicators", | |
| 767 | 759 | Type: "bool", | |
| 768 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DrawCompositingIndicators), | |
| 760 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DrawCompositingIndicators), | |
| 769 | 761 | Description: "Show compositing layer borders", | |
| 770 | 762 | Section: SectionRendering, | |
| 771 | 763 | }, | |
| 772 | 764 | { | |
| 773 | - | Key: "rendering.show_fps", | |
| 765 | + | Key: "engine.webkit.show_fps", | |
| 774 | 766 | Type: "bool", | |
| 775 | - | Default: fmt.Sprintf("%t", defaults.Rendering.ShowFPS), | |
| 767 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.ShowFPS), | |
| 776 | 768 | Description: "Display WebKit FPS counter", | |
| 777 | 769 | Section: SectionRendering, | |
| 778 | 770 | }, | |
| 779 | 771 | { | |
| 780 | - | Key: "rendering.sample_memory", | |
| 772 | + | Key: "engine.webkit.sample_memory", | |
| 781 | 773 | Type: "bool", | |
| 782 | - | Default: fmt.Sprintf("%t", defaults.Rendering.SampleMemory), | |
| 774 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.SampleMemory), | |
| 783 | 775 | Description: "Enable memory sampling", | |
| 784 | 776 | Section: SectionRendering, | |
| 785 | 777 | }, | |
| 786 | 778 | { | |
| 787 | - | Key: "rendering.debug_frames", | |
| 779 | + | Key: "engine.webkit.debug_frames", | |
| 788 | 780 | Type: "bool", | |
| 789 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DebugFrames), | |
| 781 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DebugFrames), | |
| 790 | 782 | Description: "Enable frame timing debug output", | |
| 791 | 783 | Section: SectionRendering, | |
| 792 | 784 | }, | |
| @@ -884,112 +876,112 @@ func (*SchemaProvider) getDebugKeys(defaults *Config) []entity.ConfigKeyInfo { | |||
| 884 | 876 | func (*SchemaProvider) getPerformanceKeys(defaults *Config) []entity.ConfigKeyInfo { | |
| 885 | 877 | return []entity.ConfigKeyInfo{ | |
| 886 | 878 | { | |
| 887 | - | Key: "performance.profile", | |
| 879 | + | Key: "engine.profile", | |
| 888 | 880 | Type: "string", | |
| 889 | - | Default: string(defaults.Performance.Profile), | |
| 881 | + | Default: string(defaults.Engine.Profile), | |
| 890 | 882 | Description: "Performance profile preset (custom enables manual tuning)", | |
| 891 | 883 | Values: []string{"default", "lite", "max", "custom"}, | |
| 892 | 884 | Section: SectionPerformance, | |
| 893 | 885 | }, | |
| 894 | 886 | { | |
| 895 | - | Key: "performance.zoom_cache_size", | |
| 887 | + | Key: "engine.zoom_cache_size", | |
| 896 | 888 | Type: "int", | |
| 897 | - | Default: fmt.Sprintf("%d", defaults.Performance.ZoomCacheSize), | |
| 889 | + | Default: fmt.Sprintf("%d", defaults.Engine.ZoomCacheSize), | |
| 898 | 890 | Description: "Number of domain zoom levels to cache", | |
| 899 | 891 | Range: ">=0", | |
| 900 | 892 | Section: SectionPerformance, | |
| 901 | 893 | }, | |
| 902 | 894 | { | |
| 903 | - | Key: "performance.webview_pool_prewarm_count", | |
| 895 | + | Key: "engine.pool_prewarm_count", | |
| 904 | 896 | Type: "int", | |
| 905 | - | Default: fmt.Sprintf("%d", defaults.Performance.WebViewPoolPrewarmCount), | |
| 897 | + | Default: fmt.Sprintf("%d", defaults.Engine.PoolPrewarmCount), | |
| 906 | 898 | Description: "WebViews to pre-create at startup", | |
| 907 | 899 | Range: ">=0", | |
| 908 | 900 | Section: SectionPerformance, | |
| 909 | 901 | }, | |
| 910 | 902 | { | |
| 911 | - | Key: "performance.skia_cpu_painting_threads", | |
| 903 | + | Key: "engine.webkit.skia_cpu_painting_threads", | |
| 912 | 904 | Type: "int", | |
| 913 | - | Default: fmt.Sprintf("%d", defaults.Performance.SkiaCPUPaintingThreads), | |
| 905 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.SkiaCPUPaintingThreads), | |
| 914 | 906 | Description: "Skia CPU rendering threads (0=unset, custom profile only)", | |
| 915 | 907 | Range: ">=0", | |
| 916 | 908 | Section: SectionPerformance, | |
| 917 | 909 | }, | |
| 918 | 910 | { | |
| 919 | - | Key: "performance.skia_gpu_painting_threads", | |
| 911 | + | Key: "engine.webkit.skia_gpu_painting_threads", | |
| 920 | 912 | Type: "int", | |
| 921 | - | Default: fmt.Sprintf("%d", defaults.Performance.SkiaGPUPaintingThreads), | |
| 913 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.SkiaGPUPaintingThreads), | |
| 922 | 914 | Description: "Skia GPU rendering threads (-1=unset, 0=disable, custom profile only)", | |
| 923 | 915 | Range: ">=-1", | |
| 924 | 916 | Section: SectionPerformance, | |
| 925 | 917 | }, | |
| 926 | 918 | { | |
| 927 | - | Key: "performance.skia_enable_cpu_rendering", | |
| 919 | + | Key: "engine.webkit.skia_enable_cpu_rendering", | |
| 928 | 920 | Type: "bool", | |
| 929 | - | Default: fmt.Sprintf("%t", defaults.Performance.SkiaEnableCPURendering), | |
| 921 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.SkiaEnableCPURendering), | |
| 930 | 922 | Description: "Force CPU rendering (custom profile only)", | |
| 931 | 923 | Section: SectionPerformance, | |
| 932 | 924 | }, | |
| 933 | 925 | { | |
| 934 | - | Key: "performance.web_process_memory_limit_mb", | |
| 926 | + | Key: "engine.webkit.web_process_memory_limit_mb", | |
| 935 | 927 | Type: "int", | |
| 936 | - | Default: fmt.Sprintf("%d", defaults.Performance.WebProcessMemoryLimitMB), | |
| 928 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.WebProcessMemoryLimitMB), | |
| 937 | 929 | Description: "Web process memory limit in MB (0=unset, custom profile only)", | |
| 938 | 930 | Range: ">=0", | |
| 939 | 931 | Section: SectionPerformance, | |
| 940 | 932 | }, | |
| 941 | 933 | { | |
| 942 | - | Key: "performance.web_process_memory_poll_interval_sec", | |
| 934 | + | Key: "engine.webkit.web_process_memory_poll_interval_sec", | |
| 943 | 935 | Type: "float64", | |
| 944 | - | Default: fmt.Sprintf("%.1f", defaults.Performance.WebProcessMemoryPollIntervalSec), | |
| 936 | + | Default: fmt.Sprintf("%.1f", defaults.Engine.WebKit.WebProcessMemoryPollIntervalSec), | |
| 945 | 937 | Description: "Memory check interval in seconds (0=default 30s, custom profile only)", | |
| 946 | 938 | Range: ">=0", | |
| 947 | 939 | Section: SectionPerformance, | |
| 948 | 940 | }, | |
| 949 | 941 | { | |
| 950 | - | Key: "performance.web_process_memory_conservative_threshold", | |
| 942 | + | Key: "engine.webkit.web_process_memory_conservative_threshold", | |
| 951 | 943 | Type: "float64", | |
| 952 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.WebProcessMemoryConservativeThreshold), | |
| 944 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.WebProcessMemoryConservativeThreshold), | |
| 953 | 945 | Description: "Conservative memory cleanup threshold (0-1, custom profile only)", | |
| 954 | 946 | Range: "0-1", | |
| 955 | 947 | Section: SectionPerformance, | |
| 956 | 948 | }, | |
| 957 | 949 | { | |
| 958 | - | Key: "performance.web_process_memory_strict_threshold", | |
| 950 | + | Key: "engine.webkit.web_process_memory_strict_threshold", | |
| 959 | 951 | Type: "float64", | |
| 960 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.WebProcessMemoryStrictThreshold), | |
| 952 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.WebProcessMemoryStrictThreshold), | |
| 961 | 953 | Description: "Strict memory cleanup threshold (0-1, custom profile only)", | |
| 962 | 954 | Range: "0-1", | |
| 963 | 955 | Section: SectionPerformance, | |
| 964 | 956 | }, | |
| 965 | 957 | { | |
| 966 | - | Key: "performance.network_process_memory_limit_mb", | |
| 958 | + | Key: "engine.webkit.network_process_memory_limit_mb", | |
| 967 | 959 | Type: "int", | |
| 968 | - | Default: fmt.Sprintf("%d", defaults.Performance.NetworkProcessMemoryLimitMB), | |
| 960 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.NetworkProcessMemoryLimitMB), | |
| 969 | 961 | Description: "Network process memory limit in MB (0=unset, custom profile only)", | |
| 970 | 962 | Range: ">=0", | |
| 971 | 963 | Section: SectionPerformance, | |
| 972 | 964 | }, | |
| 973 | 965 | { | |
| 974 | - | Key: "performance.network_process_memory_poll_interval_sec", | |
| 966 | + | Key: "engine.webkit.network_process_memory_poll_interval_sec", | |
| 975 | 967 | Type: "float64", | |
| 976 | - | Default: fmt.Sprintf("%.1f", defaults.Performance.NetworkProcessMemoryPollIntervalSec), | |
| 968 | + | Default: fmt.Sprintf("%.1f", defaults.Engine.WebKit.NetworkProcessMemoryPollIntervalSec), | |
| 977 | 969 | Description: "Network memory check interval in seconds (custom profile only)", | |
| 978 | 970 | Range: ">=0", | |
| 979 | 971 | Section: SectionPerformance, | |
| 980 | 972 | }, | |
| 981 | 973 | { | |
| 982 | - | Key: "performance.network_process_memory_conservative_threshold", | |
| 974 | + | Key: "engine.webkit.network_process_memory_conservative_threshold", | |
| 983 | 975 | Type: "float64", | |
| 984 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.NetworkProcessMemoryConservativeThreshold), | |
| 976 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.NetworkProcessMemoryConservativeThreshold), | |
| 985 | 977 | Description: "Network conservative memory threshold (0-1, custom profile only)", | |
| 986 | 978 | Range: "0-1", | |
| 987 | 979 | Section: SectionPerformance, | |
| 988 | 980 | }, | |
| 989 | 981 | { | |
| 990 | - | Key: "performance.network_process_memory_strict_threshold", | |
| 982 | + | Key: "engine.webkit.network_process_memory_strict_threshold", | |
| 991 | 983 | Type: "float64", | |
| 992 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.NetworkProcessMemoryStrictThreshold), | |
| 984 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.NetworkProcessMemoryStrictThreshold), | |
| 993 | 985 | Description: "Network strict memory threshold (0-1, custom profile only)", | |
| 994 | 986 | Range: "0-1", | |
| 995 | 987 | Section: SectionPerformance, | |
| @@ -997,12 +989,12 @@ func (*SchemaProvider) getPerformanceKeys(defaults *Config) []entity.ConfigKeyIn | |||
| 997 | 989 | } | |
| 998 | 990 | } | |
| 999 | 991 | ||
| 1000 | - | func (*SchemaProvider) getRuntimeKeys(_ *Config) []entity.ConfigKeyInfo { | |
| 992 | + | func (*SchemaProvider) getRuntimeKeys(defaults *Config) []entity.ConfigKeyInfo { | |
| 1001 | 993 | return []entity.ConfigKeyInfo{ | |
| 1002 | 994 | { | |
| 1003 | - | Key: "runtime.prefix", | |
| 995 | + | Key: "engine.webkit.prefix", | |
| 1004 | 996 | Type: "string", | |
| 1005 | - | Default: "(empty)", | |
| 997 | + | Default: defaults.Engine.WebKit.Prefix, | |
| 1006 | 998 | Description: "Custom runtime prefix for WebKitGTK/GTK", | |
| 1007 | 999 | Section: SectionRuntime, | |
| 1008 | 1000 | }, | |
| @@ -712,81 +712,73 @@ func (*SchemaProvider) getClipboardKeys(defaults *Config) []entity.ConfigKeyInfo | |||||
| 712 | func (*SchemaProvider) getRenderingKeys(defaults *Config) []entity.ConfigKeyInfo { | 712 | func (*SchemaProvider) getRenderingKeys(defaults *Config) []entity.ConfigKeyInfo { | ||
| 713 | return []entity.ConfigKeyInfo{ | 713 | return []entity.ConfigKeyInfo{ | ||
| 714 | { | 714 | { | ||
| 715 | - | Key: "rendering.mode", | 715 | + | Key: "engine.webkit.gsk_renderer", |
| 716 | Type: "string", | 716 | Type: "string", | ||
| 717 | - | Default: string(defaults.Rendering.Mode), | 717 | + | Default: string(defaults.Engine.WebKit.GSKRenderer), |
| 718 | - | Description: "GPU/CPU rendering selection for WebKit", | |||
| 719 | - | Values: []string{"auto", "gpu", "cpu"}, | |||
| 720 | - | Section: SectionRendering, | |||
| 721 | - | }, | |||
| 722 | - | { | |||
| 723 | - | Key: "rendering.gsk_renderer", | |||
| 724 | - | Type: "string", | |||
| 725 | - | Default: string(defaults.Rendering.GSKRenderer), | |||
| 726 | Description: "GTK Scene Kit renderer selection", | 718 | Description: "GTK Scene Kit renderer selection", | ||
| 727 | Values: []string{"auto", "opengl", "vulkan", "cairo"}, | 719 | Values: []string{"auto", "opengl", "vulkan", "cairo"}, | ||
| 728 | Section: SectionRendering, | 720 | Section: SectionRendering, | ||
| 729 | }, | 721 | }, | ||
| 730 | { | 722 | { | ||
| 731 | - | Key: "rendering.disable_dmabuf_renderer", | 723 | + | Key: "engine.webkit.disable_dmabuf_renderer", |
| 732 | Type: "bool", | 724 | Type: "bool", | ||
| 733 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DisableDMABufRenderer), | 725 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DisableDMABufRenderer), |
| 734 | Description: "Disable DMA-BUF accelerated renderer", | 726 | Description: "Disable DMA-BUF accelerated renderer", | ||
| 735 | Section: SectionRendering, | 727 | Section: SectionRendering, | ||
| 736 | }, | 728 | }, | ||
| 737 | { | 729 | { | ||
| 738 | - | Key: "rendering.force_compositing_mode", | 730 | + | Key: "engine.webkit.force_compositing_mode", |
| 739 | Type: "bool", | 731 | Type: "bool", | ||
| 740 | - | Default: fmt.Sprintf("%t", defaults.Rendering.ForceCompositingMode), | 732 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.ForceCompositingMode), |
| 741 | Description: "Force accelerated compositing", | 733 | Description: "Force accelerated compositing", | ||
| 742 | Section: SectionRendering, | 734 | Section: SectionRendering, | ||
| 743 | }, | 735 | }, | ||
| 744 | { | 736 | { | ||
| 745 | - | Key: "rendering.disable_compositing_mode", | 737 | + | Key: "engine.webkit.disable_compositing_mode", |
| 746 | Type: "bool", | 738 | Type: "bool", | ||
| 747 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DisableCompositingMode), | 739 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DisableCompositingMode), |
| 748 | Description: "Disable accelerated compositing", | 740 | Description: "Disable accelerated compositing", | ||
| 749 | Section: SectionRendering, | 741 | Section: SectionRendering, | ||
| 750 | }, | 742 | }, | ||
| 751 | { | 743 | { | ||
| 752 | - | Key: "rendering.disable_mipmaps", | 744 | + | Key: "engine.webkit.disable_mipmaps", |
| 753 | Type: "bool", | 745 | Type: "bool", | ||
| 754 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DisableMipmaps), | 746 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DisableMipmaps), |
| 755 | Description: "Disable mipmap generation", | 747 | Description: "Disable mipmap generation", | ||
| 756 | Section: SectionRendering, | 748 | Section: SectionRendering, | ||
| 757 | }, | 749 | }, | ||
| 758 | { | 750 | { | ||
| 759 | - | Key: "rendering.prefer_gl", | 751 | + | Key: "engine.webkit.prefer_gl", |
| 760 | Type: "bool", | 752 | Type: "bool", | ||
| 761 | - | Default: fmt.Sprintf("%t", defaults.Rendering.PreferGL), | 753 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.PreferGL), |
| 762 | Description: "Force OpenGL over GLES", | 754 | Description: "Force OpenGL over GLES", | ||
| 763 | Section: SectionRendering, | 755 | Section: SectionRendering, | ||
| 764 | }, | 756 | }, | ||
| 765 | { | 757 | { | ||
| 766 | - | Key: "rendering.draw_compositing_indicators", | 758 | + | Key: "engine.webkit.draw_compositing_indicators", |
| 767 | Type: "bool", | 759 | Type: "bool", | ||
| 768 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DrawCompositingIndicators), | 760 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DrawCompositingIndicators), |
| 769 | Description: "Show compositing layer borders", | 761 | Description: "Show compositing layer borders", | ||
| 770 | Section: SectionRendering, | 762 | Section: SectionRendering, | ||
| 771 | }, | 763 | }, | ||
| 772 | { | 764 | { | ||
| 773 | - | Key: "rendering.show_fps", | 765 | + | Key: "engine.webkit.show_fps", |
| 774 | Type: "bool", | 766 | Type: "bool", | ||
| 775 | - | Default: fmt.Sprintf("%t", defaults.Rendering.ShowFPS), | 767 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.ShowFPS), |
| 776 | Description: "Display WebKit FPS counter", | 768 | Description: "Display WebKit FPS counter", | ||
| 777 | Section: SectionRendering, | 769 | Section: SectionRendering, | ||
| 778 | }, | 770 | }, | ||
| 779 | { | 771 | { | ||
| 780 | - | Key: "rendering.sample_memory", | 772 | + | Key: "engine.webkit.sample_memory", |
| 781 | Type: "bool", | 773 | Type: "bool", | ||
| 782 | - | Default: fmt.Sprintf("%t", defaults.Rendering.SampleMemory), | 774 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.SampleMemory), |
| 783 | Description: "Enable memory sampling", | 775 | Description: "Enable memory sampling", | ||
| 784 | Section: SectionRendering, | 776 | Section: SectionRendering, | ||
| 785 | }, | 777 | }, | ||
| 786 | { | 778 | { | ||
| 787 | - | Key: "rendering.debug_frames", | 779 | + | Key: "engine.webkit.debug_frames", |
| 788 | Type: "bool", | 780 | Type: "bool", | ||
| 789 | - | Default: fmt.Sprintf("%t", defaults.Rendering.DebugFrames), | 781 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.DebugFrames), |
| 790 | Description: "Enable frame timing debug output", | 782 | Description: "Enable frame timing debug output", | ||
| 791 | Section: SectionRendering, | 783 | Section: SectionRendering, | ||
| 792 | }, | 784 | }, | ||
| @@ -884,112 +876,112 @@ func (*SchemaProvider) getDebugKeys(defaults *Config) []entity.ConfigKeyInfo { | |||||
| 884 | func (*SchemaProvider) getPerformanceKeys(defaults *Config) []entity.ConfigKeyInfo { | 876 | func (*SchemaProvider) getPerformanceKeys(defaults *Config) []entity.ConfigKeyInfo { | ||
| 885 | return []entity.ConfigKeyInfo{ | 877 | return []entity.ConfigKeyInfo{ | ||
| 886 | { | 878 | { | ||
| 887 | - | Key: "performance.profile", | 879 | + | Key: "engine.profile", |
| 888 | Type: "string", | 880 | Type: "string", | ||
| 889 | - | Default: string(defaults.Performance.Profile), | 881 | + | Default: string(defaults.Engine.Profile), |
| 890 | Description: "Performance profile preset (custom enables manual tuning)", | 882 | Description: "Performance profile preset (custom enables manual tuning)", | ||
| 891 | Values: []string{"default", "lite", "max", "custom"}, | 883 | Values: []string{"default", "lite", "max", "custom"}, | ||
| 892 | Section: SectionPerformance, | 884 | Section: SectionPerformance, | ||
| 893 | }, | 885 | }, | ||
| 894 | { | 886 | { | ||
| 895 | - | Key: "performance.zoom_cache_size", | 887 | + | Key: "engine.zoom_cache_size", |
| 896 | Type: "int", | 888 | Type: "int", | ||
| 897 | - | Default: fmt.Sprintf("%d", defaults.Performance.ZoomCacheSize), | 889 | + | Default: fmt.Sprintf("%d", defaults.Engine.ZoomCacheSize), |
| 898 | Description: "Number of domain zoom levels to cache", | 890 | Description: "Number of domain zoom levels to cache", | ||
| 899 | Range: ">=0", | 891 | Range: ">=0", | ||
| 900 | Section: SectionPerformance, | 892 | Section: SectionPerformance, | ||
| 901 | }, | 893 | }, | ||
| 902 | { | 894 | { | ||
| 903 | - | Key: "performance.webview_pool_prewarm_count", | 895 | + | Key: "engine.pool_prewarm_count", |
| 904 | Type: "int", | 896 | Type: "int", | ||
| 905 | - | Default: fmt.Sprintf("%d", defaults.Performance.WebViewPoolPrewarmCount), | 897 | + | Default: fmt.Sprintf("%d", defaults.Engine.PoolPrewarmCount), |
| 906 | Description: "WebViews to pre-create at startup", | 898 | Description: "WebViews to pre-create at startup", | ||
| 907 | Range: ">=0", | 899 | Range: ">=0", | ||
| 908 | Section: SectionPerformance, | 900 | Section: SectionPerformance, | ||
| 909 | }, | 901 | }, | ||
| 910 | { | 902 | { | ||
| 911 | - | Key: "performance.skia_cpu_painting_threads", | 903 | + | Key: "engine.webkit.skia_cpu_painting_threads", |
| 912 | Type: "int", | 904 | Type: "int", | ||
| 913 | - | Default: fmt.Sprintf("%d", defaults.Performance.SkiaCPUPaintingThreads), | 905 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.SkiaCPUPaintingThreads), |
| 914 | Description: "Skia CPU rendering threads (0=unset, custom profile only)", | 906 | Description: "Skia CPU rendering threads (0=unset, custom profile only)", | ||
| 915 | Range: ">=0", | 907 | Range: ">=0", | ||
| 916 | Section: SectionPerformance, | 908 | Section: SectionPerformance, | ||
| 917 | }, | 909 | }, | ||
| 918 | { | 910 | { | ||
| 919 | - | Key: "performance.skia_gpu_painting_threads", | 911 | + | Key: "engine.webkit.skia_gpu_painting_threads", |
| 920 | Type: "int", | 912 | Type: "int", | ||
| 921 | - | Default: fmt.Sprintf("%d", defaults.Performance.SkiaGPUPaintingThreads), | 913 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.SkiaGPUPaintingThreads), |
| 922 | Description: "Skia GPU rendering threads (-1=unset, 0=disable, custom profile only)", | 914 | Description: "Skia GPU rendering threads (-1=unset, 0=disable, custom profile only)", | ||
| 923 | Range: ">=-1", | 915 | Range: ">=-1", | ||
| 924 | Section: SectionPerformance, | 916 | Section: SectionPerformance, | ||
| 925 | }, | 917 | }, | ||
| 926 | { | 918 | { | ||
| 927 | - | Key: "performance.skia_enable_cpu_rendering", | 919 | + | Key: "engine.webkit.skia_enable_cpu_rendering", |
| 928 | Type: "bool", | 920 | Type: "bool", | ||
| 929 | - | Default: fmt.Sprintf("%t", defaults.Performance.SkiaEnableCPURendering), | 921 | + | Default: fmt.Sprintf("%t", defaults.Engine.WebKit.SkiaEnableCPURendering), |
| 930 | Description: "Force CPU rendering (custom profile only)", | 922 | Description: "Force CPU rendering (custom profile only)", | ||
| 931 | Section: SectionPerformance, | 923 | Section: SectionPerformance, | ||
| 932 | }, | 924 | }, | ||
| 933 | { | 925 | { | ||
| 934 | - | Key: "performance.web_process_memory_limit_mb", | 926 | + | Key: "engine.webkit.web_process_memory_limit_mb", |
| 935 | Type: "int", | 927 | Type: "int", | ||
| 936 | - | Default: fmt.Sprintf("%d", defaults.Performance.WebProcessMemoryLimitMB), | 928 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.WebProcessMemoryLimitMB), |
| 937 | Description: "Web process memory limit in MB (0=unset, custom profile only)", | 929 | Description: "Web process memory limit in MB (0=unset, custom profile only)", | ||
| 938 | Range: ">=0", | 930 | Range: ">=0", | ||
| 939 | Section: SectionPerformance, | 931 | Section: SectionPerformance, | ||
| 940 | }, | 932 | }, | ||
| 941 | { | 933 | { | ||
| 942 | - | Key: "performance.web_process_memory_poll_interval_sec", | 934 | + | Key: "engine.webkit.web_process_memory_poll_interval_sec", |
| 943 | Type: "float64", | 935 | Type: "float64", | ||
| 944 | - | Default: fmt.Sprintf("%.1f", defaults.Performance.WebProcessMemoryPollIntervalSec), | 936 | + | Default: fmt.Sprintf("%.1f", defaults.Engine.WebKit.WebProcessMemoryPollIntervalSec), |
| 945 | Description: "Memory check interval in seconds (0=default 30s, custom profile only)", | 937 | Description: "Memory check interval in seconds (0=default 30s, custom profile only)", | ||
| 946 | Range: ">=0", | 938 | Range: ">=0", | ||
| 947 | Section: SectionPerformance, | 939 | Section: SectionPerformance, | ||
| 948 | }, | 940 | }, | ||
| 949 | { | 941 | { | ||
| 950 | - | Key: "performance.web_process_memory_conservative_threshold", | 942 | + | Key: "engine.webkit.web_process_memory_conservative_threshold", |
| 951 | Type: "float64", | 943 | Type: "float64", | ||
| 952 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.WebProcessMemoryConservativeThreshold), | 944 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.WebProcessMemoryConservativeThreshold), |
| 953 | Description: "Conservative memory cleanup threshold (0-1, custom profile only)", | 945 | Description: "Conservative memory cleanup threshold (0-1, custom profile only)", | ||
| 954 | Range: "0-1", | 946 | Range: "0-1", | ||
| 955 | Section: SectionPerformance, | 947 | Section: SectionPerformance, | ||
| 956 | }, | 948 | }, | ||
| 957 | { | 949 | { | ||
| 958 | - | Key: "performance.web_process_memory_strict_threshold", | 950 | + | Key: "engine.webkit.web_process_memory_strict_threshold", |
| 959 | Type: "float64", | 951 | Type: "float64", | ||
| 960 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.WebProcessMemoryStrictThreshold), | 952 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.WebProcessMemoryStrictThreshold), |
| 961 | Description: "Strict memory cleanup threshold (0-1, custom profile only)", | 953 | Description: "Strict memory cleanup threshold (0-1, custom profile only)", | ||
| 962 | Range: "0-1", | 954 | Range: "0-1", | ||
| 963 | Section: SectionPerformance, | 955 | Section: SectionPerformance, | ||
| 964 | }, | 956 | }, | ||
| 965 | { | 957 | { | ||
| 966 | - | Key: "performance.network_process_memory_limit_mb", | 958 | + | Key: "engine.webkit.network_process_memory_limit_mb", |
| 967 | Type: "int", | 959 | Type: "int", | ||
| 968 | - | Default: fmt.Sprintf("%d", defaults.Performance.NetworkProcessMemoryLimitMB), | 960 | + | Default: fmt.Sprintf("%d", defaults.Engine.WebKit.NetworkProcessMemoryLimitMB), |
| 969 | Description: "Network process memory limit in MB (0=unset, custom profile only)", | 961 | Description: "Network process memory limit in MB (0=unset, custom profile only)", | ||
| 970 | Range: ">=0", | 962 | Range: ">=0", | ||
| 971 | Section: SectionPerformance, | 963 | Section: SectionPerformance, | ||
| 972 | }, | 964 | }, | ||
| 973 | { | 965 | { | ||
| 974 | - | Key: "performance.network_process_memory_poll_interval_sec", | 966 | + | Key: "engine.webkit.network_process_memory_poll_interval_sec", |
| 975 | Type: "float64", | 967 | Type: "float64", | ||
| 976 | - | Default: fmt.Sprintf("%.1f", defaults.Performance.NetworkProcessMemoryPollIntervalSec), | 968 | + | Default: fmt.Sprintf("%.1f", defaults.Engine.WebKit.NetworkProcessMemoryPollIntervalSec), |
| 977 | Description: "Network memory check interval in seconds (custom profile only)", | 969 | Description: "Network memory check interval in seconds (custom profile only)", | ||
| 978 | Range: ">=0", | 970 | Range: ">=0", | ||
| 979 | Section: SectionPerformance, | 971 | Section: SectionPerformance, | ||
| 980 | }, | 972 | }, | ||
| 981 | { | 973 | { | ||
| 982 | - | Key: "performance.network_process_memory_conservative_threshold", | 974 | + | Key: "engine.webkit.network_process_memory_conservative_threshold", |
| 983 | Type: "float64", | 975 | Type: "float64", | ||
| 984 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.NetworkProcessMemoryConservativeThreshold), | 976 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.NetworkProcessMemoryConservativeThreshold), |
| 985 | Description: "Network conservative memory threshold (0-1, custom profile only)", | 977 | Description: "Network conservative memory threshold (0-1, custom profile only)", | ||
| 986 | Range: "0-1", | 978 | Range: "0-1", | ||
| 987 | Section: SectionPerformance, | 979 | Section: SectionPerformance, | ||
| 988 | }, | 980 | }, | ||
| 989 | { | 981 | { | ||
| 990 | - | Key: "performance.network_process_memory_strict_threshold", | 982 | + | Key: "engine.webkit.network_process_memory_strict_threshold", |
| 991 | Type: "float64", | 983 | Type: "float64", | ||
| 992 | - | Default: fmt.Sprintf("%.2f", defaults.Performance.NetworkProcessMemoryStrictThreshold), | 984 | + | Default: fmt.Sprintf("%.2f", defaults.Engine.WebKit.NetworkProcessMemoryStrictThreshold), |
| 993 | Description: "Network strict memory threshold (0-1, custom profile only)", | 985 | Description: "Network strict memory threshold (0-1, custom profile only)", | ||
| 994 | Range: "0-1", | 986 | Range: "0-1", | ||
| 995 | Section: SectionPerformance, | 987 | Section: SectionPerformance, | ||
| @@ -997,12 +989,12 @@ func (*SchemaProvider) getPerformanceKeys(defaults *Config) []entity.ConfigKeyIn | |||||
| 997 | } | 989 | } | ||
| 998 | } | 990 | } | ||
| 999 | 991 | ||||
| 1000 | - | func (*SchemaProvider) getRuntimeKeys(_ *Config) []entity.ConfigKeyInfo { | 992 | + | func (*SchemaProvider) getRuntimeKeys(defaults *Config) []entity.ConfigKeyInfo { |
| 1001 | return []entity.ConfigKeyInfo{ | 993 | return []entity.ConfigKeyInfo{ | ||
| 1002 | { | 994 | { | ||
| 1003 | - | Key: "runtime.prefix", | 995 | + | Key: "engine.webkit.prefix", |
| 1004 | Type: "string", | 996 | Type: "string", | ||
| 1005 | - | Default: "(empty)", | 997 | + | Default: defaults.Engine.WebKit.Prefix, |
| 1006 | Description: "Custom runtime prefix for WebKitGTK/GTK", | 998 | Description: "Custom runtime prefix for WebKitGTK/GTK", | ||
| 1007 | Section: SectionRuntime, | 999 | Section: SectionRuntime, | ||
| 1008 | }, | 1000 | }, | ||
M internal/infrastructure/config/validation.go +21 -29
| @@ -379,30 +379,21 @@ func validateOmnibox(config *Config) []string { | |||
| 379 | 379 | func validateRendering(config *Config) []string { | |
| 380 | 380 | var validationErrors []string | |
| 381 | 381 | ||
| 382 | - | switch config.Rendering.Mode { | |
| 383 | - | case RenderingModeAuto, RenderingModeGPU, RenderingModeCPU, "": | |
| 384 | - | default: | |
| 385 | - | validationErrors = append( | |
| 386 | - | validationErrors, | |
| 387 | - | fmt.Sprintf("rendering.mode must be one of: auto, gpu, cpu (got: %s)", config.Rendering.Mode), | |
| 388 | - | ) | |
| 389 | - | } | |
| 390 | - | ||
| 391 | - | switch config.Rendering.GSKRenderer { | |
| 382 | + | switch config.Engine.WebKit.GSKRenderer { | |
| 392 | 383 | case GSKRendererAuto, GSKRendererOpenGL, GSKRendererVulkan, GSKRendererCairo, "": | |
| 393 | 384 | default: | |
| 394 | 385 | validationErrors = append( | |
| 395 | 386 | validationErrors, | |
| 396 | 387 | fmt.Sprintf( | |
| 397 | - | "rendering.gsk_renderer must be one of: auto, opengl, vulkan, cairo (got: %s)", | |
| 398 | - | config.Rendering.GSKRenderer, | |
| 388 | + | "engine.webkit.gsk_renderer must be one of: auto, opengl, vulkan, cairo (got: %s)", | |
| 389 | + | config.Engine.WebKit.GSKRenderer, | |
| 399 | 390 | ), | |
| 400 | 391 | ) | |
| 401 | 392 | } | |
| 402 | 393 | ||
| 403 | - | if config.Rendering.ForceCompositingMode && config.Rendering.DisableCompositingMode { | |
| 394 | + | if config.Engine.WebKit.ForceCompositingMode && config.Engine.WebKit.DisableCompositingMode { | |
| 404 | 395 | validationErrors = append(validationErrors, | |
| 405 | - | "rendering.force_compositing_mode and rendering.disable_compositing_mode cannot both be true", | |
| 396 | + | "engine.webkit.force_compositing_mode and engine.webkit.disable_compositing_mode cannot both be true", | |
| 406 | 397 | ) | |
| 407 | 398 | } | |
| 408 | 399 | ||
| @@ -410,13 +401,13 @@ func validateRendering(config *Config) []string { | |||
| 410 | 401 | } | |
| 411 | 402 | ||
| 412 | 403 | func validatePrivacy(config *Config) []string { | |
| 413 | - | switch config.Privacy.CookiePolicy { | |
| 404 | + | switch config.Engine.CookiePolicy { | |
| 414 | 405 | case CookiePolicyAlways, CookiePolicyNoThirdParty, CookiePolicyNever, "": | |
| 415 | 406 | return nil | |
| 416 | 407 | default: | |
| 417 | 408 | return []string{fmt.Sprintf( | |
| 418 | - | "privacy.cookie_policy must be one of: always, no_third_party, never (got: %s)", | |
| 419 | - | config.Privacy.CookiePolicy, | |
| 409 | + | "engine.cookie_policy must be one of: always, no_third_party, never (got: %s)", | |
| 410 | + | config.Engine.CookiePolicy, | |
| 420 | 411 | )} | |
| 421 | 412 | } | |
| 422 | 413 | } | |
| @@ -451,39 +442,40 @@ func validatePerformanceProfile(config *Config) []string { | |||
| 451 | 442 | var validationErrors []string | |
| 452 | 443 | ||
| 453 | 444 | // Validate profile name | |
| 454 | - | if !IsValidPerformanceProfile(config.Performance.Profile) { | |
| 445 | + | if !IsValidPerformanceProfile(config.Engine.Profile) { | |
| 455 | 446 | validationErrors = append(validationErrors, fmt.Sprintf( | |
| 456 | - | "performance.profile must be one of: default, lite, max, custom (got: %s)", | |
| 457 | - | config.Performance.Profile, | |
| 447 | + | "engine.profile must be one of: default, lite, max, custom (got: %s)", | |
| 448 | + | config.Engine.Profile, | |
| 458 | 449 | )) | |
| 459 | 450 | } | |
| 460 | 451 | ||
| 461 | 452 | // When profile is not "custom", warn if individual fields are set | |
| 462 | 453 | // (they will be ignored in favor of profile-computed values) | |
| 463 | - | if config.Performance.Profile != ProfileCustom && config.Performance.Profile != "" { | |
| 464 | - | if HasCustomPerformanceFields(&config.Performance) { | |
| 454 | + | if config.Engine.Profile != ProfileCustom && config.Engine.Profile != "" { | |
| 455 | + | perfCfg := PerformanceConfigFromEngine(&config.Engine) | |
| 456 | + | if HasCustomPerformanceFields(&perfCfg) { | |
| 465 | 457 | validationErrors = append(validationErrors, | |
| 466 | - | "performance tuning fields (skia_*, *_memory_*) are ignored when profile is not 'custom'; "+ | |
| 458 | + | "engine performance tuning fields (skia_*, *_memory_*) are ignored when profile is not 'custom'; "+ | |
| 467 | 459 | "set profile = \"custom\" to use individual field values", | |
| 468 | 460 | ) | |
| 469 | 461 | } | |
| 470 | 462 | } | |
| 471 | 463 | ||
| 472 | 464 | // Validate memory pressure threshold ordering: WebKit requires conservative < strict | |
| 473 | - | webCons := config.Performance.WebProcessMemoryConservativeThreshold | |
| 474 | - | webStrict := config.Performance.WebProcessMemoryStrictThreshold | |
| 465 | + | webCons := config.Engine.WebKit.WebProcessMemoryConservativeThreshold | |
| 466 | + | webStrict := config.Engine.WebKit.WebProcessMemoryStrictThreshold | |
| 475 | 467 | if webCons > 0 && webStrict > 0 && webCons >= webStrict { | |
| 476 | 468 | validationErrors = append(validationErrors, | |
| 477 | - | "performance.web_process_memory_conservative_threshold must be less than "+ | |
| 469 | + | "engine.webkit.web_process_memory_conservative_threshold must be less than "+ | |
| 478 | 470 | "web_process_memory_strict_threshold when both are set", | |
| 479 | 471 | ) | |
| 480 | 472 | } | |
| 481 | 473 | ||
| 482 | - | netCons := config.Performance.NetworkProcessMemoryConservativeThreshold | |
| 483 | - | netStrict := config.Performance.NetworkProcessMemoryStrictThreshold | |
| 474 | + | netCons := config.Engine.WebKit.NetworkProcessMemoryConservativeThreshold | |
| 475 | + | netStrict := config.Engine.WebKit.NetworkProcessMemoryStrictThreshold | |
| 484 | 476 | if netCons > 0 && netStrict > 0 && netCons >= netStrict { | |
| 485 | 477 | validationErrors = append(validationErrors, | |
| 486 | - | "performance.network_process_memory_conservative_threshold must be less than "+ | |
| 478 | + | "engine.webkit.network_process_memory_conservative_threshold must be less than "+ | |
| 487 | 479 | "network_process_memory_strict_threshold when both are set", | |
| 488 | 480 | ) | |
| 489 | 481 | } | |
| @@ -379,30 +379,21 @@ func validateOmnibox(config *Config) []string { | |||||
| 379 | func validateRendering(config *Config) []string { | 379 | func validateRendering(config *Config) []string { | ||
| 380 | var validationErrors []string | 380 | var validationErrors []string | ||
| 381 | 381 | ||||
| 382 | - | switch config.Rendering.Mode { | 382 | + | switch config.Engine.WebKit.GSKRenderer { |
| 383 | - | case RenderingModeAuto, RenderingModeGPU, RenderingModeCPU, "": | |||
| 384 | - | default: | |||
| 385 | - | validationErrors = append( | |||
| 386 | - | validationErrors, | |||
| 387 | - | fmt.Sprintf("rendering.mode must be one of: auto, gpu, cpu (got: %s)", config.Rendering.Mode), | |||
| 388 | - | ) | |||
| 389 | - | } | |||
| 390 | - | ||||
| 391 | - | switch config.Rendering.GSKRenderer { | |||
| 392 | case GSKRendererAuto, GSKRendererOpenGL, GSKRendererVulkan, GSKRendererCairo, "": | 383 | case GSKRendererAuto, GSKRendererOpenGL, GSKRendererVulkan, GSKRendererCairo, "": | ||
| 393 | default: | 384 | default: | ||
| 394 | validationErrors = append( | 385 | validationErrors = append( | ||
| 395 | validationErrors, | 386 | validationErrors, | ||
| 396 | fmt.Sprintf( | 387 | fmt.Sprintf( | ||
| 397 | - | "rendering.gsk_renderer must be one of: auto, opengl, vulkan, cairo (got: %s)", | 388 | + | "engine.webkit.gsk_renderer must be one of: auto, opengl, vulkan, cairo (got: %s)", |
| 398 | - | config.Rendering.GSKRenderer, | 389 | + | config.Engine.WebKit.GSKRenderer, |
| 399 | ), | 390 | ), | ||
| 400 | ) | 391 | ) | ||
| 401 | } | 392 | } | ||
| 402 | 393 | ||||
| 403 | - | if config.Rendering.ForceCompositingMode && config.Rendering.DisableCompositingMode { | 394 | + | if config.Engine.WebKit.ForceCompositingMode && config.Engine.WebKit.DisableCompositingMode { |
| 404 | validationErrors = append(validationErrors, | 395 | validationErrors = append(validationErrors, | ||
| 405 | - | "rendering.force_compositing_mode and rendering.disable_compositing_mode cannot both be true", | 396 | + | "engine.webkit.force_compositing_mode and engine.webkit.disable_compositing_mode cannot both be true", |
| 406 | ) | 397 | ) | ||
| 407 | } | 398 | } | ||
| 408 | 399 | ||||
| @@ -410,13 +401,13 @@ func validateRendering(config *Config) []string { | |||||
| 410 | } | 401 | } | ||
| 411 | 402 | ||||
| 412 | func validatePrivacy(config *Config) []string { | 403 | func validatePrivacy(config *Config) []string { | ||
| 413 | - | switch config.Privacy.CookiePolicy { | 404 | + | switch config.Engine.CookiePolicy { |
| 414 | case CookiePolicyAlways, CookiePolicyNoThirdParty, CookiePolicyNever, "": | 405 | case CookiePolicyAlways, CookiePolicyNoThirdParty, CookiePolicyNever, "": | ||
| 415 | return nil | 406 | return nil | ||
| 416 | default: | 407 | default: | ||
| 417 | return []string{fmt.Sprintf( | 408 | return []string{fmt.Sprintf( | ||
| 418 | - | "privacy.cookie_policy must be one of: always, no_third_party, never (got: %s)", | 409 | + | "engine.cookie_policy must be one of: always, no_third_party, never (got: %s)", |
| 419 | - | config.Privacy.CookiePolicy, | 410 | + | config.Engine.CookiePolicy, |
| 420 | )} | 411 | )} | ||
| 421 | } | 412 | } | ||
| 422 | } | 413 | } | ||
| @@ -451,39 +442,40 @@ func validatePerformanceProfile(config *Config) []string { | |||||
| 451 | var validationErrors []string | 442 | var validationErrors []string | ||
| 452 | 443 | ||||
| 453 | // Validate profile name | 444 | // Validate profile name | ||
| 454 | - | if !IsValidPerformanceProfile(config.Performance.Profile) { | 445 | + | if !IsValidPerformanceProfile(config.Engine.Profile) { |
| 455 | validationErrors = append(validationErrors, fmt.Sprintf( | 446 | validationErrors = append(validationErrors, fmt.Sprintf( | ||
| 456 | - | "performance.profile must be one of: default, lite, max, custom (got: %s)", | 447 | + | "engine.profile must be one of: default, lite, max, custom (got: %s)", |
| 457 | - | config.Performance.Profile, | 448 | + | config.Engine.Profile, |
| 458 | )) | 449 | )) | ||
| 459 | } | 450 | } | ||
| 460 | 451 | ||||
| 461 | // When profile is not "custom", warn if individual fields are set | 452 | // When profile is not "custom", warn if individual fields are set | ||
| 462 | // (they will be ignored in favor of profile-computed values) | 453 | // (they will be ignored in favor of profile-computed values) | ||
| 463 | - | if config.Performance.Profile != ProfileCustom && config.Performance.Profile != "" { | 454 | + | if config.Engine.Profile != ProfileCustom && config.Engine.Profile != "" { |
| 464 | - | if HasCustomPerformanceFields(&config.Performance) { | 455 | + | perfCfg := PerformanceConfigFromEngine(&config.Engine) |
| 456 | + | if HasCustomPerformanceFields(&perfCfg) { | |||
| 465 | validationErrors = append(validationErrors, | 457 | validationErrors = append(validationErrors, | ||
| 466 | - | "performance tuning fields (skia_*, *_memory_*) are ignored when profile is not 'custom'; "+ | 458 | + | "engine performance tuning fields (skia_*, *_memory_*) are ignored when profile is not 'custom'; "+ |
| 467 | "set profile = \"custom\" to use individual field values", | 459 | "set profile = \"custom\" to use individual field values", | ||
| 468 | ) | 460 | ) | ||
| 469 | } | 461 | } | ||
| 470 | } | 462 | } | ||
| 471 | 463 | ||||
| 472 | // Validate memory pressure threshold ordering: WebKit requires conservative < strict | 464 | // Validate memory pressure threshold ordering: WebKit requires conservative < strict | ||
| 473 | - | webCons := config.Performance.WebProcessMemoryConservativeThreshold | 465 | + | webCons := config.Engine.WebKit.WebProcessMemoryConservativeThreshold |
| 474 | - | webStrict := config.Performance.WebProcessMemoryStrictThreshold | 466 | + | webStrict := config.Engine.WebKit.WebProcessMemoryStrictThreshold |
| 475 | if webCons > 0 && webStrict > 0 && webCons >= webStrict { | 467 | if webCons > 0 && webStrict > 0 && webCons >= webStrict { | ||
| 476 | validationErrors = append(validationErrors, | 468 | validationErrors = append(validationErrors, | ||
| 477 | - | "performance.web_process_memory_conservative_threshold must be less than "+ | 469 | + | "engine.webkit.web_process_memory_conservative_threshold must be less than "+ |
| 478 | "web_process_memory_strict_threshold when both are set", | 470 | "web_process_memory_strict_threshold when both are set", | ||
| 479 | ) | 471 | ) | ||
| 480 | } | 472 | } | ||
| 481 | 473 | ||||
| 482 | - | netCons := config.Performance.NetworkProcessMemoryConservativeThreshold | 474 | + | netCons := config.Engine.WebKit.NetworkProcessMemoryConservativeThreshold |
| 483 | - | netStrict := config.Performance.NetworkProcessMemoryStrictThreshold | 475 | + | netStrict := config.Engine.WebKit.NetworkProcessMemoryStrictThreshold |
| 484 | if netCons > 0 && netStrict > 0 && netCons >= netStrict { | 476 | if netCons > 0 && netStrict > 0 && netCons >= netStrict { | ||
| 485 | validationErrors = append(validationErrors, | 477 | validationErrors = append(validationErrors, | ||
| 486 | - | "performance.network_process_memory_conservative_threshold must be less than "+ | 478 | + | "engine.webkit.network_process_memory_conservative_threshold must be less than "+ |
| 487 | "network_process_memory_strict_threshold when both are set", | 479 | "network_process_memory_strict_threshold when both are set", | ||
| 488 | ) | 480 | ) | ||
| 489 | } | 481 | } | ||
M internal/infrastructure/config/validation_test.go +3 -3
| @@ -7,7 +7,7 @@ import ( | |||
| 7 | 7 | "github.com/stretchr/testify/require" | |
| 8 | 8 | ) | |
| 9 | 9 | ||
| 10 | - | func TestValidateConfig_PrivacyCookiePolicy(t *testing.T) { | |
| 10 | + | func TestValidateConfig_EngineCookiePolicy(t *testing.T) { | |
| 11 | 11 | tests := []struct { | |
| 12 | 12 | name string | |
| 13 | 13 | cookiePolicy CookiePolicy | |
| @@ -22,12 +22,12 @@ func TestValidateConfig_PrivacyCookiePolicy(t *testing.T) { | |||
| 22 | 22 | for _, tt := range tests { | |
| 23 | 23 | t.Run(tt.name, func(t *testing.T) { | |
| 24 | 24 | cfg := DefaultConfig() | |
| 25 | - | cfg.Privacy.CookiePolicy = tt.cookiePolicy | |
| 25 | + | cfg.Engine.CookiePolicy = tt.cookiePolicy | |
| 26 | 26 | ||
| 27 | 27 | err := validateConfig(cfg) | |
| 28 | 28 | if tt.wantErr { | |
| 29 | 29 | require.Error(t, err) | |
| 30 | - | assert.Contains(t, err.Error(), "privacy.cookie_policy") | |
| 30 | + | assert.Contains(t, err.Error(), "engine.cookie_policy") | |
| 31 | 31 | return | |
| 32 | 32 | } | |
| 33 | 33 | require.NoError(t, err) | |
| @@ -7,7 +7,7 @@ import ( | |||||
| 7 | "github.com/stretchr/testify/require" | 7 | "github.com/stretchr/testify/require" | ||
| 8 | ) | 8 | ) | ||
| 9 | 9 | ||||
| 10 | - | func TestValidateConfig_PrivacyCookiePolicy(t *testing.T) { | 10 | + | func TestValidateConfig_EngineCookiePolicy(t *testing.T) { |
| 11 | tests := []struct { | 11 | tests := []struct { | ||
| 12 | name string | 12 | name string | ||
| 13 | cookiePolicy CookiePolicy | 13 | cookiePolicy CookiePolicy | ||
| @@ -22,12 +22,12 @@ func TestValidateConfig_PrivacyCookiePolicy(t *testing.T) { | |||||
| 22 | for _, tt := range tests { | 22 | for _, tt := range tests { | ||
| 23 | t.Run(tt.name, func(t *testing.T) { | 23 | t.Run(tt.name, func(t *testing.T) { | ||
| 24 | cfg := DefaultConfig() | 24 | cfg := DefaultConfig() | ||
| 25 | - | cfg.Privacy.CookiePolicy = tt.cookiePolicy | 25 | + | cfg.Engine.CookiePolicy = tt.cookiePolicy |
| 26 | 26 | ||||
| 27 | err := validateConfig(cfg) | 27 | err := validateConfig(cfg) | ||
| 28 | if tt.wantErr { | 28 | if tt.wantErr { | ||
| 29 | require.Error(t, err) | 29 | require.Error(t, err) | ||
| 30 | - | assert.Contains(t, err.Error(), "privacy.cookie_policy") | 30 | + | assert.Contains(t, err.Error(), "engine.cookie_policy") |
| 31 | return | 31 | return | ||
| 32 | } | 32 | } | ||
| 33 | require.NoError(t, err) | 33 | require.NoError(t, err) | ||
M internal/infrastructure/config/webui_gateway.go +6 -6
| @@ -80,16 +80,16 @@ func (g *WebUIConfigGateway) SaveWebUIConfig(ctx context.Context, cfg port.WebUI | |||
| 80 | 80 | ||
| 81 | 81 | // Performance profile (requires restart to take effect) | |
| 82 | 82 | if cfg.Performance.Profile != "" { | |
| 83 | - | current.Performance.Profile = PerformanceProfile(cfg.Performance.Profile) | |
| 83 | + | current.Engine.Profile = PerformanceProfile(cfg.Performance.Profile) | |
| 84 | 84 | } | |
| 85 | 85 | ||
| 86 | 86 | // Custom performance fields (only used when profile is "custom") | |
| 87 | 87 | if cfg.Performance.Profile == string(ProfileCustom) { | |
| 88 | - | current.Performance.SkiaCPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaCPUThreads, 0, maxSkiaCPUThreads) | |
| 89 | - | current.Performance.SkiaGPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaGPUThreads, -1, maxSkiaGPUThreads) | |
| 90 | - | current.Performance.WebProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.WebProcessMemoryMB, 0, maxWebProcessMemoryMB) | |
| 91 | - | current.Performance.NetworkProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.NetworkProcessMemoryMB, 0, maxNetworkProcessMemoryMB) | |
| 92 | - | current.Performance.WebViewPoolPrewarmCount = clampInt(cfg.Performance.Custom.WebViewPoolPrewarm, 0, maxWebViewPoolPrewarm) | |
| 88 | + | current.Engine.WebKit.SkiaCPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaCPUThreads, 0, maxSkiaCPUThreads) | |
| 89 | + | current.Engine.WebKit.SkiaGPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaGPUThreads, -1, maxSkiaGPUThreads) | |
| 90 | + | current.Engine.WebKit.WebProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.WebProcessMemoryMB, 0, maxWebProcessMemoryMB) | |
| 91 | + | current.Engine.WebKit.NetworkProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.NetworkProcessMemoryMB, 0, maxNetworkProcessMemoryMB) | |
| 92 | + | current.Engine.PoolPrewarmCount = clampInt(cfg.Performance.Custom.WebViewPoolPrewarm, 0, maxWebViewPoolPrewarm) | |
| 93 | 93 | } | |
| 94 | 94 | ||
| 95 | 95 | return g.mgr.Save(current) | |
| @@ -80,16 +80,16 @@ func (g *WebUIConfigGateway) SaveWebUIConfig(ctx context.Context, cfg port.WebUI | |||||
| 80 | 80 | ||||
| 81 | // Performance profile (requires restart to take effect) | 81 | // Performance profile (requires restart to take effect) | ||
| 82 | if cfg.Performance.Profile != "" { | 82 | if cfg.Performance.Profile != "" { | ||
| 83 | - | current.Performance.Profile = PerformanceProfile(cfg.Performance.Profile) | 83 | + | current.Engine.Profile = PerformanceProfile(cfg.Performance.Profile) |
| 84 | } | 84 | } | ||
| 85 | 85 | ||||
| 86 | // Custom performance fields (only used when profile is "custom") | 86 | // Custom performance fields (only used when profile is "custom") | ||
| 87 | if cfg.Performance.Profile == string(ProfileCustom) { | 87 | if cfg.Performance.Profile == string(ProfileCustom) { | ||
| 88 | - | current.Performance.SkiaCPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaCPUThreads, 0, maxSkiaCPUThreads) | 88 | + | current.Engine.WebKit.SkiaCPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaCPUThreads, 0, maxSkiaCPUThreads) |
| 89 | - | current.Performance.SkiaGPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaGPUThreads, -1, maxSkiaGPUThreads) | 89 | + | current.Engine.WebKit.SkiaGPUPaintingThreads = clampInt(cfg.Performance.Custom.SkiaGPUThreads, -1, maxSkiaGPUThreads) |
| 90 | - | current.Performance.WebProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.WebProcessMemoryMB, 0, maxWebProcessMemoryMB) | 90 | + | current.Engine.WebKit.WebProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.WebProcessMemoryMB, 0, maxWebProcessMemoryMB) |
| 91 | - | current.Performance.NetworkProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.NetworkProcessMemoryMB, 0, maxNetworkProcessMemoryMB) | 91 | + | current.Engine.WebKit.NetworkProcessMemoryLimitMB = clampInt(cfg.Performance.Custom.NetworkProcessMemoryMB, 0, maxNetworkProcessMemoryMB) |
| 92 | - | current.Performance.WebViewPoolPrewarmCount = clampInt(cfg.Performance.Custom.WebViewPoolPrewarm, 0, maxWebViewPoolPrewarm) | 92 | + | current.Engine.PoolPrewarmCount = clampInt(cfg.Performance.Custom.WebViewPoolPrewarm, 0, maxWebViewPoolPrewarm) |
| 93 | } | 93 | } | ||
| 94 | 94 | ||||
| 95 | return g.mgr.Save(current) | 95 | return g.mgr.Save(current) | ||
M internal/infrastructure/webkit/context.go +12 -13
| @@ -6,7 +6,6 @@ import ( | |||
| 6 | 6 | "path/filepath" | |
| 7 | 7 | "sync" | |
| 8 | 8 | ||
| 9 | - | "github.com/bnema/dumber/internal/application/port" | |
| 10 | 9 | "github.com/bnema/dumber/internal/logging" | |
| 11 | 10 | "github.com/bnema/puregotk-webkit/webkit" | |
| 12 | 11 | "github.com/rs/zerolog" | |
| @@ -36,17 +35,17 @@ type WebKitContext struct { | |||
| 36 | 35 | // The dataDir and cacheDir are used for cookie storage, cache, and other persistent data. | |
| 37 | 36 | // This MUST be called before creating any WebViews to ensure they use persistent storage. | |
| 38 | 37 | func NewWebKitContext(ctx context.Context, dataDir, cacheDir string) (*WebKitContext, error) { | |
| 39 | - | return NewWebKitContextWithOptions(ctx, port.WebKitContextOptions{ | |
| 38 | + | return NewWebKitContextWithOptions(ctx, webKitContextOptions{ | |
| 40 | 39 | DataDir: dataDir, | |
| 41 | 40 | CacheDir: cacheDir, | |
| 42 | - | CookiePolicy: port.WebKitCookiePolicyNoThirdParty, | |
| 41 | + | CookiePolicy: cookiePolicyNoThirdParty, | |
| 43 | 42 | ITPEnabled: true, | |
| 44 | 43 | }) | |
| 45 | 44 | } | |
| 46 | 45 | ||
| 47 | 46 | // NewWebKitContextWithOptions creates and initializes a WebKitContext with the given options. | |
| 48 | 47 | // This allows configuring memory pressure settings for web and network processes. | |
| 49 | - | func NewWebKitContextWithOptions(ctx context.Context, opts port.WebKitContextOptions) (*WebKitContext, error) { | |
| 48 | + | func NewWebKitContextWithOptions(ctx context.Context, opts webKitContextOptions) (*WebKitContext, error) { | |
| 50 | 49 | log := logging.FromContext(ctx).With().Str("component", "webkit-context").Logger() | |
| 51 | 50 | ||
| 52 | 51 | if opts.DataDir == "" { | |
| @@ -114,7 +113,7 @@ func NewWebKitContextWithOptions(ctx context.Context, opts port.WebKitContextOpt | |||
| 114 | 113 | } | |
| 115 | 114 | ||
| 116 | 115 | // initNetworkSession creates and configures the persistent network session. | |
| 117 | - | func (c *WebKitContext) initNetworkSession(opts port.WebKitContextOptions) error { | |
| 116 | + | func (c *WebKitContext) initNetworkSession(opts webKitContextOptions) error { | |
| 118 | 117 | // Create persistent network session | |
| 119 | 118 | session := webkit.NewNetworkSession(&c.dataDir, &c.cacheDir) | |
| 120 | 119 | if session == nil { | |
| @@ -188,16 +187,16 @@ func (c *WebKitContext) initNetworkSession(opts port.WebKitContextOptions) error | |||
| 188 | 187 | return nil | |
| 189 | 188 | } | |
| 190 | 189 | ||
| 191 | - | func mapCookiePolicy(policy port.WebKitCookiePolicy) (webkit.CookieAcceptPolicy, string) { | |
| 190 | + | func mapCookiePolicy(policy cookiePolicy) (webkit.CookieAcceptPolicy, string) { | |
| 192 | 191 | switch policy { | |
| 193 | - | case port.WebKitCookiePolicyAlways: | |
| 194 | - | return webkit.CookiePolicyAcceptAlwaysValue, string(port.WebKitCookiePolicyAlways) | |
| 195 | - | case port.WebKitCookiePolicyNever: | |
| 196 | - | return webkit.CookiePolicyAcceptNeverValue, string(port.WebKitCookiePolicyNever) | |
| 197 | - | case port.WebKitCookiePolicyNoThirdParty, "": | |
| 198 | - | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(port.WebKitCookiePolicyNoThirdParty) | |
| 192 | + | case cookiePolicyAlways: | |
| 193 | + | return webkit.CookiePolicyAcceptAlwaysValue, string(cookiePolicyAlways) | |
| 194 | + | case cookiePolicyNever: | |
| 195 | + | return webkit.CookiePolicyAcceptNeverValue, string(cookiePolicyNever) | |
| 196 | + | case cookiePolicyNoThirdParty, "": | |
| 197 | + | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(cookiePolicyNoThirdParty) | |
| 199 | 198 | default: | |
| 200 | - | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(port.WebKitCookiePolicyNoThirdParty) | |
| 199 | + | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(cookiePolicyNoThirdParty) | |
| 201 | 200 | } | |
| 202 | 201 | } | |
| 203 | 202 | ||
| @@ -6,7 +6,6 @@ import ( | |||||
| 6 | "path/filepath" | 6 | "path/filepath" | ||
| 7 | "sync" | 7 | "sync" | ||
| 8 | 8 | ||||
| 9 | - | "github.com/bnema/dumber/internal/application/port" | |||
| 10 | "github.com/bnema/dumber/internal/logging" | 9 | "github.com/bnema/dumber/internal/logging" | ||
| 11 | "github.com/bnema/puregotk-webkit/webkit" | 10 | "github.com/bnema/puregotk-webkit/webkit" | ||
| 12 | "github.com/rs/zerolog" | 11 | "github.com/rs/zerolog" | ||
| @@ -36,17 +35,17 @@ type WebKitContext struct { | |||||
| 36 | // The dataDir and cacheDir are used for cookie storage, cache, and other persistent data. | 35 | // The dataDir and cacheDir are used for cookie storage, cache, and other persistent data. | ||
| 37 | // This MUST be called before creating any WebViews to ensure they use persistent storage. | 36 | // This MUST be called before creating any WebViews to ensure they use persistent storage. | ||
| 38 | func NewWebKitContext(ctx context.Context, dataDir, cacheDir string) (*WebKitContext, error) { | 37 | func NewWebKitContext(ctx context.Context, dataDir, cacheDir string) (*WebKitContext, error) { | ||
| 39 | - | return NewWebKitContextWithOptions(ctx, port.WebKitContextOptions{ | 38 | + | return NewWebKitContextWithOptions(ctx, webKitContextOptions{ |
| 40 | DataDir: dataDir, | 39 | DataDir: dataDir, | ||
| 41 | CacheDir: cacheDir, | 40 | CacheDir: cacheDir, | ||
| 42 | - | CookiePolicy: port.WebKitCookiePolicyNoThirdParty, | 41 | + | CookiePolicy: cookiePolicyNoThirdParty, |
| 43 | ITPEnabled: true, | 42 | ITPEnabled: true, | ||
| 44 | }) | 43 | }) | ||
| 45 | } | 44 | } | ||
| 46 | 45 | ||||
| 47 | // NewWebKitContextWithOptions creates and initializes a WebKitContext with the given options. | 46 | // NewWebKitContextWithOptions creates and initializes a WebKitContext with the given options. | ||
| 48 | // This allows configuring memory pressure settings for web and network processes. | 47 | // This allows configuring memory pressure settings for web and network processes. | ||
| 49 | - | func NewWebKitContextWithOptions(ctx context.Context, opts port.WebKitContextOptions) (*WebKitContext, error) { | 48 | + | func NewWebKitContextWithOptions(ctx context.Context, opts webKitContextOptions) (*WebKitContext, error) { |
| 50 | log := logging.FromContext(ctx).With().Str("component", "webkit-context").Logger() | 49 | log := logging.FromContext(ctx).With().Str("component", "webkit-context").Logger() | ||
| 51 | 50 | ||||
| 52 | if opts.DataDir == "" { | 51 | if opts.DataDir == "" { | ||
| @@ -114,7 +113,7 @@ func NewWebKitContextWithOptions(ctx context.Context, opts port.WebKitContextOpt | |||||
| 114 | } | 113 | } | ||
| 115 | 114 | ||||
| 116 | // initNetworkSession creates and configures the persistent network session. | 115 | // initNetworkSession creates and configures the persistent network session. | ||
| 117 | - | func (c *WebKitContext) initNetworkSession(opts port.WebKitContextOptions) error { | 116 | + | func (c *WebKitContext) initNetworkSession(opts webKitContextOptions) error { |
| 118 | // Create persistent network session | 117 | // Create persistent network session | ||
| 119 | session := webkit.NewNetworkSession(&c.dataDir, &c.cacheDir) | 118 | session := webkit.NewNetworkSession(&c.dataDir, &c.cacheDir) | ||
| 120 | if session == nil { | 119 | if session == nil { | ||
| @@ -188,16 +187,16 @@ func (c *WebKitContext) initNetworkSession(opts port.WebKitContextOptions) error | |||||
| 188 | return nil | 187 | return nil | ||
| 189 | } | 188 | } | ||
| 190 | 189 | ||||
| 191 | - | func mapCookiePolicy(policy port.WebKitCookiePolicy) (webkit.CookieAcceptPolicy, string) { | 190 | + | func mapCookiePolicy(policy cookiePolicy) (webkit.CookieAcceptPolicy, string) { |
| 192 | switch policy { | 191 | switch policy { | ||
| 193 | - | case port.WebKitCookiePolicyAlways: | 192 | + | case cookiePolicyAlways: |
| 194 | - | return webkit.CookiePolicyAcceptAlwaysValue, string(port.WebKitCookiePolicyAlways) | 193 | + | return webkit.CookiePolicyAcceptAlwaysValue, string(cookiePolicyAlways) |
| 195 | - | case port.WebKitCookiePolicyNever: | 194 | + | case cookiePolicyNever: |
| 196 | - | return webkit.CookiePolicyAcceptNeverValue, string(port.WebKitCookiePolicyNever) | 195 | + | return webkit.CookiePolicyAcceptNeverValue, string(cookiePolicyNever) |
| 197 | - | case port.WebKitCookiePolicyNoThirdParty, "": | 196 | + | case cookiePolicyNoThirdParty, "": |
| 198 | - | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(port.WebKitCookiePolicyNoThirdParty) | 197 | + | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(cookiePolicyNoThirdParty) |
| 199 | default: | 198 | default: | ||
| 200 | - | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(port.WebKitCookiePolicyNoThirdParty) | 199 | + | return webkit.CookiePolicyAcceptNoThirdPartyValue, string(cookiePolicyNoThirdParty) |
| 201 | } | 200 | } | ||
| 202 | } | 201 | } | ||
| 203 | 202 | ||||
A internal/infrastructure/webkit/context_options.go +56 -0
| @@ -0,0 +1,56 @@ | |||
| 1 | + | package webkit | |
| 2 | + | ||
| 3 | + | import "github.com/bnema/dumber/internal/application/port" | |
| 4 | + | ||
| 5 | + | // cookiePolicy controls cookie acceptance behavior for the WebKit NetworkSession. | |
| 6 | + | // This is a webkit-internal type; values match port.CookiePolicy string values. | |
| 7 | + | type cookiePolicy = port.CookiePolicy | |
| 8 | + | ||
| 9 | + | const ( | |
| 10 | + | cookiePolicyAlways cookiePolicy = port.CookiePolicyAlways | |
| 11 | + | cookiePolicyNoThirdParty cookiePolicy = port.CookiePolicyNoThirdParty | |
| 12 | + | cookiePolicyNever cookiePolicy = port.CookiePolicyNever | |
| 13 | + | ) | |
| 14 | + | ||
| 15 | + | // webKitContextOptions configures WebKitContext creation. | |
| 16 | + | // This is a webkit-specific options struct that extends EngineOptions with | |
| 17 | + | // WebKit-specific fields (e.g. ITPEnabled). | |
| 18 | + | type webKitContextOptions struct { | |
| 19 | + | // DataDir is the directory for persistent data (cookies, storage, etc.). | |
| 20 | + | DataDir string | |
| 21 | + | ||
| 22 | + | // CacheDir is the directory for cache data. | |
| 23 | + | CacheDir string | |
| 24 | + | ||
| 25 | + | // CookiePolicy controls cookie acceptance behavior. | |
| 26 | + | // Empty value means runtime defaults are used. | |
| 27 | + | CookiePolicy cookiePolicy | |
| 28 | + | ||
| 29 | + | // ITPEnabled controls Intelligent Tracking Prevention for NetworkSession. | |
| 30 | + | // False means ITP remains disabled unless enabled explicitly. | |
| 31 | + | ITPEnabled bool | |
| 32 | + | ||
| 33 | + | // WebProcessMemory configures memory pressure for web processes. | |
| 34 | + | // nil means use WebKit defaults. | |
| 35 | + | WebProcessMemory *port.MemoryPressureConfig | |
| 36 | + | ||
| 37 | + | // NetworkProcessMemory configures memory pressure for the network process. | |
| 38 | + | // nil means use WebKit defaults. | |
| 39 | + | NetworkProcessMemory *port.MemoryPressureConfig | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | // IsWebProcessMemoryConfigured returns true if web process memory settings are configured. | |
| 43 | + | func (o *webKitContextOptions) IsWebProcessMemoryConfigured() bool { | |
| 44 | + | if o == nil || o.WebProcessMemory == nil { | |
| 45 | + | return false | |
| 46 | + | } | |
| 47 | + | return o.WebProcessMemory.IsConfigured() | |
| 48 | + | } | |
| 49 | + | ||
| 50 | + | // IsNetworkProcessMemoryConfigured returns true if network process memory settings are configured. | |
| 51 | + | func (o *webKitContextOptions) IsNetworkProcessMemoryConfigured() bool { | |
| 52 | + | if o == nil || o.NetworkProcessMemory == nil { | |
| 53 | + | return false | |
| 54 | + | } | |
| 55 | + | return o.NetworkProcessMemory.IsConfigured() | |
| 56 | + | } | |
| @@ -0,0 +1,56 @@ | |||||
| 1 | + | package webkit | |||
| 2 | + | ||||
| 3 | + | import "github.com/bnema/dumber/internal/application/port" | |||
| 4 | + | ||||
| 5 | + | // cookiePolicy controls cookie acceptance behavior for the WebKit NetworkSession. | |||
| 6 | + | // This is a webkit-internal type; values match port.CookiePolicy string values. | |||
| 7 | + | type cookiePolicy = port.CookiePolicy | |||
| 8 | + | ||||
| 9 | + | const ( | |||
| 10 | + | cookiePolicyAlways cookiePolicy = port.CookiePolicyAlways | |||
| 11 | + | cookiePolicyNoThirdParty cookiePolicy = port.CookiePolicyNoThirdParty | |||
| 12 | + | cookiePolicyNever cookiePolicy = port.CookiePolicyNever | |||
| 13 | + | ) | |||
| 14 | + | ||||
| 15 | + | // webKitContextOptions configures WebKitContext creation. | |||
| 16 | + | // This is a webkit-specific options struct that extends EngineOptions with | |||
| 17 | + | // WebKit-specific fields (e.g. ITPEnabled). | |||
| 18 | + | type webKitContextOptions struct { | |||
| 19 | + | // DataDir is the directory for persistent data (cookies, storage, etc.). | |||
| 20 | + | DataDir string | |||
| 21 | + | ||||
| 22 | + | // CacheDir is the directory for cache data. | |||
| 23 | + | CacheDir string | |||
| 24 | + | ||||
| 25 | + | // CookiePolicy controls cookie acceptance behavior. | |||
| 26 | + | // Empty value means runtime defaults are used. | |||
| 27 | + | CookiePolicy cookiePolicy | |||
| 28 | + | ||||
| 29 | + | // ITPEnabled controls Intelligent Tracking Prevention for NetworkSession. | |||
| 30 | + | // False means ITP remains disabled unless enabled explicitly. | |||
| 31 | + | ITPEnabled bool | |||
| 32 | + | ||||
| 33 | + | // WebProcessMemory configures memory pressure for web processes. | |||
| 34 | + | // nil means use WebKit defaults. | |||
| 35 | + | WebProcessMemory *port.MemoryPressureConfig | |||
| 36 | + | ||||
| 37 | + | // NetworkProcessMemory configures memory pressure for the network process. | |||
| 38 | + | // nil means use WebKit defaults. | |||
| 39 | + | NetworkProcessMemory *port.MemoryPressureConfig | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | // IsWebProcessMemoryConfigured returns true if web process memory settings are configured. | |||
| 43 | + | func (o *webKitContextOptions) IsWebProcessMemoryConfigured() bool { | |||
| 44 | + | if o == nil || o.WebProcessMemory == nil { | |||
| 45 | + | return false | |||
| 46 | + | } | |||
| 47 | + | return o.WebProcessMemory.IsConfigured() | |||
| 48 | + | } | |||
| 49 | + | ||||
| 50 | + | // IsNetworkProcessMemoryConfigured returns true if network process memory settings are configured. | |||
| 51 | + | func (o *webKitContextOptions) IsNetworkProcessMemoryConfigured() bool { | |||
| 52 | + | if o == nil || o.NetworkProcessMemory == nil { | |||
| 53 | + | return false | |||
| 54 | + | } | |||
| 55 | + | return o.NetworkProcessMemory.IsConfigured() | |||
| 56 | + | } | |||
M internal/infrastructure/webkit/engine.go +5 -8
| @@ -10,6 +10,7 @@ import ( | |||
| 10 | 10 | ||
| 11 | 11 | // Engine implements port.Engine for the WebKit browser engine. | |
| 12 | 12 | type Engine struct { | |
| 13 | + | ctx context.Context | |
| 13 | 14 | wkCtx *WebKitContext | |
| 14 | 15 | settings *SettingsManager | |
| 15 | 16 | injector *ContentInjector | |
| @@ -25,11 +26,6 @@ type Engine struct { | |||
| 25 | 26 | // Compile-time check that Engine implements port.Engine. | |
| 26 | 27 | var _ port.Engine = (*Engine)(nil) | |
| 27 | 28 | ||
| 28 | - | // Init is a no-op for WebKit — initialization happens in NewEngine. | |
| 29 | - | func (*Engine) Init(_ context.Context, _ port.EngineOptions) error { | |
| 30 | - | return nil | |
| 31 | - | } | |
| 32 | - | ||
| 33 | 29 | // Factory returns the WebViewFactory wrapped as a port.WebViewFactory. | |
| 34 | 30 | func (e *Engine) Factory() port.WebViewFactory { | |
| 35 | 31 | return &webViewFactoryAdapter{factory: e.factory} | |
| @@ -37,7 +33,7 @@ func (e *Engine) Factory() port.WebViewFactory { | |||
| 37 | 33 | ||
| 38 | 34 | // Pool returns the WebViewPool wrapped as a port.WebViewPool. | |
| 39 | 35 | func (e *Engine) Pool() port.WebViewPool { | |
| 40 | - | return &webViewPoolAdapter{pool: e.pool, logger: e.logger} | |
| 36 | + | return &webViewPoolAdapter{pool: e.pool, ctx: e.ctx} | |
| 41 | 37 | } | |
| 42 | 38 | ||
| 43 | 39 | // ContentInjector returns the ContentInjector implementing port.ContentInjector. | |
| @@ -53,7 +49,7 @@ func (e *Engine) InternalSchemePath() string { | |||
| 53 | 49 | // Close releases all resources held by the engine. | |
| 54 | 50 | func (e *Engine) Close() error { | |
| 55 | 51 | if e.pool != nil { | |
| 56 | - | e.pool.Close(context.Background()) | |
| 52 | + | e.pool.Close(e.ctx) | |
| 57 | 53 | } | |
| 58 | 54 | return nil | |
| 59 | 55 | } | |
| @@ -65,7 +61,7 @@ func (e *Engine) SchemeHandler() port.SchemeHandler { | |||
| 65 | 61 | ||
| 66 | 62 | // MessageRouter returns a port.MessageRouter adapter for the internal MessageRouter. | |
| 67 | 63 | func (e *Engine) MessageRouter() port.MessageRouter { | |
| 68 | - | return &messageRouterAdapter{router: e.messageRouter} | |
| 64 | + | return &messageRouterAdapter{router: e.messageRouter, logger: e.logger} | |
| 69 | 65 | } | |
| 70 | 66 | ||
| 71 | 67 | // SettingsApplier returns a port.SettingsApplier adapter for the SettingsManager. | |
| @@ -94,4 +90,5 @@ func (e *Engine) InternalSettings() *SettingsManager { return e.settings | |||
| 94 | 90 | func (e *Engine) InternalInjector() *ContentInjector { return e.injector } | |
| 95 | 91 | func (e *Engine) InternalMessageRouter() *MessageRouter { return e.messageRouter } | |
| 96 | 92 | func (e *Engine) InternalPool() *WebViewPool { return e.pool } | |
| 93 | + | func (e *Engine) InternalFactory() *WebViewFactory { return e.factory } | |
| 97 | 94 | func (e *Engine) InternalFilterManager() *filtering.Manager { return e.filterManager } | |
| @@ -10,6 +10,7 @@ import ( | |||||
| 10 | 10 | ||||
| 11 | // Engine implements port.Engine for the WebKit browser engine. | 11 | // Engine implements port.Engine for the WebKit browser engine. | ||
| 12 | type Engine struct { | 12 | type Engine struct { | ||
| 13 | + | ctx context.Context | |||
| 13 | wkCtx *WebKitContext | 14 | wkCtx *WebKitContext | ||
| 14 | settings *SettingsManager | 15 | settings *SettingsManager | ||
| 15 | injector *ContentInjector | 16 | injector *ContentInjector | ||
| @@ -25,11 +26,6 @@ type Engine struct { | |||||
| 25 | // Compile-time check that Engine implements port.Engine. | 26 | // Compile-time check that Engine implements port.Engine. | ||
| 26 | var _ port.Engine = (*Engine)(nil) | 27 | var _ port.Engine = (*Engine)(nil) | ||
| 27 | 28 | ||||
| 28 | - | // Init is a no-op for WebKit — initialization happens in NewEngine. | |||
| 29 | - | func (*Engine) Init(_ context.Context, _ port.EngineOptions) error { | |||
| 30 | - | return nil | |||
| 31 | - | } | |||
| 32 | - | ||||
| 33 | // Factory returns the WebViewFactory wrapped as a port.WebViewFactory. | 29 | // Factory returns the WebViewFactory wrapped as a port.WebViewFactory. | ||
| 34 | func (e *Engine) Factory() port.WebViewFactory { | 30 | func (e *Engine) Factory() port.WebViewFactory { | ||
| 35 | return &webViewFactoryAdapter{factory: e.factory} | 31 | return &webViewFactoryAdapter{factory: e.factory} | ||
| @@ -37,7 +33,7 @@ func (e *Engine) Factory() port.WebViewFactory { | |||||
| 37 | 33 | ||||
| 38 | // Pool returns the WebViewPool wrapped as a port.WebViewPool. | 34 | // Pool returns the WebViewPool wrapped as a port.WebViewPool. | ||
| 39 | func (e *Engine) Pool() port.WebViewPool { | 35 | func (e *Engine) Pool() port.WebViewPool { | ||
| 40 | - | return &webViewPoolAdapter{pool: e.pool, logger: e.logger} | 36 | + | return &webViewPoolAdapter{pool: e.pool, ctx: e.ctx} |
| 41 | } | 37 | } | ||
| 42 | 38 | ||||
| 43 | // ContentInjector returns the ContentInjector implementing port.ContentInjector. | 39 | // ContentInjector returns the ContentInjector implementing port.ContentInjector. | ||
| @@ -53,7 +49,7 @@ func (e *Engine) InternalSchemePath() string { | |||||
| 53 | // Close releases all resources held by the engine. | 49 | // Close releases all resources held by the engine. | ||
| 54 | func (e *Engine) Close() error { | 50 | func (e *Engine) Close() error { | ||
| 55 | if e.pool != nil { | 51 | if e.pool != nil { | ||
| 56 | - | e.pool.Close(context.Background()) | 52 | + | e.pool.Close(e.ctx) |
| 57 | } | 53 | } | ||
| 58 | return nil | 54 | return nil | ||
| 59 | } | 55 | } | ||
| @@ -65,7 +61,7 @@ func (e *Engine) SchemeHandler() port.SchemeHandler { | |||||
| 65 | 61 | ||||
| 66 | // MessageRouter returns a port.MessageRouter adapter for the internal MessageRouter. | 62 | // MessageRouter returns a port.MessageRouter adapter for the internal MessageRouter. | ||
| 67 | func (e *Engine) MessageRouter() port.MessageRouter { | 63 | func (e *Engine) MessageRouter() port.MessageRouter { | ||
| 68 | - | return &messageRouterAdapter{router: e.messageRouter} | 64 | + | return &messageRouterAdapter{router: e.messageRouter, logger: e.logger} |
| 69 | } | 65 | } | ||
| 70 | 66 | ||||
| 71 | // SettingsApplier returns a port.SettingsApplier adapter for the SettingsManager. | 67 | // SettingsApplier returns a port.SettingsApplier adapter for the SettingsManager. | ||
| @@ -94,4 +90,5 @@ func (e *Engine) InternalSettings() *SettingsManager { return e.settings | |||||
| 94 | func (e *Engine) InternalInjector() *ContentInjector { return e.injector } | 90 | func (e *Engine) InternalInjector() *ContentInjector { return e.injector } | ||
| 95 | func (e *Engine) InternalMessageRouter() *MessageRouter { return e.messageRouter } | 91 | func (e *Engine) InternalMessageRouter() *MessageRouter { return e.messageRouter } | ||
| 96 | func (e *Engine) InternalPool() *WebViewPool { return e.pool } | 92 | func (e *Engine) InternalPool() *WebViewPool { return e.pool } | ||
| 93 | + | func (e *Engine) InternalFactory() *WebViewFactory { return e.factory } | |||
| 97 | func (e *Engine) InternalFilterManager() *filtering.Manager { return e.filterManager } | 94 | func (e *Engine) InternalFilterManager() *filtering.Manager { return e.filterManager } | ||
M internal/infrastructure/webkit/engine_adapters.go +38 -14
| @@ -6,6 +6,8 @@ import ( | |||
| 6 | 6 | ||
| 7 | 7 | "github.com/bnema/dumber/internal/application/port" | |
| 8 | 8 | "github.com/bnema/dumber/internal/infrastructure/filtering" | |
| 9 | + | "github.com/bnema/dumber/internal/logging" | |
| 10 | + | "github.com/jwijenbergh/puregotk/v4/gio" | |
| 9 | 11 | "github.com/rs/zerolog" | |
| 10 | 12 | ) | |
| 11 | 13 | ||
| @@ -40,8 +42,8 @@ func (a *webViewFactoryAdapter) CreateRelated(ctx context.Context, parentID port | |||
| 40 | 42 | // WebViewPool methods use *WebView and require a context; this adapter adapts | |
| 41 | 43 | // the signatures to match the port interface. | |
| 42 | 44 | type webViewPoolAdapter struct { | |
| 43 | - | pool *WebViewPool | |
| 44 | - | logger zerolog.Logger | |
| 45 | + | pool *WebViewPool | |
| 46 | + | ctx context.Context | |
| 45 | 47 | } | |
| 46 | 48 | ||
| 47 | 49 | func (a *webViewPoolAdapter) Acquire(ctx context.Context) (port.WebView, error) { | |
| @@ -58,16 +60,16 @@ func (a *webViewPoolAdapter) Release(wv port.WebView) { | |||
| 58 | 60 | } | |
| 59 | 61 | wwv, ok := wv.(*WebView) | |
| 60 | 62 | if !ok { | |
| 61 | - | a.logger.Warn(). | |
| 63 | + | logging.FromContext(a.ctx).Warn(). | |
| 62 | 64 | Str("concrete_type", fmt.Sprintf("%T", wv)). | |
| 63 | 65 | Msg("webViewPoolAdapter.Release: unexpected type, cannot release to pool") | |
| 64 | 66 | return | |
| 65 | 67 | } | |
| 66 | - | a.pool.Release(context.Background(), wwv) | |
| 68 | + | a.pool.Release(a.ctx, wwv) | |
| 67 | 69 | } | |
| 68 | 70 | ||
| 69 | 71 | func (a *webViewPoolAdapter) Prewarm(count int) { | |
| 70 | - | a.pool.Prewarm(context.Background(), count) | |
| 72 | + | a.pool.Prewarm(a.ctx, count) | |
| 71 | 73 | } | |
| 72 | 74 | ||
| 73 | 75 | func (a *webViewPoolAdapter) Size() int { | |
| @@ -75,7 +77,7 @@ func (a *webViewPoolAdapter) Size() int { | |||
| 75 | 77 | } | |
| 76 | 78 | ||
| 77 | 79 | func (a *webViewPoolAdapter) Close() { | |
| 78 | - | a.pool.Close(context.Background()) | |
| 80 | + | a.pool.Close(a.ctx) | |
| 79 | 81 | } | |
| 80 | 82 | ||
| 81 | 83 | // --- SchemeHandler adapter --- | |
| @@ -105,12 +107,15 @@ func (a *schemeHandlerAdapter) RegisterScheme(scheme string, _ func(uri string) | |||
| 105 | 107 | // PostMessage is also not directly available on the internal type. | |
| 106 | 108 | type messageRouterAdapter struct { | |
| 107 | 109 | router *MessageRouter | |
| 110 | + | logger zerolog.Logger | |
| 108 | 111 | } | |
| 109 | 112 | ||
| 110 | - | func (*messageRouterAdapter) RegisterHandler(_ string, _ func(message string) (string, error)) { | |
| 113 | + | func (a *messageRouterAdapter) RegisterHandler(name string, _ func(message string) (string, error)) { | |
| 111 | 114 | // Internal MessageRouter.RegisterHandler takes a MessageHandler interface, not a plain func. | |
| 112 | 115 | // Wire up via RegisterHandler(msgType, MessageHandlerFunc{...}) when consumers are migrated. | |
| 113 | - | panic("not implemented — use MessageRouter.RegisterHandler(msgType, MessageHandler) directly") | |
| 116 | + | a.logger.Warn(). | |
| 117 | + | Str("handler", name). | |
| 118 | + | Msg("messageRouterAdapter.RegisterHandler: not implemented — use MessageRouter.RegisterHandler(msgType, MessageHandler) directly") | |
| 114 | 119 | } | |
| 115 | 120 | ||
| 116 | 121 | func (*messageRouterAdapter) PostMessage(webviewID port.WebViewID, message string) error { | |
| @@ -118,7 +123,7 @@ func (*messageRouterAdapter) PostMessage(webviewID port.WebViewID, message strin | |||
| 118 | 123 | if wv == nil { | |
| 119 | 124 | return fmt.Errorf("webview %d not found", webviewID) | |
| 120 | 125 | } | |
| 121 | - | wv.RunJavaScript(context.Background(), message, "") | |
| 126 | + | wv.RunJavaScript(context.Background(), message) | |
| 122 | 127 | return nil | |
| 123 | 128 | } | |
| 124 | 129 | ||
| @@ -161,9 +166,28 @@ type faviconDatabaseAdapter struct { | |||
| 161 | 166 | wkCtx *WebKitContext | |
| 162 | 167 | } | |
| 163 | 168 | ||
| 164 | - | func (*faviconDatabaseAdapter) GetFaviconAsync(_ string, callback func(port.Texture)) { | |
| 165 | - | // FaviconDatabase async lookup is not yet wired through this adapter. | |
| 166 | - | // The underlying API is: wkCtx.FaviconDatabase().GetFavicon(uri, callback). | |
| 167 | - | // This stub satisfies the interface contract; callers will receive nil. | |
| 168 | - | callback(nil) | |
| 169 | + | func (a *faviconDatabaseAdapter) GetFaviconAsync(pageURL string, callback func(port.Texture)) { | |
| 170 | + | db := a.wkCtx.FaviconDatabase() | |
| 171 | + | if db == nil { | |
| 172 | + | callback(nil) | |
| 173 | + | return | |
| 174 | + | } | |
| 175 | + | ||
| 176 | + | asyncCb := gio.AsyncReadyCallback(func(_ uintptr, resultPtr uintptr, _ uintptr) { | |
| 177 | + | if resultPtr == 0 { | |
| 178 | + | callback(nil) | |
| 179 | + | return | |
| 180 | + | } | |
| 181 | + | ||
| 182 | + | result := &gio.AsyncResultBase{Ptr: resultPtr} | |
| 183 | + | texture, err := db.GetFaviconFinish(result) | |
| 184 | + | if err != nil || texture == nil { | |
| 185 | + | callback(nil) | |
| 186 | + | return | |
| 187 | + | } | |
| 188 | + | ||
| 189 | + | callback(texture) | |
| 190 | + | }) | |
| 191 | + | ||
| 192 | + | db.GetFavicon(pageURL, nil, &asyncCb, 0) | |
| 169 | 193 | } | |
| @@ -6,6 +6,8 @@ import ( | |||||
| 6 | 6 | ||||
| 7 | "github.com/bnema/dumber/internal/application/port" | 7 | "github.com/bnema/dumber/internal/application/port" | ||
| 8 | "github.com/bnema/dumber/internal/infrastructure/filtering" | 8 | "github.com/bnema/dumber/internal/infrastructure/filtering" | ||
| 9 | + | "github.com/bnema/dumber/internal/logging" | |||
| 10 | + | "github.com/jwijenbergh/puregotk/v4/gio" | |||
| 9 | "github.com/rs/zerolog" | 11 | "github.com/rs/zerolog" | ||
| 10 | ) | 12 | ) | ||
| 11 | 13 | ||||
| @@ -40,8 +42,8 @@ func (a *webViewFactoryAdapter) CreateRelated(ctx context.Context, parentID port | |||||
| 40 | // WebViewPool methods use *WebView and require a context; this adapter adapts | 42 | // WebViewPool methods use *WebView and require a context; this adapter adapts | ||
| 41 | // the signatures to match the port interface. | 43 | // the signatures to match the port interface. | ||
| 42 | type webViewPoolAdapter struct { | 44 | type webViewPoolAdapter struct { | ||
| 43 | - | pool *WebViewPool | 45 | + | pool *WebViewPool |
| 44 | - | logger zerolog.Logger | 46 | + | ctx context.Context |
| 45 | } | 47 | } | ||
| 46 | 48 | ||||
| 47 | func (a *webViewPoolAdapter) Acquire(ctx context.Context) (port.WebView, error) { | 49 | func (a *webViewPoolAdapter) Acquire(ctx context.Context) (port.WebView, error) { | ||
| @@ -58,16 +60,16 @@ func (a *webViewPoolAdapter) Release(wv port.WebView) { | |||||
| 58 | } | 60 | } | ||
| 59 | wwv, ok := wv.(*WebView) | 61 | wwv, ok := wv.(*WebView) | ||
| 60 | if !ok { | 62 | if !ok { | ||
| 61 | - | a.logger.Warn(). | 63 | + | logging.FromContext(a.ctx).Warn(). |
| 62 | Str("concrete_type", fmt.Sprintf("%T", wv)). | 64 | Str("concrete_type", fmt.Sprintf("%T", wv)). | ||
| 63 | Msg("webViewPoolAdapter.Release: unexpected type, cannot release to pool") | 65 | Msg("webViewPoolAdapter.Release: unexpected type, cannot release to pool") | ||
| 64 | return | 66 | return | ||
| 65 | } | 67 | } | ||
| 66 | - | a.pool.Release(context.Background(), wwv) | 68 | + | a.pool.Release(a.ctx, wwv) |
| 67 | } | 69 | } | ||
| 68 | 70 | ||||
| 69 | func (a *webViewPoolAdapter) Prewarm(count int) { | 71 | func (a *webViewPoolAdapter) Prewarm(count int) { | ||
| 70 | - | a.pool.Prewarm(context.Background(), count) | 72 | + | a.pool.Prewarm(a.ctx, count) |
| 71 | } | 73 | } | ||
| 72 | 74 | ||||
| 73 | func (a *webViewPoolAdapter) Size() int { | 75 | func (a *webViewPoolAdapter) Size() int { | ||
| @@ -75,7 +77,7 @@ func (a *webViewPoolAdapter) Size() int { | |||||
| 75 | } | 77 | } | ||
| 76 | 78 | ||||
| 77 | func (a *webViewPoolAdapter) Close() { | 79 | func (a *webViewPoolAdapter) Close() { | ||
| 78 | - | a.pool.Close(context.Background()) | 80 | + | a.pool.Close(a.ctx) |
| 79 | } | 81 | } | ||
| 80 | 82 | ||||
| 81 | // --- SchemeHandler adapter --- | 83 | // --- SchemeHandler adapter --- | ||
| @@ -105,12 +107,15 @@ func (a *schemeHandlerAdapter) RegisterScheme(scheme string, _ func(uri string) | |||||
| 105 | // PostMessage is also not directly available on the internal type. | 107 | // PostMessage is also not directly available on the internal type. | ||
| 106 | type messageRouterAdapter struct { | 108 | type messageRouterAdapter struct { | ||
| 107 | router *MessageRouter | 109 | router *MessageRouter | ||
| 110 | + | logger zerolog.Logger | |||
| 108 | } | 111 | } | ||
| 109 | 112 | ||||
| 110 | - | func (*messageRouterAdapter) RegisterHandler(_ string, _ func(message string) (string, error)) { | 113 | + | func (a *messageRouterAdapter) RegisterHandler(name string, _ func(message string) (string, error)) { |
| 111 | // Internal MessageRouter.RegisterHandler takes a MessageHandler interface, not a plain func. | 114 | // Internal MessageRouter.RegisterHandler takes a MessageHandler interface, not a plain func. | ||
| 112 | // Wire up via RegisterHandler(msgType, MessageHandlerFunc{...}) when consumers are migrated. | 115 | // Wire up via RegisterHandler(msgType, MessageHandlerFunc{...}) when consumers are migrated. | ||
| 113 | - | panic("not implemented — use MessageRouter.RegisterHandler(msgType, MessageHandler) directly") | 116 | + | a.logger.Warn(). |
| 117 | + | Str("handler", name). | |||
| 118 | + | Msg("messageRouterAdapter.RegisterHandler: not implemented — use MessageRouter.RegisterHandler(msgType, MessageHandler) directly") | |||
| 114 | } | 119 | } | ||
| 115 | 120 | ||||
| 116 | func (*messageRouterAdapter) PostMessage(webviewID port.WebViewID, message string) error { | 121 | func (*messageRouterAdapter) PostMessage(webviewID port.WebViewID, message string) error { | ||
| @@ -118,7 +123,7 @@ func (*messageRouterAdapter) PostMessage(webviewID port.WebViewID, message strin | |||||
| 118 | if wv == nil { | 123 | if wv == nil { | ||
| 119 | return fmt.Errorf("webview %d not found", webviewID) | 124 | return fmt.Errorf("webview %d not found", webviewID) | ||
| 120 | } | 125 | } | ||
| 121 | - | wv.RunJavaScript(context.Background(), message, "") | 126 | + | wv.RunJavaScript(context.Background(), message) |
| 122 | return nil | 127 | return nil | ||
| 123 | } | 128 | } | ||
| 124 | 129 | ||||
| @@ -161,9 +166,28 @@ type faviconDatabaseAdapter struct { | |||||
| 161 | wkCtx *WebKitContext | 166 | wkCtx *WebKitContext | ||
| 162 | } | 167 | } | ||
| 163 | 168 | ||||
| 164 | - | func (*faviconDatabaseAdapter) GetFaviconAsync(_ string, callback func(port.Texture)) { | 169 | + | func (a *faviconDatabaseAdapter) GetFaviconAsync(pageURL string, callback func(port.Texture)) { |
| 165 | - | // FaviconDatabase async lookup is not yet wired through this adapter. | 170 | + | db := a.wkCtx.FaviconDatabase() |
| 166 | - | // The underlying API is: wkCtx.FaviconDatabase().GetFavicon(uri, callback). | 171 | + | if db == nil { |
| 167 | - | // This stub satisfies the interface contract; callers will receive nil. | 172 | + | callback(nil) |
| 168 | - | callback(nil) | 173 | + | return |
| 174 | + | } | |||
| 175 | + | ||||
| 176 | + | asyncCb := gio.AsyncReadyCallback(func(_ uintptr, resultPtr uintptr, _ uintptr) { | |||
| 177 | + | if resultPtr == 0 { | |||
| 178 | + | callback(nil) | |||
| 179 | + | return | |||
| 180 | + | } | |||
| 181 | + | ||||
| 182 | + | result := &gio.AsyncResultBase{Ptr: resultPtr} | |||
| 183 | + | texture, err := db.GetFaviconFinish(result) | |||
| 184 | + | if err != nil || texture == nil { | |||
| 185 | + | callback(nil) | |||
| 186 | + | return | |||
| 187 | + | } | |||
| 188 | + | ||||
| 189 | + | callback(texture) | |||
| 190 | + | }) | |||
| 191 | + | ||||
| 192 | + | db.GetFavicon(pageURL, nil, &asyncCb, 0) | |||
| 169 | } | 193 | } | ||
M internal/infrastructure/webkit/engine_init.go +11 -9
| @@ -34,7 +34,7 @@ func NewEngine( | |||
| 34 | 34 | engineConfigureRenderingEnvironment(ctx, cfg, wkCfg, &perfSettings, logger) | |
| 35 | 35 | logging.Trace().Mark("render_env") | |
| 36 | 36 | ||
| 37 | - | // --- Build WebKitContextOptions from opts + wkCfg + perfSettings --- | |
| 37 | + | // --- Build webKitContextOptions from opts + wkCfg + perfSettings --- | |
| 38 | 38 | wkOpts := engineBuildContextOptions(opts, wkCfg, &perfSettings) | |
| 39 | 39 | logger.Info(). | |
| 40 | 40 | Str("cookie_policy", string(wkOpts.CookiePolicy)). | |
| @@ -104,6 +104,7 @@ func NewEngine( | |||
| 104 | 104 | ||
| 105 | 105 | // --- Assemble Engine --- | |
| 106 | 106 | engine := &Engine{ | |
| 107 | + | ctx: ctx, | |
| 107 | 108 | wkCtx: wkCtx, | |
| 108 | 109 | settings: settings, | |
| 109 | 110 | injector: injector, | |
| @@ -134,10 +135,11 @@ func engineSurveyHardwareAndResolveProfile( | |||
| 134 | 135 | Uint64("vram_mb", hwInfo.VRAM/(1024*1024)). | |
| 135 | 136 | Msg("hardware survey completed") | |
| 136 | 137 | ||
| 137 | - | perfSettings := config.ResolvePerformanceProfile(&cfg.Performance, &hwInfo) | |
| 138 | + | perfCfg := config.PerformanceConfigFromEngine(&cfg.Engine) | |
| 139 | + | perfSettings := config.ResolvePerformanceProfile(&perfCfg, &hwInfo) | |
| 138 | 140 | logging.Trace().Mark("performance_profile") | |
| 139 | 141 | logger.Info(). | |
| 140 | - | Str("profile", string(cfg.Performance.Profile)). | |
| 142 | + | Str("profile", string(cfg.Engine.Profile)). | |
| 141 | 143 | Int("skia_cpu_threads", perfSettings.SkiaCPUPaintingThreads). | |
| 142 | 144 | Int("skia_gpu_threads", perfSettings.SkiaGPUPaintingThreads). | |
| 143 | 145 | Int("webview_pool_prewarm", perfSettings.WebViewPoolPrewarmCount). | |
| @@ -194,21 +196,21 @@ func engineConfigureRenderingEnvironment( | |||
| 194 | 196 | Msg("rendering environment configured") | |
| 195 | 197 | } | |
| 196 | 198 | ||
| 197 | - | // engineBuildContextOptions builds port.WebKitContextOptions from EngineOptions, wkCfg and perfSettings. | |
| 199 | + | // engineBuildContextOptions builds webKitContextOptions from EngineOptions, wkCfg and perfSettings. | |
| 198 | 200 | func engineBuildContextOptions( | |
| 199 | 201 | opts port.EngineOptions, | |
| 200 | 202 | wkCfg WebKitEngineConfig, | |
| 201 | 203 | perfSettings *config.ResolvedPerformanceSettings, | |
| 202 | - | ) port.WebKitContextOptions { | |
| 203 | - | cookiePolicy := port.WebKitCookiePolicyNoThirdParty | |
| 204 | + | ) webKitContextOptions { | |
| 205 | + | cp := cookiePolicyNoThirdParty | |
| 204 | 206 | if opts.CookiePolicy != "" { | |
| 205 | - | cookiePolicy = port.WebKitCookiePolicy(opts.CookiePolicy) | |
| 207 | + | cp = opts.CookiePolicy | |
| 206 | 208 | } | |
| 207 | 209 | ||
| 208 | - | wkOpts := port.WebKitContextOptions{ | |
| 210 | + | wkOpts := webKitContextOptions{ | |
| 209 | 211 | DataDir: opts.DataDir, | |
| 210 | 212 | CacheDir: opts.CacheDir, | |
| 211 | - | CookiePolicy: cookiePolicy, | |
| 213 | + | CookiePolicy: cp, | |
| 212 | 214 | ITPEnabled: wkCfg.ITPEnabled, | |
| 213 | 215 | } | |
| 214 | 216 | ||
| @@ -34,7 +34,7 @@ func NewEngine( | |||||
| 34 | engineConfigureRenderingEnvironment(ctx, cfg, wkCfg, &perfSettings, logger) | 34 | engineConfigureRenderingEnvironment(ctx, cfg, wkCfg, &perfSettings, logger) | ||
| 35 | logging.Trace().Mark("render_env") | 35 | logging.Trace().Mark("render_env") | ||
| 36 | 36 | ||||
| 37 | - | // --- Build WebKitContextOptions from opts + wkCfg + perfSettings --- | 37 | + | // --- Build webKitContextOptions from opts + wkCfg + perfSettings --- |
| 38 | wkOpts := engineBuildContextOptions(opts, wkCfg, &perfSettings) | 38 | wkOpts := engineBuildContextOptions(opts, wkCfg, &perfSettings) | ||
| 39 | logger.Info(). | 39 | logger.Info(). | ||
| 40 | Str("cookie_policy", string(wkOpts.CookiePolicy)). | 40 | Str("cookie_policy", string(wkOpts.CookiePolicy)). | ||
| @@ -104,6 +104,7 @@ func NewEngine( | |||||
| 104 | 104 | ||||
| 105 | // --- Assemble Engine --- | 105 | // --- Assemble Engine --- | ||
| 106 | engine := &Engine{ | 106 | engine := &Engine{ | ||
| 107 | + | ctx: ctx, | |||
| 107 | wkCtx: wkCtx, | 108 | wkCtx: wkCtx, | ||
| 108 | settings: settings, | 109 | settings: settings, | ||
| 109 | injector: injector, | 110 | injector: injector, | ||
| @@ -134,10 +135,11 @@ func engineSurveyHardwareAndResolveProfile( | |||||
| 134 | Uint64("vram_mb", hwInfo.VRAM/(1024*1024)). | 135 | Uint64("vram_mb", hwInfo.VRAM/(1024*1024)). | ||
| 135 | Msg("hardware survey completed") | 136 | Msg("hardware survey completed") | ||
| 136 | 137 | ||||
| 137 | - | perfSettings := config.ResolvePerformanceProfile(&cfg.Performance, &hwInfo) | 138 | + | perfCfg := config.PerformanceConfigFromEngine(&cfg.Engine) |
| 139 | + | perfSettings := config.ResolvePerformanceProfile(&perfCfg, &hwInfo) | |||
| 138 | logging.Trace().Mark("performance_profile") | 140 | logging.Trace().Mark("performance_profile") | ||
| 139 | logger.Info(). | 141 | logger.Info(). | ||
| 140 | - | Str("profile", string(cfg.Performance.Profile)). | 142 | + | Str("profile", string(cfg.Engine.Profile)). |
| 141 | Int("skia_cpu_threads", perfSettings.SkiaCPUPaintingThreads). | 143 | Int("skia_cpu_threads", perfSettings.SkiaCPUPaintingThreads). | ||
| 142 | Int("skia_gpu_threads", perfSettings.SkiaGPUPaintingThreads). | 144 | Int("skia_gpu_threads", perfSettings.SkiaGPUPaintingThreads). | ||
| 143 | Int("webview_pool_prewarm", perfSettings.WebViewPoolPrewarmCount). | 145 | Int("webview_pool_prewarm", perfSettings.WebViewPoolPrewarmCount). | ||
| @@ -194,21 +196,21 @@ func engineConfigureRenderingEnvironment( | |||||
| 194 | Msg("rendering environment configured") | 196 | Msg("rendering environment configured") | ||
| 195 | } | 197 | } | ||
| 196 | 198 | ||||
| 197 | - | // engineBuildContextOptions builds port.WebKitContextOptions from EngineOptions, wkCfg and perfSettings. | 199 | + | // engineBuildContextOptions builds webKitContextOptions from EngineOptions, wkCfg and perfSettings. |
| 198 | func engineBuildContextOptions( | 200 | func engineBuildContextOptions( | ||
| 199 | opts port.EngineOptions, | 201 | opts port.EngineOptions, | ||
| 200 | wkCfg WebKitEngineConfig, | 202 | wkCfg WebKitEngineConfig, | ||
| 201 | perfSettings *config.ResolvedPerformanceSettings, | 203 | perfSettings *config.ResolvedPerformanceSettings, | ||
| 202 | - | ) port.WebKitContextOptions { | 204 | + | ) webKitContextOptions { |
| 203 | - | cookiePolicy := port.WebKitCookiePolicyNoThirdParty | 205 | + | cp := cookiePolicyNoThirdParty |
| 204 | if opts.CookiePolicy != "" { | 206 | if opts.CookiePolicy != "" { | ||
| 205 | - | cookiePolicy = port.WebKitCookiePolicy(opts.CookiePolicy) | 207 | + | cp = opts.CookiePolicy |
| 206 | } | 208 | } | ||
| 207 | 209 | ||||
| 208 | - | wkOpts := port.WebKitContextOptions{ | 210 | + | wkOpts := webKitContextOptions{ |
| 209 | DataDir: opts.DataDir, | 211 | DataDir: opts.DataDir, | ||
| 210 | CacheDir: opts.CacheDir, | 212 | CacheDir: opts.CacheDir, | ||
| 211 | - | CookiePolicy: cookiePolicy, | 213 | + | CookiePolicy: cp, |
| 212 | ITPEnabled: wkCfg.ITPEnabled, | 214 | ITPEnabled: wkCfg.ITPEnabled, | ||
| 213 | } | 215 | } | ||
| 214 | 216 | ||||
M internal/infrastructure/webkit/factory.go +1 -1
| @@ -103,7 +103,7 @@ func (f *WebViewFactory) CreateRelated(ctx context.Context, parentID port.WebVie | |||
| 103 | 103 | ||
| 104 | 104 | // Set background color to match theme (eliminates white flash) | |
| 105 | 105 | if r, g, b, a := f.bg.get(); a > 0 { | |
| 106 | - | wv.SetBackgroundColor(r, g, b, a) | |
| 106 | + | wv.SetBackgroundColor(float64(r), float64(g), float64(b), float64(a)) | |
| 107 | 107 | } | |
| 108 | 108 | ||
| 109 | 109 | // Keep hidden until content is painted | |
| @@ -103,7 +103,7 @@ func (f *WebViewFactory) CreateRelated(ctx context.Context, parentID port.WebVie | |||||
| 103 | 103 | ||||
| 104 | // Set background color to match theme (eliminates white flash) | 104 | // Set background color to match theme (eliminates white flash) | ||
| 105 | if r, g, b, a := f.bg.get(); a > 0 { | 105 | if r, g, b, a := f.bg.get(); a > 0 { | ||
| 106 | - | wv.SetBackgroundColor(r, g, b, a) | 106 | + | wv.SetBackgroundColor(float64(r), float64(g), float64(b), float64(a)) |
| 107 | } | 107 | } | ||
| 108 | 108 | ||||
| 109 | // Keep hidden until content is painted | 109 | // Keep hidden until content is painted | ||
M internal/infrastructure/webkit/injector.go +25 -0
| @@ -413,3 +413,28 @@ func (ci *ContentInjector) InjectScripts(ctx context.Context, ucm *webkit.UserCo | |||
| 413 | 413 | ||
| 414 | 414 | log.Debug().Bool("prefers_dark", prefersDark).Bool("auto_copy", autoCopyEnabled).Msg("scripts injected") | |
| 415 | 415 | } | |
| 416 | + | ||
| 417 | + | // RefreshScripts clears and re-injects user scripts for a single WebView. | |
| 418 | + | // Implements port.ContentInjector. | |
| 419 | + | // Returns nil for "not applicable" cases (nil wv, wrong engine type, nil UCM). | |
| 420 | + | func (ci *ContentInjector) RefreshScripts(ctx context.Context, wv port.WebView) error { | |
| 421 | + | log := logging.FromContext(ctx).With().Str("component", "content-injector").Logger() | |
| 422 | + | if wv == nil { | |
| 423 | + | log.Debug().Msg("RefreshScripts: nil webview") | |
| 424 | + | return nil | |
| 425 | + | } | |
| 426 | + | wkWV, ok := wv.(*WebView) | |
| 427 | + | if !ok { | |
| 428 | + | log.Debug().Msg("RefreshScripts: webview is not *webkit.WebView") | |
| 429 | + | return nil | |
| 430 | + | } | |
| 431 | + | ucm := wkWV.UserContentManager() | |
| 432 | + | if ucm == nil { | |
| 433 | + | log.Debug().Uint64("webview_id", uint64(wv.ID())).Msg("RefreshScripts: nil UserContentManager") | |
| 434 | + | return nil | |
| 435 | + | } | |
| 436 | + | ucm.RemoveAllScripts() | |
| 437 | + | ucm.RemoveAllStyleSheets() | |
| 438 | + | ci.InjectScripts(ctx, ucm, wv.ID()) | |
| 439 | + | return nil | |
| 440 | + | } | |
| @@ -413,3 +413,28 @@ func (ci *ContentInjector) InjectScripts(ctx context.Context, ucm *webkit.UserCo | |||||
| 413 | 413 | ||||
| 414 | log.Debug().Bool("prefers_dark", prefersDark).Bool("auto_copy", autoCopyEnabled).Msg("scripts injected") | 414 | log.Debug().Bool("prefers_dark", prefersDark).Bool("auto_copy", autoCopyEnabled).Msg("scripts injected") | ||
| 415 | } | 415 | } | ||
| 416 | + | ||||
| 417 | + | // RefreshScripts clears and re-injects user scripts for a single WebView. | |||
| 418 | + | // Implements port.ContentInjector. | |||
| 419 | + | // Returns nil for "not applicable" cases (nil wv, wrong engine type, nil UCM). | |||
| 420 | + | func (ci *ContentInjector) RefreshScripts(ctx context.Context, wv port.WebView) error { | |||
| 421 | + | log := logging.FromContext(ctx).With().Str("component", "content-injector").Logger() | |||
| 422 | + | if wv == nil { | |||
| 423 | + | log.Debug().Msg("RefreshScripts: nil webview") | |||
| 424 | + | return nil | |||
| 425 | + | } | |||
| 426 | + | wkWV, ok := wv.(*WebView) | |||
| 427 | + | if !ok { | |||
| 428 | + | log.Debug().Msg("RefreshScripts: webview is not *webkit.WebView") | |||
| 429 | + | return nil | |||
| 430 | + | } | |||
| 431 | + | ucm := wkWV.UserContentManager() | |||
| 432 | + | if ucm == nil { | |||
| 433 | + | log.Debug().Uint64("webview_id", uint64(wv.ID())).Msg("RefreshScripts: nil UserContentManager") | |||
| 434 | + | return nil | |||
| 435 | + | } | |||
| 436 | + | ucm.RemoveAllScripts() | |||
| 437 | + | ucm.RemoveAllStyleSheets() | |||
| 438 | + | ci.InjectScripts(ctx, ucm, wv.ID()) | |||
| 439 | + | return nil | |||
| 440 | + | } | |||
M internal/infrastructure/webkit/messaging.go +2 -2
| @@ -276,7 +276,7 @@ func (r *MessageRouter) syncWebViewID(wv *WebView) { | |||
| 276 | 276 | return | |
| 277 | 277 | } | |
| 278 | 278 | script := fmt.Sprintf("window.__dumber_webview_id=%d;", uint64(wv.ID())) | |
| 279 | - | wv.RunJavaScript(r.baseCtx, script, "") | |
| 279 | + | wv.RunJavaScriptInWorld(r.baseCtx, script, "") | |
| 280 | 280 | } | |
| 281 | 281 | ||
| 282 | 282 | func (r *MessageRouter) markWebViewIDSynced(id WebViewID) bool { | |
| @@ -329,6 +329,6 @@ func (r *MessageRouter) dispatchResponse(ctx context.Context, webviewID WebViewI | |||
| 329 | 329 | string(data), | |
| 330 | 330 | ) | |
| 331 | 331 | ||
| 332 | - | wv.RunJavaScript(ctx, script, world) | |
| 332 | + | wv.RunJavaScriptInWorld(ctx, script, world) | |
| 333 | 333 | return nil | |
| 334 | 334 | } | |
| @@ -276,7 +276,7 @@ func (r *MessageRouter) syncWebViewID(wv *WebView) { | |||||
| 276 | return | 276 | return | ||
| 277 | } | 277 | } | ||
| 278 | script := fmt.Sprintf("window.__dumber_webview_id=%d;", uint64(wv.ID())) | 278 | script := fmt.Sprintf("window.__dumber_webview_id=%d;", uint64(wv.ID())) | ||
| 279 | - | wv.RunJavaScript(r.baseCtx, script, "") | 279 | + | wv.RunJavaScriptInWorld(r.baseCtx, script, "") |
| 280 | } | 280 | } | ||
| 281 | 281 | ||||
| 282 | func (r *MessageRouter) markWebViewIDSynced(id WebViewID) bool { | 282 | func (r *MessageRouter) markWebViewIDSynced(id WebViewID) bool { | ||
| @@ -329,6 +329,6 @@ func (r *MessageRouter) dispatchResponse(ctx context.Context, webviewID WebViewI | |||||
| 329 | string(data), | 329 | string(data), | ||
| 330 | ) | 330 | ) | ||
| 331 | 331 | ||||
| 332 | - | wv.RunJavaScript(ctx, script, world) | 332 | + | wv.RunJavaScriptInWorld(ctx, script, world) |
| 333 | return nil | 333 | return nil | ||
| 334 | } | 334 | } | ||
M internal/infrastructure/webkit/pool.go +1 -1
| @@ -159,7 +159,7 @@ func (p *WebViewPool) Acquire(ctx context.Context) (*WebView, error) { | |||
| 159 | 159 | case wv := <-p.pool: | |
| 160 | 160 | if wv != nil && !wv.IsDestroyed() { | |
| 161 | 161 | if r, g, b, a := p.bg.get(); a > 0 { | |
| 162 | - | wv.SetBackgroundColor(r, g, b, a) | |
| 162 | + | wv.SetBackgroundColor(float64(r), float64(g), float64(b), float64(a)) | |
| 163 | 163 | } | |
| 164 | 164 | wv.inner.AddCssClass("webview-themed") | |
| 165 | 165 | // Keep pooled WebViews hidden until we explicitly reveal them. | |
| @@ -159,7 +159,7 @@ func (p *WebViewPool) Acquire(ctx context.Context) (*WebView, error) { | |||||
| 159 | case wv := <-p.pool: | 159 | case wv := <-p.pool: | ||
| 160 | if wv != nil && !wv.IsDestroyed() { | 160 | if wv != nil && !wv.IsDestroyed() { | ||
| 161 | if r, g, b, a := p.bg.get(); a > 0 { | 161 | if r, g, b, a := p.bg.get(); a > 0 { | ||
| 162 | - | wv.SetBackgroundColor(r, g, b, a) | 162 | + | wv.SetBackgroundColor(float64(r), float64(g), float64(b), float64(a)) |
| 163 | } | 163 | } | ||
| 164 | wv.inner.AddCssClass("webview-themed") | 164 | wv.inner.AddCssClass("webview-themed") | ||
| 165 | // Keep pooled WebViews hidden until we explicitly reveal them. | 165 | // Keep pooled WebViews hidden until we explicitly reveal them. | ||
M internal/infrastructure/webkit/scheme_handler.go +8 -7
| @@ -347,7 +347,8 @@ func (h *DumbSchemeHandler) buildConfigResponse(cfg *config.Config) *SchemeRespo | |||
| 347 | 347 | } | |
| 348 | 348 | ||
| 349 | 349 | // Resolve performance profile with hardware info | |
| 350 | - | resolved := config.ResolvePerformanceProfile(&cfg.Performance, hw) | |
| 350 | + | perfCfg := config.PerformanceConfigFromEngine(&cfg.Engine) | |
| 351 | + | resolved := config.ResolvePerformanceProfile(&perfCfg, hw) | |
| 351 | 352 | ||
| 352 | 353 | resp := configPayload{ | |
| 353 | 354 | DefaultUIScale: cfg.DefaultUIScale, | |
| @@ -363,13 +364,13 @@ func (h *DumbSchemeHandler) buildConfigResponse(cfg *config.Config) *SchemeRespo | |||
| 363 | 364 | DarkPalette: cfg.Appearance.DarkPalette, | |
| 364 | 365 | }, | |
| 365 | 366 | Performance: configPerformancePayload{ | |
| 366 | - | Profile: string(cfg.Performance.Profile), | |
| 367 | + | Profile: string(cfg.Engine.Profile), | |
| 367 | 368 | Custom: configCustomPerformance{ | |
| 368 | - | SkiaCPUThreads: cfg.Performance.SkiaCPUPaintingThreads, | |
| 369 | - | SkiaGPUThreads: cfg.Performance.SkiaGPUPaintingThreads, | |
| 370 | - | WebProcessMemoryMB: cfg.Performance.WebProcessMemoryLimitMB, | |
| 371 | - | NetworkProcessMemoryMB: cfg.Performance.NetworkProcessMemoryLimitMB, | |
| 372 | - | WebViewPoolPrewarm: cfg.Performance.WebViewPoolPrewarmCount, | |
| 369 | + | SkiaCPUThreads: cfg.Engine.WebKit.SkiaCPUPaintingThreads, | |
| 370 | + | SkiaGPUThreads: cfg.Engine.WebKit.SkiaGPUPaintingThreads, | |
| 371 | + | WebProcessMemoryMB: cfg.Engine.WebKit.WebProcessMemoryLimitMB, | |
| 372 | + | NetworkProcessMemoryMB: cfg.Engine.WebKit.NetworkProcessMemoryLimitMB, | |
| 373 | + | WebViewPoolPrewarm: cfg.Engine.PoolPrewarmCount, | |
| 373 | 374 | }, | |
| 374 | 375 | Resolved: configResolvedPerformance{ | |
| 375 | 376 | SkiaCPUThreads: resolved.SkiaCPUPaintingThreads, | |
| @@ -347,7 +347,8 @@ func (h *DumbSchemeHandler) buildConfigResponse(cfg *config.Config) *SchemeRespo | |||||
| 347 | } | 347 | } | ||
| 348 | 348 | ||||
| 349 | // Resolve performance profile with hardware info | 349 | // Resolve performance profile with hardware info | ||
| 350 | - | resolved := config.ResolvePerformanceProfile(&cfg.Performance, hw) | 350 | + | perfCfg := config.PerformanceConfigFromEngine(&cfg.Engine) |
| 351 | + | resolved := config.ResolvePerformanceProfile(&perfCfg, hw) | |||
| 351 | 352 | ||||
| 352 | resp := configPayload{ | 353 | resp := configPayload{ | ||
| 353 | DefaultUIScale: cfg.DefaultUIScale, | 354 | DefaultUIScale: cfg.DefaultUIScale, | ||
| @@ -363,13 +364,13 @@ func (h *DumbSchemeHandler) buildConfigResponse(cfg *config.Config) *SchemeRespo | |||||
| 363 | DarkPalette: cfg.Appearance.DarkPalette, | 364 | DarkPalette: cfg.Appearance.DarkPalette, | ||
| 364 | }, | 365 | }, | ||
| 365 | Performance: configPerformancePayload{ | 366 | Performance: configPerformancePayload{ | ||
| 366 | - | Profile: string(cfg.Performance.Profile), | 367 | + | Profile: string(cfg.Engine.Profile), |
| 367 | Custom: configCustomPerformance{ | 368 | Custom: configCustomPerformance{ | ||
| 368 | - | SkiaCPUThreads: cfg.Performance.SkiaCPUPaintingThreads, | 369 | + | SkiaCPUThreads: cfg.Engine.WebKit.SkiaCPUPaintingThreads, |
| 369 | - | SkiaGPUThreads: cfg.Performance.SkiaGPUPaintingThreads, | 370 | + | SkiaGPUThreads: cfg.Engine.WebKit.SkiaGPUPaintingThreads, |
| 370 | - | WebProcessMemoryMB: cfg.Performance.WebProcessMemoryLimitMB, | 371 | + | WebProcessMemoryMB: cfg.Engine.WebKit.WebProcessMemoryLimitMB, |
| 371 | - | NetworkProcessMemoryMB: cfg.Performance.NetworkProcessMemoryLimitMB, | 372 | + | NetworkProcessMemoryMB: cfg.Engine.WebKit.NetworkProcessMemoryLimitMB, |
| 372 | - | WebViewPoolPrewarm: cfg.Performance.WebViewPoolPrewarmCount, | 373 | + | WebViewPoolPrewarm: cfg.Engine.PoolPrewarmCount, |
| 373 | }, | 374 | }, | ||
| 374 | Resolved: configResolvedPerformance{ | 375 | Resolved: configResolvedPerformance{ | ||
| 375 | SkiaCPUThreads: resolved.SkiaCPUPaintingThreads, | 376 | SkiaCPUThreads: resolved.SkiaCPUPaintingThreads, | ||
M internal/infrastructure/webkit/settings.go +4 -11
| @@ -65,7 +65,6 @@ func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.S | |||
| 65 | 65 | ||
| 66 | 66 | log.Debug(). | |
| 67 | 67 | Str("sans_font", cfg.Appearance.SansFont). | |
| 68 | - | Str("rendering_mode", string(cfg.Rendering.Mode)). | |
| 69 | 68 | Bool("developer_extras", cfg.Debug.EnableDevTools). | |
| 70 | 69 | Bool("webrtc_enabled", webrtcEnabled). | |
| 71 | 70 | Bool("media_stream_enabled", mediaStreamEnabled). | |
| @@ -93,21 +92,15 @@ func applyFontSettings(settings *webkit.Settings, cfg *config.Config) { | |||
| 93 | 92 | } | |
| 94 | 93 | } | |
| 95 | 94 | ||
| 96 | - | func applyRenderingSettings(settings *webkit.Settings, cfg *config.Config) { | |
| 97 | - | switch cfg.Rendering.Mode { | |
| 98 | - | case config.RenderingModeGPU: | |
| 99 | - | settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlwaysValue) | |
| 100 | - | case config.RenderingModeCPU: | |
| 101 | - | settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyNeverValue) | |
| 102 | - | case config.RenderingModeAuto: | |
| 103 | - | settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlwaysValue) | |
| 104 | - | } | |
| 95 | + | func applyRenderingSettings(_ *webkit.Settings, _ *config.Config) { | |
| 96 | + | // Hardware acceleration policy is now managed by the engine layer via | |
| 97 | + | // cfg.Engine.WebKit. No WebKit settings to apply here at the settings layer. | |
| 105 | 98 | } | |
| 106 | 99 | ||
| 107 | 100 | func applyDebugSettings(settings *webkit.Settings, cfg *config.Config) { | |
| 108 | 101 | settings.SetEnableDeveloperExtras(cfg.Debug.EnableDevTools) | |
| 109 | 102 | settings.SetEnableWriteConsoleMessagesToStdout(cfg.Logging.CaptureConsole) | |
| 110 | - | settings.SetDrawCompositingIndicators(cfg.Rendering.DrawCompositingIndicators) | |
| 103 | + | settings.SetDrawCompositingIndicators(cfg.Engine.WebKit.DrawCompositingIndicators) | |
| 111 | 104 | } | |
| 112 | 105 | ||
| 113 | 106 | func applyBrowsingSettings(settings *webkit.Settings) { | |
| @@ -65,7 +65,6 @@ func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.S | |||||
| 65 | 65 | ||||
| 66 | log.Debug(). | 66 | log.Debug(). | ||
| 67 | Str("sans_font", cfg.Appearance.SansFont). | 67 | Str("sans_font", cfg.Appearance.SansFont). | ||
| 68 | - | Str("rendering_mode", string(cfg.Rendering.Mode)). | |||
| 69 | Bool("developer_extras", cfg.Debug.EnableDevTools). | 68 | Bool("developer_extras", cfg.Debug.EnableDevTools). | ||
| 70 | Bool("webrtc_enabled", webrtcEnabled). | 69 | Bool("webrtc_enabled", webrtcEnabled). | ||
| 71 | Bool("media_stream_enabled", mediaStreamEnabled). | 70 | Bool("media_stream_enabled", mediaStreamEnabled). | ||
| @@ -93,21 +92,15 @@ func applyFontSettings(settings *webkit.Settings, cfg *config.Config) { | |||||
| 93 | } | 92 | } | ||
| 94 | } | 93 | } | ||
| 95 | 94 | ||||
| 96 | - | func applyRenderingSettings(settings *webkit.Settings, cfg *config.Config) { | 95 | + | func applyRenderingSettings(_ *webkit.Settings, _ *config.Config) { |
| 97 | - | switch cfg.Rendering.Mode { | 96 | + | // Hardware acceleration policy is now managed by the engine layer via |
| 98 | - | case config.RenderingModeGPU: | 97 | + | // cfg.Engine.WebKit. No WebKit settings to apply here at the settings layer. |
| 99 | - | settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlwaysValue) | |||
| 100 | - | case config.RenderingModeCPU: | |||
| 101 | - | settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyNeverValue) | |||
| 102 | - | case config.RenderingModeAuto: | |||
| 103 | - | settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyAlwaysValue) | |||
| 104 | - | } | |||
| 105 | } | 98 | } | ||
| 106 | 99 | ||||
| 107 | func applyDebugSettings(settings *webkit.Settings, cfg *config.Config) { | 100 | func applyDebugSettings(settings *webkit.Settings, cfg *config.Config) { | ||
| 108 | settings.SetEnableDeveloperExtras(cfg.Debug.EnableDevTools) | 101 | settings.SetEnableDeveloperExtras(cfg.Debug.EnableDevTools) | ||
| 109 | settings.SetEnableWriteConsoleMessagesToStdout(cfg.Logging.CaptureConsole) | 102 | settings.SetEnableWriteConsoleMessagesToStdout(cfg.Logging.CaptureConsole) | ||
| 110 | - | settings.SetDrawCompositingIndicators(cfg.Rendering.DrawCompositingIndicators) | 103 | + | settings.SetDrawCompositingIndicators(cfg.Engine.WebKit.DrawCompositingIndicators) |
| 111 | } | 104 | } | ||
| 112 | 105 | ||||
| 113 | func applyBrowsingSettings(settings *webkit.Settings) { | 106 | func applyBrowsingSettings(settings *webkit.Settings) { | ||
M internal/infrastructure/webkit/webview.go +46 -10
| @@ -1400,9 +1400,22 @@ func (wv *WebView) Title() string { | |||
| 1400 | 1400 | return wv.title | |
| 1401 | 1401 | } | |
| 1402 | 1402 | ||
| 1403 | - | // Favicon returns the current page favicon as a GdkTexture. | |
| 1403 | + | // Favicon returns the current page favicon as a Texture. | |
| 1404 | 1404 | // Returns nil if no favicon is available. | |
| 1405 | - | func (wv *WebView) Favicon() *gdk.Texture { | |
| 1405 | + | func (wv *WebView) Favicon() port.Texture { | |
| 1406 | + | if wv.destroyed.Load() { | |
| 1407 | + | return nil | |
| 1408 | + | } | |
| 1409 | + | tex := wv.inner.GetFavicon() | |
| 1410 | + | if tex == nil { | |
| 1411 | + | return nil | |
| 1412 | + | } | |
| 1413 | + | return tex | |
| 1414 | + | } | |
| 1415 | + | ||
| 1416 | + | // FaviconGdk returns the current page favicon as a *gdk.Texture. | |
| 1417 | + | // Used by internal WebKit code that needs the concrete type. | |
| 1418 | + | func (wv *WebView) FaviconGdk() *gdk.Texture { | |
| 1406 | 1419 | if wv.destroyed.Load() { | |
| 1407 | 1420 | return nil | |
| 1408 | 1421 | } | |
| @@ -1447,18 +1460,18 @@ func (wv *WebView) GetZoomLevel() float64 { | |||
| 1447 | 1460 | return wv.inner.GetZoomLevel() | |
| 1448 | 1461 | } | |
| 1449 | 1462 | ||
| 1450 | - | // SetBackgroundColor sets the WebView background color. | |
| 1463 | + | // SetBackgroundColor sets the WebView background color (port.WebView interface). | |
| 1451 | 1464 | // This color is shown before content is painted, eliminating white flash. | |
| 1452 | 1465 | // Values are in range 0.0-1.0 for red, green, blue, alpha. | |
| 1453 | - | func (wv *WebView) SetBackgroundColor(r, g, b, a float32) { | |
| 1466 | + | func (wv *WebView) SetBackgroundColor(r, g, b, a float64) { | |
| 1454 | 1467 | if wv.destroyed.Load() { | |
| 1455 | 1468 | return | |
| 1456 | 1469 | } | |
| 1457 | 1470 | rgba := &gdk.RGBA{ | |
| 1458 | - | Red: r, | |
| 1459 | - | Green: g, | |
| 1460 | - | Blue: b, | |
| 1461 | - | Alpha: a, | |
| 1471 | + | Red: float32(r), | |
| 1472 | + | Green: float32(g), | |
| 1473 | + | Blue: float32(b), | |
| 1474 | + | Alpha: float32(a), | |
| 1462 | 1475 | } | |
| 1463 | 1476 | wv.inner.SetBackgroundColor(rgba) | |
| 1464 | 1477 | } | |
| @@ -1469,6 +1482,19 @@ func (wv *WebView) ResetBackgroundToDefault() { | |||
| 1469 | 1482 | wv.SetBackgroundColor(1.0, 1.0, 1.0, 1.0) | |
| 1470 | 1483 | } | |
| 1471 | 1484 | ||
| 1485 | + | // NativeWidget returns the underlying GTK widget pointer for UI embedding. | |
| 1486 | + | // Implements port.NativeWidgetProvider. | |
| 1487 | + | func (wv *WebView) NativeWidget() uintptr { | |
| 1488 | + | if wv.destroyed.Load() { | |
| 1489 | + | return 0 | |
| 1490 | + | } | |
| 1491 | + | w := wv.Widget() | |
| 1492 | + | if w == nil { | |
| 1493 | + | return 0 | |
| 1494 | + | } | |
| 1495 | + | return w.Widget.GoPointer() | |
| 1496 | + | } | |
| 1497 | + | ||
| 1472 | 1498 | // Show makes the WebView widget visible. | |
| 1473 | 1499 | // This should be called after the WebView is ready to be displayed. | |
| 1474 | 1500 | func (wv *WebView) Show() { | |
| @@ -1576,6 +1602,10 @@ func (wv *WebView) SetCallbacks(callbacks *port.WebViewCallbacks) { | |||
| 1576 | 1602 | wv.OnWebProcessTerminated = nil | |
| 1577 | 1603 | } | |
| 1578 | 1604 | wv.OnPermissionRequest = callbacks.OnPermissionRequest | |
| 1605 | + | wv.OnLinkMiddleClick = callbacks.OnLinkMiddleClick | |
| 1606 | + | wv.OnEnterFullscreen = callbacks.OnEnterFullscreen | |
| 1607 | + | wv.OnLeaveFullscreen = callbacks.OnLeaveFullscreen | |
| 1608 | + | wv.OnAudioStateChanged = callbacks.OnAudioStateChanged | |
| 1579 | 1609 | } | |
| 1580 | 1610 | ||
| 1581 | 1611 | // ShowDevTools opens the WebKit inspector/developer tools. | |
| @@ -1969,10 +1999,16 @@ func (wv *WebView) shouldLogRunJSError(domain, signature string, nonFatal bool, | |||
| 1969 | 1999 | return shouldLog, count | |
| 1970 | 2000 | } | |
| 1971 | 2001 | ||
| 1972 | - | // RunJavaScript executes script in the specified world (empty for main world). | |
| 2002 | + | // RunJavaScript executes script in the main world (port.WebView interface). | |
| 2003 | + | // This is fire-and-forget: it does not block and errors are logged asynchronously. | |
| 2004 | + | func (wv *WebView) RunJavaScript(ctx context.Context, script string) { | |
| 2005 | + | wv.RunJavaScriptInWorld(ctx, script, "") | |
| 2006 | + | } | |
| 2007 | + | ||
| 2008 | + | // RunJavaScriptInWorld executes script in the specified world (empty for main world). | |
| 1973 | 2009 | // This is fire-and-forget: it does not block and errors are logged asynchronously. | |
| 1974 | 2010 | // Safe to call from any context including GTK signal handlers. | |
| 1975 | - | func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string) { | |
| 2011 | + | func (wv *WebView) RunJavaScriptInWorld(ctx context.Context, script, worldName string) { | |
| 1976 | 2012 | if wv.destroyed.Load() { | |
| 1977 | 2013 | return | |
| 1978 | 2014 | } | |
| @@ -1400,9 +1400,22 @@ func (wv *WebView) Title() string { | |||||
| 1400 | return wv.title | 1400 | return wv.title | ||
| 1401 | } | 1401 | } | ||
| 1402 | 1402 | ||||
| 1403 | - | // Favicon returns the current page favicon as a GdkTexture. | 1403 | + | // Favicon returns the current page favicon as a Texture. |
| 1404 | // Returns nil if no favicon is available. | 1404 | // Returns nil if no favicon is available. | ||
| 1405 | - | func (wv *WebView) Favicon() *gdk.Texture { | 1405 | + | func (wv *WebView) Favicon() port.Texture { |
| 1406 | + | if wv.destroyed.Load() { | |||
| 1407 | + | return nil | |||
| 1408 | + | } | |||
| 1409 | + | tex := wv.inner.GetFavicon() | |||
| 1410 | + | if tex == nil { | |||
| 1411 | + | return nil | |||
| 1412 | + | } | |||
| 1413 | + | return tex | |||
| 1414 | + | } | |||
| 1415 | + | ||||
| 1416 | + | // FaviconGdk returns the current page favicon as a *gdk.Texture. | |||
| 1417 | + | // Used by internal WebKit code that needs the concrete type. | |||
| 1418 | + | func (wv *WebView) FaviconGdk() *gdk.Texture { | |||
| 1406 | if wv.destroyed.Load() { | 1419 | if wv.destroyed.Load() { | ||
| 1407 | return nil | 1420 | return nil | ||
| 1408 | } | 1421 | } | ||
| @@ -1447,18 +1460,18 @@ func (wv *WebView) GetZoomLevel() float64 { | |||||
| 1447 | return wv.inner.GetZoomLevel() | 1460 | return wv.inner.GetZoomLevel() | ||
| 1448 | } | 1461 | } | ||
| 1449 | 1462 | ||||
| 1450 | - | // SetBackgroundColor sets the WebView background color. | 1463 | + | // SetBackgroundColor sets the WebView background color (port.WebView interface). |
| 1451 | // This color is shown before content is painted, eliminating white flash. | 1464 | // This color is shown before content is painted, eliminating white flash. | ||
| 1452 | // Values are in range 0.0-1.0 for red, green, blue, alpha. | 1465 | // Values are in range 0.0-1.0 for red, green, blue, alpha. | ||
| 1453 | - | func (wv *WebView) SetBackgroundColor(r, g, b, a float32) { | 1466 | + | func (wv *WebView) SetBackgroundColor(r, g, b, a float64) { |
| 1454 | if wv.destroyed.Load() { | 1467 | if wv.destroyed.Load() { | ||
| 1455 | return | 1468 | return | ||
| 1456 | } | 1469 | } | ||
| 1457 | rgba := &gdk.RGBA{ | 1470 | rgba := &gdk.RGBA{ | ||
| 1458 | - | Red: r, | 1471 | + | Red: float32(r), |
| 1459 | - | Green: g, | 1472 | + | Green: float32(g), |
| 1460 | - | Blue: b, | 1473 | + | Blue: float32(b), |
| 1461 | - | Alpha: a, | 1474 | + | Alpha: float32(a), |
| 1462 | } | 1475 | } | ||
| 1463 | wv.inner.SetBackgroundColor(rgba) | 1476 | wv.inner.SetBackgroundColor(rgba) | ||
| 1464 | } | 1477 | } | ||
| @@ -1469,6 +1482,19 @@ func (wv *WebView) ResetBackgroundToDefault() { | |||||
| 1469 | wv.SetBackgroundColor(1.0, 1.0, 1.0, 1.0) | 1482 | wv.SetBackgroundColor(1.0, 1.0, 1.0, 1.0) | ||
| 1470 | } | 1483 | } | ||
| 1471 | 1484 | ||||
| 1485 | + | // NativeWidget returns the underlying GTK widget pointer for UI embedding. | |||
| 1486 | + | // Implements port.NativeWidgetProvider. | |||
| 1487 | + | func (wv *WebView) NativeWidget() uintptr { | |||
| 1488 | + | if wv.destroyed.Load() { | |||
| 1489 | + | return 0 | |||
| 1490 | + | } | |||
| 1491 | + | w := wv.Widget() | |||
| 1492 | + | if w == nil { | |||
| 1493 | + | return 0 | |||
| 1494 | + | } | |||
| 1495 | + | return w.Widget.GoPointer() | |||
| 1496 | + | } | |||
| 1497 | + | ||||
| 1472 | // Show makes the WebView widget visible. | 1498 | // Show makes the WebView widget visible. | ||
| 1473 | // This should be called after the WebView is ready to be displayed. | 1499 | // This should be called after the WebView is ready to be displayed. | ||
| 1474 | func (wv *WebView) Show() { | 1500 | func (wv *WebView) Show() { | ||
| @@ -1576,6 +1602,10 @@ func (wv *WebView) SetCallbacks(callbacks *port.WebViewCallbacks) { | |||||
| 1576 | wv.OnWebProcessTerminated = nil | 1602 | wv.OnWebProcessTerminated = nil | ||
| 1577 | } | 1603 | } | ||
| 1578 | wv.OnPermissionRequest = callbacks.OnPermissionRequest | 1604 | wv.OnPermissionRequest = callbacks.OnPermissionRequest | ||
| 1605 | + | wv.OnLinkMiddleClick = callbacks.OnLinkMiddleClick | |||
| 1606 | + | wv.OnEnterFullscreen = callbacks.OnEnterFullscreen | |||
| 1607 | + | wv.OnLeaveFullscreen = callbacks.OnLeaveFullscreen | |||
| 1608 | + | wv.OnAudioStateChanged = callbacks.OnAudioStateChanged | |||
| 1579 | } | 1609 | } | ||
| 1580 | 1610 | ||||
| 1581 | // ShowDevTools opens the WebKit inspector/developer tools. | 1611 | // ShowDevTools opens the WebKit inspector/developer tools. | ||
| @@ -1969,10 +1999,16 @@ func (wv *WebView) shouldLogRunJSError(domain, signature string, nonFatal bool, | |||||
| 1969 | return shouldLog, count | 1999 | return shouldLog, count | ||
| 1970 | } | 2000 | } | ||
| 1971 | 2001 | ||||
| 1972 | - | // RunJavaScript executes script in the specified world (empty for main world). | 2002 | + | // RunJavaScript executes script in the main world (port.WebView interface). |
| 2003 | + | // This is fire-and-forget: it does not block and errors are logged asynchronously. | |||
| 2004 | + | func (wv *WebView) RunJavaScript(ctx context.Context, script string) { | |||
| 2005 | + | wv.RunJavaScriptInWorld(ctx, script, "") | |||
| 2006 | + | } | |||
| 2007 | + | ||||
| 2008 | + | // RunJavaScriptInWorld executes script in the specified world (empty for main world). | |||
| 1973 | // This is fire-and-forget: it does not block and errors are logged asynchronously. | 2009 | // This is fire-and-forget: it does not block and errors are logged asynchronously. | ||
| 1974 | // Safe to call from any context including GTK signal handlers. | 2010 | // Safe to call from any context including GTK signal handlers. | ||
| 1975 | - | func (wv *WebView) RunJavaScript(ctx context.Context, script, worldName string) { | 2011 | + | func (wv *WebView) RunJavaScriptInWorld(ctx context.Context, script, worldName string) { |
| 1976 | if wv.destroyed.Load() { | 2012 | if wv.destroyed.Load() { | ||
| 1977 | return | 2013 | return | ||
| 1978 | } | 2014 | } | ||
M internal/ui/adapter/favicon.go +14 -23
| @@ -5,12 +5,11 @@ import ( | |||
| 5 | 5 | "context" | |
| 6 | 6 | "sync" | |
| 7 | 7 | ||
| 8 | + | "github.com/bnema/dumber/internal/application/port" | |
| 8 | 9 | domainurl "github.com/bnema/dumber/internal/domain/url" | |
| 9 | 10 | "github.com/bnema/dumber/internal/infrastructure/favicon" | |
| 10 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 11 | 11 | "github.com/bnema/dumber/internal/logging" | |
| 12 | 12 | "github.com/jwijenbergh/puregotk/v4/gdk" | |
| 13 | - | "github.com/jwijenbergh/puregotk/v4/gio" | |
| 14 | 13 | "github.com/jwijenbergh/puregotk/v4/glib" | |
| 15 | 14 | "github.com/rs/zerolog" | |
| 16 | 15 | ) | |
| @@ -19,7 +18,7 @@ import ( | |||
| 19 | 18 | // gdk.Texture conversion and WebKit FaviconDatabase integration. | |
| 20 | 19 | type FaviconAdapter struct { | |
| 21 | 20 | service *favicon.Service | |
| 22 | - | faviconDB *webkit.FaviconDatabase | |
| 21 | + | faviconDB port.FaviconDatabase | |
| 23 | 22 | textureCache map[string]*gdk.Texture | |
| 24 | 23 | mu sync.RWMutex | |
| 25 | 24 | warnMu sync.Mutex | |
| @@ -29,8 +28,8 @@ type FaviconAdapter struct { | |||
| 29 | 28 | type warningLogFunc func(log *zerolog.Logger, err error) | |
| 30 | 29 | ||
| 31 | 30 | // NewFaviconAdapter creates a new FaviconAdapter. | |
| 32 | - | // The faviconDB can be nil if WebKit favicon database is not available. | |
| 33 | - | func NewFaviconAdapter(service *favicon.Service, faviconDB *webkit.FaviconDatabase) *FaviconAdapter { | |
| 31 | + | // The faviconDB can be nil if a favicon database is not available. | |
| 32 | + | func NewFaviconAdapter(service *favicon.Service, faviconDB port.FaviconDatabase) *FaviconAdapter { | |
| 34 | 33 | return &FaviconAdapter{ | |
| 35 | 34 | service: service, | |
| 36 | 35 | faviconDB: faviconDB, | |
| @@ -127,32 +126,24 @@ func (a *FaviconAdapter) GetOrFetch(ctx context.Context, pageURL string, callbac | |||
| 127 | 126 | }() | |
| 128 | 127 | } | |
| 129 | 128 | ||
| 130 | - | // Try WebKit FaviconDatabase if available | |
| 129 | + | // Try engine FaviconDatabase if available | |
| 131 | 130 | if a.faviconDB != nil { | |
| 132 | - | asyncCb := gio.AsyncReadyCallback(func(_ uintptr, resultPtr uintptr, _ uintptr) { | |
| 133 | - | if resultPtr == 0 { | |
| 134 | - | log.Debug().Str("domain", domain).Msg("favicon not in webkit db, fetching via service") | |
| 131 | + | a.faviconDB.GetFaviconAsync(pageURL, func(tex port.Texture) { | |
| 132 | + | if tex == nil { | |
| 133 | + | log.Debug().Str("domain", domain).Msg("favicon not in engine db, fetching via service") | |
| 135 | 134 | fetchViaService() | |
| 136 | 135 | return | |
| 137 | 136 | } | |
| 138 | - | ||
| 139 | - | result := &gio.AsyncResultBase{Ptr: resultPtr} | |
| 140 | - | texture, err := a.faviconDB.GetFaviconFinish(result) | |
| 141 | - | if err != nil || texture == nil { | |
| 142 | - | log.Debug().Str("domain", domain).Msg("favicon not in webkit db, fetching via service") | |
| 137 | + | // Convert port.Texture to *gdk.Texture | |
| 138 | + | gdkTex, ok := tex.(*gdk.Texture) | |
| 139 | + | if !ok { | |
| 143 | 140 | fetchViaService() | |
| 144 | 141 | return | |
| 145 | 142 | } | |
| 146 | - | ||
| 147 | - | // Found in WebKit database | |
| 148 | - | a.setTexture(domain, texture) | |
| 149 | - | invokeCallback(texture) | |
| 150 | - | ||
| 151 | - | // Ensure disk cache is populated (async) | |
| 152 | - | go a.service.EnsureDiskCache(ctx, domain) | |
| 143 | + | a.setTexture(domain, gdkTex) | |
| 144 | + | invokeCallback(gdkTex) | |
| 145 | + | a.saveFaviconToDisk(ctx, domain, gdkTex) | |
| 153 | 146 | }) | |
| 154 | - | ||
| 155 | - | a.faviconDB.GetFavicon(pageURL, nil, &asyncCb, 0) | |
| 156 | 147 | return | |
| 157 | 148 | } | |
| 158 | 149 | ||
| @@ -5,12 +5,11 @@ import ( | |||||
| 5 | "context" | 5 | "context" | ||
| 6 | "sync" | 6 | "sync" | ||
| 7 | 7 | ||||
| 8 | + | "github.com/bnema/dumber/internal/application/port" | |||
| 8 | domainurl "github.com/bnema/dumber/internal/domain/url" | 9 | domainurl "github.com/bnema/dumber/internal/domain/url" | ||
| 9 | "github.com/bnema/dumber/internal/infrastructure/favicon" | 10 | "github.com/bnema/dumber/internal/infrastructure/favicon" | ||
| 10 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |||
| 11 | "github.com/bnema/dumber/internal/logging" | 11 | "github.com/bnema/dumber/internal/logging" | ||
| 12 | "github.com/jwijenbergh/puregotk/v4/gdk" | 12 | "github.com/jwijenbergh/puregotk/v4/gdk" | ||
| 13 | - | "github.com/jwijenbergh/puregotk/v4/gio" | |||
| 14 | "github.com/jwijenbergh/puregotk/v4/glib" | 13 | "github.com/jwijenbergh/puregotk/v4/glib" | ||
| 15 | "github.com/rs/zerolog" | 14 | "github.com/rs/zerolog" | ||
| 16 | ) | 15 | ) | ||
| @@ -19,7 +18,7 @@ import ( | |||||
| 19 | // gdk.Texture conversion and WebKit FaviconDatabase integration. | 18 | // gdk.Texture conversion and WebKit FaviconDatabase integration. | ||
| 20 | type FaviconAdapter struct { | 19 | type FaviconAdapter struct { | ||
| 21 | service *favicon.Service | 20 | service *favicon.Service | ||
| 22 | - | faviconDB *webkit.FaviconDatabase | 21 | + | faviconDB port.FaviconDatabase |
| 23 | textureCache map[string]*gdk.Texture | 22 | textureCache map[string]*gdk.Texture | ||
| 24 | mu sync.RWMutex | 23 | mu sync.RWMutex | ||
| 25 | warnMu sync.Mutex | 24 | warnMu sync.Mutex | ||
| @@ -29,8 +28,8 @@ type FaviconAdapter struct { | |||||
| 29 | type warningLogFunc func(log *zerolog.Logger, err error) | 28 | type warningLogFunc func(log *zerolog.Logger, err error) | ||
| 30 | 29 | ||||
| 31 | // NewFaviconAdapter creates a new FaviconAdapter. | 30 | // NewFaviconAdapter creates a new FaviconAdapter. | ||
| 32 | - | // The faviconDB can be nil if WebKit favicon database is not available. | 31 | + | // The faviconDB can be nil if a favicon database is not available. |
| 33 | - | func NewFaviconAdapter(service *favicon.Service, faviconDB *webkit.FaviconDatabase) *FaviconAdapter { | 32 | + | func NewFaviconAdapter(service *favicon.Service, faviconDB port.FaviconDatabase) *FaviconAdapter { |
| 34 | return &FaviconAdapter{ | 33 | return &FaviconAdapter{ | ||
| 35 | service: service, | 34 | service: service, | ||
| 36 | faviconDB: faviconDB, | 35 | faviconDB: faviconDB, | ||
| @@ -127,32 +126,24 @@ func (a *FaviconAdapter) GetOrFetch(ctx context.Context, pageURL string, callbac | |||||
| 127 | }() | 126 | }() | ||
| 128 | } | 127 | } | ||
| 129 | 128 | ||||
| 130 | - | // Try WebKit FaviconDatabase if available | 129 | + | // Try engine FaviconDatabase if available |
| 131 | if a.faviconDB != nil { | 130 | if a.faviconDB != nil { | ||
| 132 | - | asyncCb := gio.AsyncReadyCallback(func(_ uintptr, resultPtr uintptr, _ uintptr) { | 131 | + | a.faviconDB.GetFaviconAsync(pageURL, func(tex port.Texture) { |
| 133 | - | if resultPtr == 0 { | 132 | + | if tex == nil { |
| 134 | - | log.Debug().Str("domain", domain).Msg("favicon not in webkit db, fetching via service") | 133 | + | log.Debug().Str("domain", domain).Msg("favicon not in engine db, fetching via service") |
| 135 | fetchViaService() | 134 | fetchViaService() | ||
| 136 | return | 135 | return | ||
| 137 | } | 136 | } | ||
| 138 | - | 137 | + | // Convert port.Texture to *gdk.Texture | |
| 139 | - | result := &gio.AsyncResultBase{Ptr: resultPtr} | 138 | + | gdkTex, ok := tex.(*gdk.Texture) |
| 140 | - | texture, err := a.faviconDB.GetFaviconFinish(result) | 139 | + | if !ok { |
| 141 | - | if err != nil || texture == nil { | |||
| 142 | - | log.Debug().Str("domain", domain).Msg("favicon not in webkit db, fetching via service") | |||
| 143 | fetchViaService() | 140 | fetchViaService() | ||
| 144 | return | 141 | return | ||
| 145 | } | 142 | } | ||
| 146 | - | 143 | + | a.setTexture(domain, gdkTex) | |
| 147 | - | // Found in WebKit database | 144 | + | invokeCallback(gdkTex) |
| 148 | - | a.setTexture(domain, texture) | 145 | + | a.saveFaviconToDisk(ctx, domain, gdkTex) |
| 149 | - | invokeCallback(texture) | |||
| 150 | - | ||||
| 151 | - | // Ensure disk cache is populated (async) | |||
| 152 | - | go a.service.EnsureDiskCache(ctx, domain) | |||
| 153 | }) | 146 | }) | ||
| 154 | - | ||||
| 155 | - | a.faviconDB.GetFavicon(pageURL, nil, &asyncCb, 0) | |||
| 156 | return | 147 | return | ||
| 157 | } | 148 | } | ||
| 158 | 149 | ||||
M internal/ui/app.go +65 -51
| @@ -102,14 +102,9 @@ type App struct { | |||
| 102 | 102 | ||
| 103 | 103 | // Engine (port-level and concrete for webkit-specific operations) | |
| 104 | 104 | engine port.Engine | |
| 105 | - | wkEngine *webkit.Engine | |
| 105 | + | wkEngine *webkit.Engine // single webkit escape hatch; all webkit-specific ops go through this | |
| 106 | 106 | ||
| 107 | 107 | // Web content (managed by content.Coordinator) | |
| 108 | - | pool *webkit.WebViewPool | |
| 109 | - | webViewFactory *webkit.WebViewFactory | |
| 110 | - | injector *webkit.ContentInjector | |
| 111 | - | router *webkit.MessageRouter | |
| 112 | - | settings *webkit.SettingsManager | |
| 113 | 108 | faviconAdapter *adapter.FaviconAdapter | |
| 114 | 109 | ||
| 115 | 110 | // App-level toaster for system notifications (filter status, etc.) | |
| @@ -191,18 +186,20 @@ func New(deps *Dependencies) (*App, error) { | |||
| 191 | 186 | // Type-assert engine to concrete *webkit.Engine for webkit-specific operations. | |
| 192 | 187 | if wke, ok := deps.Engine.(*webkit.Engine); ok { | |
| 193 | 188 | app.wkEngine = wke | |
| 194 | - | app.pool = wke.InternalPool() | |
| 195 | - | app.injector = wke.InternalInjector() | |
| 196 | - | app.router = wke.InternalMessageRouter() | |
| 197 | - | app.settings = wke.InternalSettings() | |
| 198 | 189 | } | |
| 199 | - | if app.router == nil { | |
| 200 | - | app.router = webkit.NewMessageRouter(ctx) | |
| 190 | + | ||
| 191 | + | // Resolve the message router via wkEngine, with a standalone fallback. | |
| 192 | + | var router *webkit.MessageRouter | |
| 193 | + | if app.wkEngine != nil { | |
| 194 | + | router = app.wkEngine.InternalMessageRouter() | |
| 195 | + | } | |
| 196 | + | if router == nil { | |
| 197 | + | router = webkit.NewMessageRouter(ctx) | |
| 201 | 198 | } | |
| 202 | 199 | ||
| 203 | 200 | // Register message handlers | |
| 204 | - | if app.router != nil { | |
| 205 | - | if err := handlers.RegisterAll(ctx, app.router, handlers.Config{ | |
| 201 | + | if router != nil { | |
| 202 | + | if err := handlers.RegisterAll(ctx, router, handlers.Config{ | |
| 206 | 203 | HistoryUC: deps.HistoryUC, | |
| 207 | 204 | FavoritesUC: deps.FavoritesUC, | |
| 208 | 205 | Clipboard: deps.Clipboard, | |
| @@ -249,8 +246,10 @@ func (a *App) Run(ctx context.Context, args []string) int { | |||
| 249 | 246 | ||
| 250 | 247 | // Refresh scripts in pooled WebViews that were prewarmed before adw.Init(). | |
| 251 | 248 | // They have the wrong dark mode preference injected; re-inject with correct value. | |
| 252 | - | if a.pool != nil { | |
| 253 | - | a.pool.RefreshScripts(ctx) | |
| 249 | + | if a.wkEngine != nil { | |
| 250 | + | if pool := a.wkEngine.InternalPool(); pool != nil { | |
| 251 | + | pool.RefreshScripts(ctx) | |
| 252 | + | } | |
| 254 | 253 | } | |
| 255 | 254 | } | |
| 256 | 255 | ||
| @@ -375,7 +374,12 @@ func (a *App) setupPoolBackgroundColor(ctx context.Context) { | |||
| 375 | 374 | ||
| 376 | 375 | // Set theme background color on pool to eliminate white flash. | |
| 377 | 376 | // Must be done before any WebView creation so WebViews get the correct color. | |
| 378 | - | if a.pool == nil { | |
| 377 | + | if a.wkEngine == nil { | |
| 378 | + | log.Debug().Msg("webview pool not available; skipping background color setup") | |
| 379 | + | return | |
| 380 | + | } | |
| 381 | + | pool := a.wkEngine.InternalPool() | |
| 382 | + | if pool == nil { | |
| 379 | 383 | log.Debug().Msg("webview pool not available; skipping background color setup") | |
| 380 | 384 | return | |
| 381 | 385 | } | |
| @@ -385,16 +389,20 @@ func (a *App) setupPoolBackgroundColor(ctx context.Context) { | |||
| 385 | 389 | } | |
| 386 | 390 | ||
| 387 | 391 | r, g, b, alpha := a.deps.Theme.GetBackgroundRGBA() | |
| 388 | - | a.pool.SetBackgroundColor(r, g, b, alpha) | |
| 392 | + | pool.SetBackgroundColor(r, g, b, alpha) | |
| 389 | 393 | log.Debug().Msg("configured webview pool background color") | |
| 390 | 394 | } | |
| 391 | 395 | ||
| 392 | 396 | func (a *App) prewarmWebViewPoolAsync(ctx context.Context) { | |
| 393 | 397 | // Prewarm WebView pool after startup so cold-start navigation is not blocked. | |
| 394 | - | if a.pool == nil { | |
| 398 | + | if a.wkEngine == nil { | |
| 395 | 399 | return | |
| 396 | 400 | } | |
| 397 | - | a.pool.PrewarmAsync(ctx, 0) | |
| 401 | + | pool := a.wkEngine.InternalPool() | |
| 402 | + | if pool == nil { | |
| 403 | + | return | |
| 404 | + | } | |
| 405 | + | pool.PrewarmAsync(ctx, 0) | |
| 398 | 406 | } | |
| 399 | 407 | ||
| 400 | 408 | func (a *App) createMainWindow(ctx context.Context) error { | |
| @@ -558,12 +566,20 @@ func (a *App) initAccentPicker(ctx context.Context) { | |||
| 558 | 566 | func (a *App) registerAccentHandlers(ctx context.Context) { | |
| 559 | 567 | log := logging.FromContext(ctx) | |
| 560 | 568 | ||
| 561 | - | if a.router == nil || a.insertAccentUC == nil { | |
| 562 | - | log.Debug().Msg("router or insertAccentUC not available, skipping accent handler registration") | |
| 569 | + | if a.insertAccentUC == nil { | |
| 570 | + | log.Debug().Msg("insertAccentUC not available, skipping accent handler registration") | |
| 571 | + | return | |
| 572 | + | } | |
| 573 | + | var router *webkit.MessageRouter | |
| 574 | + | if a.wkEngine != nil { | |
| 575 | + | router = a.wkEngine.InternalMessageRouter() | |
| 576 | + | } | |
| 577 | + | if router == nil { | |
| 578 | + | log.Debug().Msg("router not available, skipping accent handler registration") | |
| 563 | 579 | return | |
| 564 | 580 | } | |
| 565 | 581 | ||
| 566 | - | if err := handlers.RegisterAccentHandlers(ctx, a.router, a.insertAccentUC); err != nil { | |
| 582 | + | if err := handlers.RegisterAccentHandlers(ctx, router, a.insertAccentUC); err != nil { | |
| 567 | 583 | log.Error().Err(err).Msg("failed to register accent handlers") | |
| 568 | 584 | } else { | |
| 569 | 585 | log.Info().Msg("registered accent key handlers") | |
| @@ -1492,8 +1508,10 @@ func (a *App) onShutdown(ctx context.Context) { | |||
| 1492 | 1508 | for _, tabID := range tabIDs { | |
| 1493 | 1509 | a.releaseFloatingSessionsForTab(ctx, tabID) | |
| 1494 | 1510 | } | |
| 1495 | - | if a.pool != nil { | |
| 1496 | - | a.pool.Close(ctx) | |
| 1511 | + | if a.engine != nil { | |
| 1512 | + | if err := a.engine.Close(); err != nil { | |
| 1513 | + | log.Warn().Err(err).Msg("failed to close engine") | |
| 1514 | + | } | |
| 1497 | 1515 | } | |
| 1498 | 1516 | // Close idle inhibitor to release D-Bus connection | |
| 1499 | 1517 | if a.deps.IdleInhibitor != nil { | |
| @@ -1515,17 +1533,14 @@ func (a *App) initCoordinators(ctx context.Context) { | |||
| 1515 | 1533 | return a.activeWorkspace(), a.activeWorkspaceView() | |
| 1516 | 1534 | } | |
| 1517 | 1535 | ||
| 1518 | - | // Create FaviconAdapter with service and WebKit FaviconDatabase | |
| 1519 | - | var faviconDB *webkit.FaviconDatabase | |
| 1520 | - | if a.wkEngine != nil { | |
| 1521 | - | faviconDB = a.wkEngine.InternalContext().FaviconDatabase() | |
| 1522 | - | } | |
| 1523 | - | a.faviconAdapter = adapter.NewFaviconAdapter(a.deps.FaviconService, faviconDB) | |
| 1536 | + | // Create FaviconAdapter with service and engine FaviconDatabase | |
| 1537 | + | a.faviconAdapter = adapter.NewFaviconAdapter(a.deps.FaviconService, a.engine.FaviconDatabase()) | |
| 1524 | 1538 | ||
| 1525 | 1539 | // 1. Content Coordinator (no dependencies on other coordinators) | |
| 1526 | 1540 | a.contentCoord = content.NewCoordinator( | |
| 1527 | 1541 | ctx, | |
| 1528 | 1542 | a.engine.Pool(), | |
| 1543 | + | a.engine.ContentInjector(), | |
| 1529 | 1544 | a.widgetFactory, | |
| 1530 | 1545 | a.faviconAdapter, | |
| 1531 | 1546 | getActiveWS, | |
| @@ -1602,21 +1617,12 @@ func (a *App) initCoordinators(ctx context.Context) { | |||
| 1602 | 1617 | a.wsCoord.SetOnStateChanged(a.MarkDirty) | |
| 1603 | 1618 | ||
| 1604 | 1619 | // Wire popup handling | |
| 1605 | - | var wkCtx *webkit.WebKitContext | |
| 1606 | - | if a.wkEngine != nil { | |
| 1607 | - | wkCtx = a.wkEngine.InternalContext() | |
| 1608 | - | } | |
| 1609 | - | a.webViewFactory = webkit.NewWebViewFactory( | |
| 1610 | - | wkCtx, | |
| 1611 | - | a.settings, | |
| 1612 | - | a.pool, | |
| 1613 | - | a.injector, | |
| 1614 | - | a.router, | |
| 1615 | - | ) | |
| 1616 | - | // Set theme background color on factory to eliminate white flash | |
| 1617 | - | if a.deps.Theme != nil { | |
| 1620 | + | // Set theme background color on the engine's popup factory to eliminate white flash. | |
| 1621 | + | if a.wkEngine != nil && a.deps.Theme != nil { | |
| 1618 | 1622 | r, g, b, alpha := a.deps.Theme.GetBackgroundRGBA() | |
| 1619 | - | a.webViewFactory.SetBackgroundColor(r, g, b, alpha) | |
| 1623 | + | if f := a.wkEngine.InternalFactory(); f != nil { | |
| 1624 | + | f.SetBackgroundColor(r, g, b, alpha) | |
| 1625 | + | } | |
| 1620 | 1626 | } | |
| 1621 | 1627 | a.contentCoord.SetPopupConfig( | |
| 1622 | 1628 | a.engine.Factory(), | |
| @@ -3095,8 +3101,10 @@ func (a *App) applyAppearanceConfig(ctx context.Context, cfg *config.Config) { | |||
| 3095 | 3101 | } | |
| 3096 | 3102 | ||
| 3097 | 3103 | // Update WebKit settings manager | |
| 3098 | - | if a.settings != nil { | |
| 3099 | - | a.settings.UpdateFromConfig(ctx, cfg) | |
| 3104 | + | if a.wkEngine != nil { | |
| 3105 | + | if settings := a.wkEngine.InternalSettings(); settings != nil { | |
| 3106 | + | settings.UpdateFromConfig(ctx, cfg) | |
| 3107 | + | } | |
| 3100 | 3108 | } | |
| 3101 | 3109 | ||
| 3102 | 3110 | // Apply settings to existing webviews via coordinator | |
| @@ -3112,22 +3120,28 @@ func (a *App) applyAppearanceConfig(ctx context.Context, cfg *config.Config) { | |||
| 3112 | 3120 | } | |
| 3113 | 3121 | a.deps.Theme.UpdateFromConfig(ctx, cfg, display) | |
| 3114 | 3122 | ||
| 3123 | + | // Resolve injector once for all webkit-specific theme updates below. | |
| 3124 | + | var injector *webkit.ContentInjector | |
| 3125 | + | if a.wkEngine != nil { | |
| 3126 | + | injector = a.wkEngine.InternalInjector() | |
| 3127 | + | } | |
| 3128 | + | ||
| 3115 | 3129 | // Update find highlight CSS for future navigations | |
| 3116 | - | if a.injector != nil { | |
| 3130 | + | if injector != nil { | |
| 3117 | 3131 | findCSS := theme.GenerateFindHighlightCSS(a.deps.Theme.GetCurrentPalette()) | |
| 3118 | - | if err := a.injector.InjectFindHighlightCSS(ctx, findCSS); err != nil { | |
| 3132 | + | if err := injector.InjectFindHighlightCSS(ctx, findCSS); err != nil { | |
| 3119 | 3133 | log.Warn().Err(err).Msg("failed to update find highlight CSS") | |
| 3120 | 3134 | } | |
| 3121 | 3135 | } | |
| 3122 | 3136 | ||
| 3123 | - | prepareThemeUC := usecase.NewPrepareWebUIThemeUseCase(a.injector) | |
| 3137 | + | prepareThemeUC := usecase.NewPrepareWebUIThemeUseCase(injector) | |
| 3124 | 3138 | cssText := a.deps.Theme.GetWebUIThemeCSS() | |
| 3125 | 3139 | if err := prepareThemeUC.Execute(ctx, usecase.PrepareWebUIThemeInput{CSSVars: cssText}); err != nil { | |
| 3126 | 3140 | log.Warn().Err(err).Msg("failed to update WebUI theme CSS") | |
| 3127 | 3141 | } | |
| 3128 | 3142 | ||
| 3129 | 3143 | // Refresh injected scripts so future navigations use the latest theme. | |
| 3130 | - | if a.contentCoord != nil && a.injector != nil { | |
| 3144 | + | if a.contentCoord != nil && injector != nil { | |
| 3131 | 3145 | a.contentCoord.RefreshInjectedScriptsToAll(ctx) | |
| 3132 | 3146 | } | |
| 3133 | 3147 | ||
| @@ -102,14 +102,9 @@ type App struct { | |||||
| 102 | 102 | ||||
| 103 | // Engine (port-level and concrete for webkit-specific operations) | 103 | // Engine (port-level and concrete for webkit-specific operations) | ||
| 104 | engine port.Engine | 104 | engine port.Engine | ||
| 105 | - | wkEngine *webkit.Engine | 105 | + | wkEngine *webkit.Engine // single webkit escape hatch; all webkit-specific ops go through this |
| 106 | 106 | ||||
| 107 | // Web content (managed by content.Coordinator) | 107 | // Web content (managed by content.Coordinator) | ||
| 108 | - | pool *webkit.WebViewPool | |||
| 109 | - | webViewFactory *webkit.WebViewFactory | |||
| 110 | - | injector *webkit.ContentInjector | |||
| 111 | - | router *webkit.MessageRouter | |||
| 112 | - | settings *webkit.SettingsManager | |||
| 113 | faviconAdapter *adapter.FaviconAdapter | 108 | faviconAdapter *adapter.FaviconAdapter | ||
| 114 | 109 | ||||
| 115 | // App-level toaster for system notifications (filter status, etc.) | 110 | // App-level toaster for system notifications (filter status, etc.) | ||
| @@ -191,18 +186,20 @@ func New(deps *Dependencies) (*App, error) { | |||||
| 191 | // Type-assert engine to concrete *webkit.Engine for webkit-specific operations. | 186 | // Type-assert engine to concrete *webkit.Engine for webkit-specific operations. | ||
| 192 | if wke, ok := deps.Engine.(*webkit.Engine); ok { | 187 | if wke, ok := deps.Engine.(*webkit.Engine); ok { | ||
| 193 | app.wkEngine = wke | 188 | app.wkEngine = wke | ||
| 194 | - | app.pool = wke.InternalPool() | |||
| 195 | - | app.injector = wke.InternalInjector() | |||
| 196 | - | app.router = wke.InternalMessageRouter() | |||
| 197 | - | app.settings = wke.InternalSettings() | |||
| 198 | } | 189 | } | ||
| 199 | - | if app.router == nil { | 190 | + | |
| 200 | - | app.router = webkit.NewMessageRouter(ctx) | 191 | + | // Resolve the message router via wkEngine, with a standalone fallback. |
| 192 | + | var router *webkit.MessageRouter | |||
| 193 | + | if app.wkEngine != nil { | |||
| 194 | + | router = app.wkEngine.InternalMessageRouter() | |||
| 195 | + | } | |||
| 196 | + | if router == nil { | |||
| 197 | + | router = webkit.NewMessageRouter(ctx) | |||
| 201 | } | 198 | } | ||
| 202 | 199 | ||||
| 203 | // Register message handlers | 200 | // Register message handlers | ||
| 204 | - | if app.router != nil { | 201 | + | if router != nil { |
| 205 | - | if err := handlers.RegisterAll(ctx, app.router, handlers.Config{ | 202 | + | if err := handlers.RegisterAll(ctx, router, handlers.Config{ |
| 206 | HistoryUC: deps.HistoryUC, | 203 | HistoryUC: deps.HistoryUC, | ||
| 207 | FavoritesUC: deps.FavoritesUC, | 204 | FavoritesUC: deps.FavoritesUC, | ||
| 208 | Clipboard: deps.Clipboard, | 205 | Clipboard: deps.Clipboard, | ||
| @@ -249,8 +246,10 @@ func (a *App) Run(ctx context.Context, args []string) int { | |||||
| 249 | 246 | ||||
| 250 | // Refresh scripts in pooled WebViews that were prewarmed before adw.Init(). | 247 | // Refresh scripts in pooled WebViews that were prewarmed before adw.Init(). | ||
| 251 | // They have the wrong dark mode preference injected; re-inject with correct value. | 248 | // They have the wrong dark mode preference injected; re-inject with correct value. | ||
| 252 | - | if a.pool != nil { | 249 | + | if a.wkEngine != nil { |
| 253 | - | a.pool.RefreshScripts(ctx) | 250 | + | if pool := a.wkEngine.InternalPool(); pool != nil { |
| 251 | + | pool.RefreshScripts(ctx) | |||
| 252 | + | } | |||
| 254 | } | 253 | } | ||
| 255 | } | 254 | } | ||
| 256 | 255 | ||||
| @@ -375,7 +374,12 @@ func (a *App) setupPoolBackgroundColor(ctx context.Context) { | |||||
| 375 | 374 | ||||
| 376 | // Set theme background color on pool to eliminate white flash. | 375 | // Set theme background color on pool to eliminate white flash. | ||
| 377 | // Must be done before any WebView creation so WebViews get the correct color. | 376 | // Must be done before any WebView creation so WebViews get the correct color. | ||
| 378 | - | if a.pool == nil { | 377 | + | if a.wkEngine == nil { |
| 378 | + | log.Debug().Msg("webview pool not available; skipping background color setup") | |||
| 379 | + | return | |||
| 380 | + | } | |||
| 381 | + | pool := a.wkEngine.InternalPool() | |||
| 382 | + | if pool == nil { | |||
| 379 | log.Debug().Msg("webview pool not available; skipping background color setup") | 383 | log.Debug().Msg("webview pool not available; skipping background color setup") | ||
| 380 | return | 384 | return | ||
| 381 | } | 385 | } | ||
| @@ -385,16 +389,20 @@ func (a *App) setupPoolBackgroundColor(ctx context.Context) { | |||||
| 385 | } | 389 | } | ||
| 386 | 390 | ||||
| 387 | r, g, b, alpha := a.deps.Theme.GetBackgroundRGBA() | 391 | r, g, b, alpha := a.deps.Theme.GetBackgroundRGBA() | ||
| 388 | - | a.pool.SetBackgroundColor(r, g, b, alpha) | 392 | + | pool.SetBackgroundColor(r, g, b, alpha) |
| 389 | log.Debug().Msg("configured webview pool background color") | 393 | log.Debug().Msg("configured webview pool background color") | ||
| 390 | } | 394 | } | ||
| 391 | 395 | ||||
| 392 | func (a *App) prewarmWebViewPoolAsync(ctx context.Context) { | 396 | func (a *App) prewarmWebViewPoolAsync(ctx context.Context) { | ||
| 393 | // Prewarm WebView pool after startup so cold-start navigation is not blocked. | 397 | // Prewarm WebView pool after startup so cold-start navigation is not blocked. | ||
| 394 | - | if a.pool == nil { | 398 | + | if a.wkEngine == nil { |
| 395 | return | 399 | return | ||
| 396 | } | 400 | } | ||
| 397 | - | a.pool.PrewarmAsync(ctx, 0) | 401 | + | pool := a.wkEngine.InternalPool() |
| 402 | + | if pool == nil { | |||
| 403 | + | return | |||
| 404 | + | } | |||
| 405 | + | pool.PrewarmAsync(ctx, 0) | |||
| 398 | } | 406 | } | ||
| 399 | 407 | ||||
| 400 | func (a *App) createMainWindow(ctx context.Context) error { | 408 | func (a *App) createMainWindow(ctx context.Context) error { | ||
| @@ -558,12 +566,20 @@ func (a *App) initAccentPicker(ctx context.Context) { | |||||
| 558 | func (a *App) registerAccentHandlers(ctx context.Context) { | 566 | func (a *App) registerAccentHandlers(ctx context.Context) { | ||
| 559 | log := logging.FromContext(ctx) | 567 | log := logging.FromContext(ctx) | ||
| 560 | 568 | ||||
| 561 | - | if a.router == nil || a.insertAccentUC == nil { | 569 | + | if a.insertAccentUC == nil { |
| 562 | - | log.Debug().Msg("router or insertAccentUC not available, skipping accent handler registration") | 570 | + | log.Debug().Msg("insertAccentUC not available, skipping accent handler registration") |
| 571 | + | return | |||
| 572 | + | } | |||
| 573 | + | var router *webkit.MessageRouter | |||
| 574 | + | if a.wkEngine != nil { | |||
| 575 | + | router = a.wkEngine.InternalMessageRouter() | |||
| 576 | + | } | |||
| 577 | + | if router == nil { | |||
| 578 | + | log.Debug().Msg("router not available, skipping accent handler registration") | |||
| 563 | return | 579 | return | ||
| 564 | } | 580 | } | ||
| 565 | 581 | ||||
| 566 | - | if err := handlers.RegisterAccentHandlers(ctx, a.router, a.insertAccentUC); err != nil { | 582 | + | if err := handlers.RegisterAccentHandlers(ctx, router, a.insertAccentUC); err != nil { |
| 567 | log.Error().Err(err).Msg("failed to register accent handlers") | 583 | log.Error().Err(err).Msg("failed to register accent handlers") | ||
| 568 | } else { | 584 | } else { | ||
| 569 | log.Info().Msg("registered accent key handlers") | 585 | log.Info().Msg("registered accent key handlers") | ||
| @@ -1492,8 +1508,10 @@ func (a *App) onShutdown(ctx context.Context) { | |||||
| 1492 | for _, tabID := range tabIDs { | 1508 | for _, tabID := range tabIDs { | ||
| 1493 | a.releaseFloatingSessionsForTab(ctx, tabID) | 1509 | a.releaseFloatingSessionsForTab(ctx, tabID) | ||
| 1494 | } | 1510 | } | ||
| 1495 | - | if a.pool != nil { | 1511 | + | if a.engine != nil { |
| 1496 | - | a.pool.Close(ctx) | 1512 | + | if err := a.engine.Close(); err != nil { |
| 1513 | + | log.Warn().Err(err).Msg("failed to close engine") | |||
| 1514 | + | } | |||
| 1497 | } | 1515 | } | ||
| 1498 | // Close idle inhibitor to release D-Bus connection | 1516 | // Close idle inhibitor to release D-Bus connection | ||
| 1499 | if a.deps.IdleInhibitor != nil { | 1517 | if a.deps.IdleInhibitor != nil { | ||
| @@ -1515,17 +1533,14 @@ func (a *App) initCoordinators(ctx context.Context) { | |||||
| 1515 | return a.activeWorkspace(), a.activeWorkspaceView() | 1533 | return a.activeWorkspace(), a.activeWorkspaceView() | ||
| 1516 | } | 1534 | } | ||
| 1517 | 1535 | ||||
| 1518 | - | // Create FaviconAdapter with service and WebKit FaviconDatabase | 1536 | + | // Create FaviconAdapter with service and engine FaviconDatabase |
| 1519 | - | var faviconDB *webkit.FaviconDatabase | 1537 | + | a.faviconAdapter = adapter.NewFaviconAdapter(a.deps.FaviconService, a.engine.FaviconDatabase()) |
| 1520 | - | if a.wkEngine != nil { | |||
| 1521 | - | faviconDB = a.wkEngine.InternalContext().FaviconDatabase() | |||
| 1522 | - | } | |||
| 1523 | - | a.faviconAdapter = adapter.NewFaviconAdapter(a.deps.FaviconService, faviconDB) | |||
| 1524 | 1538 | ||||
| 1525 | // 1. Content Coordinator (no dependencies on other coordinators) | 1539 | // 1. Content Coordinator (no dependencies on other coordinators) | ||
| 1526 | a.contentCoord = content.NewCoordinator( | 1540 | a.contentCoord = content.NewCoordinator( | ||
| 1527 | ctx, | 1541 | ctx, | ||
| 1528 | a.engine.Pool(), | 1542 | a.engine.Pool(), | ||
| 1543 | + | a.engine.ContentInjector(), | |||
| 1529 | a.widgetFactory, | 1544 | a.widgetFactory, | ||
| 1530 | a.faviconAdapter, | 1545 | a.faviconAdapter, | ||
| 1531 | getActiveWS, | 1546 | getActiveWS, | ||
| @@ -1602,21 +1617,12 @@ func (a *App) initCoordinators(ctx context.Context) { | |||||
| 1602 | a.wsCoord.SetOnStateChanged(a.MarkDirty) | 1617 | a.wsCoord.SetOnStateChanged(a.MarkDirty) | ||
| 1603 | 1618 | ||||
| 1604 | // Wire popup handling | 1619 | // Wire popup handling | ||
| 1605 | - | var wkCtx *webkit.WebKitContext | 1620 | + | // Set theme background color on the engine's popup factory to eliminate white flash. |
| 1606 | - | if a.wkEngine != nil { | 1621 | + | if a.wkEngine != nil && a.deps.Theme != nil { |
| 1607 | - | wkCtx = a.wkEngine.InternalContext() | |||
| 1608 | - | } | |||
| 1609 | - | a.webViewFactory = webkit.NewWebViewFactory( | |||
| 1610 | - | wkCtx, | |||
| 1611 | - | a.settings, | |||
| 1612 | - | a.pool, | |||
| 1613 | - | a.injector, | |||
| 1614 | - | a.router, | |||
| 1615 | - | ) | |||
| 1616 | - | // Set theme background color on factory to eliminate white flash | |||
| 1617 | - | if a.deps.Theme != nil { | |||
| 1618 | r, g, b, alpha := a.deps.Theme.GetBackgroundRGBA() | 1622 | r, g, b, alpha := a.deps.Theme.GetBackgroundRGBA() | ||
| 1619 | - | a.webViewFactory.SetBackgroundColor(r, g, b, alpha) | 1623 | + | if f := a.wkEngine.InternalFactory(); f != nil { |
| 1624 | + | f.SetBackgroundColor(r, g, b, alpha) | |||
| 1625 | + | } | |||
| 1620 | } | 1626 | } | ||
| 1621 | a.contentCoord.SetPopupConfig( | 1627 | a.contentCoord.SetPopupConfig( | ||
| 1622 | a.engine.Factory(), | 1628 | a.engine.Factory(), | ||
| @@ -3095,8 +3101,10 @@ func (a *App) applyAppearanceConfig(ctx context.Context, cfg *config.Config) { | |||||
| 3095 | } | 3101 | } | ||
| 3096 | 3102 | ||||
| 3097 | // Update WebKit settings manager | 3103 | // Update WebKit settings manager | ||
| 3098 | - | if a.settings != nil { | 3104 | + | if a.wkEngine != nil { |
| 3099 | - | a.settings.UpdateFromConfig(ctx, cfg) | 3105 | + | if settings := a.wkEngine.InternalSettings(); settings != nil { |
| 3106 | + | settings.UpdateFromConfig(ctx, cfg) | |||
| 3107 | + | } | |||
| 3100 | } | 3108 | } | ||
| 3101 | 3109 | ||||
| 3102 | // Apply settings to existing webviews via coordinator | 3110 | // Apply settings to existing webviews via coordinator | ||
| @@ -3112,22 +3120,28 @@ func (a *App) applyAppearanceConfig(ctx context.Context, cfg *config.Config) { | |||||
| 3112 | } | 3120 | } | ||
| 3113 | a.deps.Theme.UpdateFromConfig(ctx, cfg, display) | 3121 | a.deps.Theme.UpdateFromConfig(ctx, cfg, display) | ||
| 3114 | 3122 | ||||
| 3123 | + | // Resolve injector once for all webkit-specific theme updates below. | |||
| 3124 | + | var injector *webkit.ContentInjector | |||
| 3125 | + | if a.wkEngine != nil { | |||
| 3126 | + | injector = a.wkEngine.InternalInjector() | |||
| 3127 | + | } | |||
| 3128 | + | ||||
| 3115 | // Update find highlight CSS for future navigations | 3129 | // Update find highlight CSS for future navigations | ||
| 3116 | - | if a.injector != nil { | 3130 | + | if injector != nil { |
| 3117 | findCSS := theme.GenerateFindHighlightCSS(a.deps.Theme.GetCurrentPalette()) | 3131 | findCSS := theme.GenerateFindHighlightCSS(a.deps.Theme.GetCurrentPalette()) | ||
| 3118 | - | if err := a.injector.InjectFindHighlightCSS(ctx, findCSS); err != nil { | 3132 | + | if err := injector.InjectFindHighlightCSS(ctx, findCSS); err != nil { |
| 3119 | log.Warn().Err(err).Msg("failed to update find highlight CSS") | 3133 | log.Warn().Err(err).Msg("failed to update find highlight CSS") | ||
| 3120 | } | 3134 | } | ||
| 3121 | } | 3135 | } | ||
| 3122 | 3136 | ||||
| 3123 | - | prepareThemeUC := usecase.NewPrepareWebUIThemeUseCase(a.injector) | 3137 | + | prepareThemeUC := usecase.NewPrepareWebUIThemeUseCase(injector) |
| 3124 | cssText := a.deps.Theme.GetWebUIThemeCSS() | 3138 | cssText := a.deps.Theme.GetWebUIThemeCSS() | ||
| 3125 | if err := prepareThemeUC.Execute(ctx, usecase.PrepareWebUIThemeInput{CSSVars: cssText}); err != nil { | 3139 | if err := prepareThemeUC.Execute(ctx, usecase.PrepareWebUIThemeInput{CSSVars: cssText}); err != nil { | ||
| 3126 | log.Warn().Err(err).Msg("failed to update WebUI theme CSS") | 3140 | log.Warn().Err(err).Msg("failed to update WebUI theme CSS") | ||
| 3127 | } | 3141 | } | ||
| 3128 | 3142 | ||||
| 3129 | // Refresh injected scripts so future navigations use the latest theme. | 3143 | // Refresh injected scripts so future navigations use the latest theme. | ||
| 3130 | - | if a.contentCoord != nil && a.injector != nil { | 3144 | + | if a.contentCoord != nil && injector != nil { |
| 3131 | a.contentCoord.RefreshInjectedScriptsToAll(ctx) | 3145 | a.contentCoord.RefreshInjectedScriptsToAll(ctx) | ||
| 3132 | } | 3146 | } | ||
| 3133 | 3147 | ||||
M internal/ui/coordinator/content/appearance.go +12 -22
| @@ -9,7 +9,6 @@ import ( | |||
| 9 | 9 | ||
| 10 | 10 | "github.com/bnema/dumber/internal/application/port" | |
| 11 | 11 | "github.com/bnema/dumber/internal/domain/entity" | |
| 12 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 13 | 12 | "github.com/bnema/dumber/internal/logging" | |
| 14 | 13 | ) | |
| 15 | 14 | ||
| @@ -42,7 +41,15 @@ func (c *Coordinator) ApplyWebUIThemeToAll(ctx context.Context, prefersDark bool | |||
| 42 | 41 | return | |
| 43 | 42 | } | |
| 44 | 43 | ||
| 45 | - | for paneID, wv := range c.webViews { | |
| 44 | + | // Snapshot webViews under lock to avoid data race with concurrent popup create/close. | |
| 45 | + | c.webViewsMu.RLock() | |
| 46 | + | snapshot := make(map[entity.PaneID]port.WebView, len(c.webViews)) | |
| 47 | + | for k, v := range c.webViews { | |
| 48 | + | snapshot[k] = v | |
| 49 | + | } | |
| 50 | + | c.webViewsMu.RUnlock() | |
| 51 | + | ||
| 52 | + | for paneID, wv := range snapshot { | |
| 46 | 53 | if wv == nil || wv.IsDestroyed() { | |
| 47 | 54 | continue | |
| 48 | 55 | } | |
| @@ -126,10 +133,7 @@ func (c *Coordinator) applyWebUITheme( | |||
| 126 | 133 | if !strings.HasPrefix(uri, "dumb://") { | |
| 127 | 134 | return | |
| 128 | 135 | } | |
| 129 | - | // Type-assert to access webkit-specific RunJavaScript | |
| 130 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |
| 131 | - | wkWV.RunJavaScript(ctx, script, "") | |
| 132 | - | } | |
| 136 | + | wv.RunJavaScript(ctx, script) | |
| 133 | 137 | logging.FromContext(ctx). | |
| 134 | 138 | Debug(). | |
| 135 | 139 | Str("pane_id", string(paneID)). | |
| @@ -269,24 +273,10 @@ func (c *Coordinator) refreshInjectedScripts( | |||
| 269 | 273 | if injector == nil || wv == nil || wv.IsDestroyed() { | |
| 270 | 274 | return | |
| 271 | 275 | } | |
| 272 | - | // Type-assert to access webkit-specific UserContentManager and InjectScripts. | |
| 273 | - | // refreshInjectedScripts is a webkit-specific operation; other engines will | |
| 274 | - | // need their own implementation when wired through a port.ScriptRefresher. | |
| 275 | - | wkInjector, ok := injector.(*webkit.ContentInjector) | |
| 276 | - | if !ok { | |
| 277 | - | return | |
| 278 | - | } | |
| 279 | - | wkWV, ok := wv.(*webkit.WebView) | |
| 280 | - | if !ok { | |
| 281 | - | return | |
| 282 | - | } | |
| 283 | - | ucm := wkWV.UserContentManager() | |
| 284 | - | if ucm == nil { | |
| 276 | + | if err := injector.RefreshScripts(ctx, wv); err != nil { | |
| 277 | + | logging.FromContext(ctx).Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to refresh injected scripts") | |
| 285 | 278 | return | |
| 286 | 279 | } | |
| 287 | - | ucm.RemoveAllScripts() | |
| 288 | - | ucm.RemoveAllStyleSheets() | |
| 289 | - | wkInjector.InjectScripts(ctx, ucm, wv.ID()) | |
| 290 | 280 | logging.FromContext(ctx).Debug().Str("pane_id", string(paneID)).Msg("refreshed injected scripts for webview") | |
| 291 | 281 | } | |
| 292 | 282 | ||
| @@ -9,7 +9,6 @@ import ( | |||||
| 9 | 9 | ||||
| 10 | "github.com/bnema/dumber/internal/application/port" | 10 | "github.com/bnema/dumber/internal/application/port" | ||
| 11 | "github.com/bnema/dumber/internal/domain/entity" | 11 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 12 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |||
| 13 | "github.com/bnema/dumber/internal/logging" | 12 | "github.com/bnema/dumber/internal/logging" | ||
| 14 | ) | 13 | ) | ||
| 15 | 14 | ||||
| @@ -42,7 +41,15 @@ func (c *Coordinator) ApplyWebUIThemeToAll(ctx context.Context, prefersDark bool | |||||
| 42 | return | 41 | return | ||
| 43 | } | 42 | } | ||
| 44 | 43 | ||||
| 45 | - | for paneID, wv := range c.webViews { | 44 | + | // Snapshot webViews under lock to avoid data race with concurrent popup create/close. |
| 45 | + | c.webViewsMu.RLock() | |||
| 46 | + | snapshot := make(map[entity.PaneID]port.WebView, len(c.webViews)) | |||
| 47 | + | for k, v := range c.webViews { | |||
| 48 | + | snapshot[k] = v | |||
| 49 | + | } | |||
| 50 | + | c.webViewsMu.RUnlock() | |||
| 51 | + | ||||
| 52 | + | for paneID, wv := range snapshot { | |||
| 46 | if wv == nil || wv.IsDestroyed() { | 53 | if wv == nil || wv.IsDestroyed() { | ||
| 47 | continue | 54 | continue | ||
| 48 | } | 55 | } | ||
| @@ -126,10 +133,7 @@ func (c *Coordinator) applyWebUITheme( | |||||
| 126 | if !strings.HasPrefix(uri, "dumb://") { | 133 | if !strings.HasPrefix(uri, "dumb://") { | ||
| 127 | return | 134 | return | ||
| 128 | } | 135 | } | ||
| 129 | - | // Type-assert to access webkit-specific RunJavaScript | 136 | + | wv.RunJavaScript(ctx, script) |
| 130 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |||
| 131 | - | wkWV.RunJavaScript(ctx, script, "") | |||
| 132 | - | } | |||
| 133 | logging.FromContext(ctx). | 137 | logging.FromContext(ctx). | ||
| 134 | Debug(). | 138 | Debug(). | ||
| 135 | Str("pane_id", string(paneID)). | 139 | Str("pane_id", string(paneID)). | ||
| @@ -269,24 +273,10 @@ func (c *Coordinator) refreshInjectedScripts( | |||||
| 269 | if injector == nil || wv == nil || wv.IsDestroyed() { | 273 | if injector == nil || wv == nil || wv.IsDestroyed() { | ||
| 270 | return | 274 | return | ||
| 271 | } | 275 | } | ||
| 272 | - | // Type-assert to access webkit-specific UserContentManager and InjectScripts. | 276 | + | if err := injector.RefreshScripts(ctx, wv); err != nil { |
| 273 | - | // refreshInjectedScripts is a webkit-specific operation; other engines will | 277 | + | logging.FromContext(ctx).Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to refresh injected scripts") |
| 274 | - | // need their own implementation when wired through a port.ScriptRefresher. | |||
| 275 | - | wkInjector, ok := injector.(*webkit.ContentInjector) | |||
| 276 | - | if !ok { | |||
| 277 | - | return | |||
| 278 | - | } | |||
| 279 | - | wkWV, ok := wv.(*webkit.WebView) | |||
| 280 | - | if !ok { | |||
| 281 | - | return | |||
| 282 | - | } | |||
| 283 | - | ucm := wkWV.UserContentManager() | |||
| 284 | - | if ucm == nil { | |||
| 285 | return | 278 | return | ||
| 286 | } | 279 | } | ||
| 287 | - | ucm.RemoveAllScripts() | |||
| 288 | - | ucm.RemoveAllStyleSheets() | |||
| 289 | - | wkInjector.InjectScripts(ctx, ucm, wv.ID()) | |||
| 290 | logging.FromContext(ctx).Debug().Str("pane_id", string(paneID)).Msg("refreshed injected scripts for webview") | 280 | logging.FromContext(ctx).Debug().Str("pane_id", string(paneID)).Msg("refreshed injected scripts for webview") | ||
| 291 | } | 281 | } | ||
| 292 | 282 | ||||
M internal/ui/coordinator/content/bulk.go +11 -1
| @@ -3,6 +3,8 @@ package content | |||
| 3 | 3 | import ( | |
| 4 | 4 | "context" | |
| 5 | 5 | ||
| 6 | + | "github.com/bnema/dumber/internal/application/port" | |
| 7 | + | "github.com/bnema/dumber/internal/domain/entity" | |
| 6 | 8 | "github.com/bnema/dumber/internal/logging" | |
| 7 | 9 | ) | |
| 8 | 10 | ||
| @@ -35,7 +37,15 @@ func (c *Coordinator) RefreshInjectedScriptsToAll(ctx context.Context) { | |||
| 35 | 37 | return | |
| 36 | 38 | } | |
| 37 | 39 | ||
| 38 | - | for paneID, wv := range c.webViews { | |
| 40 | + | // Snapshot webViews under lock to avoid data race with concurrent popup create/close. | |
| 41 | + | c.webViewsMu.RLock() | |
| 42 | + | snapshot := make(map[entity.PaneID]port.WebView, len(c.webViews)) | |
| 43 | + | for k, v := range c.webViews { | |
| 44 | + | snapshot[k] = v | |
| 45 | + | } | |
| 46 | + | c.webViewsMu.RUnlock() | |
| 47 | + | ||
| 48 | + | for paneID, wv := range snapshot { | |
| 39 | 49 | if wv == nil || wv.IsDestroyed() { | |
| 40 | 50 | continue | |
| 41 | 51 | } | |
| @@ -3,6 +3,8 @@ package content | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "context" | 4 | "context" | ||
| 5 | 5 | ||||
| 6 | + | "github.com/bnema/dumber/internal/application/port" | |||
| 7 | + | "github.com/bnema/dumber/internal/domain/entity" | |||
| 6 | "github.com/bnema/dumber/internal/logging" | 8 | "github.com/bnema/dumber/internal/logging" | ||
| 7 | ) | 9 | ) | ||
| 8 | 10 | ||||
| @@ -35,7 +37,15 @@ func (c *Coordinator) RefreshInjectedScriptsToAll(ctx context.Context) { | |||||
| 35 | return | 37 | return | ||
| 36 | } | 38 | } | ||
| 37 | 39 | ||||
| 38 | - | for paneID, wv := range c.webViews { | 40 | + | // Snapshot webViews under lock to avoid data race with concurrent popup create/close. |
| 41 | + | c.webViewsMu.RLock() | |||
| 42 | + | snapshot := make(map[entity.PaneID]port.WebView, len(c.webViews)) | |||
| 43 | + | for k, v := range c.webViews { | |||
| 44 | + | snapshot[k] = v | |||
| 45 | + | } | |||
| 46 | + | c.webViewsMu.RUnlock() | |||
| 47 | + | ||||
| 48 | + | for paneID, wv := range snapshot { | |||
| 39 | if wv == nil || wv.IsDestroyed() { | 49 | if wv == nil || wv.IsDestroyed() { | ||
| 40 | continue | 50 | continue | ||
| 41 | } | 51 | } | ||
M internal/ui/coordinator/content/callbacks.go +52 -79
| @@ -8,7 +8,6 @@ import ( | |||
| 8 | 8 | "github.com/bnema/dumber/internal/application/port" | |
| 9 | 9 | "github.com/bnema/dumber/internal/application/usecase" | |
| 10 | 10 | "github.com/bnema/dumber/internal/domain/entity" | |
| 11 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 12 | 11 | "github.com/bnema/dumber/internal/logging" | |
| 13 | 12 | "github.com/jwijenbergh/puregotk/v4/gdk" | |
| 14 | 13 | ) | |
| @@ -123,15 +122,59 @@ func (c *Coordinator) setupWebViewCallbacks(ctx context.Context, paneID entity.P | |||
| 123 | 122 | }, | |
| 124 | 123 | } | |
| 125 | 124 | ||
| 126 | - | // Favicon changes - need webkit-specific Generation() to detect stale callbacks | |
| 127 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |
| 128 | - | faviconGen := wkWV.Generation() | |
| 129 | - | callbacks.OnFaviconChanged = func(favicon port.Texture) { | |
| 130 | - | if wkWV.Generation() != faviconGen { | |
| 131 | - | return // WebView was reused, ignore stale signal | |
| 125 | + | // Favicon changes - use Generation() from port.WebView to detect stale callbacks | |
| 126 | + | faviconGen := wv.Generation() | |
| 127 | + | callbacks.OnFaviconChanged = func(favicon port.Texture) { | |
| 128 | + | if wv.Generation() != faviconGen { | |
| 129 | + | return // WebView was reused, ignore stale signal | |
| 130 | + | } | |
| 131 | + | if gdkTexture, ok := favicon.(*gdk.Texture); ok { | |
| 132 | + | c.onFaviconChanged(ctx, paneID, wv, gdkTexture) | |
| 133 | + | } | |
| 134 | + | } | |
| 135 | + | ||
| 136 | + | // Middle-click link handler | |
| 137 | + | callbacks.OnLinkMiddleClick = func(uri string) bool { | |
| 138 | + | return c.handleLinkMiddleClick(ctx, paneID, uri) | |
| 139 | + | } | |
| 140 | + | ||
| 141 | + | // Fullscreen handlers for idle inhibition | |
| 142 | + | callbacks.OnEnterFullscreen = func() bool { | |
| 143 | + | if c.idleInhibitor != nil { | |
| 144 | + | if err := c.idleInhibitor.Inhibit(ctx, "Fullscreen video playback"); err != nil { | |
| 145 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle") | |
| 146 | + | } | |
| 147 | + | } | |
| 148 | + | if c.onFullscreenChanged != nil { | |
| 149 | + | c.onFullscreenChanged(true) | |
| 150 | + | } | |
| 151 | + | return false // Allow fullscreen | |
| 152 | + | } | |
| 153 | + | ||
| 154 | + | callbacks.OnLeaveFullscreen = func() bool { | |
| 155 | + | if c.idleInhibitor != nil { | |
| 156 | + | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |
| 157 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle") | |
| 158 | + | } | |
| 159 | + | } | |
| 160 | + | if c.onFullscreenChanged != nil { | |
| 161 | + | c.onFullscreenChanged(false) | |
| 162 | + | } | |
| 163 | + | return false // Allow leaving fullscreen | |
| 164 | + | } | |
| 165 | + | ||
| 166 | + | // Audio playback handling | |
| 167 | + | callbacks.OnAudioStateChanged = func(playing bool) { | |
| 168 | + | if c.idleInhibitor == nil { | |
| 169 | + | return | |
| 170 | + | } | |
| 171 | + | if playing { | |
| 172 | + | if err := c.idleInhibitor.Inhibit(ctx, "Media playback"); err != nil { | |
| 173 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle for audio") | |
| 132 | 174 | } | |
| 133 | - | if gdkTexture, ok := favicon.(*gdk.Texture); ok { | |
| 134 | - | c.onFaviconChanged(ctx, paneID, wkWV, gdkTexture) | |
| 175 | + | } else { | |
| 176 | + | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |
| 177 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle for audio") | |
| 135 | 178 | } | |
| 136 | 179 | } | |
| 137 | 180 | } | |
| @@ -140,16 +183,6 @@ func (c *Coordinator) setupWebViewCallbacks(ctx context.Context, paneID entity.P | |||
| 140 | 183 | callbacks.OnCreate = c.buildPopupCreateHandler(ctx, paneID, wv) | |
| 141 | 184 | ||
| 142 | 185 | wv.SetCallbacks(callbacks) | |
| 143 | - | ||
| 144 | - | // Webkit-specific callbacks not in port.WebViewCallbacks (middle-click, fullscreen, audio) | |
| 145 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |
| 146 | - | wkWV.OnLinkMiddleClick = func(uri string) bool { | |
| 147 | - | return c.handleLinkMiddleClick(ctx, paneID, uri) | |
| 148 | - | } | |
| 149 | - | } | |
| 150 | - | ||
| 151 | - | // Fullscreen handlers for idle inhibition | |
| 152 | - | c.setupIdleInhibitionHandlers(ctx, paneID, wv) | |
| 153 | 186 | } | |
| 154 | 187 | ||
| 155 | 188 | // handlePermissionRequest processes media permission requests from WebKit. | |
| @@ -243,63 +276,3 @@ func filterWebRTCPermissionTypes(types []entity.PermissionType) []entity.Permiss | |||
| 243 | 276 | } | |
| 244 | 277 | return filtered | |
| 245 | 278 | } | |
| 246 | - | ||
| 247 | - | // setupIdleInhibitionHandlers configures fullscreen and audio callbacks for idle inhibition. | |
| 248 | - | // Idle is inhibited when: | |
| 249 | - | // - The webview enters fullscreen mode (e.g., fullscreen video) | |
| 250 | - | // - The webview is playing audio (e.g., video/music playback) | |
| 251 | - | // The inhibitor uses refcounting, so both can be active simultaneously. | |
| 252 | - | func (c *Coordinator) setupIdleInhibitionHandlers(ctx context.Context, paneID entity.PaneID, wv port.WebView) { | |
| 253 | - | log := logging.FromContext(ctx) | |
| 254 | - | ||
| 255 | - | if wv == nil { | |
| 256 | - | return | |
| 257 | - | } | |
| 258 | - | ||
| 259 | - | // Type-assert to access webkit-specific fullscreen/audio callbacks | |
| 260 | - | wkWV, ok := wv.(*webkit.WebView) | |
| 261 | - | if !ok { | |
| 262 | - | return | |
| 263 | - | } | |
| 264 | - | ||
| 265 | - | // Fullscreen handling | |
| 266 | - | wkWV.OnEnterFullscreen = func() bool { | |
| 267 | - | if c.idleInhibitor != nil { | |
| 268 | - | if err := c.idleInhibitor.Inhibit(ctx, "Fullscreen video playback"); err != nil { | |
| 269 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle") | |
| 270 | - | } | |
| 271 | - | } | |
| 272 | - | if c.onFullscreenChanged != nil { | |
| 273 | - | c.onFullscreenChanged(true) | |
| 274 | - | } | |
| 275 | - | return false // Allow fullscreen | |
| 276 | - | } | |
| 277 | - | ||
| 278 | - | wkWV.OnLeaveFullscreen = func() bool { | |
| 279 | - | if c.idleInhibitor != nil { | |
| 280 | - | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |
| 281 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle") | |
| 282 | - | } | |
| 283 | - | } | |
| 284 | - | if c.onFullscreenChanged != nil { | |
| 285 | - | c.onFullscreenChanged(false) | |
| 286 | - | } | |
| 287 | - | return false // Allow leaving fullscreen | |
| 288 | - | } | |
| 289 | - | ||
| 290 | - | // Audio playback handling | |
| 291 | - | wkWV.OnAudioStateChanged = func(playing bool) { | |
| 292 | - | if c.idleInhibitor == nil { | |
| 293 | - | return | |
| 294 | - | } | |
| 295 | - | if playing { | |
| 296 | - | if err := c.idleInhibitor.Inhibit(ctx, "Media playback"); err != nil { | |
| 297 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle for audio") | |
| 298 | - | } | |
| 299 | - | } else { | |
| 300 | - | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |
| 301 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle for audio") | |
| 302 | - | } | |
| 303 | - | } | |
| 304 | - | } | |
| 305 | - | } | |
| @@ -8,7 +8,6 @@ import ( | |||||
| 8 | "github.com/bnema/dumber/internal/application/port" | 8 | "github.com/bnema/dumber/internal/application/port" | ||
| 9 | "github.com/bnema/dumber/internal/application/usecase" | 9 | "github.com/bnema/dumber/internal/application/usecase" | ||
| 10 | "github.com/bnema/dumber/internal/domain/entity" | 10 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 11 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |||
| 12 | "github.com/bnema/dumber/internal/logging" | 11 | "github.com/bnema/dumber/internal/logging" | ||
| 13 | "github.com/jwijenbergh/puregotk/v4/gdk" | 12 | "github.com/jwijenbergh/puregotk/v4/gdk" | ||
| 14 | ) | 13 | ) | ||
| @@ -123,15 +122,59 @@ func (c *Coordinator) setupWebViewCallbacks(ctx context.Context, paneID entity.P | |||||
| 123 | }, | 122 | }, | ||
| 124 | } | 123 | } | ||
| 125 | 124 | ||||
| 126 | - | // Favicon changes - need webkit-specific Generation() to detect stale callbacks | 125 | + | // Favicon changes - use Generation() from port.WebView to detect stale callbacks |
| 127 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | 126 | + | faviconGen := wv.Generation() |
| 128 | - | faviconGen := wkWV.Generation() | 127 | + | callbacks.OnFaviconChanged = func(favicon port.Texture) { |
| 129 | - | callbacks.OnFaviconChanged = func(favicon port.Texture) { | 128 | + | if wv.Generation() != faviconGen { |
| 130 | - | if wkWV.Generation() != faviconGen { | 129 | + | return // WebView was reused, ignore stale signal |
| 131 | - | return // WebView was reused, ignore stale signal | 130 | + | } |
| 131 | + | if gdkTexture, ok := favicon.(*gdk.Texture); ok { | |||
| 132 | + | c.onFaviconChanged(ctx, paneID, wv, gdkTexture) | |||
| 133 | + | } | |||
| 134 | + | } | |||
| 135 | + | ||||
| 136 | + | // Middle-click link handler | |||
| 137 | + | callbacks.OnLinkMiddleClick = func(uri string) bool { | |||
| 138 | + | return c.handleLinkMiddleClick(ctx, paneID, uri) | |||
| 139 | + | } | |||
| 140 | + | ||||
| 141 | + | // Fullscreen handlers for idle inhibition | |||
| 142 | + | callbacks.OnEnterFullscreen = func() bool { | |||
| 143 | + | if c.idleInhibitor != nil { | |||
| 144 | + | if err := c.idleInhibitor.Inhibit(ctx, "Fullscreen video playback"); err != nil { | |||
| 145 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle") | |||
| 146 | + | } | |||
| 147 | + | } | |||
| 148 | + | if c.onFullscreenChanged != nil { | |||
| 149 | + | c.onFullscreenChanged(true) | |||
| 150 | + | } | |||
| 151 | + | return false // Allow fullscreen | |||
| 152 | + | } | |||
| 153 | + | ||||
| 154 | + | callbacks.OnLeaveFullscreen = func() bool { | |||
| 155 | + | if c.idleInhibitor != nil { | |||
| 156 | + | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |||
| 157 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle") | |||
| 158 | + | } | |||
| 159 | + | } | |||
| 160 | + | if c.onFullscreenChanged != nil { | |||
| 161 | + | c.onFullscreenChanged(false) | |||
| 162 | + | } | |||
| 163 | + | return false // Allow leaving fullscreen | |||
| 164 | + | } | |||
| 165 | + | ||||
| 166 | + | // Audio playback handling | |||
| 167 | + | callbacks.OnAudioStateChanged = func(playing bool) { | |||
| 168 | + | if c.idleInhibitor == nil { | |||
| 169 | + | return | |||
| 170 | + | } | |||
| 171 | + | if playing { | |||
| 172 | + | if err := c.idleInhibitor.Inhibit(ctx, "Media playback"); err != nil { | |||
| 173 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle for audio") | |||
| 132 | } | 174 | } | ||
| 133 | - | if gdkTexture, ok := favicon.(*gdk.Texture); ok { | 175 | + | } else { |
| 134 | - | c.onFaviconChanged(ctx, paneID, wkWV, gdkTexture) | 176 | + | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { |
| 177 | + | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle for audio") | |||
| 135 | } | 178 | } | ||
| 136 | } | 179 | } | ||
| 137 | } | 180 | } | ||
| @@ -140,16 +183,6 @@ func (c *Coordinator) setupWebViewCallbacks(ctx context.Context, paneID entity.P | |||||
| 140 | callbacks.OnCreate = c.buildPopupCreateHandler(ctx, paneID, wv) | 183 | callbacks.OnCreate = c.buildPopupCreateHandler(ctx, paneID, wv) | ||
| 141 | 184 | ||||
| 142 | wv.SetCallbacks(callbacks) | 185 | wv.SetCallbacks(callbacks) | ||
| 143 | - | ||||
| 144 | - | // Webkit-specific callbacks not in port.WebViewCallbacks (middle-click, fullscreen, audio) | |||
| 145 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |||
| 146 | - | wkWV.OnLinkMiddleClick = func(uri string) bool { | |||
| 147 | - | return c.handleLinkMiddleClick(ctx, paneID, uri) | |||
| 148 | - | } | |||
| 149 | - | } | |||
| 150 | - | ||||
| 151 | - | // Fullscreen handlers for idle inhibition | |||
| 152 | - | c.setupIdleInhibitionHandlers(ctx, paneID, wv) | |||
| 153 | } | 186 | } | ||
| 154 | 187 | ||||
| 155 | // handlePermissionRequest processes media permission requests from WebKit. | 188 | // handlePermissionRequest processes media permission requests from WebKit. | ||
| @@ -243,63 +276,3 @@ func filterWebRTCPermissionTypes(types []entity.PermissionType) []entity.Permiss | |||||
| 243 | } | 276 | } | ||
| 244 | return filtered | 277 | return filtered | ||
| 245 | } | 278 | } | ||
| 246 | - | ||||
| 247 | - | // setupIdleInhibitionHandlers configures fullscreen and audio callbacks for idle inhibition. | |||
| 248 | - | // Idle is inhibited when: | |||
| 249 | - | // - The webview enters fullscreen mode (e.g., fullscreen video) | |||
| 250 | - | // - The webview is playing audio (e.g., video/music playback) | |||
| 251 | - | // The inhibitor uses refcounting, so both can be active simultaneously. | |||
| 252 | - | func (c *Coordinator) setupIdleInhibitionHandlers(ctx context.Context, paneID entity.PaneID, wv port.WebView) { | |||
| 253 | - | log := logging.FromContext(ctx) | |||
| 254 | - | ||||
| 255 | - | if wv == nil { | |||
| 256 | - | return | |||
| 257 | - | } | |||
| 258 | - | ||||
| 259 | - | // Type-assert to access webkit-specific fullscreen/audio callbacks | |||
| 260 | - | wkWV, ok := wv.(*webkit.WebView) | |||
| 261 | - | if !ok { | |||
| 262 | - | return | |||
| 263 | - | } | |||
| 264 | - | ||||
| 265 | - | // Fullscreen handling | |||
| 266 | - | wkWV.OnEnterFullscreen = func() bool { | |||
| 267 | - | if c.idleInhibitor != nil { | |||
| 268 | - | if err := c.idleInhibitor.Inhibit(ctx, "Fullscreen video playback"); err != nil { | |||
| 269 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle") | |||
| 270 | - | } | |||
| 271 | - | } | |||
| 272 | - | if c.onFullscreenChanged != nil { | |||
| 273 | - | c.onFullscreenChanged(true) | |||
| 274 | - | } | |||
| 275 | - | return false // Allow fullscreen | |||
| 276 | - | } | |||
| 277 | - | ||||
| 278 | - | wkWV.OnLeaveFullscreen = func() bool { | |||
| 279 | - | if c.idleInhibitor != nil { | |||
| 280 | - | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |||
| 281 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle") | |||
| 282 | - | } | |||
| 283 | - | } | |||
| 284 | - | if c.onFullscreenChanged != nil { | |||
| 285 | - | c.onFullscreenChanged(false) | |||
| 286 | - | } | |||
| 287 | - | return false // Allow leaving fullscreen | |||
| 288 | - | } | |||
| 289 | - | ||||
| 290 | - | // Audio playback handling | |||
| 291 | - | wkWV.OnAudioStateChanged = func(playing bool) { | |||
| 292 | - | if c.idleInhibitor == nil { | |||
| 293 | - | return | |||
| 294 | - | } | |||
| 295 | - | if playing { | |||
| 296 | - | if err := c.idleInhibitor.Inhibit(ctx, "Media playback"); err != nil { | |||
| 297 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to inhibit idle for audio") | |||
| 298 | - | } | |||
| 299 | - | } else { | |||
| 300 | - | if err := c.idleInhibitor.Uninhibit(ctx); err != nil { | |||
| 301 | - | log.Warn().Err(err).Str("pane_id", string(paneID)).Msg("failed to uninhibit idle for audio") | |||
| 302 | - | } | |||
| 303 | - | } | |||
| 304 | - | } | |||
| 305 | - | } | |||
M internal/ui/coordinator/content/coordinator.go +2 -0
| @@ -134,6 +134,7 @@ const ( | |||
| 134 | 134 | func NewCoordinator( | |
| 135 | 135 | ctx context.Context, | |
| 136 | 136 | pool port.WebViewPool, | |
| 137 | + | injector port.ContentInjector, | |
| 137 | 138 | widgetFactory layout.WidgetFactory, | |
| 138 | 139 | faviconAdapter *adapter.FaviconAdapter, | |
| 139 | 140 | getActiveWS func() (*entity.Workspace, *component.WorkspaceView), | |
| @@ -145,6 +146,7 @@ func NewCoordinator( | |||
| 145 | 146 | ||
| 146 | 147 | return &Coordinator{ | |
| 147 | 148 | pool: pool, | |
| 149 | + | injector: injector, | |
| 148 | 150 | widgetFactory: widgetFactory, | |
| 149 | 151 | faviconAdapter: faviconAdapter, | |
| 150 | 152 | zoomUC: zoomUC, | |
| @@ -134,6 +134,7 @@ const ( | |||||
| 134 | func NewCoordinator( | 134 | func NewCoordinator( | ||
| 135 | ctx context.Context, | 135 | ctx context.Context, | ||
| 136 | pool port.WebViewPool, | 136 | pool port.WebViewPool, | ||
| 137 | + | injector port.ContentInjector, | |||
| 137 | widgetFactory layout.WidgetFactory, | 138 | widgetFactory layout.WidgetFactory, | ||
| 138 | faviconAdapter *adapter.FaviconAdapter, | 139 | faviconAdapter *adapter.FaviconAdapter, | ||
| 139 | getActiveWS func() (*entity.Workspace, *component.WorkspaceView), | 140 | getActiveWS func() (*entity.Workspace, *component.WorkspaceView), | ||
| @@ -145,6 +146,7 @@ func NewCoordinator( | |||||
| 145 | 146 | ||||
| 146 | return &Coordinator{ | 147 | return &Coordinator{ | ||
| 147 | pool: pool, | 148 | pool: pool, | ||
| 149 | + | injector: injector, | |||
| 148 | widgetFactory: widgetFactory, | 150 | widgetFactory: widgetFactory, | ||
| 149 | faviconAdapter: faviconAdapter, | 151 | faviconAdapter: faviconAdapter, | ||
| 150 | zoomUC: zoomUC, | 152 | zoomUC: zoomUC, | ||
M internal/ui/coordinator/content/lifecycle.go +8 -6
| @@ -6,11 +6,11 @@ import ( | |||
| 6 | 6 | ||
| 7 | 7 | "github.com/bnema/dumber/internal/application/port" | |
| 8 | 8 | "github.com/bnema/dumber/internal/domain/entity" | |
| 9 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 10 | 9 | "github.com/bnema/dumber/internal/logging" | |
| 11 | 10 | "github.com/bnema/dumber/internal/ui/component" | |
| 12 | 11 | "github.com/bnema/dumber/internal/ui/input" | |
| 13 | 12 | "github.com/bnema/dumber/internal/ui/layout" | |
| 13 | + | "github.com/jwijenbergh/puregotk/v4/gtk" | |
| 14 | 14 | ) | |
| 15 | 15 | ||
| 16 | 16 | // EnsureWebView acquires or reuses a WebView for the given pane. | |
| @@ -138,19 +138,21 @@ func (c *Coordinator) WrapWidget(ctx context.Context, wv port.WebView) layout.Wi | |||
| 138 | 138 | return nil | |
| 139 | 139 | } | |
| 140 | 140 | ||
| 141 | - | // Type-assert to access webkit-specific Widget() for GTK embedding | |
| 142 | - | wkWV, ok := wv.(*webkit.WebView) | |
| 141 | + | // Use NativeWidgetProvider interface for GTK embedding (engine-agnostic) | |
| 142 | + | nwp, ok := wv.(port.NativeWidgetProvider) | |
| 143 | 143 | if !ok { | |
| 144 | 144 | log.Debug().Msg("webview does not support widget embedding") | |
| 145 | 145 | return nil | |
| 146 | 146 | } | |
| 147 | 147 | ||
| 148 | - | gtkView := wkWV.Widget() | |
| 149 | - | if gtkView == nil { | |
| 148 | + | ptr := nwp.NativeWidget() | |
| 149 | + | if ptr == 0 { | |
| 150 | 150 | return nil | |
| 151 | 151 | } | |
| 152 | 152 | ||
| 153 | - | widget := c.widgetFactory.WrapWidget(>kView.Widget) | |
| 153 | + | gtkWidget := >k.Widget{} | |
| 154 | + | gtkWidget.Ptr = ptr | |
| 155 | + | widget := c.widgetFactory.WrapWidget(gtkWidget) | |
| 154 | 156 | ||
| 155 | 157 | // Attach gesture handler for mouse button 8/9 navigation | |
| 156 | 158 | if widget != nil { | |
| @@ -6,11 +6,11 @@ import ( | |||||
| 6 | 6 | ||||
| 7 | "github.com/bnema/dumber/internal/application/port" | 7 | "github.com/bnema/dumber/internal/application/port" | ||
| 8 | "github.com/bnema/dumber/internal/domain/entity" | 8 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 9 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |||
| 10 | "github.com/bnema/dumber/internal/logging" | 9 | "github.com/bnema/dumber/internal/logging" | ||
| 11 | "github.com/bnema/dumber/internal/ui/component" | 10 | "github.com/bnema/dumber/internal/ui/component" | ||
| 12 | "github.com/bnema/dumber/internal/ui/input" | 11 | "github.com/bnema/dumber/internal/ui/input" | ||
| 13 | "github.com/bnema/dumber/internal/ui/layout" | 12 | "github.com/bnema/dumber/internal/ui/layout" | ||
| 13 | + | "github.com/jwijenbergh/puregotk/v4/gtk" | |||
| 14 | ) | 14 | ) | ||
| 15 | 15 | ||||
| 16 | // EnsureWebView acquires or reuses a WebView for the given pane. | 16 | // EnsureWebView acquires or reuses a WebView for the given pane. | ||
| @@ -138,19 +138,21 @@ func (c *Coordinator) WrapWidget(ctx context.Context, wv port.WebView) layout.Wi | |||||
| 138 | return nil | 138 | return nil | ||
| 139 | } | 139 | } | ||
| 140 | 140 | ||||
| 141 | - | // Type-assert to access webkit-specific Widget() for GTK embedding | 141 | + | // Use NativeWidgetProvider interface for GTK embedding (engine-agnostic) |
| 142 | - | wkWV, ok := wv.(*webkit.WebView) | 142 | + | nwp, ok := wv.(port.NativeWidgetProvider) |
| 143 | if !ok { | 143 | if !ok { | ||
| 144 | log.Debug().Msg("webview does not support widget embedding") | 144 | log.Debug().Msg("webview does not support widget embedding") | ||
| 145 | return nil | 145 | return nil | ||
| 146 | } | 146 | } | ||
| 147 | 147 | ||||
| 148 | - | gtkView := wkWV.Widget() | 148 | + | ptr := nwp.NativeWidget() |
| 149 | - | if gtkView == nil { | 149 | + | if ptr == 0 { |
| 150 | return nil | 150 | return nil | ||
| 151 | } | 151 | } | ||
| 152 | 152 | ||||
| 153 | - | widget := c.widgetFactory.WrapWidget(>kView.Widget) | 153 | + | gtkWidget := >k.Widget{} |
| 154 | + | gtkWidget.Ptr = ptr | |||
| 155 | + | widget := c.widgetFactory.WrapWidget(gtkWidget) | |||
| 154 | 156 | ||||
| 155 | // Attach gesture handler for mouse button 8/9 navigation | 157 | // Attach gesture handler for mouse button 8/9 navigation | ||
| 156 | if widget != nil { | 158 | if widget != nil { | ||
M internal/ui/coordinator/content/lifecycle_test.go +2 -0
| @@ -53,6 +53,7 @@ func TestLifecycle_EnsureWebView_AcquiresFromPoolWhenNoneExists(t *testing.T) { | |||
| 53 | 53 | ||
| 54 | 54 | newWV := mocks.NewMockWebView(t) | |
| 55 | 55 | newWV.EXPECT().SetCallbacks(mock.Anything).Maybe() | |
| 56 | + | newWV.EXPECT().Generation().Return(uint64(0)).Maybe() | |
| 56 | 57 | ||
| 57 | 58 | pool := mocks.NewMockWebViewPool(t) | |
| 58 | 59 | pool.EXPECT().Acquire(mock.Anything).Return(newWV, nil) | |
| @@ -75,6 +76,7 @@ func TestLifecycle_EnsureWebView_AcquiresFromPoolWhenExistingIsDestroyed(t *test | |||
| 75 | 76 | ||
| 76 | 77 | newWV := mocks.NewMockWebView(t) | |
| 77 | 78 | newWV.EXPECT().SetCallbacks(mock.Anything).Maybe() | |
| 79 | + | newWV.EXPECT().Generation().Return(uint64(0)).Maybe() | |
| 78 | 80 | ||
| 79 | 81 | pool := mocks.NewMockWebViewPool(t) | |
| 80 | 82 | pool.EXPECT().Acquire(mock.Anything).Return(newWV, nil) | |
| @@ -53,6 +53,7 @@ func TestLifecycle_EnsureWebView_AcquiresFromPoolWhenNoneExists(t *testing.T) { | |||||
| 53 | 53 | ||||
| 54 | newWV := mocks.NewMockWebView(t) | 54 | newWV := mocks.NewMockWebView(t) | ||
| 55 | newWV.EXPECT().SetCallbacks(mock.Anything).Maybe() | 55 | newWV.EXPECT().SetCallbacks(mock.Anything).Maybe() | ||
| 56 | + | newWV.EXPECT().Generation().Return(uint64(0)).Maybe() | |||
| 56 | 57 | ||||
| 57 | pool := mocks.NewMockWebViewPool(t) | 58 | pool := mocks.NewMockWebViewPool(t) | ||
| 58 | pool.EXPECT().Acquire(mock.Anything).Return(newWV, nil) | 59 | pool.EXPECT().Acquire(mock.Anything).Return(newWV, nil) | ||
| @@ -75,6 +76,7 @@ func TestLifecycle_EnsureWebView_AcquiresFromPoolWhenExistingIsDestroyed(t *test | |||||
| 75 | 76 | ||||
| 76 | newWV := mocks.NewMockWebView(t) | 77 | newWV := mocks.NewMockWebView(t) | ||
| 77 | newWV.EXPECT().SetCallbacks(mock.Anything).Maybe() | 78 | newWV.EXPECT().SetCallbacks(mock.Anything).Maybe() | ||
| 79 | + | newWV.EXPECT().Generation().Return(uint64(0)).Maybe() | |||
| 78 | 80 | ||||
| 79 | pool := mocks.NewMockWebViewPool(t) | 81 | pool := mocks.NewMockWebViewPool(t) | ||
| 80 | pool.EXPECT().Acquire(mock.Anything).Return(newWV, nil) | 82 | pool.EXPECT().Acquire(mock.Anything).Return(newWV, nil) | ||
M internal/ui/coordinator/content/navigation.go +20 -21
| @@ -9,8 +9,8 @@ import ( | |||
| 9 | 9 | "github.com/bnema/dumber/internal/domain/entity" | |
| 10 | 10 | urlutil "github.com/bnema/dumber/internal/domain/url" | |
| 11 | 11 | "github.com/bnema/dumber/internal/infrastructure/desktop" | |
| 12 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 13 | 12 | "github.com/bnema/dumber/internal/logging" | |
| 13 | + | "github.com/jwijenbergh/puregotk/v4/gtk" | |
| 14 | 14 | ) | |
| 15 | 15 | ||
| 16 | 16 | // onLoadCommitted re-applies zoom when page content starts loading and records history. | |
| @@ -27,23 +27,20 @@ func (c *Coordinator) onLoadCommitted(ctx context.Context, paneID entity.PaneID, | |||
| 27 | 27 | } | |
| 28 | 28 | ||
| 29 | 29 | // Set appropriate background color based on page type to prevent dark background bleeding. | |
| 30 | - | // Type-assert to access webkit-specific background color methods. | |
| 31 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |
| 32 | - | switch { | |
| 33 | - | case strings.HasPrefix(uri, "dumb://"): | |
| 34 | - | // Internal pages: apply themed background | |
| 35 | - | theme, ok := c.getCurrentTheme() | |
| 36 | - | if ok && theme.prefersDark { | |
| 37 | - | wkWV.SetBackgroundColor(darkBgR, darkBgG, darkBgB, darkBgA) | |
| 38 | - | } else { | |
| 39 | - | wkWV.ResetBackgroundToDefault() | |
| 40 | - | } | |
| 41 | - | case strings.HasPrefix(uri, "about:"): | |
| 42 | - | // Keep pool background (no action) | |
| 43 | - | default: | |
| 44 | - | // External pages: white background | |
| 45 | - | wkWV.ResetBackgroundToDefault() | |
| 30 | + | switch { | |
| 31 | + | case strings.HasPrefix(uri, "dumb://"): | |
| 32 | + | // Internal pages: apply themed background | |
| 33 | + | theme, ok := c.getCurrentTheme() | |
| 34 | + | if ok && theme.prefersDark { | |
| 35 | + | wv.SetBackgroundColor(darkBgR, darkBgG, darkBgB, darkBgA) | |
| 36 | + | } else { | |
| 37 | + | wv.ResetBackgroundToDefault() | |
| 46 | 38 | } | |
| 39 | + | case strings.HasPrefix(uri, "about:"): | |
| 40 | + | // Keep pool background (no action) | |
| 41 | + | default: | |
| 42 | + | // External pages: white background | |
| 43 | + | wv.ResetBackgroundToDefault() | |
| 47 | 44 | } | |
| 48 | 45 | ||
| 49 | 46 | // Show the WebView now that content is being painted | |
| @@ -259,10 +256,12 @@ func (c *Coordinator) revealIfPending(ctx context.Context, paneID entity.PaneID, | |||
| 259 | 256 | return | |
| 260 | 257 | } | |
| 261 | 258 | ||
| 262 | - | // Type-assert to access webkit-specific Widget() for visibility control | |
| 263 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | |
| 264 | - | if inner := wkWV.Widget(); inner != nil { | |
| 265 | - | inner.SetVisible(true) | |
| 259 | + | // Use NativeWidgetProvider to make the widget visible (engine-agnostic) | |
| 260 | + | if nwp, ok := wv.(port.NativeWidgetProvider); ok { | |
| 261 | + | if ptr := nwp.NativeWidget(); ptr != 0 { | |
| 262 | + | gtkWidget := >k.Widget{} | |
| 263 | + | gtkWidget.Ptr = ptr | |
| 264 | + | gtkWidget.SetVisible(true) | |
| 266 | 265 | logging.FromContext(ctx). | |
| 267 | 266 | Debug(). | |
| 268 | 267 | Str("pane_id", string(paneID)). | |
| @@ -9,8 +9,8 @@ import ( | |||||
| 9 | "github.com/bnema/dumber/internal/domain/entity" | 9 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 10 | urlutil "github.com/bnema/dumber/internal/domain/url" | 10 | urlutil "github.com/bnema/dumber/internal/domain/url" | ||
| 11 | "github.com/bnema/dumber/internal/infrastructure/desktop" | 11 | "github.com/bnema/dumber/internal/infrastructure/desktop" | ||
| 12 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |||
| 13 | "github.com/bnema/dumber/internal/logging" | 12 | "github.com/bnema/dumber/internal/logging" | ||
| 13 | + | "github.com/jwijenbergh/puregotk/v4/gtk" | |||
| 14 | ) | 14 | ) | ||
| 15 | 15 | ||||
| 16 | // onLoadCommitted re-applies zoom when page content starts loading and records history. | 16 | // onLoadCommitted re-applies zoom when page content starts loading and records history. | ||
| @@ -27,23 +27,20 @@ func (c *Coordinator) onLoadCommitted(ctx context.Context, paneID entity.PaneID, | |||||
| 27 | } | 27 | } | ||
| 28 | 28 | ||||
| 29 | // Set appropriate background color based on page type to prevent dark background bleeding. | 29 | // Set appropriate background color based on page type to prevent dark background bleeding. | ||
| 30 | - | // Type-assert to access webkit-specific background color methods. | 30 | + | switch { |
| 31 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | 31 | + | case strings.HasPrefix(uri, "dumb://"): |
| 32 | - | switch { | 32 | + | // Internal pages: apply themed background |
| 33 | - | case strings.HasPrefix(uri, "dumb://"): | 33 | + | theme, ok := c.getCurrentTheme() |
| 34 | - | // Internal pages: apply themed background | 34 | + | if ok && theme.prefersDark { |
| 35 | - | theme, ok := c.getCurrentTheme() | 35 | + | wv.SetBackgroundColor(darkBgR, darkBgG, darkBgB, darkBgA) |
| 36 | - | if ok && theme.prefersDark { | 36 | + | } else { |
| 37 | - | wkWV.SetBackgroundColor(darkBgR, darkBgG, darkBgB, darkBgA) | 37 | + | wv.ResetBackgroundToDefault() |
| 38 | - | } else { | |||
| 39 | - | wkWV.ResetBackgroundToDefault() | |||
| 40 | - | } | |||
| 41 | - | case strings.HasPrefix(uri, "about:"): | |||
| 42 | - | // Keep pool background (no action) | |||
| 43 | - | default: | |||
| 44 | - | // External pages: white background | |||
| 45 | - | wkWV.ResetBackgroundToDefault() | |||
| 46 | } | 38 | } | ||
| 39 | + | case strings.HasPrefix(uri, "about:"): | |||
| 40 | + | // Keep pool background (no action) | |||
| 41 | + | default: | |||
| 42 | + | // External pages: white background | |||
| 43 | + | wv.ResetBackgroundToDefault() | |||
| 47 | } | 44 | } | ||
| 48 | 45 | ||||
| 49 | // Show the WebView now that content is being painted | 46 | // Show the WebView now that content is being painted | ||
| @@ -259,10 +256,12 @@ func (c *Coordinator) revealIfPending(ctx context.Context, paneID entity.PaneID, | |||||
| 259 | return | 256 | return | ||
| 260 | } | 257 | } | ||
| 261 | 258 | ||||
| 262 | - | // Type-assert to access webkit-specific Widget() for visibility control | 259 | + | // Use NativeWidgetProvider to make the widget visible (engine-agnostic) |
| 263 | - | if wkWV, ok := wv.(*webkit.WebView); ok { | 260 | + | if nwp, ok := wv.(port.NativeWidgetProvider); ok { |
| 264 | - | if inner := wkWV.Widget(); inner != nil { | 261 | + | if ptr := nwp.NativeWidget(); ptr != 0 { |
| 265 | - | inner.SetVisible(true) | 262 | + | gtkWidget := >k.Widget{} |
| 263 | + | gtkWidget.Ptr = ptr | |||
| 264 | + | gtkWidget.SetVisible(true) | |||
| 266 | logging.FromContext(ctx). | 265 | logging.FromContext(ctx). | ||
| 267 | Debug(). | 266 | Debug(). | ||
| 268 | Str("pane_id", string(paneID)). | 267 | Str("pane_id", string(paneID)). | ||
M internal/ui/coordinator/content/title.go +15 -20
| @@ -6,7 +6,6 @@ import ( | |||
| 6 | 6 | ||
| 7 | 7 | "github.com/bnema/dumber/internal/application/port" | |
| 8 | 8 | "github.com/bnema/dumber/internal/domain/entity" | |
| 9 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |
| 10 | 9 | "github.com/bnema/dumber/internal/logging" | |
| 11 | 10 | "github.com/bnema/dumber/internal/ui/adapter" | |
| 12 | 11 | "github.com/bnema/dumber/internal/ui/layout" | |
| @@ -209,27 +208,23 @@ func (c *Coordinator) resolveCommittedFavicon(ctx context.Context, paneID entity | |||
| 209 | 208 | return | |
| 210 | 209 | } | |
| 211 | 210 | ||
| 212 | - | // Type-assert to access webkit-specific Favicon() and Generation() | |
| 213 | - | wkWV, ok := wv.(*webkit.WebView) | |
| 214 | - | if !ok { | |
| 215 | - | return | |
| 216 | - | } | |
| 217 | - | ||
| 218 | - | // Check if WebKit already has a favicon for this page | |
| 219 | - | if icon := wkWV.Favicon(); icon != nil { | |
| 220 | - | log.Debug().Str("pane_id", string(paneID)).Str("uri", uri).Msg("using existing WebKit favicon for committed page") | |
| 221 | - | // Store and update through the normal path | |
| 222 | - | c.navOriginMu.RLock() | |
| 223 | - | originURL := c.navOrigins[paneID] | |
| 224 | - | c.navOriginMu.RUnlock() | |
| 225 | - | c.faviconAdapter.StoreFromWebKitWithOrigin(ctx, uri, originURL, icon) | |
| 226 | - | c.updateStackedFaviconForPane(ctx, paneID, icon) | |
| 227 | - | return | |
| 211 | + | // Check if the WebView already has a favicon for this page | |
| 212 | + | if icon := wv.Favicon(); icon != nil { | |
| 213 | + | if gdkIcon, ok := icon.(*gdk.Texture); ok { | |
| 214 | + | log.Debug().Str("pane_id", string(paneID)).Str("uri", uri).Msg("using existing favicon for committed page") | |
| 215 | + | // Store and update through the normal path | |
| 216 | + | c.navOriginMu.RLock() | |
| 217 | + | originURL := c.navOrigins[paneID] | |
| 218 | + | c.navOriginMu.RUnlock() | |
| 219 | + | c.faviconAdapter.StoreFromWebKitWithOrigin(ctx, uri, originURL, gdkIcon) | |
| 220 | + | c.updateStackedFaviconForPane(ctx, paneID, gdkIcon) | |
| 221 | + | return | |
| 222 | + | } | |
| 228 | 223 | } | |
| 229 | 224 | ||
| 230 | - | // Fall back to GetOrFetch (checks service cache, WebKit DB, then DuckDuckGo API) | |
| 225 | + | // Fall back to GetOrFetch (checks service cache, engine DB, then DuckDuckGo API) | |
| 231 | 226 | // Capture current generation to guard against stale callbacks | |
| 232 | - | gen := wkWV.Generation() | |
| 227 | + | gen := wv.Generation() | |
| 233 | 228 | capturedURI := uri | |
| 234 | 229 | c.faviconAdapter.GetOrFetch(ctx, uri, func(texture *gdk.Texture) { | |
| 235 | 230 | // Skip nil results — a nil means "couldn't resolve", not "no favicon". | |
| @@ -239,7 +234,7 @@ func (c *Coordinator) resolveCommittedFavicon(ctx context.Context, paneID entity | |||
| 239 | 234 | return | |
| 240 | 235 | } | |
| 241 | 236 | // Verify WebView is still bound to pane and hasn't been reused | |
| 242 | - | if wkWV.Generation() != gen { | |
| 237 | + | if wv.Generation() != gen { | |
| 243 | 238 | return | |
| 244 | 239 | } | |
| 245 | 240 | currentWV := c.getWebViewLocked(paneID) | |
| @@ -6,7 +6,6 @@ import ( | |||||
| 6 | 6 | ||||
| 7 | "github.com/bnema/dumber/internal/application/port" | 7 | "github.com/bnema/dumber/internal/application/port" | ||
| 8 | "github.com/bnema/dumber/internal/domain/entity" | 8 | "github.com/bnema/dumber/internal/domain/entity" | ||
| 9 | - | "github.com/bnema/dumber/internal/infrastructure/webkit" | |||
| 10 | "github.com/bnema/dumber/internal/logging" | 9 | "github.com/bnema/dumber/internal/logging" | ||
| 11 | "github.com/bnema/dumber/internal/ui/adapter" | 10 | "github.com/bnema/dumber/internal/ui/adapter" | ||
| 12 | "github.com/bnema/dumber/internal/ui/layout" | 11 | "github.com/bnema/dumber/internal/ui/layout" | ||
| @@ -209,27 +208,23 @@ func (c *Coordinator) resolveCommittedFavicon(ctx context.Context, paneID entity | |||||
| 209 | return | 208 | return | ||
| 210 | } | 209 | } | ||
| 211 | 210 | ||||
| 212 | - | // Type-assert to access webkit-specific Favicon() and Generation() | 211 | + | // Check if the WebView already has a favicon for this page |
| 213 | - | wkWV, ok := wv.(*webkit.WebView) | 212 | + | if icon := wv.Favicon(); icon != nil { |
| 214 | - | if !ok { | 213 | + | if gdkIcon, ok := icon.(*gdk.Texture); ok { |
| 215 | - | return | 214 | + | log.Debug().Str("pane_id", string(paneID)).Str("uri", uri).Msg("using existing favicon for committed page") |
| 216 | - | } | 215 | + | // Store and update through the normal path |
| 217 | - | 216 | + | c.navOriginMu.RLock() | |
| 218 | - | // Check if WebKit already has a favicon for this page | 217 | + | originURL := c.navOrigins[paneID] |
| 219 | - | if icon := wkWV.Favicon(); icon != nil { | 218 | + | c.navOriginMu.RUnlock() |
| 220 | - | log.Debug().Str("pane_id", string(paneID)).Str("uri", uri).Msg("using existing WebKit favicon for committed page") | 219 | + | c.faviconAdapter.StoreFromWebKitWithOrigin(ctx, uri, originURL, gdkIcon) |
| 221 | - | // Store and update through the normal path | 220 | + | c.updateStackedFaviconForPane(ctx, paneID, gdkIcon) |
| 222 | - | c.navOriginMu.RLock() | 221 | + | return |
| 223 | - | originURL := c.navOrigins[paneID] | 222 | + | } |
| 224 | - | c.navOriginMu.RUnlock() | |||
| 225 | - | c.faviconAdapter.StoreFromWebKitWithOrigin(ctx, uri, originURL, icon) | |||
| 226 | - | c.updateStackedFaviconForPane(ctx, paneID, icon) | |||
| 227 | - | return | |||
| 228 | } | 223 | } | ||
| 229 | 224 | ||||
| 230 | - | // Fall back to GetOrFetch (checks service cache, WebKit DB, then DuckDuckGo API) | 225 | + | // Fall back to GetOrFetch (checks service cache, engine DB, then DuckDuckGo API) |
| 231 | // Capture current generation to guard against stale callbacks | 226 | // Capture current generation to guard against stale callbacks | ||
| 232 | - | gen := wkWV.Generation() | 227 | + | gen := wv.Generation() |
| 233 | capturedURI := uri | 228 | capturedURI := uri | ||
| 234 | c.faviconAdapter.GetOrFetch(ctx, uri, func(texture *gdk.Texture) { | 229 | c.faviconAdapter.GetOrFetch(ctx, uri, func(texture *gdk.Texture) { | ||
| 235 | // Skip nil results — a nil means "couldn't resolve", not "no favicon". | 230 | // Skip nil results — a nil means "couldn't resolve", not "no favicon". | ||
| @@ -239,7 +234,7 @@ func (c *Coordinator) resolveCommittedFavicon(ctx context.Context, paneID entity | |||||
| 239 | return | 234 | return | ||
| 240 | } | 235 | } | ||
| 241 | // Verify WebView is still bound to pane and hasn't been reused | 236 | // Verify WebView is still bound to pane and hasn't been reused | ||
| 242 | - | if wkWV.Generation() != gen { | 237 | + | if wv.Generation() != gen { |
| 243 | return | 238 | return | ||
| 244 | } | 239 | } | ||
| 245 | currentWV := c.getWebViewLocked(paneID) | 240 | currentWV := c.getWebViewLocked(paneID) | ||