v0.20.0 c741a39

CONFIG.md RawHistoryFolder

Configuration Reference

Primary format: TOML (recommended) Location: ~/.config/dumber/config.toml Also supports: JSON (.json) and YAML (.yaml) JSON Schema: ~/.config/dumber/config.schema.json (auto-generated for JSON format)

Why TOML?

TOML is the recommended format for dumber configuration because:

  • Clear structure: Explicit sections make complex configs easy to read and modify
  • No ambiguity: No whitespace sensitivity or type coercion issues
  • Comments supported: Add documentation directly in your config
  • Industry standard: Used by Cargo, Hugo, and many modern tools

You can still use JSON or YAML if you prefer - dumber automatically detects the format.

Database

Key Type Default Description
database.path string ~/.local/share/dumber/dumber.db Database file path

History

Key Type Default Valid Values Description
history.max_entries int 10000 > 0 Maximum number of history entries
history.retention_period_days int 365 > 0 Days to keep history (1 year)
history.cleanup_interval_days int 1 > 0 How often to run cleanup

Search Configuration

Key Type Default Description
default_search_engine string "https://duckduckgo.com/?q=%s" Default search engine URL template (must contain %s placeholder)
search_shortcuts map See defaults Map of shortcut aliases to URLs

Example:

# Default search engine - used when no shortcut is specified
default_search_engine = "https://duckduckgo.com/?q=%s"

# Alternative search engines:
# default_search_engine = "https://www.google.com/search?q=%s"
# default_search_engine = "https://www.startpage.com/search?q=%s"
# default_search_engine = "https://search.brave.com/search?q=%s"

Default shortcuts (usage: !shortcut query):

# Examples:
#   !ddg golang      → DuckDuckGo search for "golang"
#   !g rust tutorial → Google search for "rust tutorial"
#   !gi cats         → Google Images search for "cats"
#   !gh opencode     → GitHub search for "opencode"
#   !yt music video  → YouTube search for "music video"

[search_shortcuts.ddg]
url = "https://duckduckgo.com/?q=%s"
description = "DuckDuckGo search"

[search_shortcuts.g]
url = "https://google.com/search?q=%s"
description = "Google Search"

[search_shortcuts.gi]
url = "https://google.com/search?tbm=isch&q=%s"
description = "Google Images"

[search_shortcuts.gh]
url = "https://github.com/search?q=%s"
description = "GitHub"

[search_shortcuts.yt]
url = "https://youtube.com/results?search_query=%s"
description = "YouTube"

Dmenu / Launcher

These settings control the dumber dmenu CLI command for rofi/fuzzel integration.

Key Type Default Description
dmenu.max_history_items int 20 Max items shown in launcher
dmenu.show_visit_count bool true Show visit counts in output
dmenu.show_last_visited bool true Show last visited dates in output
dmenu.history_prefix string "🕒" Prefix for history items
dmenu.shortcut_prefix string "🔍" Prefix for shortcuts
dmenu.url_prefix string "🌐" Prefix for URLs
dmenu.date_format string "2006-01-02 15:04" Go time format string
dmenu.sort_by_visit_count bool true Sort by popularity

CLI Usage:

# Pipe mode (default) - outputs history for rofi/fuzzel with favicons
dumber dmenu | rofi -dmenu -show-icons -p "Browse: " | dumber dmenu --select
dumber dmenu | fuzzel --dmenu -p "Browse: " | dumber dmenu --select

# Interactive TUI mode
dumber dmenu --interactive

# Override max items via CLI flag
dumber dmenu --max 50

Omnibox

Key Type Default Valid Values Description
omnibox.initial_behavior string "recent" recent, most_visited, none Initial history display behavior

Example:

[omnibox]
initial_behavior = "recent"  # Show recent history when omnibox opens

# Alternative options:
# initial_behavior = "most_visited"  # Show most visited sites
# initial_behavior = "none"          # Show no initial suggestions

Logging

Key Type Default Valid Values Description
logging.level string "info" debug, info, warn, error Log level
logging.format string "text" text, json Log format
logging.max_age int 7 >= 0 Days to keep logs
logging.log_dir string ~/.local/state/dumber/logs/ any Log directory
logging.enable_file_log bool true - Enable file logging
logging.capture_console bool false - Capture browser console to logs

Appearance

Key Type Default Description
appearance.sans_font string "Fira Sans" Sans-serif font
appearance.serif_font string "Fira Sans" Serif font
appearance.monospace_font string "Fira Code" Monospace font
appearance.default_font_size int 16 Font size in points
appearance.color_scheme string "default" prefer-dark, prefer-light, default

Color Palettes

Light palette:

[appearance.light_palette]
background = "#f8f8f8"
surface = "#f2f2f2"
surface_variant = "#ececec"
text = "#1a1a1a"
muted = "#6e6e6e"
accent = "#404040"
border = "#d2d2d2"

Dark palette:

[appearance.dark_palette]
background = "#0e0e0e"
surface = "#1a1a1a"
surface_variant = "#141414"
text = "#e4e4e4"
muted = "#848484"
accent = "#a8a8a8"
border = "#363636"

Debug Options

Key Type Default Description
debug.enable_devtools bool true Enable browser developer tools (F12, Inspect Element)

Rendering, UI Scale & Zoom

Key Type Default Valid Values Description
rendering.mode string "gpu" auto, gpu, cpu WebKit hardware acceleration policy
rendering.disable_dmabuf_renderer bool false - Disable WebKit DMA-BUF renderer (may fix flicker on Wayland; slower)
rendering.force_compositing_mode bool false - Force WebKit compositing mode (WEBKIT_FORCE_COMPOSITING_MODE)
rendering.disable_compositing_mode bool false - Disable WebKit compositing mode (WEBKIT_DISABLE_COMPOSITING_MODE)
rendering.gsk_renderer string "vulkan" auto, opengl, vulkan, cairo GTK renderer selection (GSK_RENDERER)
rendering.disable_mipmaps bool false - Disable GTK mipmaps (GSK_GPU_DISABLE=mipmap)
rendering.prefer_gl bool false - Prefer OpenGL over GLES (GDK_DEBUG=gl-prefer-gl)
rendering.draw_compositing_indicators bool false - Draw WebKit compositing indicators (debug)
rendering.show_fps bool false - Show WebKit FPS counter (WEBKIT_SHOW_FPS)
rendering.sample_memory bool false - Enable WebKit memory sampling (WEBKIT_SAMPLE_MEMORY)
rendering.debug_frames bool false - Enable GTK frame timing debug (GDK_DEBUG=frames)
default_ui_scale float 1.0 > 0 GTK widget UI scale (1.0=100%, 2.0=200%)
default_webpage_zoom float 1.2 > 0 Default page zoom (1.0=100%, 1.2=120%)

Workspace Configuration

Pane Mode

Key Type Default Description
workspace.pane_mode.activation_shortcut string "ctrl+p" Pane mode activation key
workspace.pane_mode.timeout_ms int 3000 Pane mode timeout (ms)
workspace.pane_mode.actions map See below Action→keys mappings

Default pane mode actions:

[workspace.pane_mode.actions]
split-right = ["arrowright", "r"]
split-left = ["arrowleft", "l"]
split-up = ["arrowup", "u"]
split-down = ["arrowdown", "d"]
stack-pane = ["s"]
close-pane = ["x"]
focus-right = ["shift+arrowright", "shift+l"]
focus-left = ["shift+arrowleft", "shift+h"]
focus-up = ["shift+arrowup", "shift+k"]
focus-down = ["shift+arrowdown", "shift+j"]
confirm = ["enter"]
cancel = ["escape"]

Note: Actions are inverted to key→action map in memory for O(1) lookup performance during navigation.

Tab Mode

Key Type Default Description
workspace.tab_mode.activation_shortcut string "ctrl+t" Tab mode activation key
workspace.tab_mode.timeout_ms int 3000 Tab mode timeout (ms)
workspace.tab_mode.actions map See below Action→keys mappings

Default tab mode actions:

[workspace.tab_mode.actions]
new-tab = ["n", "c"]
close-tab = ["x"]
next-tab = ["l", "tab"]
previous-tab = ["h", "shift+tab"]
rename-tab = ["r"]
confirm = ["enter"]
cancel = ["escape"]

Note: Actions are inverted to key→action map in memory for O(1) lookup performance during navigation.

Global Shortcuts

Key Type Default Description
workspace.shortcuts.close_pane string "ctrl+w" Close active pane (closes tab if last pane)
workspace.shortcuts.next_tab string "ctrl+tab" Next tab shortcut
workspace.shortcuts.previous_tab string "ctrl+shift+tab" Previous tab shortcut

Note: New tab creation uses modal tab mode (Ctrl+T then n/c). This follows the Zellij-style modal keyboard interface.

Popup Behavior

Key Type Default Valid Values Description
workspace.popups.behavior string "split" split, stacked, tabbed, windowed Popup opening mode
workspace.popups.placement string "right" right, left, top, bottom Split direction
workspace.popups.open_in_new_pane bool true - Open popups in workspace
workspace.popups.follow_pane_context bool true - Follow parent pane context
workspace.popups.blank_target_behavior string "pane" pane, tab _blank target handling
workspace.popups.enable_smart_detection bool true - Use WindowProperties for detection
workspace.popups.oauth_auto_close bool true - Auto-close OAuth popups

Workspace Styling

Key Type Default Description
workspace.styling.border_width int 1 Active pane border width (px) - overlay
workspace.styling.border_color string "@theme_selected_bg_color" Active pane border color
workspace.styling.pane_mode_border_width int 4 Pane mode border width (px) - Ctrl+P N overlay
workspace.styling.pane_mode_border_color string "#4A90E2" Pane mode border color (blue)
workspace.styling.tab_mode_border_width int 4 Tab mode border width (px) - Ctrl+P T overlay
workspace.styling.tab_mode_border_color string "#FFA500" Tab mode border color (orange)
workspace.styling.transition_duration int 120 Border transition duration (ms)

Media

Key Type Default Valid Values Description
media.hardware_decoding string "auto" auto, force, disable Hardware video decoding mode
media.prefer_av1 bool true - Prefer AV1 codec when available
media.show_diagnostics bool true - Show media diagnostics warnings at startup
media.force_vsync bool false - Force VSync for video playback (may help with tearing)
media.gl_rendering_mode string "auto" auto, gles2, gl3, none OpenGL API selection for video rendering
media.gstreamer_debug_level int 0 0-5 GStreamer debug verbosity (0=off)
media.video_buffer_size_mb int 64 > 0 Video buffer size in MB for smoother streaming
media.queue_buffer_time_sec int 20 > 0 Queue prebuffer time in seconds

Hardware decoding modes:

  • auto (recommended): Hardware preferred with software fallback - fixes Twitch Error #4000
  • force: Hardware only - fails if unavailable
  • disable: Software only - higher CPU usage

GL rendering modes:

  • auto (default): Let GStreamer choose the best OpenGL API
  • gles2: Force GLES2 (better for some mobile/embedded GPUs)
  • gl3: Force OpenGL 3.x desktop
  • none: Disable GL-based rendering

GPU auto-detection: Dumber automatically detects your GPU vendor (AMD/Intel/NVIDIA) and sets optimal VA-API driver settings:

  • AMD: Uses radeonsi driver
  • Intel: Uses iHD driver (modern, for Broadwell+)
  • NVIDIA: Uses nvidia driver with EGL platform

Buffering settings:

  • video_buffer_size_mb: Controls GStreamer buffer size. Larger buffers reduce rebuffering on bursty streams (Twitch, YouTube). Uses more memory.
  • queue_buffer_time_sec: Controls prebuffer duration. Higher values allow more data to be buffered ahead of playback.

Example:

[media]
hardware_decoding = "auto"    # HW preferred, SW fallback
prefer_av1 = true             # AV1 is most efficient codec
show_diagnostics = true       # Log warnings if HW accel unavailable
force_vsync = false           # Let compositor handle VSync
gl_rendering_mode = "auto"    # GStreamer picks best GL API
gstreamer_debug_level = 0     # Increase to 3-5 for debugging
video_buffer_size_mb = 64     # 64 MB buffer for smooth streaming
queue_buffer_time_sec = 20    # 20 seconds prebuffer

Diagnostics CLI:

# Check GStreamer plugins and VA-API status
dumber doctor --media

Runtime

Key Type Default Description
runtime.prefix string "" Optional runtime prefix (e.g., /opt/webkitgtk) used to locate newer GTK/WebKitGTK installs

If set, dumber prepends prefix-derived paths to:

  • PKG_CONFIG_PATH (for version checks)
  • LD_LIBRARY_PATH (for runtime library loading)
  • GI_TYPELIB_PATH (GObject introspection)
  • XDG_DATA_DIRS (schemas/resources)

Example:

[runtime]
prefix = "/opt/webkitgtk"

Content Filtering

Key Type Default Description
content_filtering.enabled bool true Enable ad blocking
content_filtering.auto_update bool true Automatically update filters

Notes:

  • Filter data is downloaded from bnema/ublock-webkit-filters GitHub releases.
  • Domain whitelist is managed via the database (content_whitelist table), not the config file.

Environment Variables

All config values can be overridden via environment variables with the prefix DUMBER_:

# Database
DUMBER_DATABASE_PATH=/custom/path/db.sqlite

# Rendering (examples)
# Defaults: rendering.disable_dmabuf_renderer=false, rendering.gsk_renderer="vulkan"
DUMBER_RENDERING_MODE=cpu
# DUMBER_RENDERING_DISABLE_DMABUF_RENDERER=true
# DUMBER_RENDERING_GSK_RENDERER=opengl
DUMBER_DEFAULT_WEBPAGE_ZOOM=1.5

# Logging
DUMBER_LOG_LEVEL=debug
DUMBER_LOG_FORMAT=json
source
1# Configuration Reference
2
3**Primary format**: TOML (recommended)
4**Location**: `~/.config/dumber/config.toml`
5**Also supports**: JSON (`.json`) and YAML (`.yaml`)
6**JSON Schema**: `~/.config/dumber/config.schema.json` (auto-generated for JSON format)
7
8## Why TOML?
9
10TOML is the recommended format for dumber configuration because:
11- **Clear structure**: Explicit sections make complex configs easy to read and modify
12- **No ambiguity**: No whitespace sensitivity or type coercion issues
13- **Comments supported**: Add documentation directly in your config
14- **Industry standard**: Used by Cargo, Hugo, and many modern tools
15
16You can still use JSON or YAML if you prefer - dumber automatically detects the format.
17
18## Database
19
20| Key | Type | Default | Description |
21|-----|------|---------|-------------|
22| `database.path` | string | `~/.local/share/dumber/dumber.db` | Database file path |
23
24## History
25
26| Key | Type | Default | Valid Values | Description |
27|-----|------|---------|--------------|-------------|
28| `history.max_entries` | int | `10000` | > 0 | Maximum number of history entries |
29| `history.retention_period_days` | int | `365` | > 0 | Days to keep history (1 year) |
30| `history.cleanup_interval_days` | int | `1` | > 0 | How often to run cleanup |
31
32## Search Configuration
33
34| Key | Type | Default | Description |
35|-----|------|---------|-------------|
36| `default_search_engine` | string | `"https://duckduckgo.com/?q=%s"` | Default search engine URL template (must contain `%s` placeholder) |
37| `search_shortcuts` | map | See defaults | Map of shortcut aliases to URLs |
38
39**Example:**
40```toml
41# Default search engine - used when no shortcut is specified
42default_search_engine = "https://duckduckgo.com/?q=%s"
43
44# Alternative search engines:
45# default_search_engine = "https://www.google.com/search?q=%s"
46# default_search_engine = "https://www.startpage.com/search?q=%s"
47# default_search_engine = "https://search.brave.com/search?q=%s"
48```
49
50**Default shortcuts (usage: `!shortcut query`):**
51```toml
52# Examples:
53#   !ddg golang      → DuckDuckGo search for "golang"
54#   !g rust tutorial → Google search for "rust tutorial"
55#   !gi cats         → Google Images search for "cats"
56#   !gh opencode     → GitHub search for "opencode"
57#   !yt music video  → YouTube search for "music video"
58
59[search_shortcuts.ddg]
60url = "https://duckduckgo.com/?q=%s"
61description = "DuckDuckGo search"
62
63[search_shortcuts.g]
64url = "https://google.com/search?q=%s"
65description = "Google Search"
66
67[search_shortcuts.gi]
68url = "https://google.com/search?tbm=isch&q=%s"
69description = "Google Images"
70
71[search_shortcuts.gh]
72url = "https://github.com/search?q=%s"
73description = "GitHub"
74
75[search_shortcuts.yt]
76url = "https://youtube.com/results?search_query=%s"
77description = "YouTube"
78```
79
80## Dmenu / Launcher
81
82These settings control the `dumber dmenu` CLI command for rofi/fuzzel integration.
83
84| Key | Type | Default | Description |
85|-----|------|---------|-------------|
86| `dmenu.max_history_items` | int | `20` | Max items shown in launcher |
87| `dmenu.show_visit_count` | bool | `true` | Show visit counts in output |
88| `dmenu.show_last_visited` | bool | `true` | Show last visited dates in output |
89| `dmenu.history_prefix` | string | `"🕒"` | Prefix for history items |
90| `dmenu.shortcut_prefix` | string | `"🔍"` | Prefix for shortcuts |
91| `dmenu.url_prefix` | string | `"🌐"` | Prefix for URLs |
92| `dmenu.date_format` | string | `"2006-01-02 15:04"` | Go time format string |
93| `dmenu.sort_by_visit_count` | bool | `true` | Sort by popularity |
94
95**CLI Usage:**
96```bash
97# Pipe mode (default) - outputs history for rofi/fuzzel with favicons
98dumber dmenu | rofi -dmenu -show-icons -p "Browse: " | dumber dmenu --select
99dumber dmenu | fuzzel --dmenu -p "Browse: " | dumber dmenu --select
100
101# Interactive TUI mode
102dumber dmenu --interactive
103
104# Override max items via CLI flag
105dumber dmenu --max 50
106```
107
108## Omnibox
109
110| Key | Type | Default | Valid Values | Description |
111|-----|------|---------|--------------|-------------|
112| `omnibox.initial_behavior` | string | `"recent"` | `recent`, `most_visited`, `none` | Initial history display behavior |
113
114**Example:**
115```toml
116[omnibox]
117initial_behavior = "recent"  # Show recent history when omnibox opens
118
119# Alternative options:
120# initial_behavior = "most_visited"  # Show most visited sites
121# initial_behavior = "none"          # Show no initial suggestions
122```
123
124## Logging
125
126| Key | Type | Default | Valid Values | Description |
127|-----|------|---------|--------------|-------------|
128| `logging.level` | string | `"info"` | `debug`, `info`, `warn`, `error` | Log level |
129| `logging.format` | string | `"text"` | `text`, `json` | Log format |
130| `logging.max_age` | int | `7` | >= 0 | Days to keep logs |
131| `logging.log_dir` | string | `~/.local/state/dumber/logs/` | any | Log directory |
132| `logging.enable_file_log` | bool | `true` | - | Enable file logging |
133| `logging.capture_console` | bool | `false` | - | Capture browser console to logs |
134
135## Appearance
136
137| Key | Type | Default | Description |
138|-----|------|---------|-------------|
139| `appearance.sans_font` | string | `"Fira Sans"` | Sans-serif font |
140| `appearance.serif_font` | string | `"Fira Sans"` | Serif font |
141| `appearance.monospace_font` | string | `"Fira Code"` | Monospace font |
142| `appearance.default_font_size` | int | `16` | Font size in points |
143| `appearance.color_scheme` | string | `"default"` | `prefer-dark`, `prefer-light`, `default` |
144
145### Color Palettes
146
147**Light palette:**
148```toml
149[appearance.light_palette]
150background = "#f8f8f8"
151surface = "#f2f2f2"
152surface_variant = "#ececec"
153text = "#1a1a1a"
154muted = "#6e6e6e"
155accent = "#404040"
156border = "#d2d2d2"
157```
158
159**Dark palette:**
160```toml
161[appearance.dark_palette]
162background = "#0e0e0e"
163surface = "#1a1a1a"
164surface_variant = "#141414"
165text = "#e4e4e4"
166muted = "#848484"
167accent = "#a8a8a8"
168border = "#363636"
169```
170
171## Debug Options
172
173| Key | Type | Default | Description |
174|-----|------|---------|-------------|
175| `debug.enable_devtools` | bool | `true` | Enable browser developer tools (F12, Inspect Element) |
176
177## Rendering, UI Scale & Zoom
178
179| Key | Type | Default | Valid Values | Description |
180|-----|------|---------|--------------|-------------|
181| `rendering.mode` | string | `"gpu"` | `auto`, `gpu`, `cpu` | WebKit hardware acceleration policy |
182| `rendering.disable_dmabuf_renderer` | bool | `false` | - | Disable WebKit DMA-BUF renderer (may fix flicker on Wayland; slower) |
183| `rendering.force_compositing_mode` | bool | `false` | - | Force WebKit compositing mode (`WEBKIT_FORCE_COMPOSITING_MODE`) |
184| `rendering.disable_compositing_mode` | bool | `false` | - | Disable WebKit compositing mode (`WEBKIT_DISABLE_COMPOSITING_MODE`) |
185| `rendering.gsk_renderer` | string | `"vulkan"` | `auto`, `opengl`, `vulkan`, `cairo` | GTK renderer selection (`GSK_RENDERER`) |
186| `rendering.disable_mipmaps` | bool | `false` | - | Disable GTK mipmaps (`GSK_GPU_DISABLE=mipmap`) |
187| `rendering.prefer_gl` | bool | `false` | - | Prefer OpenGL over GLES (`GDK_DEBUG=gl-prefer-gl`) |
188| `rendering.draw_compositing_indicators` | bool | `false` | - | Draw WebKit compositing indicators (debug) |
189| `rendering.show_fps` | bool | `false` | - | Show WebKit FPS counter (`WEBKIT_SHOW_FPS`) |
190| `rendering.sample_memory` | bool | `false` | - | Enable WebKit memory sampling (`WEBKIT_SAMPLE_MEMORY`) |
191| `rendering.debug_frames` | bool | `false` | - | Enable GTK frame timing debug (`GDK_DEBUG=frames`) |
192| `default_ui_scale` | float | `1.0` | > 0 | GTK widget UI scale (1.0=100%, 2.0=200%) |
193| `default_webpage_zoom` | float | `1.2` | > 0 | Default page zoom (1.0=100%, 1.2=120%) |
194
195## Workspace Configuration
196
197### Pane Mode
198
199| Key | Type | Default | Description |
200|-----|------|---------|-------------|
201| `workspace.pane_mode.activation_shortcut` | string | `"ctrl+p"` | Pane mode activation key |
202| `workspace.pane_mode.timeout_ms` | int | `3000` | Pane mode timeout (ms) |
203| `workspace.pane_mode.actions` | map | See below | Action→keys mappings |
204
205**Default pane mode actions:**
206```toml
207[workspace.pane_mode.actions]
208split-right = ["arrowright", "r"]
209split-left = ["arrowleft", "l"]
210split-up = ["arrowup", "u"]
211split-down = ["arrowdown", "d"]
212stack-pane = ["s"]
213close-pane = ["x"]
214focus-right = ["shift+arrowright", "shift+l"]
215focus-left = ["shift+arrowleft", "shift+h"]
216focus-up = ["shift+arrowup", "shift+k"]
217focus-down = ["shift+arrowdown", "shift+j"]
218confirm = ["enter"]
219cancel = ["escape"]
220```
221
222> **Note:** Actions are inverted to key→action map in memory for O(1) lookup performance during navigation.
223
224### Tab Mode
225
226| Key | Type | Default | Description |
227|-----|------|---------|-------------|
228| `workspace.tab_mode.activation_shortcut` | string | `"ctrl+t"` | Tab mode activation key |
229| `workspace.tab_mode.timeout_ms` | int | `3000` | Tab mode timeout (ms) |
230| `workspace.tab_mode.actions` | map | See below | Action→keys mappings |
231
232**Default tab mode actions:**
233```toml
234[workspace.tab_mode.actions]
235new-tab = ["n", "c"]
236close-tab = ["x"]
237next-tab = ["l", "tab"]
238previous-tab = ["h", "shift+tab"]
239rename-tab = ["r"]
240confirm = ["enter"]
241cancel = ["escape"]
242```
243
244> **Note:** Actions are inverted to key→action map in memory for O(1) lookup performance during navigation.
245
246### Global Shortcuts
247
248| Key | Type | Default | Description |
249|-----|------|---------|-------------|
250| `workspace.shortcuts.close_pane` | string | `"ctrl+w"` | Close active pane (closes tab if last pane) |
251| `workspace.shortcuts.next_tab` | string | `"ctrl+tab"` | Next tab shortcut |
252| `workspace.shortcuts.previous_tab` | string | `"ctrl+shift+tab"` | Previous tab shortcut |
253
254> **Note:** New tab creation uses modal tab mode (Ctrl+T then n/c). This follows the Zellij-style modal keyboard interface.
255
256### Popup Behavior
257
258| Key | Type | Default | Valid Values | Description |
259|-----|------|---------|--------------|-------------|
260| `workspace.popups.behavior` | string | `"split"` | `split`, `stacked`, `tabbed`, `windowed` | Popup opening mode |
261| `workspace.popups.placement` | string | `"right"` | `right`, `left`, `top`, `bottom` | Split direction |
262| `workspace.popups.open_in_new_pane` | bool | `true` | - | Open popups in workspace |
263| `workspace.popups.follow_pane_context` | bool | `true` | - | Follow parent pane context |
264| `workspace.popups.blank_target_behavior` | string | `"pane"` | `pane`, `tab` | `_blank` target handling |
265| `workspace.popups.enable_smart_detection` | bool | `true` | - | Use WindowProperties for detection |
266| `workspace.popups.oauth_auto_close` | bool | `true` | - | Auto-close OAuth popups |
267
268### Workspace Styling
269
270| Key | Type | Default | Description |
271|-----|------|---------|-------------|
272| `workspace.styling.border_width` | int | `1` | Active pane border width (px) - overlay |
273| `workspace.styling.border_color` | string | `"@theme_selected_bg_color"` | Active pane border color |
274| `workspace.styling.pane_mode_border_width` | int | `4` | Pane mode border width (px) - Ctrl+P N overlay |
275| `workspace.styling.pane_mode_border_color` | string | `"#4A90E2"` | Pane mode border color (blue) |
276| `workspace.styling.tab_mode_border_width` | int | `4` | Tab mode border width (px) - Ctrl+P T overlay |
277| `workspace.styling.tab_mode_border_color` | string | `"#FFA500"` | Tab mode border color (orange) |
278| `workspace.styling.transition_duration` | int | `120` | Border transition duration (ms) |
279
280## Media
281
282| Key | Type | Default | Valid Values | Description |
283|-----|------|---------|--------------|-------------|
284| `media.hardware_decoding` | string | `"auto"` | `auto`, `force`, `disable` | Hardware video decoding mode |
285| `media.prefer_av1` | bool | `true` | - | Prefer AV1 codec when available |
286| `media.show_diagnostics` | bool | `true` | - | Show media diagnostics warnings at startup |
287| `media.force_vsync` | bool | `false` | - | Force VSync for video playback (may help with tearing) |
288| `media.gl_rendering_mode` | string | `"auto"` | `auto`, `gles2`, `gl3`, `none` | OpenGL API selection for video rendering |
289| `media.gstreamer_debug_level` | int | `0` | `0-5` | GStreamer debug verbosity (0=off) |
290| `media.video_buffer_size_mb` | int | `64` | > 0 | Video buffer size in MB for smoother streaming |
291| `media.queue_buffer_time_sec` | int | `20` | > 0 | Queue prebuffer time in seconds |
292
293**Hardware decoding modes:**
294- `auto` (recommended): Hardware preferred with software fallback - fixes Twitch Error #4000
295- `force`: Hardware only - fails if unavailable
296- `disable`: Software only - higher CPU usage
297
298**GL rendering modes:**
299- `auto` (default): Let GStreamer choose the best OpenGL API
300- `gles2`: Force GLES2 (better for some mobile/embedded GPUs)
301- `gl3`: Force OpenGL 3.x desktop
302- `none`: Disable GL-based rendering
303
304**GPU auto-detection:**
305Dumber automatically detects your GPU vendor (AMD/Intel/NVIDIA) and sets optimal VA-API driver settings:
306- **AMD**: Uses `radeonsi` driver
307- **Intel**: Uses `iHD` driver (modern, for Broadwell+)
308- **NVIDIA**: Uses `nvidia` driver with EGL platform
309
310**Buffering settings:**
311- `video_buffer_size_mb`: Controls GStreamer buffer size. Larger buffers reduce rebuffering on bursty streams (Twitch, YouTube). Uses more memory.
312- `queue_buffer_time_sec`: Controls prebuffer duration. Higher values allow more data to be buffered ahead of playback.
313
314**Example:**
315```toml
316[media]
317hardware_decoding = "auto"    # HW preferred, SW fallback
318prefer_av1 = true             # AV1 is most efficient codec
319show_diagnostics = true       # Log warnings if HW accel unavailable
320force_vsync = false           # Let compositor handle VSync
321gl_rendering_mode = "auto"    # GStreamer picks best GL API
322gstreamer_debug_level = 0     # Increase to 3-5 for debugging
323video_buffer_size_mb = 64     # 64 MB buffer for smooth streaming
324queue_buffer_time_sec = 20    # 20 seconds prebuffer
325```
326
327**Diagnostics CLI:**
328```bash
329# Check GStreamer plugins and VA-API status
330dumber doctor --media
331```
332
333## Runtime
334
335| Key | Type | Default | Description |
336|-----|------|---------|-------------|
337| `runtime.prefix` | string | `""` | Optional runtime prefix (e.g., `/opt/webkitgtk`) used to locate newer GTK/WebKitGTK installs |
338
339If set, dumber prepends prefix-derived paths to:
340- `PKG_CONFIG_PATH` (for version checks)
341- `LD_LIBRARY_PATH` (for runtime library loading)
342- `GI_TYPELIB_PATH` (GObject introspection)
343- `XDG_DATA_DIRS` (schemas/resources)
344
345**Example:**
346```toml
347[runtime]
348prefix = "/opt/webkitgtk"
349```
350
351## Content Filtering
352
353| Key | Type | Default | Description |
354|-----|------|---------|-------------|
355| `content_filtering.enabled` | bool | `true` | Enable ad blocking |
356| `content_filtering.auto_update` | bool | `true` | Automatically update filters |
357
358Notes:
359- Filter data is downloaded from `bnema/ublock-webkit-filters` GitHub releases.
360- Domain whitelist is managed via the database (`content_whitelist` table), not the config file.
361
362## Environment Variables
363
364All config values can be overridden via environment variables with the prefix `DUMBER_`:
365
366```bash
367# Database
368DUMBER_DATABASE_PATH=/custom/path/db.sqlite
369
370# Rendering (examples)
371# Defaults: rendering.disable_dmabuf_renderer=false, rendering.gsk_renderer="vulkan"
372DUMBER_RENDERING_MODE=cpu
373# DUMBER_RENDERING_DISABLE_DMABUF_RENDERER=true
374# DUMBER_RENDERING_GSK_RENDERER=opengl
375DUMBER_DEFAULT_WEBPAGE_ZOOM=1.5
376
377# Logging
378DUMBER_LOG_LEVEL=debug
379DUMBER_LOG_FORMAT=json
380```

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