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 defaultMaxHistoryItems = 20 // items
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 // Pane mode border (Ctrl+P N - overlay)
50 defaultPaneModeBorderWidth = 4
51 defaultPaneModeBorderColor = "#4A90E2" // Blue for pane mode indicator
52
53 // Tab mode border (Ctrl+P T - overlay)
54 defaultTabModeBorderWidth = 4
55 defaultTabModeBorderColor = "#FFA500" // Orange for tab mode indicator
56
57 // Session mode border (Ctrl+O - overlay)
58 defaultSessionModeBorderWidth = 4
59 defaultSessionModeBorderColor = "#9B59B6" // Purple for session mode indicator
60
61 // Resize mode border (Ctrl+N - overlay)
62 defaultResizeModeBorderWidth = 4
63 defaultResizeModeBorderColor = "#00D4AA" // Cyan/teal for resize mode indicator
64
65 // Other styling
66 defaultTransitionDuration = 120
67 defaultUIScale = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%)
68
69 // Performance defaults
70 defaultZoomCacheSize = 256 // domains to cache (~20KB memory)
71 defaultWebViewPoolPrewarmCount = 4 // WebViews to pre-create at startup
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 MaxHistoryItems: defaultMaxHistoryItems,
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 PaneMode: PaneModeConfig{
160 ActivationShortcut: defaultPaneActivationShortcut,
161 TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
162 Actions: map[string][]string{
163 "split-right": {"arrowright", "r"},
164 "split-left": {"arrowleft", "l"},
165 "split-up": {"arrowup", "u"},
166 "split-down": {"arrowdown", "d"},
167 "stack-pane": {"s"},
168 "close-pane": {"x"},
169
170 "consume-or-expel-left": {"bracketleft", "["},
171 "consume-or-expel-right": {"bracketright", "]"},
172 "consume-or-expel-up": {"shift+bracketleft", "braceleft", "{"},
173 "consume-or-expel-down": {"shift+bracketright", "braceright", "}"},
174
175 "focus-right": {"shift+arrowright", "shift+l"},
176 "focus-left": {"shift+arrowleft", "shift+h"},
177 "focus-up": {"shift+arrowup", "shift+k"},
178 "focus-down": {"shift+arrowdown", "shift+j"},
179 "confirm": {"enter"},
180 "cancel": {"escape"},
181 },
182 },
183 TabMode: TabModeConfig{
184 ActivationShortcut: defaultTabActivationShortcut,
185 TimeoutMilliseconds: defaultTabTimeoutMilliseconds,
186 Actions: map[string][]string{
187 "new-tab": {"n", "c"},
188 "close-tab": {"x"},
189 "next-tab": {"l", "tab"},
190 "previous-tab": {"h", "shift+tab"},
191 "rename-tab": {"r"},
192 "confirm": {"enter"},
193 "cancel": {"escape"},
194 },
195 },
196 ResizeMode: ResizeModeConfig{
197 ActivationShortcut: defaultResizeActivationShortcut,
198 TimeoutMilliseconds: defaultResizeTimeoutMilliseconds,
199 StepPercent: defaultResizeStepPercent,
200 MinPanePercent: defaultResizeMinPanePercent,
201 Actions: map[string][]string{
202 "resize-increase-left": {"h", "arrowleft"},
203 "resize-increase-down": {"j", "arrowdown"},
204 "resize-increase-up": {"k", "arrowup"},
205 "resize-increase-right": {"l", "arrowright"},
206 "resize-decrease-left": {"H"},
207 "resize-decrease-down": {"J"},
208 "resize-decrease-up": {"K"},
209 "resize-decrease-right": {"L"},
210 "resize-increase": {"+", "="},
211 "resize-decrease": {"-"},
212 "confirm": {"enter"},
213 "cancel": {"escape"},
214 },
215 },
216 Shortcuts: GlobalShortcutsConfig{
217 ClosePane: "ctrl+w",
218 NextTab: "ctrl+tab",
219 PreviousTab: "ctrl+shift+tab",
220
221 ConsumeOrExpelLeft: "alt+bracketleft",
222 ConsumeOrExpelRight: "alt+bracketright",
223 ConsumeOrExpelUp: "alt+shift+bracketleft",
224 ConsumeOrExpelDown: "alt+shift+bracketright",
225 },
226 TabBarPosition: defaultTabBarPosition,
227 HideTabBarWhenSingleTab: true,
228 Popups: PopupBehaviorConfig{
229 Behavior: PopupBehaviorSplit, // Default: open JavaScript popups in split panes
230 Placement: defaultPopupPlacement,
231 OpenInNewPane: true,
232 FollowPaneContext: true,
233 BlankTargetBehavior: "stacked", // Default: open _blank links in stacked mode
234 EnableSmartDetection: true, // Use WindowProperties to detect popup vs tab
235 OAuthAutoClose: true, // Auto-close OAuth popups on success
236 },
237 Styling: WorkspaceStylingConfig{
238 BorderWidth: defaultBorderWidth,
239 BorderColor: defaultBorderColor,
240 PaneModeBorderWidth: defaultPaneModeBorderWidth,
241 PaneModeBorderColor: defaultPaneModeBorderColor,
242 TabModeBorderWidth: defaultTabModeBorderWidth,
243 TabModeBorderColor: defaultTabModeBorderColor,
244 SessionModeBorderWidth: defaultSessionModeBorderWidth,
245 SessionModeBorderColor: defaultSessionModeBorderColor,
246 ResizeModeBorderWidth: defaultResizeModeBorderWidth,
247 ResizeModeBorderColor: defaultResizeModeBorderColor,
248 TransitionDuration: defaultTransitionDuration,
249 },
250 },
251 ContentFiltering: ContentFilteringConfig{
252 Enabled: true, // Ad blocking enabled by default
253 AutoUpdate: true, // Auto-update filters from GitHub releases
254 },
255 Omnibox: OmniboxConfig{
256 InitialBehavior: defaultOmniboxInitialBehavior,
257 AutoOpenOnNewPane: defaultOmniboxAutoOpenOnNewPane,
258 },
259 Session: SessionConfig{
260 AutoRestore: false,
261 SnapshotIntervalMs: defaultSnapshotIntervalMs,
262 MaxExitedSessions: defaultMaxExitedSessions,
263 MaxExitedSessionAgeDays: defaultMaxExitedSessionAgeDays,
264 SessionMode: SessionModeConfig{
265 ActivationShortcut: defaultSessionActivationShortcut,
266 TimeoutMilliseconds: defaultSessionTimeoutMilliseconds,
267 Actions: map[string][]string{
268 "session-manager": {"s", "w"},
269 "confirm": {"enter"},
270 "cancel": {"escape"},
271 },
272 },
273 },
274 Media: MediaConfig{
275 HardwareDecodingMode: HardwareDecodingAuto, // auto allows sw fallback
276 PreferAV1: false, // Don't force codec preference, let site choose
277 ShowDiagnosticsOnStartup: false, // Disabled - diagnostics can be noisy
278 ForceVSync: false, // Let compositor handle VSync
279 GLRenderingMode: GLRenderingModeAuto, // GStreamer picks best GL API
280 GStreamerDebugLevel: 0, // Disabled by default
281 VideoBufferSizeMB: 0, // Not a valid GStreamer env var, removed
282 QueueBufferTimeSec: 0, // Not a valid GStreamer env var, removed
283 },
284 Runtime: RuntimeConfig{
285 Prefix: "",
286 },
287 Performance: PerformanceConfig{
288 ZoomCacheSize: defaultZoomCacheSize,
289 WebViewPoolPrewarmCount: defaultWebViewPoolPrewarmCount,
290 },
291 Update: UpdateConfig{
292 EnableOnStartup: true, // Check for updates on startup by default
293 AutoDownload: false, // Conservative: don't auto-download by default
294 },
295 }
296}
297
298// GetDefaultSearchShortcuts returns the default search shortcuts.
299func GetDefaultSearchShortcuts() map[string]SearchShortcut {
300 return map[string]SearchShortcut{
301 "ddg": {
302 URL: "https://duckduckgo.com/?q=%s",
303 Description: "DuckDuckGo search",
304 },
305 "g": {
306 URL: "https://www.google.com/search?q=%s",
307 Description: "Google search",
308 },
309 "gi": {
310 URL: "https://www.google.com/search?tbm=isch&q=%s",
311 Description: "Google Images search",
312 },
313 "gh": {
314 URL: "https://github.com/search?q=%s",
315 Description: "GitHub search",
316 },
317 "go": {
318 URL: "https://pkg.go.dev/search?q=%s",
319 Description: "Go package search",
320 },
321 "mdn": {
322 URL: "https://developer.mozilla.org/en-US/search?q=%s",
323 Description: "MDN Web Docs search",
324 },
325 "npm": {
326 URL: "https://www.npmjs.com/search?q=%s",
327 Description: "npm package search",
328 },
329 "r": {
330 URL: "https://www.reddit.com/search?q=%s",
331 Description: "Reddit search",
332 },
333 "so": {
334 URL: "https://stackoverflow.com/search?q=%s",
335 Description: "Stack Overflow search",
336 },
337 "w": {
338 URL: "https://en.wikipedia.org/wiki/%s",
339 Description: "Wikipedia search",
340 },
341 "yt": {
342 URL: "https://www.youtube.com/results?search_query=%s",
343 Description: "YouTube search",
344 },
345 }
346}