v0.14.0 76d1892

defaults.go RawHistoryFolder

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	defaultTabActivationShortcut   = "ctrl+t"
25	defaultTabTimeoutMilliseconds  = 3000
26	defaultTabBarPosition          = "bottom"
27	defaultPopupPlacement          = "right"
28
29	// Workspace styling defaults
30	defaultBorderWidth            = 1
31	defaultBorderColor            = "@theme_selected_bg_color"
32	defaultInactiveBorderWidth    = 1                             // Same width as active to prevent layout shift
33	defaultInactiveBorderColor    = "@theme_unfocused_bg_color"   // GTK theme variable
34	defaultShowStackedTitleBorder = false                         // Hidden by default
35	defaultPaneModeBorderColor    = "#4A90E2"                     // Blue for pane mode indicator
36	defaultTabModeBorderColor     = "#FFA500"                     // Orange for tab mode indicator (distinct from pane mode)
37	defaultTransitionDuration     = 120
38	defaultBorderRadius           = 0
39	defaultUIScale                = 1.0 // UI scale multiplier (1.0 = 100%, 1.2 = 120%)
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			// Path is set dynamically in config.Load()
56		},
57		History: HistoryConfig{
58			MaxEntries:          defaultMaxHistoryEntries,
59			RetentionPeriodDays: defaultRetentionDays, // 1 year
60			CleanupIntervalDays: 1,                    // daily cleanup
61		},
62		SearchShortcuts:     GetDefaultSearchShortcuts(),
63		DefaultSearchEngine: "https://duckduckgo.com/?q=%s",
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			ColorScheme: "default", // default follows system theme
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		Debug: DebugConfig{
137			EnableWebKitDebug:     false,
138			WebKitDebugCategories: "Network:preconnectTo,ContentFilters",
139			EnableFilteringDebug:  false,
140			EnableWebViewDebug:    false,
141			LogWebKitCrashes:      true, // Always log crashes
142			EnableScriptDebug:     false,
143			EnableGeneralDebug:    false,
144			EnableWorkspaceDebug:  false,
145			EnableFocusDebug:      false,
146			EnableCSSDebug:        false,
147			EnableFocusMetrics:    false,
148			EnablePaneCloseDebug:  false,
149		},
150		RenderingMode: RenderingModeGPU,
151		UseDomZoom:    false,
152		DefaultZoom:   1.2, // 120% default zoom for better readability
153		Workspace: WorkspaceConfig{
154			PaneMode: PaneModeConfig{
155				ActivationShortcut:  defaultPaneActivationShortcut,
156				TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
157				Actions: map[string][]string{
158					"split-right": {"arrowright", "r"},
159					"split-left":  {"arrowleft", "l"},
160					"split-up":    {"arrowup", "u"},
161					"split-down":  {"arrowdown", "d"},
162					"close-pane":  {"x"},
163					"confirm":     {"enter"},
164					"cancel":      {"escape"},
165				},
166			},
167			TabMode: TabModeConfig{
168				ActivationShortcut:  defaultTabActivationShortcut,
169				TimeoutMilliseconds: defaultTabTimeoutMilliseconds,
170				Actions: map[string][]string{
171					"new-tab":      {"n", "c"},
172					"close-tab":    {"x"},
173					"next-tab":     {"l", "tab"},
174					"previous-tab": {"h", "shift+tab"},
175					"rename-tab":   {"r"},
176					"confirm":      {"enter"},
177					"cancel":       {"escape"},
178				},
179			},
180			Tabs: TabKeyConfig{
181				NewTab:      "ctrl+t",
182				CloseTab:    "ctrl+w",
183				NextTab:     "ctrl+tab",
184				PreviousTab: "ctrl+shift+tab",
185			},
186			TabBarPosition: defaultTabBarPosition,
187			Popups: PopupBehaviorConfig{
188				Behavior:             PopupBehaviorSplit, // Default: open JavaScript popups in split panes
189				Placement:            defaultPopupPlacement,
190				OpenInNewPane:        true,
191				FollowPaneContext:    true,
192				BlankTargetBehavior:  "stacked", // Default: open _blank links in stacked mode
193				EnableSmartDetection: true,   // Use WindowProperties to detect popup vs tab
194				OAuthAutoClose:       true,   // Auto-close OAuth popups on success
195			},
196			Styling: WorkspaceStylingConfig{
197				BorderWidth:            defaultBorderWidth,
198				BorderColor:            defaultBorderColor,
199				InactiveBorderWidth:    defaultInactiveBorderWidth,
200				InactiveBorderColor:    defaultInactiveBorderColor,
201				ShowStackedTitleBorder: defaultShowStackedTitleBorder,
202				PaneModeBorderColor:    defaultPaneModeBorderColor,
203				TabModeBorderColor:     defaultTabModeBorderColor,
204				TransitionDuration:     defaultTransitionDuration,
205				BorderRadius:           defaultBorderRadius,
206				UIScale:                defaultUIScale,
207			},
208		},
209		ContentFilteringWhitelist: []string{
210			"twitch.tv",          // Arkose Labs bot detection breaks with filtering
211			"passport.twitch.tv", // Auth subdomain
212			"gql.twitch.tv",      // GraphQL API
213		},
214	}
215}
216
217// GetDefaultSearchShortcuts returns the default search shortcuts.
218func GetDefaultSearchShortcuts() map[string]SearchShortcut {
219	return map[string]SearchShortcut{
220		"ddg": {
221			URL:         "https://duckduckgo.com/?q=%s",
222			Description: "DuckDuckGo search",
223		},
224		"g": {
225			URL:         "https://www.google.com/search?q=%s",
226			Description: "Google search",
227		},
228		"gh": {
229			URL:         "https://github.com/search?q=%s",
230			Description: "GitHub search",
231		},
232		"go": {
233			URL:         "https://pkg.go.dev/search?q=%s",
234			Description: "Go package search",
235		},
236		"mdn": {
237			URL:         "https://developer.mozilla.org/en-US/search?q=%s",
238			Description: "MDN Web Docs search",
239		},
240		"npm": {
241			URL:         "https://www.npmjs.com/search?q=%s",
242			Description: "npm package search",
243		},
244		"r": {
245			URL:         "https://www.reddit.com/search?q=%s",
246			Description: "Reddit search",
247		},
248		"so": {
249			URL:         "https://stackoverflow.com/search?q=%s",
250			Description: "Stack Overflow search",
251		},
252		"w": {
253			URL:         "https://en.wikipedia.org/wiki/%s",
254			Description: "Wikipedia search",
255		},
256		"yt": {
257			URL:         "https://www.youtube.com/results?search_query=%s",
258			Description: "YouTube search",
259		},
260	}
261}
262
263// Note: We build our own browser, so no external browser commands needed

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close