1package config
2
3// Config represents the complete configuration for dumber.
4type Config struct {
5 Database DatabaseConfig `mapstructure:"database" yaml:"database" toml:"database"`
6 History HistoryConfig `mapstructure:"history" yaml:"history" toml:"history"`
7 SearchShortcuts map[string]SearchShortcut `mapstructure:"search_shortcuts" yaml:"search_shortcuts" toml:"search_shortcuts"`
8 // DefaultSearchEngine is the URL template for the default search engine (must contain %s placeholder)
9 DefaultSearchEngine string `mapstructure:"default_search_engine" yaml:"default_search_engine" toml:"default_search_engine"`
10 Dmenu DmenuConfig `mapstructure:"dmenu" yaml:"dmenu" toml:"dmenu"`
11 Logging LoggingConfig `mapstructure:"logging" yaml:"logging" toml:"logging"`
12 Appearance AppearanceConfig `mapstructure:"appearance" yaml:"appearance" toml:"appearance"`
13 Debug DebugConfig `mapstructure:"debug" yaml:"debug" toml:"debug"`
14 // DefaultWebpageZoom sets the default zoom level for pages without saved zoom settings (1.0 = 100%, 1.2 = 120%)
15 DefaultWebpageZoom float64 `mapstructure:"default_webpage_zoom" yaml:"default_webpage_zoom" toml:"default_webpage_zoom"`
16 // DefaultUIScale sets the default UI scale for GTK widgets (1.0 = 100%, 2.0 = 200%)
17 DefaultUIScale float64 `mapstructure:"default_ui_scale" yaml:"default_ui_scale" toml:"default_ui_scale"`
18 // Workspace defines workspace, pane, and tab handling behavior.
19 Workspace WorkspaceConfig `mapstructure:"workspace" yaml:"workspace" toml:"workspace"`
20 // Session controls session persistence and restoration.
21 Session SessionConfig `mapstructure:"session" yaml:"session" toml:"session"`
22 // ContentFiltering controls ad blocking and content filtering
23 ContentFiltering ContentFilteringConfig `mapstructure:"content_filtering" yaml:"content_filtering" toml:"content_filtering"`
24 // Omnibox controls the omnibox behavior (initial history display)
25 Omnibox OmniboxConfig `mapstructure:"omnibox" yaml:"omnibox" toml:"omnibox"`
26 // Rendering controls WebKit, GTK and compositor behavior.
27 Rendering RenderingConfig `mapstructure:"rendering" yaml:"rendering" toml:"rendering"`
28 // Media controls video playback and hardware acceleration
29 Media MediaConfig `mapstructure:"media" yaml:"media" toml:"media"`
30 // Runtime configures optional runtime overrides (e.g., /opt prefix for WebKitGTK/GTK).
31 Runtime RuntimeConfig `mapstructure:"runtime" yaml:"runtime" toml:"runtime"`
32 // Performance holds internal performance tuning options (not exposed in UI).
33 Performance PerformanceConfig `mapstructure:"performance" yaml:"performance" toml:"performance"`
34 // Update controls automatic update checking and downloading.
35 Update UpdateConfig `mapstructure:"update" yaml:"update" toml:"update"`
36}
37
38// RenderingMode selects GPU vs CPU rendering.
39type RenderingMode string
40
41const (
42 RenderingModeAuto RenderingMode = "auto"
43 RenderingModeGPU RenderingMode = "gpu"
44 RenderingModeCPU RenderingMode = "cpu"
45)
46
47// GSKRendererMode controls the GTK Scene Kit renderer selection.
48type GSKRendererMode string
49
50const (
51 GSKRendererAuto GSKRendererMode = "auto"
52 GSKRendererOpenGL GSKRendererMode = "opengl"
53 GSKRendererVulkan GSKRendererMode = "vulkan"
54 GSKRendererCairo GSKRendererMode = "cairo"
55)
56
57// RenderingConfig controls WebKit and GTK/GSK rendering behavior.
58type RenderingConfig struct {
59 // Mode controls GPU/CPU rendering selection for WebKit (auto, gpu, cpu).
60 Mode RenderingMode `mapstructure:"mode" yaml:"mode" toml:"mode"`
61
62 // DisableDMABufRenderer disables DMA-BUF accelerated renderer.
63 // Env: WEBKIT_DISABLE_DMABUF_RENDERER
64 DisableDMABufRenderer bool `mapstructure:"disable_dmabuf_renderer" yaml:"disable_dmabuf_renderer" toml:"disable_dmabuf_renderer"`
65
66 // ForceCompositingMode forces accelerated compositing.
67 // Env: WEBKIT_FORCE_COMPOSITING_MODE
68 ForceCompositingMode bool `mapstructure:"force_compositing_mode" yaml:"force_compositing_mode" toml:"force_compositing_mode"`
69
70 // DisableCompositingMode disables accelerated compositing.
71 // Env: WEBKIT_DISABLE_COMPOSITING_MODE
72 DisableCompositingMode bool `mapstructure:"disable_compositing_mode" yaml:"disable_compositing_mode" toml:"disable_compositing_mode"`
73
74 // GSKRenderer overrides GTK Scene Kit renderer selection.
75 // Env: GSK_RENDERER
76 GSKRenderer GSKRendererMode `mapstructure:"gsk_renderer" yaml:"gsk_renderer" toml:"gsk_renderer"`
77
78 // DisableMipmaps disables mipmap generation.
79 // Env: GSK_GPU_DISABLE=mipmap
80 DisableMipmaps bool `mapstructure:"disable_mipmaps" yaml:"disable_mipmaps" toml:"disable_mipmaps"`
81
82 // PreferGL forces OpenGL over GLES.
83 // Env: GDK_DEBUG=gl-prefer-gl
84 PreferGL bool `mapstructure:"prefer_gl" yaml:"prefer_gl" toml:"prefer_gl"`
85
86 // DrawCompositingIndicators shows compositing layer borders and repaint counters.
87 DrawCompositingIndicators bool `mapstructure:"draw_compositing_indicators" yaml:"draw_compositing_indicators" toml:"draw_compositing_indicators"` //nolint:lll // struct tags exceed lll limit
88
89 // ShowFPS displays WebKit FPS counter.
90 // Env: WEBKIT_SHOW_FPS
91 ShowFPS bool `mapstructure:"show_fps" yaml:"show_fps" toml:"show_fps"`
92
93 // SampleMemory enables memory sampling.
94 // Env: WEBKIT_SAMPLE_MEMORY
95 SampleMemory bool `mapstructure:"sample_memory" yaml:"sample_memory" toml:"sample_memory"`
96
97 // DebugFrames enables frame timing debug output.
98 // Env: GDK_DEBUG=frames
99 DebugFrames bool `mapstructure:"debug_frames" yaml:"debug_frames" toml:"debug_frames"`
100}
101
102// HardwareDecodingMode controls video hardware acceleration.
103type HardwareDecodingMode string
104
105const (
106 // HardwareDecodingAuto lets GStreamer choose (hw preferred, sw fallback)
107 HardwareDecodingAuto HardwareDecodingMode = "auto"
108 // HardwareDecodingForce requires hardware decoding (fails if unavailable)
109 HardwareDecodingForce HardwareDecodingMode = "force"
110 // HardwareDecodingDisable uses software decoding only
111 HardwareDecodingDisable HardwareDecodingMode = "disable"
112)
113
114// GLRenderingMode controls OpenGL API selection for video rendering.
115type GLRenderingMode string
116
117const (
118 // GLRenderingModeAuto lets GStreamer choose the best GL API
119 GLRenderingModeAuto GLRenderingMode = "auto"
120 // GLRenderingModeGLES2 forces GLES2 (better for some mobile/embedded GPUs)
121 GLRenderingModeGLES2 GLRenderingMode = "gles2"
122 // GLRenderingModeGL3 forces OpenGL 3.x desktop
123 GLRenderingModeGL3 GLRenderingMode = "gl3"
124 // GLRenderingModeNone disables GL-based rendering
125 GLRenderingModeNone GLRenderingMode = "none"
126)
127
128// ThemeDefault is the default theme setting (follows system).
129const ThemeDefault = "default"
130
131const (
132 // ThemePreferDark explicitly selects dark theme.
133 ThemePreferDark = "prefer-dark"
134 // ThemePreferLight explicitly selects light theme.
135 ThemePreferLight = "prefer-light"
136)
137
138// MediaConfig holds video playback and hardware acceleration preferences.
139type MediaConfig struct {
140 // HardwareDecodingMode controls hardware vs software video decoding
141 // Values: "auto" (default), "force", "disable"
142 HardwareDecodingMode HardwareDecodingMode `mapstructure:"hardware_decoding" yaml:"hardware_decoding" toml:"hardware_decoding"`
143 // PreferAV1 prioritizes AV1 codec (most efficient) when available
144 PreferAV1 bool `mapstructure:"prefer_av1" yaml:"prefer_av1" toml:"prefer_av1"`
145 // ShowDiagnosticsOnStartup shows media capability warnings at startup
146 ShowDiagnosticsOnStartup bool `mapstructure:"show_diagnostics" yaml:"show_diagnostics" toml:"show_diagnostics"`
147 // ForceVSync forces vertical sync for video playback (may help with tearing)
148 ForceVSync bool `mapstructure:"force_vsync" yaml:"force_vsync" toml:"force_vsync"`
149 // GLRenderingMode controls OpenGL API selection for video rendering
150 // Values: "auto" (default), "gles2", "gl3", "none"
151 GLRenderingMode GLRenderingMode `mapstructure:"gl_rendering_mode" yaml:"gl_rendering_mode" toml:"gl_rendering_mode"`
152 // GStreamerDebugLevel sets GStreamer debug verbosity (0=off, 1-5=increasing verbosity)
153 GStreamerDebugLevel int `mapstructure:"gstreamer_debug_level" yaml:"gstreamer_debug_level" toml:"gstreamer_debug_level"`
154 // VideoBufferSizeMB sets the video buffer size in megabytes for smoother streaming
155 // Higher values reduce rebuffering but use more memory. Default: 64 MB
156 VideoBufferSizeMB int `mapstructure:"video_buffer_size_mb" yaml:"video_buffer_size_mb" toml:"video_buffer_size_mb"`
157 // QueueBufferTimeSec sets the queue buffer time in seconds
158 // Higher values allow more prebuffering for bursty streams. Default: 20 seconds
159 QueueBufferTimeSec int `mapstructure:"queue_buffer_time_sec" yaml:"queue_buffer_time_sec" toml:"queue_buffer_time_sec"`
160}
161
162// RuntimeConfig holds optional runtime overrides.
163type RuntimeConfig struct {
164 // Prefix points to a custom runtime prefix (e.g., /opt/webkitgtk).
165 // This is used to influence pkg-config lookup and dynamic library loading.
166 Prefix string `mapstructure:"prefix" yaml:"prefix" toml:"prefix"`
167}
168
169// DatabaseConfig holds database-related configuration.
170type DatabaseConfig struct {
171 Path string `mapstructure:"path" yaml:"path" toml:"path"`
172}
173
174// HistoryConfig holds history-related configuration.
175type HistoryConfig struct {
176 MaxEntries int `mapstructure:"max_entries" yaml:"max_entries" toml:"max_entries"`
177 RetentionPeriodDays int `mapstructure:"retention_period_days" yaml:"retention_period_days" toml:"retention_period_days"`
178 CleanupIntervalDays int `mapstructure:"cleanup_interval_days" yaml:"cleanup_interval_days" toml:"cleanup_interval_days"`
179}
180
181// PerformanceConfig holds internal performance tuning options.
182// These are not exposed in dumb://config UI but can be set in config file.
183type PerformanceConfig struct {
184 // ZoomCacheSize is the number of domain zoom levels to cache in memory.
185 // Higher values reduce database queries but use more memory.
186 // Default: 256 domains (~20KB memory)
187 ZoomCacheSize int `mapstructure:"zoom_cache_size" yaml:"zoom_cache_size" toml:"zoom_cache_size"`
188
189 // WebViewPoolPrewarmCount is the number of WebViews to pre-create at startup.
190 // Higher values speed up initial tab creation but use more memory.
191 // Default: 4
192 WebViewPoolPrewarmCount int `mapstructure:"webview_pool_prewarm_count" yaml:"webview_pool_prewarm_count" toml:"webview_pool_prewarm_count"` //nolint:lll // struct tags must stay on one line
193}
194
195// SearchShortcut represents a search shortcut configuration.
196type SearchShortcut struct {
197 URL string `mapstructure:"url" toml:"url" yaml:"url" json:"url"`
198 Description string `mapstructure:"description" toml:"description" yaml:"description" json:"description"`
199}
200
201// ShortcutURLs returns a simple map of shortcut keys to URL templates.
202// This is useful for passing to url.BuildSearchURL.
203func (c *Config) ShortcutURLs() map[string]string {
204 result := make(map[string]string, len(c.SearchShortcuts))
205 for key, shortcut := range c.SearchShortcuts {
206 result[key] = shortcut.URL
207 }
208 return result
209}
210
211// DmenuConfig holds dmenu/rofi integration configuration.
212type DmenuConfig struct {
213 MaxHistoryItems int `mapstructure:"max_history_items" yaml:"max_history_items" toml:"max_history_items"`
214 ShowVisitCount bool `mapstructure:"show_visit_count" yaml:"show_visit_count" toml:"show_visit_count"`
215 ShowLastVisited bool `mapstructure:"show_last_visited" yaml:"show_last_visited" toml:"show_last_visited"`
216 HistoryPrefix string `mapstructure:"history_prefix" yaml:"history_prefix" toml:"history_prefix"`
217 ShortcutPrefix string `mapstructure:"shortcut_prefix" yaml:"shortcut_prefix" toml:"shortcut_prefix"`
218 URLPrefix string `mapstructure:"url_prefix" yaml:"url_prefix" toml:"url_prefix"`
219 DateFormat string `mapstructure:"date_format" yaml:"date_format" toml:"date_format"`
220 SortByVisitCount bool `mapstructure:"sort_by_visit_count" yaml:"sort_by_visit_count" toml:"sort_by_visit_count"`
221}
222
223// LoggingConfig holds logging configuration.
224type LoggingConfig struct {
225 Level string `mapstructure:"level" yaml:"level" toml:"level"`
226 Format string `mapstructure:"format" yaml:"format" toml:"format"`
227 MaxAge int `mapstructure:"max_age" yaml:"max_age" toml:"max_age"`
228
229 // File output configuration
230 LogDir string `mapstructure:"log_dir" yaml:"log_dir" toml:"log_dir"`
231 EnableFileLog bool `mapstructure:"enable_file_log" yaml:"enable_file_log" toml:"enable_file_log"`
232
233 // Capture browser console to logs
234 CaptureConsole bool `mapstructure:"capture_console" yaml:"capture_console" toml:"capture_console" json:"capture_console"`
235}
236
237// AppearanceConfig holds UI/rendering preferences.
238type AppearanceConfig struct {
239 // Default fonts for pages that do not specify fonts.
240 SansFont string `mapstructure:"sans_font" yaml:"sans_font" toml:"sans_font"`
241 SerifFont string `mapstructure:"serif_font" yaml:"serif_font" toml:"serif_font"`
242 MonospaceFont string `mapstructure:"monospace_font" yaml:"monospace_font" toml:"monospace_font"`
243 // Default font size in CSS pixels (approx).
244 DefaultFontSize int `mapstructure:"default_font_size" yaml:"default_font_size" toml:"default_font_size"`
245 LightPalette ColorPalette `mapstructure:"light_palette" yaml:"light_palette" toml:"light_palette"`
246 DarkPalette ColorPalette `mapstructure:"dark_palette" yaml:"dark_palette" toml:"dark_palette"`
247 // ColorScheme controls the initial theme preference: "prefer-dark", "prefer-light", or "default" (follows system)
248 ColorScheme string `mapstructure:"color_scheme" yaml:"color_scheme" toml:"color_scheme"`
249}
250
251// ColorPalette contains semantic color tokens for light/dark themes.
252type ColorPalette struct {
253 Background string `mapstructure:"background" yaml:"background" toml:"background" json:"background"`
254 Surface string `mapstructure:"surface" yaml:"surface" toml:"surface" json:"surface"`
255 SurfaceVariant string `mapstructure:"surface_variant" yaml:"surface_variant" toml:"surface_variant" json:"surface_variant"`
256 Text string `mapstructure:"text" yaml:"text" toml:"text" json:"text"`
257 Muted string `mapstructure:"muted" yaml:"muted" toml:"muted" json:"muted"`
258 Accent string `mapstructure:"accent" yaml:"accent" toml:"accent" json:"accent"`
259 Border string `mapstructure:"border" yaml:"border" toml:"border" json:"border"`
260}
261
262// ContentFilteringConfig holds content filtering and ad blocking preferences
263type ContentFilteringConfig struct {
264 // Enabled controls whether ad blocking is active (default: true)
265 Enabled bool `mapstructure:"enabled" yaml:"enabled" toml:"enabled"`
266 // AutoUpdate controls whether filters are automatically updated (default: true)
267 AutoUpdate bool `mapstructure:"auto_update" yaml:"auto_update" toml:"auto_update"`
268 // Note: Filters are downloaded from bnema/ublock-webkit-filters GitHub releases
269 // Note: Whitelist is managed via database (content_whitelist table)
270}
271
272// OmniboxConfig holds omnibox behavior preferences
273type OmniboxConfig struct {
274 // InitialBehavior controls what to show when omnibox opens with empty input
275 // Values: "recent" (recent visits), "most_visited" (most visited sites), "none" (nothing)
276 InitialBehavior string `mapstructure:"initial_behavior" yaml:"initial_behavior" toml:"initial_behavior"`
277 // AutoOpenOnNewPane opens the omnibox automatically when a new pane is created.
278 // Default: false
279 AutoOpenOnNewPane bool `mapstructure:"auto_open_on_new_pane" yaml:"auto_open_on_new_pane" toml:"auto_open_on_new_pane"`
280}
281
282// DebugConfig holds debug and troubleshooting options
283type DebugConfig struct {
284 // Enable browser developer tools (F12, Inspect Element in context menu)
285 EnableDevTools bool `mapstructure:"enable_devtools" yaml:"enable_devtools" toml:"enable_devtools"`
286}
287
288// UpdateConfig holds automatic update settings.
289type UpdateConfig struct {
290 // EnableOnStartup enables checking for updates when the browser starts.
291 // Default: true
292 EnableOnStartup bool `mapstructure:"enable_on_startup" yaml:"enable_on_startup" toml:"enable_on_startup"`
293 // AutoDownload automatically downloads updates in the background.
294 // When enabled, updates are applied on browser exit.
295 // Default: false
296 AutoDownload bool `mapstructure:"auto_download" yaml:"auto_download" toml:"auto_download"`
297}
298
299// WorkspaceConfig captures layout, pane, and tab behavior preferences.
300type WorkspaceConfig struct {
301 // NewPaneURL is the URL loaded when creating a new empty pane/tab.
302 // Default: "about:blank"
303 NewPaneURL string `mapstructure:"new_pane_url" yaml:"new_pane_url" toml:"new_pane_url"`
304 // PaneMode defines modal pane behavior and bindings.
305 PaneMode PaneModeConfig `mapstructure:"pane_mode" yaml:"pane_mode" toml:"pane_mode" json:"pane_mode"`
306 // TabMode defines modal tab behavior and bindings (Alt+T).
307 TabMode TabModeConfig `mapstructure:"tab_mode" yaml:"tab_mode" toml:"tab_mode" json:"tab_mode"`
308 // ResizeMode defines modal pane resizing behavior and bindings (Ctrl+N).
309 ResizeMode ResizeModeConfig `mapstructure:"resize_mode" yaml:"resize_mode" toml:"resize_mode" json:"resize_mode"`
310 // Shortcuts holds global (non-modal) keyboard shortcuts.
311 Shortcuts GlobalShortcutsConfig `mapstructure:"shortcuts" yaml:"shortcuts" toml:"shortcuts" json:"shortcuts"`
312 // TabBarPosition determines tab bar placement: "top" or "bottom".
313 TabBarPosition string `mapstructure:"tab_bar_position" yaml:"tab_bar_position" toml:"tab_bar_position" json:"tab_bar_position"`
314 // HideTabBarWhenSingleTab hides the tab bar when only one tab exists.
315 HideTabBarWhenSingleTab bool `mapstructure:"hide_tab_bar_when_single_tab" yaml:"hide_tab_bar_when_single_tab" toml:"hide_tab_bar_when_single_tab" json:"hide_tab_bar_when_single_tab"` //nolint:lll // struct tags must stay on one line
316 // Popups configures default popup placement rules.
317 Popups PopupBehaviorConfig `mapstructure:"popups" yaml:"popups" toml:"popups" json:"popups"`
318 // Styling configures workspace visual appearance.
319 Styling WorkspaceStylingConfig `mapstructure:"styling" yaml:"styling" toml:"styling" json:"styling"`
320}
321
322// PaneModeConfig defines modal behavior for pane management.
323type PaneModeConfig struct {
324 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line
325 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`
326 Actions map[string][]string `mapstructure:"actions" yaml:"actions" toml:"actions" json:"actions"`
327}
328
329// GetKeyBindings returns an inverted map for O(1) key→action lookup.
330// This is built from the action→keys structure in the config.
331func (p *PaneModeConfig) GetKeyBindings() map[string]string {
332 keyToAction := make(map[string]string)
333 for action, keys := range p.Actions {
334 for _, key := range keys {
335 keyToAction[key] = action
336 }
337 }
338 return keyToAction
339}
340
341// TabModeConfig defines modal behavior for tab management (Zellij-style).
342type TabModeConfig struct {
343 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line
344 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`
345 Actions map[string][]string `mapstructure:"actions" yaml:"actions" toml:"actions" json:"actions"`
346}
347
348// GetKeyBindings returns an inverted map for O(1) key→action lookup.
349// This is built from the action→keys structure in the config.
350func (t *TabModeConfig) GetKeyBindings() map[string]string {
351 keyToAction := make(map[string]string)
352 for action, keys := range t.Actions {
353 for _, key := range keys {
354 keyToAction[key] = action
355 }
356 }
357 return keyToAction
358}
359
360// ResizeModeConfig defines modal behavior for resizing panes (Zellij-style).
361type ResizeModeConfig struct {
362 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line
363 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`
364 StepPercent float64 `mapstructure:"step_percent" yaml:"step_percent" toml:"step_percent" json:"step_percent"`
365 MinPanePercent float64 `mapstructure:"min_pane_percent" yaml:"min_pane_percent" toml:"min_pane_percent" json:"min_pane_percent"` //nolint:lll // struct tags must stay on one line
366 Actions map[string][]string `mapstructure:"actions" yaml:"actions" toml:"actions" json:"actions"`
367}
368
369// GetKeyBindings returns an inverted map for O(1) key→action lookup.
370// This is built from the action→keys structure in the config.
371func (r *ResizeModeConfig) GetKeyBindings() map[string]string {
372 keyToAction := make(map[string]string)
373 for action, keys := range r.Actions {
374 for _, key := range keys {
375 keyToAction[key] = action
376 }
377 }
378 return keyToAction
379}
380
381// GlobalShortcutsConfig defines global shortcuts (always active, not modal).
382type GlobalShortcutsConfig struct {
383 ClosePane string `mapstructure:"close_pane" yaml:"close_pane" toml:"close_pane" json:"close_pane"`
384 NextTab string `mapstructure:"next_tab" yaml:"next_tab" toml:"next_tab" json:"next_tab"`
385 PreviousTab string `mapstructure:"previous_tab" yaml:"previous_tab" toml:"previous_tab" json:"previous_tab"`
386
387 ConsumeOrExpelLeft string `mapstructure:"consume_or_expel_left" yaml:"consume_or_expel_left" toml:"consume_or_expel_left" json:"consume_or_expel_left"` //nolint:lll // struct tags must stay on one line
388 ConsumeOrExpelRight string `mapstructure:"consume_or_expel_right" yaml:"consume_or_expel_right" toml:"consume_or_expel_right" json:"consume_or_expel_right"` //nolint:lll // struct tags must stay on one line
389 ConsumeOrExpelUp string `mapstructure:"consume_or_expel_up" yaml:"consume_or_expel_up" toml:"consume_or_expel_up" json:"consume_or_expel_up"` //nolint:lll // struct tags must stay on one line
390 ConsumeOrExpelDown string `mapstructure:"consume_or_expel_down" yaml:"consume_or_expel_down" toml:"consume_or_expel_down" json:"consume_or_expel_down"` //nolint:lll // struct tags must stay on one line
391}
392
393// PopupBehavior defines how popup windows should be opened
394type PopupBehavior string
395
396const (
397 // PopupBehaviorSplit opens popups in a split pane (default)
398 PopupBehaviorSplit PopupBehavior = "split"
399 // PopupBehaviorStacked opens popups in a stacked pane
400 PopupBehaviorStacked PopupBehavior = "stacked"
401 // PopupBehaviorTabbed opens popups as a new tab
402 PopupBehaviorTabbed PopupBehavior = "tabbed"
403 // PopupBehaviorWindowed opens popups in a new workspace window
404 PopupBehaviorWindowed PopupBehavior = "windowed"
405)
406
407// PopupBehaviorConfig defines handling for popup windows.
408type PopupBehaviorConfig struct {
409 // Behavior determines how popups are opened (split/stacked/tabbed/windowed)
410 Behavior PopupBehavior `mapstructure:"behavior" yaml:"behavior" toml:"behavior" json:"behavior"`
411
412 // Placement specifies direction for split behavior ("right", "left", "top", "bottom")
413 // Only used when Behavior is "split"
414 Placement string `mapstructure:"placement" yaml:"placement" toml:"placement" json:"placement"`
415
416 // OpenInNewPane controls whether popups are opened in workspace or blocked
417 OpenInNewPane bool `mapstructure:"open_in_new_pane" yaml:"open_in_new_pane" toml:"open_in_new_pane" json:"open_in_new_pane"`
418
419 // FollowPaneContext determines if popup placement follows parent pane context
420 FollowPaneContext bool `mapstructure:"follow_pane_context" yaml:"follow_pane_context" toml:"follow_pane_context" json:"follow_pane_context"` //nolint:lll // struct tags must stay on one line
421
422 // BlankTargetBehavior determines how target="_blank" links are opened
423 // Accepted values: "split", "stacked" (default), "tabbed"
424 // This is separate from Behavior which controls JavaScript popups
425 BlankTargetBehavior string `mapstructure:"blank_target_behavior" yaml:"blank_target_behavior" toml:"blank_target_behavior" json:"blank_target_behavior"` //nolint:lll // struct tags must stay on one line
426
427 // EnableSmartDetection uses WebKitWindowProperties to detect popup vs tab intents
428 EnableSmartDetection bool `mapstructure:"enable_smart_detection" yaml:"enable_smart_detection" toml:"enable_smart_detection" json:"enable_smart_detection"` //nolint:lll // struct tags must stay on one line
429
430 // OAuthAutoClose enables auto-closing OAuth popups after successful auth redirects
431 OAuthAutoClose bool `mapstructure:"oauth_auto_close" yaml:"oauth_auto_close" toml:"oauth_auto_close" json:"oauth_auto_close"`
432}
433
434// WorkspaceStylingConfig defines visual styling for workspace panes.
435type WorkspaceStylingConfig struct {
436 // BorderWidth in pixels for active pane borders (overlay)
437 BorderWidth int `mapstructure:"border_width" yaml:"border_width" toml:"border_width" json:"border_width"`
438 // BorderColor for focused panes (CSS color value or theme variable)
439 BorderColor string `mapstructure:"border_color" yaml:"border_color" toml:"border_color" json:"border_color"`
440
441 // PaneModeBorderWidth in pixels for pane mode indicator border (Ctrl+P N overlay)
442 PaneModeBorderWidth int `mapstructure:"pane_mode_border_width" yaml:"pane_mode_border_width" toml:"pane_mode_border_width" json:"pane_mode_border_width"` //nolint:lll // struct tags must stay on one line
443 // PaneModeBorderColor for the pane mode indicator border (CSS color value or theme variable)
444 // Defaults to "#4A90E2" (blue) if not set
445 PaneModeBorderColor string `mapstructure:"pane_mode_border_color" yaml:"pane_mode_border_color" toml:"pane_mode_border_color" json:"pane_mode_border_color"` //nolint:lll // struct tags must stay on one line
446
447 // TabModeBorderWidth in pixels for tab mode indicator border (Ctrl+P T overlay)
448 TabModeBorderWidth int `mapstructure:"tab_mode_border_width" yaml:"tab_mode_border_width" toml:"tab_mode_border_width" json:"tab_mode_border_width"` //nolint:lll // struct tags must stay on one line
449 // TabModeBorderColor for the tab mode indicator border (CSS color value or theme variable)
450 // Defaults to "#FFA500" (orange) if not set - MUST be different from PaneModeBorderColor
451 TabModeBorderColor string `mapstructure:"tab_mode_border_color" yaml:"tab_mode_border_color" toml:"tab_mode_border_color" json:"tab_mode_border_color"` //nolint:lll // struct tags must stay on one line
452
453 // SessionModeBorderWidth in pixels for session mode indicator border (Ctrl+O overlay)
454 SessionModeBorderWidth int `mapstructure:"session_mode_border_width" yaml:"session_mode_border_width" toml:"session_mode_border_width" json:"session_mode_border_width"` //nolint:lll // struct tags must stay on one line
455 // SessionModeBorderColor for the session mode indicator border (CSS color value or theme variable)
456 // Defaults to "#9B59B6" (purple) if not set - MUST be different from other mode colors
457 SessionModeBorderColor string `mapstructure:"session_mode_border_color" yaml:"session_mode_border_color" toml:"session_mode_border_color" json:"session_mode_border_color"` //nolint:lll // struct tags must stay on one line
458
459 // ResizeModeBorderWidth in pixels for resize mode indicator border (Ctrl+N overlay)
460 ResizeModeBorderWidth int `mapstructure:"resize_mode_border_width" yaml:"resize_mode_border_width" toml:"resize_mode_border_width" json:"resize_mode_border_width"` //nolint:lll // struct tags must stay on one line
461 // ResizeModeBorderColor for the resize mode indicator border (CSS color value or theme variable)
462 // Defaults to "#00D4AA" (cyan/teal) if not set - MUST be different from other mode colors
463 ResizeModeBorderColor string `mapstructure:"resize_mode_border_color" yaml:"resize_mode_border_color" toml:"resize_mode_border_color" json:"resize_mode_border_color"` //nolint:lll // struct tags must stay on one line
464
465 // TransitionDuration in milliseconds for border animations
466 TransitionDuration int `mapstructure:"transition_duration" yaml:"transition_duration" toml:"transition_duration" json:"transition_duration"` //nolint:lll // struct tags must stay on one line
467}
468
469// SessionConfig holds session persistence settings.
470type SessionConfig struct {
471 // AutoRestore automatically restores the last session on startup.
472 // Default: false
473 AutoRestore bool `mapstructure:"auto_restore" yaml:"auto_restore" toml:"auto_restore" json:"auto_restore"`
474
475 // SnapshotIntervalMs is the minimum interval between snapshots in milliseconds.
476 // Default: 5000
477 SnapshotIntervalMs int `mapstructure:"snapshot_interval_ms" yaml:"snapshot_interval_ms" toml:"snapshot_interval_ms" json:"snapshot_interval_ms"` //nolint:lll // struct tags must stay on one line
478
479 // MaxExitedSessions is the maximum number of exited sessions to keep.
480 // Default: 50
481 MaxExitedSessions int `mapstructure:"max_exited_sessions" yaml:"max_exited_sessions" toml:"max_exited_sessions" json:"max_exited_sessions"` //nolint:lll // struct tags must stay on one line
482
483 // MaxExitedSessionAgeDays is the maximum age in days for exited sessions.
484 // Sessions older than this will be automatically deleted on startup.
485 // Default: 7
486 MaxExitedSessionAgeDays int `mapstructure:"max_exited_session_age_days" yaml:"max_exited_session_age_days" toml:"max_exited_session_age_days" json:"max_exited_session_age_days"` //nolint:lll // struct tags must stay on one line
487
488 // SessionMode defines modal behavior for session management (Ctrl+O).
489 SessionMode SessionModeConfig `mapstructure:"session_mode" yaml:"session_mode" toml:"session_mode" json:"session_mode"`
490}
491
492// SessionModeConfig defines modal behavior for session management.
493type SessionModeConfig struct {
494 ActivationShortcut string `mapstructure:"activation_shortcut" yaml:"activation_shortcut" toml:"activation_shortcut" json:"activation_shortcut"` //nolint:lll // struct tags must stay on one line
495 TimeoutMilliseconds int `mapstructure:"timeout_ms" yaml:"timeout_ms" toml:"timeout_ms" json:"timeout_ms"`
496 Actions map[string][]string `mapstructure:"actions" yaml:"actions" toml:"actions" json:"actions"`
497}
498
499// GetKeyBindings returns an inverted map for O(1) key→action lookup.
500// This is built from the action→keys structure in the config.
501func (s *SessionModeConfig) GetKeyBindings() map[string]string {
502 keyToAction := make(map[string]string)
503 for action, keys := range s.Actions {
504 for _, key := range keys {
505 keyToAction[key] = action
506 }
507 }
508 return keyToAction
509}