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