v0.29.0 21b3150

defaults.go RawHistoryFolder

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	defaultMaxHistoryDays = 30 // days
11
12	// Logging defaults
13	defaultMaxLogAgeDays = 7   // days
14	defaultMaxLogFiles   = 100 // session log files
15
16	// Appearance defaults
17	defaultFontSize = 16 // points
18
19	// Workspace defaults
20	defaultNewPaneURL = "about:blank"
21
22	// Omnibox defaults
23	defaultOmniboxInitialBehavior   = OmniboxInitialBehaviorRecent
24	defaultOmniboxMostVisitedDays   = 30
25	defaultOmniboxAutoOpenOnNewPane = false
26
27	// Workspace defaults
28	defaultPaneActivationShortcut    = "ctrl+p"
29	defaultPaneTimeoutMilliseconds   = 3000
30	defaultTabActivationShortcut     = "ctrl+t"
31	defaultTabTimeoutMilliseconds    = 3000
32	defaultResizeActivationShortcut  = "ctrl+n"
33	defaultResizeTimeoutMilliseconds = 3000
34	defaultResizeStepPercent         = 5.0
35	defaultResizeMinPanePercent      = 10.0
36	defaultTabBarPosition            = "bottom"
37	defaultPopupPlacement            = "right"
38	defaultFloatingPaneWidthPct      = 0.82
39	defaultFloatingPaneHeightPct     = 0.72
40
41	// Session defaults
42	defaultSessionActivationShortcut  = "ctrl+o"
43	defaultSessionTimeoutMilliseconds = 3000
44	defaultSnapshotIntervalMs         = 5000
45	defaultMaxExitedSessions          = 50
46	defaultMaxExitedSessionAgeDays    = 7
47
48	// Workspace styling defaults
49	// Active pane border (overlay)
50	defaultBorderWidth = 1
51	defaultBorderColor = "@theme_selected_bg_color"
52
53	// Mode border width (consolidated for all modes)
54	defaultModeBorderWidth = 4
55
56	// Mode colors (used for both borders and toaster)
57	defaultPaneModeColor    = "#4A90E2" // Blue for pane mode
58	defaultTabModeColor     = "#FFA500" // Orange for tab mode
59	defaultSessionModeColor = "#9B59B6" // Purple for session mode
60	defaultResizeModeColor  = "#00D4AA" // Cyan/teal for resize mode
61
62	// Mode indicator toaster
63	defaultModeIndicatorToasterEnabled = true
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	defaultCEFWindowlessFrameRate    = 60  // static OSR frame rate when adaptive CEF pacing is disabled
73	defaultCEFWindowlessFrameRateMax = 240 // adaptive OSR frame-rate hard cap
74
75	// Skia threading defaults (0 = unset, -1 = unset for GPU threads)
76	defaultSkiaCPUPaintingThreads = 0
77	defaultSkiaGPUPaintingThreads = -1 // -1 means unset; 0 would disable GPU tile painting
78)
79
80func defaultBrowsingContextConfig() BrowsingContextConfig {
81	return BrowsingContextConfig{
82		Behavior:             PopupBehaviorSplit,
83		Placement:            defaultPopupPlacement,
84		OpenInNewPane:        true,
85		FollowPaneContext:    true,
86		BlankTargetBehavior:  "stacked",
87		EnableSmartDetection: true,
88		OAuthAutoClose:       true,
89	}
90}
91
92// getDefaultLogDir returns the default log directory, falls back to empty string on error
93func getDefaultLogDir() string {
94	logDir, err := GetLogDir()
95	if err != nil {
96		return ""
97	}
98	return logDir
99}
100
101// DefaultConfig returns the default configuration values for dumber.
102func DefaultConfig() *Config {
103	browsingContextDefaults := defaultBrowsingContextConfig()
104
105	return &Config{
106		Database: DatabaseConfig{
107			// Path is set dynamically in config.Load()
108		},
109		History: HistoryConfig{
110			MaxEntries:          defaultMaxHistoryEntries,
111			RetentionPeriodDays: defaultRetentionDays, // 1 year
112			CleanupIntervalDays: 1,                    // daily cleanup
113		},
114		SearchShortcuts:     GetDefaultSearchShortcuts(),
115		DefaultSearchEngine: "https://duckduckgo.com/?q=%s",
116		Dmenu: DmenuConfig{
117			MaxHistoryDays:   defaultMaxHistoryDays,
118			ShowVisitCount:   true,
119			ShowLastVisited:  true,
120			HistoryPrefix:    "🕒",
121			ShortcutPrefix:   "🔍",
122			URLPrefix:        "🌐",
123			DateFormat:       "2006-01-02 15:04",
124			SortByVisitCount: true,
125		},
126		Logging: LoggingConfig{
127			Level:          "info",
128			Format:         "text", // text or json
129			MaxAge:         defaultMaxLogAgeDays,
130			MaxFiles:       defaultMaxLogFiles,
131			LogDir:         getDefaultLogDir(),
132			EnableFileLog:  true,
133			CaptureConsole: false, // Disabled by default
134			CaptureGTKLogs: false, // Disabled by default
135		},
136		Appearance: AppearanceConfig{
137			SansFont:        "Fira Sans",
138			SerifFont:       "Fira Sans",
139			MonospaceFont:   "Fira Code",
140			GtkFont:         "Adwaita Sans",
141			DefaultFontSize: defaultFontSize,
142			LightPalette: ColorPalette{
143				Background:     "#fafafa",
144				Surface:        "#f4f4f5",
145				SurfaceVariant: "#e4e4e7",
146				Text:           "#18181b",
147				Muted:          "#71717a",
148				Accent:         "#22c55e", // Green-500 - vibrant primary
149				Border:         "#d4d4d8",
150			},
151			DarkPalette: ColorPalette{
152				Background:     "#0a0a0b",
153				Surface:        "#18181b",
154				SurfaceVariant: "#27272a",
155				Text:           "#fafafa",
156				Muted:          "#a1a1aa",
157				Accent:         "#4ade80", // Green-400 - vibrant primary
158				Border:         "#3f3f46",
159			},
160			ColorScheme: "default", // default follows system theme
161		},
162		Debug: DebugConfig{
163			EnableDevTools: true,
164		},
165		Engine: EngineConfig{
166			Type:             EngineTypeCEF,
167			Profile:          ProfileDefault,
168			PoolPrewarmCount: defaultWebViewPoolPrewarmCount,
169			ZoomCacheSize:    defaultZoomCacheSize,
170			// With ITP enabled, WebKit ignores ACCEPT_NO_THIRD_PARTY — ITP handles
171			// third-party cookie isolation more intelligently. Using Always + ITP
172			// matches Epiphany's model and avoids a misleading setting.
173			CookiePolicy: CookiePolicyAlways,
174			CEF: CEFEngineConfig{
175				RenderStack:                 CEFRenderStackVulkan,
176				AdaptiveWindowlessFrameRate: true,
177				WindowlessFrameRate:         0,
178				WindowlessFrameRateMax:      defaultCEFWindowlessFrameRateMax,
179				LogFile:                     "",
180				EnableAudioHandler:          true,
181			},
182			WebKit: WebKitEngineConfig{
183				ITPEnabled:             true,
184				SkiaCPUPaintingThreads: defaultSkiaCPUPaintingThreads,
185				SkiaGPUPaintingThreads: defaultSkiaGPUPaintingThreads,
186				GSKRenderer:            GSKRendererAuto,
187				GLRenderingMode:        GLRenderingModeAuto,
188			},
189		},
190		DefaultWebpageZoom: 1.2,            // 120% default zoom for better readability
191		DefaultUIScale:     defaultUIScale, // 1.0 = 100%, 2.0 = 200%
192		Workspace: WorkspaceConfig{
193			NewPaneURL:        defaultNewPaneURL,
194			SwitchToTabOnMove: true,
195			PaneMode: PaneModeConfig{
196				ActivationShortcut:  defaultPaneActivationShortcut,
197				TimeoutMilliseconds: defaultPaneTimeoutMilliseconds,
198				Actions: map[string]ActionBinding{
199					"split-right":           {Keys: []string{"arrowright", "r"}, Desc: "Split pane to the right"},
200					"split-left":            {Keys: []string{"arrowleft", "l"}, Desc: "Split pane to the left"},
201					"split-up":              {Keys: []string{"arrowup", "u"}, Desc: "Split pane upward"},
202					"split-down":            {Keys: []string{"arrowdown", "d"}, Desc: "Split pane downward"},
203					"stack-pane":            {Keys: []string{"s"}, Desc: "Stack pane with sibling"},
204					"close-pane":            {Keys: []string{"x"}, Desc: "Close current pane"},
205					"move-pane-to-tab":      {Keys: []string{"m"}, Desc: "Move pane to different tab"},
206					"move-pane-to-next-tab": {Keys: []string{"M", "shift+m"}, Desc: "Move pane to next tab"},
207
208					"consume-or-expel-left":  {Keys: []string{"["}, Desc: "Consume/expel pane left"},
209					"consume-or-expel-right": {Keys: []string{"]"}, Desc: "Consume/expel pane right"},
210					"consume-or-expel-up":    {Keys: []string{"{"}, Desc: "Consume/expel pane up"},
211					"consume-or-expel-down":  {Keys: []string{"}"}, Desc: "Consume/expel pane down"},
212
213					"focus-right": {Keys: []string{"shift+arrowright", "shift+l"}, Desc: "Focus pane to the right"},
214					"focus-left":  {Keys: []string{"shift+arrowleft", "shift+h"}, Desc: "Focus pane to the left"},
215					"focus-up":    {Keys: []string{"shift+arrowup", "shift+k"}, Desc: "Focus pane above"},
216					"focus-down":  {Keys: []string{"shift+arrowdown", "shift+j"}, Desc: "Focus pane below"},
217					"confirm":     {Keys: []string{"enter"}, Desc: "Confirm action"},
218					"cancel":      {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
219				},
220			},
221			TabMode: TabModeConfig{
222				ActivationShortcut:  defaultTabActivationShortcut,
223				TimeoutMilliseconds: defaultTabTimeoutMilliseconds,
224				Actions: map[string]ActionBinding{
225					"new-tab":      {Keys: []string{"n", "c"}, Desc: "Create new tab"},
226					"close-tab":    {Keys: []string{"x"}, Desc: "Close current tab"},
227					"next-tab":     {Keys: []string{"l", "tab"}, Desc: "Switch to next tab"},
228					"previous-tab": {Keys: []string{"h", "shift+tab"}, Desc: "Switch to previous tab"},
229					"rename-tab":   {Keys: []string{"r"}, Desc: "Rename current tab"},
230					"confirm":      {Keys: []string{"enter"}, Desc: "Confirm action"},
231					"cancel":       {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
232				},
233			},
234			ResizeMode: ResizeModeConfig{
235				ActivationShortcut:  defaultResizeActivationShortcut,
236				TimeoutMilliseconds: defaultResizeTimeoutMilliseconds,
237				StepPercent:         defaultResizeStepPercent,
238				MinPanePercent:      defaultResizeMinPanePercent,
239				Actions: map[string]ActionBinding{
240					"resize-increase-left":  {Keys: []string{"h", "arrowleft"}, Desc: "Increase size leftward"},
241					"resize-increase-down":  {Keys: []string{"j", "arrowdown"}, Desc: "Increase size downward"},
242					"resize-increase-up":    {Keys: []string{"k", "arrowup"}, Desc: "Increase size upward"},
243					"resize-increase-right": {Keys: []string{"l", "arrowright"}, Desc: "Increase size rightward"},
244					"resize-decrease-left":  {Keys: []string{"H"}, Desc: "Decrease size leftward"},
245					"resize-decrease-down":  {Keys: []string{"J"}, Desc: "Decrease size downward"},
246					"resize-decrease-up":    {Keys: []string{"K"}, Desc: "Decrease size upward"},
247					"resize-decrease-right": {Keys: []string{"L"}, Desc: "Decrease size rightward"},
248					"resize-increase":       {Keys: []string{"+", "="}, Desc: "Increase pane size"},
249					"resize-decrease":       {Keys: []string{"-"}, Desc: "Decrease pane size"},
250					"confirm":               {Keys: []string{"enter"}, Desc: "Confirm action"},
251					"cancel":                {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
252				},
253			},
254			Shortcuts: GlobalShortcutsConfig{
255				Actions: map[string]ActionBinding{
256					"toggle-floating-pane":        {Keys: []string{"alt+f"}, Desc: "Toggle floating pane"},
257					"toggle-history-systemview":   {Keys: []string{"ctrl+h"}, Desc: "Toggle History in right split"},
258					"toggle-favorites-systemview": {Keys: []string{}, Desc: "Toggle Favorites in right split"},
259					"toggle-config-systemview":    {Keys: []string{}, Desc: "Toggle Config in right split"},
260					"close-pane":                  {Keys: []string{"ctrl+w"}, Desc: "Close active pane"},
261					"next-tab":                    {Keys: []string{"ctrl+tab"}, Desc: "Switch to next tab"},
262					"previous-tab":                {Keys: []string{"ctrl+shift+tab"}, Desc: "Switch to previous tab"},
263					"consume-or-expel-left":       {Keys: []string{"alt+["}, Desc: "Consume/expel pane left"},
264					"consume-or-expel-right":      {Keys: []string{"alt+]"}, Desc: "Consume/expel pane right"},
265					"consume-or-expel-up":         {Keys: []string{"alt+{"}, Desc: "Consume/expel pane up"},
266					"consume-or-expel-down":       {Keys: []string{"alt+}"}, Desc: "Consume/expel pane down"},
267				},
268			},
269			FloatingPane: FloatingPaneConfig{
270				WidthPct:  defaultFloatingPaneWidthPct,
271				HeightPct: defaultFloatingPaneHeightPct,
272				Profiles:  map[string]FloatingPaneProfile{},
273			},
274			TabBarPosition:          defaultTabBarPosition,
275			HideTabBarWhenSingleTab: true,
276			BrowsingContexts:        browsingContextDefaults,
277			Popups:                  browsingContextDefaults,
278			Styling: WorkspaceStylingConfig{
279				BorderWidth:                 defaultBorderWidth,
280				BorderColor:                 defaultBorderColor,
281				ModeBorderWidth:             defaultModeBorderWidth,
282				PaneModeColor:               defaultPaneModeColor,
283				TabModeColor:                defaultTabModeColor,
284				SessionModeColor:            defaultSessionModeColor,
285				ResizeModeColor:             defaultResizeModeColor,
286				ModeIndicatorToasterEnabled: defaultModeIndicatorToasterEnabled,
287				TransitionDuration:          defaultTransitionDuration,
288			},
289		},
290		ContentFiltering: ContentFilteringConfig{
291			Enabled:    true, // Ad blocking enabled by default
292			AutoUpdate: true, // Auto-update filters from GitHub releases
293		},
294		Clipboard: ClipboardConfig{
295			AutoCopyOnSelection: true, // Enabled by default (zellij-style)
296		},
297		Omnibox: OmniboxConfig{
298			InitialBehavior:   defaultOmniboxInitialBehavior,
299			MostVisitedDays:   defaultOmniboxMostVisitedDays,
300			AutoOpenOnNewPane: defaultOmniboxAutoOpenOnNewPane,
301		},
302		Session: SessionConfig{
303			AutoRestore:             false,
304			SnapshotIntervalMs:      defaultSnapshotIntervalMs,
305			MaxExitedSessions:       defaultMaxExitedSessions,
306			MaxExitedSessionAgeDays: defaultMaxExitedSessionAgeDays,
307			SessionMode: SessionModeConfig{
308				ActivationShortcut:  defaultSessionActivationShortcut,
309				TimeoutMilliseconds: defaultSessionTimeoutMilliseconds,
310				Actions: map[string]ActionBinding{
311					"session-manager": {Keys: []string{"s", "w"}, Desc: "Open session manager"},
312					"confirm":         {Keys: []string{"enter"}, Desc: "Confirm action"},
313					"cancel":          {Keys: []string{"escape"}, Desc: "Cancel/exit mode"},
314				},
315			},
316		},
317		Media: MediaConfig{
318			HardwareDecodingMode:     HardwareDecodingAuto, // auto allows sw fallback
319			PreferAV1:                false,                // Don't force codec preference, let site choose
320			ShowDiagnosticsOnStartup: false,                // Disabled - diagnostics can be noisy
321			// GStreamer fields (ForceVSync, GLRenderingMode, GStreamerDebugLevel)
322			// moved to [engine.webkit] — zero values here prevent them from being
323			// written back when marshaling the Config struct.
324		},
325		Update: UpdateConfig{
326			EnableOnStartup:     true,  // Check for updates on startup by default
327			AutoDownload:        false, // Conservative: don't auto-download by default
328			NotifyOnNewSettings: true,  // Show toast when new config settings available
329		},
330		Downloads: DownloadsConfig{
331			Path: "", // Empty = use XDG_DOWNLOAD_DIR or ~/Downloads
332		},
333	}
334}
335
336// GetDefaultSearchShortcuts returns the default search shortcuts.
337func GetDefaultSearchShortcuts() map[string]SearchShortcut {
338	return map[string]SearchShortcut{
339		"ddg": {
340			URL:         "https://duckduckgo.com/?q=%s",
341			Description: "DuckDuckGo search",
342		},
343		"g": {
344			URL:         "https://www.google.com/search?q=%s",
345			Description: "Google search",
346		},
347		"gi": {
348			URL:         "https://www.google.com/search?tbm=isch&q=%s",
349			Description: "Google Images search",
350		},
351		"gh": {
352			URL:         "https://github.com/search?q=%s",
353			Description: "GitHub search",
354		},
355		"go": {
356			URL:         "https://pkg.go.dev/search?q=%s",
357			Description: "Go package search",
358		},
359		"mdn": {
360			URL:         "https://developer.mozilla.org/en-US/search?q=%s",
361			Description: "MDN Web Docs search",
362		},
363		"npm": {
364			URL:         "https://www.npmjs.com/search?q=%s",
365			Description: "npm package search",
366		},
367		"r": {
368			URL:         "https://www.reddit.com/search?q=%s",
369			Description: "Reddit search",
370		},
371		"so": {
372			URL:         "https://stackoverflow.com/search?q=%s",
373			Description: "Stack Overflow search",
374		},
375		"w": {
376			URL:         "https://en.wikipedia.org/wiki/%s",
377			Description: "Wikipedia search",
378		},
379		"yt": {
380			URL:         "https://www.youtube.com/results?search_query=%s",
381			Description: "YouTube search",
382		},
383	}
384}

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