1// Package config provides default configuration values for dumber.
2package config
3
4import (
5 "time"
6)
7
8// Default configuration constants
9const (
10 // Database defaults
11 defaultMaxIdleTimeMin = 5 // minutes
12 defaultQueryTimeoutSec = 30 // seconds
13
14 // History defaults
15 defaultMaxHistoryEntries = 10000 // entries
16 defaultRetentionDays = 365 // 1 year
17
18 // Dmenu defaults
19 defaultMaxHistoryItems = 20 // items
20
21 // Logging defaults
22 defaultMaxLogSizeMB = 100 // MB
23 defaultMaxBackups = 3 // backup files
24 defaultMaxLogAgeDays = 7 // days
25
26 // Appearance defaults
27 defaultFontSize = 16 // points
28
29 // Workspace defaults
30 defaultPaneActivationShortcut = "cmdorctrl+p"
31 defaultPaneTimeoutMilliseconds = 3000
32 defaultPopupPlacement = "right"
33
34 // Workspace styling defaults
35 defaultBorderWidth = 2
36 defaultBorderColor = "@theme_selected_bg_color"
37 defaultTransitionDuration = 120
38 defaultBorderRadius = 0
39)
40
41// getDefaultLogDir returns the default log directory, falls back to empty string on error
42func getDefaultLogDir() string {
43 logDir, err := GetLogDir()
44 if err != nil {
45 return ""
46 }
47 return logDir
48}
49
50// DefaultConfig returns the default configuration values for dumber.
51func DefaultConfig() *Config {
52 return &Config{
53 Database: DatabaseConfig{
54 MaxConnections: 1,
55 MaxIdleTime: time.Minute * defaultMaxIdleTimeMin,
56 QueryTimeout: time.Second * defaultQueryTimeoutSec,
57 },
58 History: HistoryConfig{
59 MaxEntries: defaultMaxHistoryEntries,
60 RetentionPeriodDays: defaultRetentionDays, // 1 year
61 CleanupIntervalDays: 1, // daily cleanup
62 },
63 SearchShortcuts: GetDefaultSearchShortcuts(),
64 Dmenu: DmenuConfig{
65 MaxHistoryItems: defaultMaxHistoryItems,
66 ShowVisitCount: true,
67 ShowLastVisited: true,
68 HistoryPrefix: "🕒",
69 ShortcutPrefix: "🔍",
70 URLPrefix: "🌐",
71 DateFormat: "2006-01-02 15:04",
72 SortByVisitCount: true,
73 },
74 Logging: LoggingConfig{
75 Level: "info",
76 Format: "text", // text or json
77 Filename: "", // empty means stdout
78 MaxSize: defaultMaxLogSizeMB, // MB
79 MaxBackups: defaultMaxBackups,
80 MaxAge: defaultMaxLogAgeDays, // days
81 Compress: true,
82 LogDir: getDefaultLogDir(),
83 EnableFileLog: true,
84 CaptureStdout: false,
85 CaptureStderr: false,
86 CaptureCOutput: false, // Disabled by default to avoid performance impact
87 CaptureConsole: false, // Disabled by default
88 DebugFile: "debug.log",
89 VerboseWebKit: false,
90 },
91 Appearance: AppearanceConfig{
92 SansFont: "Fira Sans",
93 SerifFont: "Fira Sans",
94 MonospaceFont: "Fira Code",
95 DefaultFontSize: defaultFontSize,
96 LightPalette: ColorPalette{
97 Background: "#f8f8f8",
98 Surface: "#f2f2f2",
99 SurfaceVariant: "#ececec",
100 Text: "#1a1a1a",
101 Muted: "#6e6e6e",
102 Accent: "#404040",
103 Border: "#d2d2d2",
104 },
105 DarkPalette: ColorPalette{
106 Background: "#0e0e0e",
107 Surface: "#1a1a1a",
108 SurfaceVariant: "#141414",
109 Text: "#e4e4e4",
110 Muted: "#848484",
111 Accent: "#a8a8a8",
112 Border: "#363636",
113 },
114 },
115 VideoAcceleration: VideoAccelerationConfig{
116 EnableVAAPI: true,
117 AutoDetectGPU: true,
118 VAAPIDriverName: "", // Will be auto-detected
119 EnableAllDrivers: true,
120 LegacyVAAPI: false,
121 },
122 CodecPreferences: CodecConfig{
123 PreferredCodecs: "av1,h264", // AV1 first, but allow VP9 fallback for higher resolutions
124 ForceAV1: false, // Use smart AV1 negotiation instead of forcing
125 BlockVP9: false, // Allow VP9 for higher resolutions
126 BlockVP8: true, // Still block VP8 as it's outdated
127 AV1HardwareOnly: false, // Allow software AV1 fallback
128 DisableVP9Hardware: false, // Allow VP9 hardware for high res content
129 VideoBufferSizeMB: 16, // Larger buffer for AV1 streams
130 QueueBufferTimeSec: 10, // More buffering time for smooth playback
131 CustomUserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", // Chrome UA with AV1 support
132 AV1MaxResolution: "1080p", // Optimal AV1 up to 1080p, fallback to VP9 for higher res
133 DisableTwitchCodecControl: true, // Disable codec control on Twitch by default (prevents theater/fullscreen freezing)
134 },
135 WebkitMemory: WebkitMemoryConfig{
136 CacheModel: "web_browser", // Aggressive caching for fast page loads
137 EnablePageCache: true, // Instant back/forward navigation
138 MemoryLimitMB: 0, // Use system default
139 ConservativeThreshold: 0.4, // Start cleanup at 40%
140 StrictThreshold: 0.6, // Strict cleanup at 60%
141 KillThreshold: 0.8, // Kill processes at 80%
142 PollIntervalSeconds: 45.0, // Check every 45 seconds
143 EnableGCInterval: 120, // GC every 2 minutes
144 ProcessRecycleThreshold: 50, // Recycle after 50 page loads
145 EnableMemoryMonitoring: true, // Monitor for production tuning
146 },
147 Debug: DebugConfig{
148 EnableWebKitDebug: false,
149 WebKitDebugCategories: "Network:preconnectTo,ContentFilters",
150 EnableFilteringDebug: false,
151 EnableWebViewDebug: false,
152 LogWebKitCrashes: true, // Always log crashes
153 EnableScriptDebug: false,
154 EnableGeneralDebug: false,
155 EnableWorkspaceDebug: false,
156 EnableFocusDebug: false,
157 EnableCSSDebug: false,
158 EnableFocusMetrics: false,
159 EnablePaneCloseDebug: false,
160 },
161 APISecurity: APISecurityConfig{
162 Token: "",
163 RequireToken: false,
164 },
165 RenderingMode: RenderingModeGPU,
166 UseDomZoom: false,
167 DefaultZoom: 1.2, // 120% default zoom for better readability
168 Workspace: WorkspaceConfig{
169 EnableZellijControls: true,
170 PaneMode: PaneModeConfig{
171 ActivationShortcut: defaultPaneActivationShortcut,
172 TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
173 ActionBindings: map[string]string{
174 "arrowright": "split-right",
175 "arrowleft": "split-left",
176 "arrowup": "split-up",
177 "arrowdown": "split-down",
178 "r": "split-right",
179 "l": "split-left",
180 "u": "split-up",
181 "d": "split-down",
182 "x": "close-pane",
183 "enter": "confirm",
184 "escape": "cancel",
185 },
186 },
187 Tabs: TabKeyConfig{
188 NewTab: "cmdorctrl+t",
189 CloseTab: "cmdorctrl+w",
190 NextTab: "cmdorctrl+tab",
191 PreviousTab: "cmdorctrl+shift+tab",
192 },
193 Popups: PopupBehaviorConfig{
194 Placement: defaultPopupPlacement,
195 OpenInNewPane: true,
196 FollowPaneContext: true,
197 BlankTargetBehavior: "pane", // Default to pane, future: "tab"
198 EnableSmartDetection: true, // Use WindowProperties to detect popup vs tab
199 OAuthAutoClose: true, // Auto-close OAuth popups on success
200 },
201 Styling: WorkspaceStylingConfig{
202 BorderWidth: defaultBorderWidth,
203 BorderColor: defaultBorderColor,
204 TransitionDuration: defaultTransitionDuration,
205 BorderRadius: defaultBorderRadius,
206 },
207 },
208 }
209}
210
211// GetDefaultSearchShortcuts returns the default search shortcuts.
212func GetDefaultSearchShortcuts() map[string]SearchShortcut {
213 return map[string]SearchShortcut{
214 "ddg": {
215 URL: "https://duckduckgo.com/?q=%s",
216 Description: "DuckDuckGo search",
217 },
218 "g": {
219 URL: "https://www.google.com/search?q=%s",
220 Description: "Google search",
221 },
222 "gh": {
223 URL: "https://github.com/search?q=%s",
224 Description: "GitHub search",
225 },
226 "go": {
227 URL: "https://pkg.go.dev/search?q=%s",
228 Description: "Go package search",
229 },
230 "mdn": {
231 URL: "https://developer.mozilla.org/en-US/search?q=%s",
232 Description: "MDN Web Docs search",
233 },
234 "npm": {
235 URL: "https://www.npmjs.com/search?q=%s",
236 Description: "npm package search",
237 },
238 "r": {
239 URL: "https://www.reddit.com/search?q=%s",
240 Description: "Reddit search",
241 },
242 "so": {
243 URL: "https://stackoverflow.com/search?q=%s",
244 Description: "Stack Overflow search",
245 },
246 "w": {
247 URL: "https://en.wikipedia.org/wiki/%s",
248 Description: "Wikipedia search",
249 },
250 "yt": {
251 URL: "https://www.youtube.com/results?search_query=%s",
252 Description: "YouTube search",
253 },
254 }
255}
256
257// Note: We build our own browser, so no external browser commands needed