settings.go RawHistoryFolder
1package webkit
2
3import (
4 "context"
5 "sync"
6
7 "github.com/bnema/dumber/internal/infrastructure/config"
8 "github.com/bnema/dumber/internal/logging"
9 "github.com/bnema/puregotk-webkit/webkit"
10 "github.com/rs/zerolog"
11)
12
13// SettingsManager creates and manages WebKit Settings instances from config.
14type SettingsManager struct {
15 cfg *config.Config
16 mu sync.RWMutex
17}
18
19// NewSettingsManager creates a new SettingsManager with the given config.
20func NewSettingsManager(ctx context.Context, cfg *config.Config) *SettingsManager {
21 log := logging.FromContext(ctx)
22 log.Debug().Msg("creating settings manager")
23 return &SettingsManager{
24 cfg: cfg,
25 }
26}
27
28// CreateSettings creates a new webkit.Settings instance configured from the current config.
29func (sm *SettingsManager) CreateSettings(ctx context.Context) *webkit.Settings {
30 log := logging.FromContext(ctx)
31
32 sm.mu.RLock()
33 cfg := sm.cfg
34 sm.mu.RUnlock()
35
36 settings := webkit.NewSettings()
37 if settings == nil {
38 log.Error().Msg("failed to create webkit settings")
39 return nil
40 }
41
42 sm.applySettings(ctx, settings, cfg)
43 return settings
44}
45
46// applySettings applies configuration to a webkit.Settings instance.
47func (sm *SettingsManager) applySettings(ctx context.Context, settings *webkit.Settings, cfg *config.Config) {
48 if sm == nil {
49 return
50 }
51 log := logging.FromContext(ctx)
52 applyJavaScriptSettings(settings)
53 applyFontSettings(settings, cfg)
54 applyRenderingSettings(settings, cfg)
55 applyDebugSettings(settings, cfg)
56 applyBrowsingSettings(settings)
57 applyMediaSettings(settings, cfg, log)
58 applyStorageSettings(settings)
59 applyUISettings(settings)
60 applyCanvasSettings(settings)
61 applyWebRTCSettings(settings)
62
63 webrtcEnabled := settings.GetPropertyEnableWebrtc()
64 mediaStreamEnabled := settings.GetPropertyEnableMediaStream()
65
66 log.Debug().
67 Str("sans_font", cfg.Appearance.SansFont).
68 Str("rendering_mode", string(cfg.Rendering.Mode)).
69 Bool("developer_extras", cfg.Debug.EnableDevTools).
70 Bool("webrtc_enabled", webrtcEnabled).
71 Bool("media_stream_enabled", mediaStreamEnabled).
72 Msg("settings applied")
73}
74
75func applyJavaScriptSettings(settings *webkit.Settings) {
76 settings.SetEnableJavascript(true)
77 settings.SetEnableJavascriptMarkup(true)
78}
79
80func applyFontSettings(settings *webkit.Settings, cfg *config.Config) {
81 if cfg.Appearance.SansFont != "" {
82 settings.SetDefaultFontFamily(cfg.Appearance.SansFont)
83 settings.SetSansSerifFontFamily(cfg.Appearance.SansFont)
84 }
85 if cfg.Appearance.SerifFont != "" {
86 settings.SetSerifFontFamily(cfg.Appearance.SerifFont)
87 }
88 if cfg.Appearance.MonospaceFont != "" {
89 settings.SetMonospaceFontFamily(cfg.Appearance.MonospaceFont)
90 }
91 if cfg.Appearance.DefaultFontSize > 0 {
92 settings.SetDefaultFontSize(uint32(cfg.Appearance.DefaultFontSize))
93 }
94}
95
96func 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 }
105}
106
107func applyDebugSettings(settings *webkit.Settings, cfg *config.Config) {
108 settings.SetEnableDeveloperExtras(cfg.Debug.EnableDevTools)
109 settings.SetEnableWriteConsoleMessagesToStdout(cfg.Logging.CaptureConsole)
110 settings.SetDrawCompositingIndicators(cfg.Rendering.DrawCompositingIndicators)
111}
112
113func applyBrowsingSettings(settings *webkit.Settings) {
114 settings.SetEnableSmoothScrolling(true)
115 settings.SetEnablePageCache(true)
116 settings.SetEnableSiteSpecificQuirks(true)
117}
118
119func applyMediaSettings(settings *webkit.Settings, cfg *config.Config, log *zerolog.Logger) {
120 settings.SetEnableWebaudio(true)
121 settings.SetEnableWebgl(true)
122 settings.SetEnableMedia(true)
123 settings.SetEnableMediasource(true)
124 settings.SetEnableMediaCapabilities(true)
125 settings.SetEnableEncryptedMedia(true)
126 settings.SetMediaPlaybackRequiresUserGesture(true)
127 settings.SetMediaPlaybackAllowsInline(true)
128
129 switch cfg.Media.HardwareDecodingMode {
130 case config.HardwareDecodingForce:
131 hwTypes := "video/av01;video/mp4;video/webm;video/x-h264;video/x-h265"
132 settings.SetMediaContentTypesRequiringHardwareSupport(&hwTypes)
133 log.Debug().Msg("hardware decoding: forced (may fail without hw support)")
134 case config.HardwareDecodingDisable:
135 settings.SetHardwareAccelerationPolicy(webkit.HardwareAccelerationPolicyNeverValue)
136 log.Debug().Msg("hardware decoding: disabled (software only)")
137 default:
138 emptyTypes := ""
139 settings.SetMediaContentTypesRequiringHardwareSupport(&emptyTypes)
140 log.Debug().Msg("hardware decoding: auto (hw preferred, software fallback)")
141 }
142}
143
144func applyStorageSettings(settings *webkit.Settings) {
145 settings.SetEnableHtml5LocalStorage(true)
146 settings.SetEnableHtml5Database(true)
147}
148
149func applyUISettings(settings *webkit.Settings) {
150 settings.SetEnableBackForwardNavigationGestures(true)
151 settings.SetEnableFullscreen(true)
152}
153
154func applyCanvasSettings(settings *webkit.Settings) {
155 settings.SetEnable2dCanvasAcceleration(true)
156}
157
158func applyWebRTCSettings(settings *webkit.Settings) {
159 // Set both direct API and gobject properties for robustness with generated bindings.
160 settings.SetPropertyEnableMediaStream(true)
161 settings.SetPropertyEnableWebrtc(true)
162
163 settings.SetEnableMediaStream(true)
164 settings.SetEnableWebrtc(true)
165}
166
167// UpdateFromConfig updates the manager with a new config (for hot-reload).
168// Note: This doesn't update already-created Settings instances.
169// New WebViews will use the updated config.
170func (sm *SettingsManager) UpdateFromConfig(ctx context.Context, cfg *config.Config) {
171 log := logging.FromContext(ctx)
172 sm.mu.Lock()
173 defer sm.mu.Unlock()
174 sm.cfg = cfg
175 log.Debug().Msg("settings config updated")
176}
177
178// ApplyToWebView applies current settings to an existing WebView.
179// This can be used to update a WebView's settings after config hot-reload.
180func (sm *SettingsManager) ApplyToWebView(ctx context.Context, wv *webkit.WebView) {
181 if wv == nil {
182 return
183 }
184
185 settings := sm.CreateSettings(ctx)
186 if settings == nil {
187 return
188 }
189
190 // WebView.GetSettings() returns the current settings - we can modify them directly
191 // For a full replacement, we'd need webkit_web_view_set_settings which may not be available
192 // Instead, we apply to the existing settings object
193 existingSettings := wv.GetSettings()
194 if existingSettings != nil {
195 sm.mu.RLock()
196 cfg := sm.cfg
197 sm.mu.RUnlock()
198 sm.applySettings(ctx, existingSettings, cfg)
199 }
200}