1package config
2
3// Default configuration constants
4const (
5 // History defaults
6 defaultMaxHistoryEntries = 10000 // entries
7 defaultRetentionDays = 365 // 1 year
8
9 // Dmenu defaults
10 defaultMaxHistoryDays = 30 // days
11
12 // Logging defaults
13 defaultMaxLogAgeDays = 7 // days
14
15 // Appearance defaults
16 defaultFontSize = 16 // points
17
18 // Workspace defaults
19 defaultNewPaneURL = "about:blank"
20
21 // Omnibox defaults
22 defaultOmniboxInitialBehavior = "recent"
23 defaultOmniboxAutoOpenOnNewPane = false
24
25 // Workspace defaults
26 defaultPaneActivationShortcut = "ctrl+p"
27 defaultPaneTimeoutMilliseconds = 3000
28 defaultTabActivationShortcut = "ctrl+t"
29 defaultTabTimeoutMilliseconds = 3000
30 defaultResizeActivationShortcut = "ctrl+n"
31 defaultResizeTimeoutMilliseconds = 3000
32 defaultResizeStepPercent = 5.0
33 defaultResizeMinPanePercent = 10.0
34 defaultTabBarPosition = "bottom"
35 defaultPopupPlacement = "right"
36 defaultFloatingPaneWidthPct = 0.82
37 defaultFloatingPaneHeightPct = 0.72
38
39 // Session defaults
40 defaultSessionActivationShortcut = "ctrl+o"
41 defaultSessionTimeoutMilliseconds = 3000
42 defaultSnapshotIntervalMs = 5000
43 defaultMaxExitedSessions = 50
44 defaultMaxExitedSessionAgeDays = 7
45
46 // Workspace styling defaults
47 // Active pane border (overlay)
48 defaultBorderWidth = 1
49 defaultBorderColor = "@theme_selected_bg_color"
50
51 // Mode border width (consolidated for all modes)
52 defaultModeBorderWidth = 4
53
54 // Mode colors (used for both borders and toaster)
55 defaultPaneModeColor = "#4A90E2" // Blue for pane mode
56 defaultTabModeColor = "#FFA500" // Orange for tab mode
57 defaultSessionModeColor = "#9B59B6" // Purple for session mode
58 defaultResizeModeColor = "#00D4AA" // Cyan/teal for resize mode
59
60 // Mode indicator toaster
61 defaultModeIndicatorToasterEnabled = true
62
63 // Other styling
64 defaultTransitionDuration = 120
65 defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%)
66
67 // Performance defaults
68 defaultZoomCacheSize = 256 // domains to cache (~20KB memory)
69 defaultWebViewPoolPrewarmCount = 4 // WebViews to pre-create at startup
70
71 // Skia threading defaults (0 = unset, -1 = unset for GPU threads)
72 defaultSkiaCPUPaintingThreads = 0
73 defaultSkiaGPUPaintingThreads = -1 // -1 means unset; 0 would disable GPU tile painting
74)
75
76// getDefaultLogDir returns the default log directory, falls back to empty string on error
77func getDefaultLogDir() string {
78 logDir, err := GetLogDir()
79 if err != nil {
80 return ""
81 }
82 return logDir
83}
84
85// DefaultConfig returns the default configuration values for dumber.
86func DefaultConfig() *Config {
87 return &Config{
88 Database: DatabaseConfig{
89 // Path is set dynamically in config.Load()
90 },
91 History: HistoryConfig{
92 MaxEntries: defaultMaxHistoryEntries,
93 RetentionPeriodDays: defaultRetentionDays, // 1 year
94 CleanupIntervalDays: 1, // daily cleanup
95 },
96 SearchShortcuts: GetDefaultSearchShortcuts(),
97 DefaultSearchEngine: "https://duckduckgo.com/?q=%s",
98 Dmenu: DmenuConfig{
99 MaxHistoryDays: defaultMaxHistoryDays,
100 ShowVisitCount: true,
101 ShowLastVisited: true,
102 HistoryPrefix: "🕒",
103 ShortcutPrefix: "🔍",
104 URLPrefix: "🌐",
105 DateFormat: "2006-01-02 15:04",
106 SortByVisitCount: true,
107 },
108 Logging: LoggingConfig{
109 Level: "info",
110 Format: "text", // text or json
111 MaxAge: defaultMaxLogAgeDays,
112 LogDir: getDefaultLogDir(),
113 EnableFileLog: true,
114 CaptureConsole: false, // Disabled by default
115 CaptureGTKLogs: false, // Disabled by default
116 },
117 Appearance: AppearanceConfig{
118 SansFont: "Fira Sans",
119 SerifFont: "Fira Sans",
120 MonospaceFont: "Fira Code",
121 DefaultFontSize: defaultFontSize,
122 LightPalette: ColorPalette{
123 Background: "#fafafa",
124 Surface: "#f4f4f5",
125 SurfaceVariant: "#e4e4e7",
126 Text: "#18181b",
127 Muted: "#71717a",
128 Accent: "#22c55e", // Green-500 - vibrant primary
129 Border: "#d4d4d8",
130 },
131 DarkPalette: ColorPalette{
132 Background: "#0a0a0b",
133 Surface: "#18181b",
134 SurfaceVariant: "#27272a",
135 Text: "#fafafa",
136 Muted: "#a1a1aa",
137 Accent: "#4ade80", // Green-400 - vibrant primary
138 Border: "#3f3f46",
139 },
140 ColorScheme: "default", // default follows system theme
141 },
142 Debug: DebugConfig{
143 EnableDevTools: true,
144 },
145 Rendering: RenderingConfig{
146 Mode: RenderingModeGPU,
147 DisableDMABufRenderer: false,
148 ForceCompositingMode: false,
149 DisableCompositingMode: false,
150 GSKRenderer: GSKRendererAuto, // Let GTK choose - Vulkan can conflict with WebKit's DMA-BUF
151 DisableMipmaps: false,
152 PreferGL: false,
153 DrawCompositingIndicators: false,
154 ShowFPS: false,
155 SampleMemory: false,
156 DebugFrames: false,
157 },
158 Privacy: PrivacyConfig{
159 CookiePolicy: CookiePolicyNoThirdParty,
160 ITPEnabled: true,
161 },
162 DefaultWebpageZoom: 1.2, // 120% default zoom for better readability
163 DefaultUIScale: defaultUIScale, // 1.0 = 100%, 2.0 = 200%
164 Workspace: WorkspaceConfig{
165 NewPaneURL: defaultNewPaneURL,
166 SwitchToTabOnMove: true,
167 PaneMode: PaneModeConfig{
168 ActivationShortcut: defaultPaneActivationShortcut,
169 TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
170 Actions: map[string]ActionBinding{
171 "split-right": {Keys: []string{"arrowright", "r"}, Desc: "Split pane to the right"},
172 "split-left": {Keys: []string{"arrowleft", "l"}, Desc: "Split pane to the left"},
173 "split-up": {Keys: []string{"arrowup", "u"}, Desc: "Split pane upward"},
174 "split-down": {Keys: []string{"arrowdown", "d"}, Desc: "Split pane downward"},
175 "stack-pane": {Keys: []string{"s"}, Desc: "Stack pane with sibling"},
176 "close-pane": {Keys: []string{"x"}, Desc: "Close current pane"},
177 "move-pane-to-tab": {Keys: []string{"m"}, Desc: "Move pane to different tab"},
178 "move-pane-to-next-tab": {Keys: []string{"M", "shift+m"}, Desc: "Move pane to next tab"},
179
180 "consume-or-expel-left": {Keys: []string{"["}, Desc: "Consume/expel pane left"},
181 "consume-or-expel-right": {Keys: []string{"]"}, Desc: "Consume/expel pane right"},
182 "consume-or-expel-up": {Keys: []string{"{"}, Desc: "Consume/expel pane up"},
183 "consume-or-expel-down": {Keys: []string{"}"}, Desc: "Consume/expel pane down"},
184
185 "focus-right": {Keys: []string{"shift+arrowright", "shift+l"}, Desc: "Focus pane to the right"},
186 "focus-left": {Keys: []string{"shift+arrowleft", "shift+h"}, Desc: "Focus pane to the left"},
187 "focus-up": {Keys: []string{"shift+arrowup", "shift+k"}, Desc: "Focus pane above"},
188 "focus-down": {Keys: []string{"shift+arrowdown", "shift+j"}, Desc: "Focus pane below"},
189 "confirm": {Keys: []string{"enter"}, Desc: "Confirm action"},
190 "cancel": {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
191 },
192 },
193 TabMode: TabModeConfig{
194 ActivationShortcut: defaultTabActivationShortcut,
195 TimeoutMilliseconds: defaultTabTimeoutMilliseconds,
196 Actions: map[string]ActionBinding{
197 "new-tab": {Keys: []string{"n", "c"}, Desc: "Create new tab"},
198 "close-tab": {Keys: []string{"x"}, Desc: "Close current tab"},
199 "next-tab": {Keys: []string{"l", "tab"}, Desc: "Switch to next tab"},
200 "previous-tab": {Keys: []string{"h", "shift+tab"}, Desc: "Switch to previous tab"},
201 "rename-tab": {Keys: []string{"r"}, Desc: "Rename current tab"},
202 "confirm": {Keys: []string{"enter"}, Desc: "Confirm action"},
203 "cancel": {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
204 },
205 },
206 ResizeMode: ResizeModeConfig{
207 ActivationShortcut: defaultResizeActivationShortcut,
208 TimeoutMilliseconds: defaultResizeTimeoutMilliseconds,
209 StepPercent: defaultResizeStepPercent,
210 MinPanePercent: defaultResizeMinPanePercent,
211 Actions: map[string]ActionBinding{
212 "resize-increase-left": {Keys: []string{"h", "arrowleft"}, Desc: "Increase size leftward"},
213 "resize-increase-down": {Keys: []string{"j", "arrowdown"}, Desc: "Increase size downward"},
214 "resize-increase-up": {Keys: []string{"k", "arrowup"}, Desc: "Increase size upward"},
215 "resize-increase-right": {Keys: []string{"l", "arrowright"}, Desc: "Increase size rightward"},
216 "resize-decrease-left": {Keys: []string{"H"}, Desc: "Decrease size leftward"},
217 "resize-decrease-down": {Keys: []string{"J"}, Desc: "Decrease size downward"},
218 "resize-decrease-up": {Keys: []string{"K"}, Desc: "Decrease size upward"},
219 "resize-decrease-right": {Keys: []string{"L"}, Desc: "Decrease size rightward"},
220 "resize-increase": {Keys: []string{"+", "="}, Desc: "Increase pane size"},
221 "resize-decrease": {Keys: []string{"-"}, Desc: "Decrease pane size"},
222 "confirm": {Keys: []string{"enter"}, Desc: "Confirm action"},
223 "cancel": {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
224 },
225 },
226 Shortcuts: GlobalShortcutsConfig{
227 Actions: map[string]ActionBinding{
228 "toggle_floating_pane": {Keys: []string{"alt+f"}, Desc: "Toggle floating pane"},
229 "close_pane": {Keys: []string{"ctrl+w"}, Desc: "Close active pane"},
230 "next_tab": {Keys: []string{"ctrl+tab"}, Desc: "Switch to next tab"},
231 "previous_tab": {Keys: []string{"ctrl+shift+tab"}, Desc: "Switch to previous tab"},
232 "consume_or_expel_left": {Keys: []string{"alt+["}, Desc: "Consume/expel pane left"},
233 "consume_or_expel_right": {Keys: []string{"alt+]"}, Desc: "Consume/expel pane right"},
234 "consume_or_expel_up": {Keys: []string{"alt+{"}, Desc: "Consume/expel pane up"},
235 "consume_or_expel_down": {Keys: []string{"alt+}"}, Desc: "Consume/expel pane down"},
236 },
237 },
238 FloatingPane: FloatingPaneConfig{
239 WidthPct: defaultFloatingPaneWidthPct,
240 HeightPct: defaultFloatingPaneHeightPct,
241 Profiles: map[string]FloatingPaneProfile{},
242 },
243 TabBarPosition: defaultTabBarPosition,
244 HideTabBarWhenSingleTab: true,
245 Popups: PopupBehaviorConfig{
246 Behavior: PopupBehaviorSplit, // Default: open JavaScript popups in split panes
247 Placement: defaultPopupPlacement,
248 OpenInNewPane: true,
249 FollowPaneContext: true,
250 BlankTargetBehavior: "stacked", // Default: open _blank links in stacked mode
251 EnableSmartDetection: true, // Use WindowProperties to detect popup vs tab
252 OAuthAutoClose: true, // Auto-close OAuth popups on success
253 },
254 Styling: WorkspaceStylingConfig{
255 BorderWidth: defaultBorderWidth,
256 BorderColor: defaultBorderColor,
257 ModeBorderWidth: defaultModeBorderWidth,
258 PaneModeColor: defaultPaneModeColor,
259 TabModeColor: defaultTabModeColor,
260 SessionModeColor: defaultSessionModeColor,
261 ResizeModeColor: defaultResizeModeColor,
262 ModeIndicatorToasterEnabled: defaultModeIndicatorToasterEnabled,
263 TransitionDuration: defaultTransitionDuration,
264 },
265 },
266 ContentFiltering: ContentFilteringConfig{
267 Enabled: true, // Ad blocking enabled by default
268 AutoUpdate: true, // Auto-update filters from GitHub releases
269 },
270 Clipboard: ClipboardConfig{
271 AutoCopyOnSelection: true, // Enabled by default (zellij-style)
272 },
273 Omnibox: OmniboxConfig{
274 InitialBehavior: defaultOmniboxInitialBehavior,
275 AutoOpenOnNewPane: defaultOmniboxAutoOpenOnNewPane,
276 },
277 Session: SessionConfig{
278 AutoRestore: false,
279 SnapshotIntervalMs: defaultSnapshotIntervalMs,
280 MaxExitedSessions: defaultMaxExitedSessions,
281 MaxExitedSessionAgeDays: defaultMaxExitedSessionAgeDays,
282 SessionMode: SessionModeConfig{
283 ActivationShortcut: defaultSessionActivationShortcut,
284 TimeoutMilliseconds: defaultSessionTimeoutMilliseconds,
285 Actions: map[string]ActionBinding{
286 "session-manager": {Keys: []string{"s", "w"}, Desc: "Open session manager"},
287 "confirm": {Keys: []string{"enter"}, Desc: "Confirm action"},
288 "cancel": {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
289 },
290 },
291 },
292 Media: MediaConfig{
293 HardwareDecodingMode: HardwareDecodingAuto, // auto allows sw fallback
294 PreferAV1: false, // Don't force codec preference, let site choose
295 ShowDiagnosticsOnStartup: false, // Disabled - diagnostics can be noisy
296 ForceVSync: false, // Let compositor handle VSync
297 GLRenderingMode: GLRenderingModeAuto, // GStreamer picks best GL API
298 GStreamerDebugLevel: 0, // Disabled by default
299 },
300 Runtime: RuntimeConfig{
301 Prefix: "",
302 },
303 Performance: PerformanceConfig{
304 Profile: ProfileDefault, // Use WebKit defaults by default
305 ZoomCacheSize: defaultZoomCacheSize,
306 WebViewPoolPrewarmCount: defaultWebViewPoolPrewarmCount,
307 // Skia threading - balanced defaults (unset = use WebKit defaults)
308 // These only apply when Profile is "custom"
309 SkiaCPUPaintingThreads: defaultSkiaCPUPaintingThreads,
310 SkiaGPUPaintingThreads: defaultSkiaGPUPaintingThreads,
311 SkiaEnableCPURendering: false,
312 // Web process memory pressure - all unset by default
313 WebProcessMemoryLimitMB: 0,
314 WebProcessMemoryPollIntervalSec: 0,
315 WebProcessMemoryConservativeThreshold: 0,
316 WebProcessMemoryStrictThreshold: 0,
317 // Network process memory pressure - all unset by default
318 NetworkProcessMemoryLimitMB: 0,
319 NetworkProcessMemoryPollIntervalSec: 0,
320 NetworkProcessMemoryConservativeThreshold: 0,
321 NetworkProcessMemoryStrictThreshold: 0,
322 },
323 Update: UpdateConfig{
324 EnableOnStartup: true, // Check for updates on startup by default
325 AutoDownload: false, // Conservative: don't auto-download by default
326 NotifyOnNewSettings: true, // Show toast when new config settings available
327 },
328 Downloads: DownloadsConfig{
329 Path: "", // Empty = use XDG_DOWNLOAD_DIR or ~/Downloads
330 },
331 }
332}
333
334// GetDefaultSearchShortcuts returns the default search shortcuts.
335func GetDefaultSearchShortcuts() map[string]SearchShortcut {
336 return map[string]SearchShortcut{
337 "ddg": {
338 URL: "https://duckduckgo.com/?q=%s",
339 Description: "DuckDuckGo search",
340 },
341 "g": {
342 URL: "https://www.google.com/search?q=%s",
343 Description: "Google search",
344 },
345 "gi": {
346 URL: "https://www.google.com/search?tbm=isch&q=%s",
347 Description: "Google Images search",
348 },
349 "gh": {
350 URL: "https://github.com/search?q=%s",
351 Description: "GitHub search",
352 },
353 "go": {
354 URL: "https://pkg.go.dev/search?q=%s",
355 Description: "Go package search",
356 },
357 "mdn": {
358 URL: "https://developer.mozilla.org/en-US/search?q=%s",
359 Description: "MDN Web Docs search",
360 },
361 "npm": {
362 URL: "https://www.npmjs.com/search?q=%s",
363 Description: "npm package search",
364 },
365 "r": {
366 URL: "https://www.reddit.com/search?q=%s",
367 Description: "Reddit search",
368 },
369 "so": {
370 URL: "https://stackoverflow.com/search?q=%s",
371 Description: "Stack Overflow search",
372 },
373 "w": {
374 URL: "https://en.wikipedia.org/wiki/%s",
375 Description: "Wikipedia search",
376 },
377 "yt": {
378 URL: "https://www.youtube.com/results?search_query=%s",
379 Description: "YouTube search",
380 },
381 }
382}