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