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