detached 5294200

refactor(webkit): consume typed settings payload

commit
5294200ee699203df0b7ca58827593e492f2df01
author
brice · · 2026-06-23 13:31 UTC
committer
brice · · 2026-06-23 20:01 UTC
parent
4ed4d97
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
6 files · +106 -65
M internal/bootstrap/engine.go +1 -0
@@ -71,6 +71,7 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
7171
7272 return webkit.NewEngine(
7373 input.Ctx, cfg, opts, profile, wkCfg,
74+ EngineSettingsPayloadFromConfig(cfg),
7475 currentConfigPayload, defaultConfigPayload,
7576 input.ThemeManager, input.ColorResolver,
7677 contextMenuBuilder, contextMenuExecutorFactory,
@@ -71,6 +71,7 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
71 71
72 return webkit.NewEngine(72 return webkit.NewEngine(
73 input.Ctx, cfg, opts, profile, wkCfg,73 input.Ctx, cfg, opts, profile, wkCfg,
74+ EngineSettingsPayloadFromConfig(cfg),
74 currentConfigPayload, defaultConfigPayload,75 currentConfigPayload, defaultConfigPayload,
75 input.ThemeManager, input.ColorResolver,76 input.ThemeManager, input.ColorResolver,
76 contextMenuBuilder, contextMenuExecutorFactory,77 contextMenuBuilder, contextMenuExecutorFactory,
M internal/infrastructure/webkit/engine.go +1 -6
@@ -5,7 +5,6 @@ import (
55 "fmt"
66
77 "github.com/bnema/dumber/internal/application/port"
8- "github.com/bnema/dumber/internal/infrastructure/config"
98 "github.com/bnema/dumber/internal/infrastructure/filtering"
109 "github.com/bnema/dumber/internal/infrastructure/handlers"
1110 "github.com/rs/zerolog"
@@ -157,12 +156,8 @@ func (e *Engine) UpdateAppearance(_ context.Context, r, g, b, alpha float64) err
157156
158157 // UpdateSettings applies runtime config changes to engine settings.
159158 func (e *Engine) UpdateSettings(ctx context.Context, update port.EngineSettingsUpdate) error {
160- cfg, ok := update.Raw.(*config.Config)
161- if !ok {
162- return fmt.Errorf("UpdateSettings: expected *config.Config, got %T", update.Raw)
163- }
164159 if e.settings != nil {
165- e.settings.UpdateFromConfig(ctx, cfg)
160+ e.settings.UpdateFromPayload(ctx, update.Settings)
166161 }
167162 return nil
168163 }
@@ -5,7 +5,6 @@ import (
5 "fmt"5 "fmt"
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/config"
9 "github.com/bnema/dumber/internal/infrastructure/filtering"8 "github.com/bnema/dumber/internal/infrastructure/filtering"
10 "github.com/bnema/dumber/internal/infrastructure/handlers"9 "github.com/bnema/dumber/internal/infrastructure/handlers"
11 "github.com/rs/zerolog"10 "github.com/rs/zerolog"
@@ -157,12 +156,8 @@ func (e *Engine) UpdateAppearance(_ context.Context, r, g, b, alpha float64) err
157 156
158 // UpdateSettings applies runtime config changes to engine settings.157 // UpdateSettings applies runtime config changes to engine settings.
159 func (e *Engine) UpdateSettings(ctx context.Context, update port.EngineSettingsUpdate) error {158 func (e *Engine) UpdateSettings(ctx context.Context, update port.EngineSettingsUpdate) error {
160- cfg, ok := update.Raw.(*config.Config)
161- if !ok {
162- return fmt.Errorf("UpdateSettings: expected *config.Config, got %T", update.Raw)
163- }
164 if e.settings != nil {159 if e.settings != nil {
165- e.settings.UpdateFromConfig(ctx, cfg)160+ e.settings.UpdateFromPayload(ctx, update.Settings)
166 }161 }
167 return nil162 return nil
168 }163 }
M internal/infrastructure/webkit/engine_init.go +2 -1
@@ -25,6 +25,7 @@ func NewEngine(
2525 opts port.EngineOptions,
2626 profile runtimeprofile.Profile,
2727 wkCfg WebKitEngineConfig,
28+ initialSettings port.EngineSettingsPayload,
2829 currentConfigPayload func() ([]byte, error),
2930 defaultConfigPayload func() ([]byte, error),
3031 themeManager *theme.Manager,
@@ -63,7 +64,7 @@ func NewEngine(
6364 schemeHandler.RegisterWithContext(wkCtx)
6465
6566 // --- Settings, injector, message router ---
66- settings := NewSettingsManager(ctx, cfg)
67+ settings := NewSettingsManager(ctx, initialSettings)
6768 injector := NewContentInjector(colorResolver)
6869
6970 injector.SetAutoCopyConfigGetter(func() bool {
@@ -25,6 +25,7 @@ func NewEngine(
25 opts port.EngineOptions,25 opts port.EngineOptions,
26 profile runtimeprofile.Profile,26 profile runtimeprofile.Profile,
27 wkCfg WebKitEngineConfig,27 wkCfg WebKitEngineConfig,
28+ initialSettings port.EngineSettingsPayload,
28 currentConfigPayload func() ([]byte, error),29 currentConfigPayload func() ([]byte, error),
29 defaultConfigPayload func() ([]byte, error),30 defaultConfigPayload func() ([]byte, error),
30 themeManager *theme.Manager,31 themeManager *theme.Manager,
@@ -63,7 +64,7 @@ func NewEngine(
63 schemeHandler.RegisterWithContext(wkCtx)64 schemeHandler.RegisterWithContext(wkCtx)
64 65
65 // --- Settings, injector, message router ---66 // --- Settings, injector, message router ---
66- settings := NewSettingsManager(ctx, cfg)67+ settings := NewSettingsManager(ctx, initialSettings)
67 injector := NewContentInjector(colorResolver)68 injector := NewContentInjector(colorResolver)
68 69
69 injector.SetAutoCopyConfigGetter(func() bool {70 injector.SetAutoCopyConfigGetter(func() bool {
M internal/infrastructure/webkit/engine_runtime_test.go +22 -9
@@ -5,23 +5,36 @@ import (
55 "testing"
66
77 "github.com/bnema/dumber/internal/application/port"
8- "github.com/bnema/dumber/internal/infrastructure/config"
98 "github.com/stretchr/testify/require"
109 )
1110
12-func TestEngine_UpdateSettings_WrongType(t *testing.T) {
13- e := &Engine{}
14- err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: "wrong"})
15- require.Error(t, err)
16- require.Contains(t, err.Error(), "expected *config.Config")
11+func TestEngine_UpdateSettings_AcceptsTypedSettingsPayload(t *testing.T) {
12+ e := &Engine{settings: NewSettingsManager(context.Background(), port.EngineSettingsPayload{})}
13+
14+ err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{
15+ Settings: port.EngineSettingsPayload{
16+ DefaultUIScale: 1.25,
17+ WebContent: port.EngineWebContentSettingsPayload{
18+ SansFont: "Inter",
19+ EnableDevTools: true,
20+ CaptureConsole: true,
21+ DrawCompositingIndicators: true,
22+ HardwareDecoding: port.EngineHardwareDecodingDisable,
23+ },
24+ },
25+ })
26+ require.NoError(t, err)
27+ require.Equal(t, "Inter", e.settings.current().WebContent.SansFont)
28+ require.True(t, e.settings.current().WebContent.EnableDevTools)
29+ require.True(t, e.settings.current().WebContent.CaptureConsole)
30+ require.True(t, e.settings.current().WebContent.DrawCompositingIndicators)
31+ require.Equal(t, port.EngineHardwareDecodingDisable, e.settings.current().WebContent.HardwareDecoding)
1732 }
1833
1934 func TestEngine_UpdateSettings_NilSettings(t *testing.T) {
2035 // settings is nil — should not panic, just be a no-op.
2136 e := &Engine{}
22- // Use a nil *config.Config to pass the type assertion.
23- var cfg *config.Config
24- err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: cfg})
37+ err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{})
2538 require.NoError(t, err)
2639 }
2740
@@ -5,23 +5,36 @@ import (
5 "testing"5 "testing"
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/config"
9 "github.com/stretchr/testify/require"8 "github.com/stretchr/testify/require"
10 )9 )
11 10
12-func TestEngine_UpdateSettings_WrongType(t *testing.T) {11+func TestEngine_UpdateSettings_AcceptsTypedSettingsPayload(t *testing.T) {
13- e := &Engine{}12+ e := &Engine{settings: NewSettingsManager(context.Background(), port.EngineSettingsPayload{})}
14- err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: "wrong"})13+
15- require.Error(t, err)14+ err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{
16- require.Contains(t, err.Error(), "expected *config.Config")15+ Settings: port.EngineSettingsPayload{
16+ DefaultUIScale: 1.25,
17+ WebContent: port.EngineWebContentSettingsPayload{
18+ SansFont: "Inter",
19+ EnableDevTools: true,
20+ CaptureConsole: true,
21+ DrawCompositingIndicators: true,
22+ HardwareDecoding: port.EngineHardwareDecodingDisable,
23+ },
24+ },
25+ })
26+ require.NoError(t, err)
27+ require.Equal(t, "Inter", e.settings.current().WebContent.SansFont)
28+ require.True(t, e.settings.current().WebContent.EnableDevTools)
29+ require.True(t, e.settings.current().WebContent.CaptureConsole)
30+ require.True(t, e.settings.current().WebContent.DrawCompositingIndicators)
31+ require.Equal(t, port.EngineHardwareDecodingDisable, e.settings.current().WebContent.HardwareDecoding)
17 }32 }
18 33
19 func TestEngine_UpdateSettings_NilSettings(t *testing.T) {34 func TestEngine_UpdateSettings_NilSettings(t *testing.T) {
20 // settings is nil — should not panic, just be a no-op.35 // settings is nil — should not panic, just be a no-op.
21 e := &Engine{}36 e := &Engine{}
22- // Use a nil *config.Config to pass the type assertion.37+ err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{})
23- var cfg *config.Config
24- err := e.UpdateSettings(context.Background(), port.EngineSettingsUpdate{Raw: cfg})
25 require.NoError(t, err)38 require.NoError(t, err)
26 }39 }
27 40
M internal/infrastructure/webkit/settings.go +48 -49
@@ -4,34 +4,35 @@ import (
44 "context"
55 "sync"
66
7- "github.com/bnema/dumber/internal/infrastructure/config"
7+ "github.com/bnema/dumber/internal/application/port"
88 "github.com/bnema/dumber/internal/logging"
99 "github.com/bnema/puregotk/v4/webkit"
1010 "github.com/rs/zerolog"
1111 )
1212
13-// SettingsManager creates and manages WebKit Settings instances from config.
13+// SettingsManager creates and manages WebKit Settings instances from payloads.
1414 type SettingsManager struct {
15- cfg *config.Config
16- mu sync.RWMutex
15+ settings port.EngineSettingsPayload
16+ mu sync.RWMutex
1717 }
1818
19-// NewSettingsManager creates a new SettingsManager with the given config.
20-func NewSettingsManager(ctx context.Context, cfg *config.Config) *SettingsManager {
19+// NewSettingsManager creates a new SettingsManager with the given payload.
20+func NewSettingsManager(ctx context.Context, settings port.EngineSettingsPayload) *SettingsManager {
2121 log := logging.FromContext(ctx)
2222 log.Debug().Msg("creating settings manager")
23- return &SettingsManager{
24- cfg: cfg,
25- }
23+ return &SettingsManager{settings: settings}
24+}
25+
26+func (sm *SettingsManager) current() port.EngineSettingsPayload {
27+ sm.mu.RLock()
28+ defer sm.mu.RUnlock()
29+ return sm.settings
2630 }
2731
28-// CreateSettings creates a new webkit.Settings instance configured from the current config.
32+// CreateSettings creates a new webkit.Settings instance configured from the current payload.
2933 func (sm *SettingsManager) CreateSettings(ctx context.Context) *webkit.Settings {
3034 log := logging.FromContext(ctx)
31-
32- sm.mu.RLock()
33- cfg := sm.cfg
34- sm.mu.RUnlock()
35+ payload := sm.current()
3536
3637 settings := webkit.NewSettings()
3738 if settings == nil {
@@ -39,21 +40,21 @@ func (sm *SettingsManager) CreateSettings(ctx context.Context) *webkit.Settings
3940 return nil
4041 }
4142
42- sm.applySettings(ctx, settings, cfg)
43+ sm.applySettings(ctx, settings, payload)
4344 return settings
4445 }
4546
46-// applySettings applies configuration to a webkit.Settings instance.
47-func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.Settings, cfg *config.Config) {
47+// applySettings applies settings payload to a webkit.Settings instance.
48+func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.Settings, payload port.EngineSettingsPayload) {
4849 if sm == nil {
4950 return
5051 }
5152 log := logging.FromContext(ctx)
5253 applyJavaScriptSettings(settings)
53- applyFontSettings(settings, cfg)
54- applyDebugSettings(settings, cfg)
54+ applyFontSettings(settings, payload.WebContent)
55+ applyDebugSettings(settings, payload.WebContent)
5556 applyBrowsingSettings(settings)
56- applyMediaSettings(settings, cfg, log)
57+ applyMediaSettings(settings, payload.WebContent.HardwareDecoding, log)
5758 applyStorageSettings(settings)
5859 applyUISettings(settings)
5960 applyCanvasSettings(settings)
@@ -63,8 +64,8 @@ func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.S
6364 mediaStreamEnabled := settings.GetPropertyEnableMediaStream()
6465
6566 log.Debug().
66- Str("sans_font", cfg.Appearance.SansFont).
67- Bool("developer_extras", cfg.Debug.EnableDevTools).
67+ Str("sans_font", payload.WebContent.SansFont).
68+ Bool("developer_extras", payload.WebContent.EnableDevTools).
6869 Bool("webrtc_enabled", webrtcEnabled).
6970 Bool("media_stream_enabled", mediaStreamEnabled).
7071 Msg("settings applied")
@@ -75,26 +76,26 @@ func applyJavaScriptSettings(settings *webkit.Settings) {
7576 settings.SetEnableJavascriptMarkup(true)
7677 }
7778
78-func applyFontSettings(settings *webkit.Settings, cfg *config.Config) {
79- if cfg.Appearance.SansFont != "" {
80- settings.SetDefaultFontFamily(cfg.Appearance.SansFont)
81- settings.SetSansSerifFontFamily(cfg.Appearance.SansFont)
79+func applyFontSettings(settings *webkit.Settings, payload port.EngineWebContentSettingsPayload) {
80+ if payload.SansFont != "" {
81+ settings.SetDefaultFontFamily(payload.SansFont)
82+ settings.SetSansSerifFontFamily(payload.SansFont)
8283 }
83- if cfg.Appearance.SerifFont != "" {
84- settings.SetSerifFontFamily(cfg.Appearance.SerifFont)
84+ if payload.SerifFont != "" {
85+ settings.SetSerifFontFamily(payload.SerifFont)
8586 }
86- if cfg.Appearance.MonospaceFont != "" {
87- settings.SetMonospaceFontFamily(cfg.Appearance.MonospaceFont)
87+ if payload.MonospaceFont != "" {
88+ settings.SetMonospaceFontFamily(payload.MonospaceFont)
8889 }
89- if cfg.Appearance.DefaultFontSize > 0 {
90- settings.SetDefaultFontSize(uint32(cfg.Appearance.DefaultFontSize))
90+ if payload.DefaultFontSize > 0 {
91+ settings.SetDefaultFontSize(uint32(payload.DefaultFontSize))
9192 }
9293 }
9394
94-func applyDebugSettings(settings *webkit.Settings, cfg *config.Config) {
95- settings.SetEnableDeveloperExtras(cfg.Debug.EnableDevTools)
96- settings.SetEnableWriteConsoleMessagesToStdout(cfg.Logging.CaptureConsole)
97- settings.SetDrawCompositingIndicators(cfg.Engine.WebKit.DrawCompositingIndicators)
95+func applyDebugSettings(settings *webkit.Settings, payload port.EngineWebContentSettingsPayload) {
96+ settings.SetEnableDeveloperExtras(payload.EnableDevTools)
97+ settings.SetEnableWriteConsoleMessagesToStdout(payload.CaptureConsole)
98+ settings.SetDrawCompositingIndicators(payload.DrawCompositingIndicators)
9899 }
99100
100101 func applyBrowsingSettings(settings *webkit.Settings) {
@@ -103,7 +104,7 @@ func applyBrowsingSettings(settings *webkit.Settings) {
103104 settings.SetEnableSiteSpecificQuirks(true)
104105 }
105106
106-func applyMediaSettings(settings *webkit.Settings, cfg *config.Config, log *zerolog.Logger) {
107+func applyMediaSettings(settings *webkit.Settings, mode port.EngineHardwareDecodingMode, log *zerolog.Logger) {
107108 settings.SetEnableWebaudio(true)
108109 settings.SetEnableWebgl(true)
109110 settings.SetEnableMedia(true)
@@ -113,12 +114,12 @@ func applyMediaSettings(settings *webkit.Settings, cfg *config.Config, log *zero
113114 settings.SetMediaPlaybackRequiresUserGesture(true)
114115 settings.SetMediaPlaybackAllowsInline(true)
115116
116- switch cfg.Media.HardwareDecodingMode {
117- case config.HardwareDecodingForce:
117+ switch mode {
118+ case port.EngineHardwareDecodingForce:
118119 hwTypes := "video/av01;video/mp4;video/webm;video/x-h264;video/x-h265"
119120 settings.SetMediaContentTypesRequiringHardwareSupport(&hwTypes)
120121 log.Debug().Msg("hardware decoding: forced (may fail without hw support)")
121- case config.HardwareDecodingDisable:
122+ case port.EngineHardwareDecodingDisable:
122123 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyNeverValue)
123124 log.Debug().Msg("hardware decoding: disabled (software only)")
124125 default:
@@ -151,15 +152,15 @@ func applyWebRTCSettings(settings *webkit.Settings) {
151152 settings.SetEnableWebrtc(true)
152153 }
153154
154-// UpdateFromConfig updates the manager with a new config (for hot-reload).
155+// UpdateFromPayload updates the manager with a new payload (for hot-reload).
155156 // Note: This doesn't update already-created Settings instances.
156-// New WebViews will use the updated config.
157-func (sm *SettingsManager) UpdateFromConfig(ctx context.Context, cfg *config.Config) {
157+// New WebViews will use the updated payload.
158+func (sm *SettingsManager) UpdateFromPayload(ctx context.Context, settings port.EngineSettingsPayload) {
158159 log := logging.FromContext(ctx)
159160 sm.mu.Lock()
160161 defer sm.mu.Unlock()
161- sm.cfg = cfg
162- log.Debug().Msg("settings config updated")
162+ sm.settings = settings
163+ log.Debug().Msg("settings payload updated")
163164 }
164165
165166 // ApplyToWebView applies current settings to an existing WebView.
@@ -175,9 +176,7 @@ func (sm *SettingsManager) ApplyToWebView(ctx context.Context, wv *webkit.WebVie
175176 // Apply to the existing settings object attached to the WebView
176177 existingSettings := wv.GetSettings()
177178 if existingSettings != nil {
178- sm.mu.RLock()
179- cfg := sm.cfg
180- sm.mu.RUnlock()
181- sm.applySettings(ctx, existingSettings, cfg)
179+ payload := sm.current()
180+ sm.applySettings(ctx, existingSettings, payload)
182181 }
183182 }
@@ -4,34 +4,35 @@ import (
4 "context"4 "context"
5 "sync"5 "sync"
6 6
7- "github.com/bnema/dumber/internal/infrastructure/config"7+ "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/logging"8 "github.com/bnema/dumber/internal/logging"
9 "github.com/bnema/puregotk/v4/webkit"9 "github.com/bnema/puregotk/v4/webkit"
10 "github.com/rs/zerolog"10 "github.com/rs/zerolog"
11 )11 )
12 12
13-// SettingsManager creates and manages WebKit Settings instances from config.13+// SettingsManager creates and manages WebKit Settings instances from payloads.
14 type SettingsManager struct {14 type SettingsManager struct {
15- cfg *config.Config15+ settings port.EngineSettingsPayload
16- mu sync.RWMutex16+ mu sync.RWMutex
17 }17 }
18 18
19-// NewSettingsManager creates a new SettingsManager with the given config.19+// NewSettingsManager creates a new SettingsManager with the given payload.
20-func NewSettingsManager(ctx context.Context, cfg *config.Config) *SettingsManager {20+func NewSettingsManager(ctx context.Context, settings port.EngineSettingsPayload) *SettingsManager {
21 log := logging.FromContext(ctx)21 log := logging.FromContext(ctx)
22 log.Debug().Msg("creating settings manager")22 log.Debug().Msg("creating settings manager")
23- return &SettingsManager{23+ return &SettingsManager{settings: settings}
24- cfg: cfg,24+}
25- }25+
26+func (sm *SettingsManager) current() port.EngineSettingsPayload {
27+ sm.mu.RLock()
28+ defer sm.mu.RUnlock()
29+ return sm.settings
26 }30 }
27 31
28-// CreateSettings creates a new webkit.Settings instance configured from the current config.32+// CreateSettings creates a new webkit.Settings instance configured from the current payload.
29 func (sm *SettingsManager) CreateSettings(ctx context.Context) *webkit.Settings {33 func (sm *SettingsManager) CreateSettings(ctx context.Context) *webkit.Settings {
30 log := logging.FromContext(ctx)34 log := logging.FromContext(ctx)
31-35+ payload := sm.current()
32- sm.mu.RLock()
33- cfg := sm.cfg
34- sm.mu.RUnlock()
35 36
36 settings := webkit.NewSettings()37 settings := webkit.NewSettings()
37 if settings == nil {38 if settings == nil {
@@ -39,21 +40,21 @@ func (sm *SettingsManager) CreateSettings(ctx context.Context) *webkit.Settings
39 return nil40 return nil
40 }41 }
41 42
42- sm.applySettings(ctx, settings, cfg)43+ sm.applySettings(ctx, settings, payload)
43 return settings44 return settings
44 }45 }
45 46
46-// applySettings applies configuration to a webkit.Settings instance.47+// applySettings applies settings payload to a webkit.Settings instance.
47-func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.Settings, cfg *config.Config) {48+func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.Settings, payload port.EngineSettingsPayload) {
48 if sm == nil {49 if sm == nil {
49 return50 return
50 }51 }
51 log := logging.FromContext(ctx)52 log := logging.FromContext(ctx)
52 applyJavaScriptSettings(settings)53 applyJavaScriptSettings(settings)
53- applyFontSettings(settings, cfg)54+ applyFontSettings(settings, payload.WebContent)
54- applyDebugSettings(settings, cfg)55+ applyDebugSettings(settings, payload.WebContent)
55 applyBrowsingSettings(settings)56 applyBrowsingSettings(settings)
56- applyMediaSettings(settings, cfg, log)57+ applyMediaSettings(settings, payload.WebContent.HardwareDecoding, log)
57 applyStorageSettings(settings)58 applyStorageSettings(settings)
58 applyUISettings(settings)59 applyUISettings(settings)
59 applyCanvasSettings(settings)60 applyCanvasSettings(settings)
@@ -63,8 +64,8 @@ func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.S
63 mediaStreamEnabled := settings.GetPropertyEnableMediaStream()64 mediaStreamEnabled := settings.GetPropertyEnableMediaStream()
64 65
65 log.Debug().66 log.Debug().
66- Str("sans_font", cfg.Appearance.SansFont).67+ Str("sans_font", payload.WebContent.SansFont).
67- Bool("developer_extras", cfg.Debug.EnableDevTools).68+ Bool("developer_extras", payload.WebContent.EnableDevTools).
68 Bool("webrtc_enabled", webrtcEnabled).69 Bool("webrtc_enabled", webrtcEnabled).
69 Bool("media_stream_enabled", mediaStreamEnabled).70 Bool("media_stream_enabled", mediaStreamEnabled).
70 Msg("settings applied")71 Msg("settings applied")
@@ -75,26 +76,26 @@ func applyJavaScriptSettings(settings *webkit.Settings) {
75 settings.SetEnableJavascriptMarkup(true)76 settings.SetEnableJavascriptMarkup(true)
76 }77 }
77 78
78-func applyFontSettings(settings *webkit.Settings, cfg *config.Config) {79+func applyFontSettings(settings *webkit.Settings, payload port.EngineWebContentSettingsPayload) {
79- if cfg.Appearance.SansFont != "" {80+ if payload.SansFont != "" {
80- settings.SetDefaultFontFamily(cfg.Appearance.SansFont)81+ settings.SetDefaultFontFamily(payload.SansFont)
81- settings.SetSansSerifFontFamily(cfg.Appearance.SansFont)82+ settings.SetSansSerifFontFamily(payload.SansFont)
82 }83 }
83- if cfg.Appearance.SerifFont != "" {84+ if payload.SerifFont != "" {
84- settings.SetSerifFontFamily(cfg.Appearance.SerifFont)85+ settings.SetSerifFontFamily(payload.SerifFont)
85 }86 }
86- if cfg.Appearance.MonospaceFont != "" {87+ if payload.MonospaceFont != "" {
87- settings.SetMonospaceFontFamily(cfg.Appearance.MonospaceFont)88+ settings.SetMonospaceFontFamily(payload.MonospaceFont)
88 }89 }
89- if cfg.Appearance.DefaultFontSize > 0 {90+ if payload.DefaultFontSize > 0 {
90- settings.SetDefaultFontSize(uint32(cfg.Appearance.DefaultFontSize))91+ settings.SetDefaultFontSize(uint32(payload.DefaultFontSize))
91 }92 }
92 }93 }
93 94
94-func applyDebugSettings(settings *webkit.Settings, cfg *config.Config) {95+func applyDebugSettings(settings *webkit.Settings, payload port.EngineWebContentSettingsPayload) {
95- settings.SetEnableDeveloperExtras(cfg.Debug.EnableDevTools)96+ settings.SetEnableDeveloperExtras(payload.EnableDevTools)
96- settings.SetEnableWriteConsoleMessagesToStdout(cfg.Logging.CaptureConsole)97+ settings.SetEnableWriteConsoleMessagesToStdout(payload.CaptureConsole)
97- settings.SetDrawCompositingIndicators(cfg.Engine.WebKit.DrawCompositingIndicators)98+ settings.SetDrawCompositingIndicators(payload.DrawCompositingIndicators)
98 }99 }
99 100
100 func applyBrowsingSettings(settings *webkit.Settings) {101 func applyBrowsingSettings(settings *webkit.Settings) {
@@ -103,7 +104,7 @@ func applyBrowsingSettings(settings *webkit.Settings) {
103 settings.SetEnableSiteSpecificQuirks(true)104 settings.SetEnableSiteSpecificQuirks(true)
104 }105 }
105 106
106-func applyMediaSettings(settings *webkit.Settings, cfg *config.Config, log *zerolog.Logger) {107+func applyMediaSettings(settings *webkit.Settings, mode port.EngineHardwareDecodingMode, log *zerolog.Logger) {
107 settings.SetEnableWebaudio(true)108 settings.SetEnableWebaudio(true)
108 settings.SetEnableWebgl(true)109 settings.SetEnableWebgl(true)
109 settings.SetEnableMedia(true)110 settings.SetEnableMedia(true)
@@ -113,12 +114,12 @@ func applyMediaSettings(settings *webkit.Settings, cfg *config.Config, log *zero
113 settings.SetMediaPlaybackRequiresUserGesture(true)114 settings.SetMediaPlaybackRequiresUserGesture(true)
114 settings.SetMediaPlaybackAllowsInline(true)115 settings.SetMediaPlaybackAllowsInline(true)
115 116
116- switch cfg.Media.HardwareDecodingMode {117+ switch mode {
117- case config.HardwareDecodingForce:118+ case port.EngineHardwareDecodingForce:
118 hwTypes := "video/av01;video/mp4;video/webm;video/x-h264;video/x-h265"119 hwTypes := "video/av01;video/mp4;video/webm;video/x-h264;video/x-h265"
119 settings.SetMediaContentTypesRequiringHardwareSupport(&hwTypes)120 settings.SetMediaContentTypesRequiringHardwareSupport(&hwTypes)
120 log.Debug().Msg("hardware decoding: forced (may fail without hw support)")121 log.Debug().Msg("hardware decoding: forced (may fail without hw support)")
121- case config.HardwareDecodingDisable:122+ case port.EngineHardwareDecodingDisable:
122 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyNeverValue)123 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyNeverValue)
123 log.Debug().Msg("hardware decoding: disabled (software only)")124 log.Debug().Msg("hardware decoding: disabled (software only)")
124 default:125 default:
@@ -151,15 +152,15 @@ func applyWebRTCSettings(settings *webkit.Settings) {
151 settings.SetEnableWebrtc(true)152 settings.SetEnableWebrtc(true)
152 }153 }
153 154
154-// UpdateFromConfig updates the manager with a new config (for hot-reload).155+// UpdateFromPayload updates the manager with a new payload (for hot-reload).
155 // Note: This doesn't update already-created Settings instances.156 // Note: This doesn't update already-created Settings instances.
156-// New WebViews will use the updated config.157+// New WebViews will use the updated payload.
157-func (sm *SettingsManager) UpdateFromConfig(ctx context.Context, cfg *config.Config) {158+func (sm *SettingsManager) UpdateFromPayload(ctx context.Context, settings port.EngineSettingsPayload) {
158 log := logging.FromContext(ctx)159 log := logging.FromContext(ctx)
159 sm.mu.Lock()160 sm.mu.Lock()
160 defer sm.mu.Unlock()161 defer sm.mu.Unlock()
161- sm.cfg = cfg162+ sm.settings = settings
162- log.Debug().Msg("settings config updated")163+ log.Debug().Msg("settings payload updated")
163 }164 }
164 165
165 // ApplyToWebView applies current settings to an existing WebView.166 // ApplyToWebView applies current settings to an existing WebView.
@@ -175,9 +176,7 @@ func (sm *SettingsManager) ApplyToWebView(ctx context.Context, wv *webkit.WebVie
175 // Apply to the existing settings object attached to the WebView176 // Apply to the existing settings object attached to the WebView
176 existingSettings := wv.GetSettings()177 existingSettings := wv.GetSettings()
177 if existingSettings != nil {178 if existingSettings != nil {
178- sm.mu.RLock()179+ payload := sm.current()
179- cfg := sm.cfg180+ sm.applySettings(ctx, existingSettings, payload)
180- sm.mu.RUnlock()
181- sm.applySettings(ctx, existingSettings, cfg)
182 }181 }
183 }182 }
A internal/infrastructure/webkit/settings_runtime_test.go +32 -0
@@ -0,0 +1,32 @@
1+package webkit
2+
3+import (
4+ "context"
5+ "testing"
6+
7+ "github.com/bnema/dumber/internal/application/port"
8+)
9+
10+func TestSettingsManagerUpdateFromPayloadStoresTypedRuntimeSettings(t *testing.T) {
11+ sm := NewSettingsManager(context.Background(), port.EngineSettingsPayload{})
12+ payload := port.EngineSettingsPayload{
13+ WebContent: port.EngineWebContentSettingsPayload{
14+ SansFont: "Inter",
15+ SerifFont: "Literata",
16+ MonospaceFont: "Fira Code",
17+ DefaultFontSize: 16,
18+ HardwareDecoding: port.EngineHardwareDecodingForce,
19+ },
20+ }
21+
22+ sm.UpdateFromPayload(context.Background(), payload)
23+
24+ got := sm.current()
25+ if got.WebContent.SansFont != "Inter" ||
26+ got.WebContent.SerifFont != "Literata" ||
27+ got.WebContent.MonospaceFont != "Fira Code" ||
28+ got.WebContent.DefaultFontSize != 16 ||
29+ got.WebContent.HardwareDecoding != port.EngineHardwareDecodingForce {
30+ t.Fatalf("stored payload=%#v", got)
31+ }
32+}
@@ -0,0 +1,32 @@
1+package webkit
2+
3+import (
4+ "context"
5+ "testing"
6+
7+ "github.com/bnema/dumber/internal/application/port"
8+)
9+
10+func TestSettingsManagerUpdateFromPayloadStoresTypedRuntimeSettings(t *testing.T) {
11+ sm := NewSettingsManager(context.Background(), port.EngineSettingsPayload{})
12+ payload := port.EngineSettingsPayload{
13+ WebContent: port.EngineWebContentSettingsPayload{
14+ SansFont: "Inter",
15+ SerifFont: "Literata",
16+ MonospaceFont: "Fira Code",
17+ DefaultFontSize: 16,
18+ HardwareDecoding: port.EngineHardwareDecodingForce,
19+ },
20+ }
21+
22+ sm.UpdateFromPayload(context.Background(), payload)
23+
24+ got := sm.current()
25+ if got.WebContent.SansFont != "Inter" ||
26+ got.WebContent.SerifFont != "Literata" ||
27+ got.WebContent.MonospaceFont != "Fira Code" ||
28+ got.WebContent.DefaultFontSize != 16 ||
29+ got.WebContent.HardwareDecoding != port.EngineHardwareDecodingForce {
30+ t.Fatalf("stored payload=%#v", got)
31+ }
32+}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close