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/state/dumber/dumber.sqlite |
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:
[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.gh]
url = "https://github.com/search?q=%s"
description = "GitHub"
[search_shortcuts.yt]
url = "https://youtube.com/results?search_query=%s"
description = "YouTube"
| Key |
Type |
Default |
Description |
dmenu.max_history_items |
int |
20 |
Max items shown in launcher |
dmenu.show_visit_count |
bool |
true |
Show visit counts |
dmenu.show_last_visited |
bool |
true |
Show last visited dates |
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 |
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.filename |
string |
"" |
any |
Empty = stdout |
logging.max_size |
int |
100 |
> 0 |
Max log size in MB |
logging.max_backups |
int |
3 |
>= 0 |
Number of log backups |
logging.max_age |
int |
7 |
>= 0 |
Days to keep logs |
logging.compress |
bool |
true |
- |
Compress old logs |
logging.log_dir |
string |
~/.local/state/dumber/logs/ |
any |
Log directory |
logging.enable_file_log |
bool |
true |
- |
Enable file logging |
logging.capture_stdout |
bool |
false |
- |
Capture stdout to log |
logging.capture_stderr |
bool |
false |
- |
Capture stderr to log |
logging.capture_c_output |
bool |
false |
- |
Capture C/CGO output |
logging.capture_console |
bool |
false |
- |
Capture browser console |
logging.debug_file |
string |
"debug.log" |
any |
Debug log filename |
logging.verbose_webkit |
bool |
false |
- |
Verbose WebKit 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"
Video Acceleration
| Key |
Type |
Default |
Description |
video_acceleration.enable_vaapi |
bool |
true |
Enable VA-API hardware accel |
video_acceleration.auto_detect_gpu |
bool |
true |
Auto-detect GPU driver |
video_acceleration.vaapi_driver_name |
string |
"" |
Driver name (auto-detected) |
video_acceleration.enable_all_drivers |
bool |
true |
Enable all VA-API drivers |
video_acceleration.legacy_vaapi |
bool |
false |
Legacy VA-API mode |
Codec Preferences
| Key |
Type |
Default |
Valid Values |
Description |
codec_preferences.preferred_codecs |
string |
"av1,h264" |
Comma-separated |
Codec priority order |
codec_preferences.force_av1 |
bool |
false |
- |
Force AV1 codec |
codec_preferences.block_vp9 |
bool |
false |
- |
Block VP9 codec |
codec_preferences.block_vp8 |
bool |
false |
- |
Block VP8 codec |
codec_preferences.av1_hardware_only |
bool |
false |
- |
Disable AV1 software fallback |
codec_preferences.disable_vp9_hardware |
bool |
false |
- |
Disable VP9 hardware accel |
codec_preferences.video_buffer_size_mb |
int |
64 |
> 0 |
Video buffer size in MB |
codec_preferences.queue_buffer_time_sec |
int |
20 |
> 0 |
Queue buffer time in seconds |
codec_preferences.custom_user_agent |
string |
Chrome UA |
any |
Custom user agent string |
codec_preferences.av1_max_resolution |
string |
"1080p" |
720p, 1080p, 1440p, 4k, unlimited |
Max AV1 resolution |
codec_preferences.disable_twitch_codec_control |
bool |
true |
- |
Disable codec control on Twitch |
Debug Options
| Key |
Type |
Default |
Description |
debug.enable_webkit_debug |
bool |
false |
Enable WebKit debug logs |
debug.webkit_debug_categories |
string |
"Network:preconnectTo,ContentFilters" |
Debug categories |
debug.enable_filtering_debug |
bool |
false |
Content filter debug |
debug.enable_webview_debug |
bool |
false |
WebView state debug |
debug.log_webkit_crashes |
bool |
true |
Log WebKit crashes |
debug.enable_script_debug |
bool |
false |
Script injection debug |
debug.enable_general_debug |
bool |
false |
General debug mode |
debug.enable_workspace_debug |
bool |
false |
Workspace navigation debug |
debug.enable_focus_debug |
bool |
false |
Focus state debug |
debug.enable_css_debug |
bool |
false |
CSS reconciler debug |
debug.enable_focus_metrics |
bool |
false |
Focus metrics tracking |
debug.enable_pane_close_debug |
bool |
false |
Pane close debug |
Rendering & Zoom
| Key |
Type |
Default |
Valid Values |
Description |
rendering_mode |
string |
"gpu" |
auto, gpu, cpu |
Rendering mode |
use_dom_zoom |
bool |
false |
- |
Use DOM-based zoom |
default_zoom |
float |
1.2 |
> 0 |
Default zoom level (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"]
close-pane = ["x"]
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.
Tab Shortcuts
| Key |
Type |
Default |
Description |
workspace.tabs.new_tab |
string |
"ctrl+t" |
New tab shortcut |
workspace.tabs.close_tab |
string |
"ctrl+w" |
Close tab shortcut |
workspace.tabs.next_tab |
string |
"ctrl+tab" |
Next tab shortcut |
workspace.tabs.previous_tab |
string |
"ctrl+shift+tab" |
Previous tab shortcut |
| 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) |
workspace.styling.border_color |
string |
"@theme_selected_bg_color" |
Active pane border color |
workspace.styling.inactive_border_width |
int |
1 |
Inactive pane border width (px) |
workspace.styling.inactive_border_color |
string |
"@theme_unfocused_bg_color" |
Inactive pane border color |
workspace.styling.show_stacked_title_border |
bool |
false |
Show separator on stacked pane titles |
workspace.styling.pane_mode_border_color |
string |
"#4A90E2" |
Pane mode border color (blue) |
workspace.styling.tab_mode_border_color |
string |
"#FFA500" |
Tab mode border color (orange) |
workspace.styling.transition_duration |
int |
120 |
Border transition duration (ms) |
workspace.styling.border_radius |
int |
0 |
Border radius (px) |
Content Filtering
| Key |
Type |
Default |
Description |
content_filtering_whitelist |
array |
See below |
Domains to skip ad blocking |
Default whitelist:
content_filtering_whitelist = [
"twitch.tv",
"passport.twitch.tv",
"gql.twitch.tv"
]
Environment Variables
All config values can be overridden via environment variables with the prefix DUMB_BROWSER_:
# Database
DUMB_BROWSER_DATABASE_PATH=/custom/path/db.sqlite
# Rendering
DUMBER_RENDERING_MODE=cpu
DUMBER_DEFAULT_ZOOM=1.5
# Video/Codec
DUMBER_VIDEO_ACCELERATION_ENABLE=true
LIBVA_DRIVER_NAME=iHD
DUMBER_PREFERRED_CODECS=av1,vp9,h264
Note: Some video/codec env vars use DUMBER_* prefix and match GStreamer/VA-API conventions.
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/state/dumber/dumber.sqlite` | 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:**
51```toml
52[search_shortcuts.ddg]
53url = "https://duckduckgo.com/?q=%s"
54description = "DuckDuckGo search"
55
56[search_shortcuts.g]
57url = "https://google.com/search?q=%s"
58description = "Google Search"
59
60[search_shortcuts.gh]
61url = "https://github.com/search?q=%s"
62description = "GitHub"
63
64[search_shortcuts.yt]
65url = "https://youtube.com/results?search_query=%s"
66description = "YouTube"
67```
68
69## Dmenu / Launcher
70
71| Key | Type | Default | Description |
72|-----|------|---------|-------------|
73| `dmenu.max_history_items` | int | `20` | Max items shown in launcher |
74| `dmenu.show_visit_count` | bool | `true` | Show visit counts |
75| `dmenu.show_last_visited` | bool | `true` | Show last visited dates |
76| `dmenu.history_prefix` | string | `"🕒"` | Prefix for history items |
77| `dmenu.shortcut_prefix` | string | `"🔍"` | Prefix for shortcuts |
78| `dmenu.url_prefix` | string | `"🌐"` | Prefix for URLs |
79| `dmenu.date_format` | string | `"2006-01-02 15:04"` | Go time format string |
80| `dmenu.sort_by_visit_count` | bool | `true` | Sort by popularity |
81
82## Logging
83
84| Key | Type | Default | Valid Values | Description |
85|-----|------|---------|--------------|-------------|
86| `logging.level` | string | `"info"` | `debug`, `info`, `warn`, `error` | Log level |
87| `logging.format` | string | `"text"` | `text`, `json` | Log format |
88| `logging.filename` | string | `""` | any | Empty = stdout |
89| `logging.max_size` | int | `100` | > 0 | Max log size in MB |
90| `logging.max_backups` | int | `3` | >= 0 | Number of log backups |
91| `logging.max_age` | int | `7` | >= 0 | Days to keep logs |
92| `logging.compress` | bool | `true` | - | Compress old logs |
93| `logging.log_dir` | string | `~/.local/state/dumber/logs/` | any | Log directory |
94| `logging.enable_file_log` | bool | `true` | - | Enable file logging |
95| `logging.capture_stdout` | bool | `false` | - | Capture stdout to log |
96| `logging.capture_stderr` | bool | `false` | - | Capture stderr to log |
97| `logging.capture_c_output` | bool | `false` | - | Capture C/CGO output |
98| `logging.capture_console` | bool | `false` | - | Capture browser console |
99| `logging.debug_file` | string | `"debug.log"` | any | Debug log filename |
100| `logging.verbose_webkit` | bool | `false` | - | Verbose WebKit logs |
101
102## Appearance
103
104| Key | Type | Default | Description |
105|-----|------|---------|-------------|
106| `appearance.sans_font` | string | `"Fira Sans"` | Sans-serif font |
107| `appearance.serif_font` | string | `"Fira Sans"` | Serif font |
108| `appearance.monospace_font` | string | `"Fira Code"` | Monospace font |
109| `appearance.default_font_size` | int | `16` | Font size in points |
110| `appearance.color_scheme` | string | `"default"` | `prefer-dark`, `prefer-light`, `default` |
111
112### Color Palettes
113
114**Light palette:**
115```toml
116[appearance.light_palette]
117background = "#f8f8f8"
118surface = "#f2f2f2"
119surface_variant = "#ececec"
120text = "#1a1a1a"
121muted = "#6e6e6e"
122accent = "#404040"
123border = "#d2d2d2"
124```
125
126**Dark palette:**
127```toml
128[appearance.dark_palette]
129background = "#0e0e0e"
130surface = "#1a1a1a"
131surface_variant = "#141414"
132text = "#e4e4e4"
133muted = "#848484"
134accent = "#a8a8a8"
135border = "#363636"
136```
137
138## Video Acceleration
139
140| Key | Type | Default | Description |
141|-----|------|---------|-------------|
142| `video_acceleration.enable_vaapi` | bool | `true` | Enable VA-API hardware accel |
143| `video_acceleration.auto_detect_gpu` | bool | `true` | Auto-detect GPU driver |
144| `video_acceleration.vaapi_driver_name` | string | `""` | Driver name (auto-detected) |
145| `video_acceleration.enable_all_drivers` | bool | `true` | Enable all VA-API drivers |
146| `video_acceleration.legacy_vaapi` | bool | `false` | Legacy VA-API mode |
147
148## Codec Preferences
149
150| Key | Type | Default | Valid Values | Description |
151|-----|------|---------|--------------|-------------|
152| `codec_preferences.preferred_codecs` | string | `"av1,h264"` | Comma-separated | Codec priority order |
153| `codec_preferences.force_av1` | bool | `false` | - | Force AV1 codec |
154| `codec_preferences.block_vp9` | bool | `false` | - | Block VP9 codec |
155| `codec_preferences.block_vp8` | bool | `false` | - | Block VP8 codec |
156| `codec_preferences.av1_hardware_only` | bool | `false` | - | Disable AV1 software fallback |
157| `codec_preferences.disable_vp9_hardware` | bool | `false` | - | Disable VP9 hardware accel |
158| `codec_preferences.video_buffer_size_mb` | int | `64` | > 0 | Video buffer size in MB |
159| `codec_preferences.queue_buffer_time_sec` | int | `20` | > 0 | Queue buffer time in seconds |
160| `codec_preferences.custom_user_agent` | string | Chrome UA | any | Custom user agent string |
161| `codec_preferences.av1_max_resolution` | string | `"1080p"` | `720p`, `1080p`, `1440p`, `4k`, `unlimited` | Max AV1 resolution |
162| `codec_preferences.disable_twitch_codec_control` | bool | `true` | - | Disable codec control on Twitch |
163
164## Debug Options
165
166| Key | Type | Default | Description |
167|-----|------|---------|-------------|
168| `debug.enable_webkit_debug` | bool | `false` | Enable WebKit debug logs |
169| `debug.webkit_debug_categories` | string | `"Network:preconnectTo,ContentFilters"` | Debug categories |
170| `debug.enable_filtering_debug` | bool | `false` | Content filter debug |
171| `debug.enable_webview_debug` | bool | `false` | WebView state debug |
172| `debug.log_webkit_crashes` | bool | `true` | Log WebKit crashes |
173| `debug.enable_script_debug` | bool | `false` | Script injection debug |
174| `debug.enable_general_debug` | bool | `false` | General debug mode |
175| `debug.enable_workspace_debug` | bool | `false` | Workspace navigation debug |
176| `debug.enable_focus_debug` | bool | `false` | Focus state debug |
177| `debug.enable_css_debug` | bool | `false` | CSS reconciler debug |
178| `debug.enable_focus_metrics` | bool | `false` | Focus metrics tracking |
179| `debug.enable_pane_close_debug` | bool | `false` | Pane close debug |
180
181## Rendering & Zoom
182
183| Key | Type | Default | Valid Values | Description |
184|-----|------|---------|--------------|-------------|
185| `rendering_mode` | string | `"gpu"` | `auto`, `gpu`, `cpu` | Rendering mode |
186| `use_dom_zoom` | bool | `false` | - | Use DOM-based zoom |
187| `default_zoom` | float | `1.2` | > 0 | Default zoom level (120%) |
188
189## Workspace Configuration
190
191### Pane Mode
192
193| Key | Type | Default | Description |
194|-----|------|---------|-------------|
195| `workspace.pane_mode.activation_shortcut` | string | `"ctrl+p"` | Pane mode activation key |
196| `workspace.pane_mode.timeout_ms` | int | `3000` | Pane mode timeout (ms) |
197| `workspace.pane_mode.actions` | map | See below | Action→keys mappings |
198
199**Default pane mode actions:**
200```toml
201[workspace.pane_mode.actions]
202split-right = ["arrowright", "r"]
203split-left = ["arrowleft", "l"]
204split-up = ["arrowup", "u"]
205split-down = ["arrowdown", "d"]
206close-pane = ["x"]
207confirm = ["enter"]
208cancel = ["escape"]
209```
210
211> **Note:** Actions are inverted to key→action map in memory for O(1) lookup performance during navigation.
212
213### Tab Mode
214
215| Key | Type | Default | Description |
216|-----|------|---------|-------------|
217| `workspace.tab_mode.activation_shortcut` | string | `"ctrl+t"` | Tab mode activation key |
218| `workspace.tab_mode.timeout_ms` | int | `3000` | Tab mode timeout (ms) |
219| `workspace.tab_mode.actions` | map | See below | Action→keys mappings |
220
221**Default tab mode actions:**
222```toml
223[workspace.tab_mode.actions]
224new-tab = ["n", "c"]
225close-tab = ["x"]
226next-tab = ["l", "tab"]
227previous-tab = ["h", "shift+tab"]
228rename-tab = ["r"]
229confirm = ["enter"]
230cancel = ["escape"]
231```
232
233> **Note:** Actions are inverted to key→action map in memory for O(1) lookup performance during navigation.
234
235### Tab Shortcuts
236
237| Key | Type | Default | Description |
238|-----|------|---------|-------------|
239| `workspace.tabs.new_tab` | string | `"ctrl+t"` | New tab shortcut |
240| `workspace.tabs.close_tab` | string | `"ctrl+w"` | Close tab shortcut |
241| `workspace.tabs.next_tab` | string | `"ctrl+tab"` | Next tab shortcut |
242| `workspace.tabs.previous_tab` | string | `"ctrl+shift+tab"` | Previous tab shortcut |
243
244### Popup Behavior
245
246| Key | Type | Default | Valid Values | Description |
247|-----|------|---------|--------------|-------------|
248| `workspace.popups.behavior` | string | `"split"` | `split`, `stacked`, `tabbed`, `windowed` | Popup opening mode |
249| `workspace.popups.placement` | string | `"right"` | `right`, `left`, `top`, `bottom` | Split direction |
250| `workspace.popups.open_in_new_pane` | bool | `true` | - | Open popups in workspace |
251| `workspace.popups.follow_pane_context` | bool | `true` | - | Follow parent pane context |
252| `workspace.popups.blank_target_behavior` | string | `"pane"` | `pane`, `tab` | `_blank` target handling |
253| `workspace.popups.enable_smart_detection` | bool | `true` | - | Use WindowProperties for detection |
254| `workspace.popups.oauth_auto_close` | bool | `true` | - | Auto-close OAuth popups |
255
256### Workspace Styling
257
258| Key | Type | Default | Description |
259|-----|------|---------|-------------|
260| `workspace.styling.border_width` | int | `1` | Active pane border width (px) |
261| `workspace.styling.border_color` | string | `"@theme_selected_bg_color"` | Active pane border color |
262| `workspace.styling.inactive_border_width` | int | `1` | Inactive pane border width (px) |
263| `workspace.styling.inactive_border_color` | string | `"@theme_unfocused_bg_color"` | Inactive pane border color |
264| `workspace.styling.show_stacked_title_border` | bool | `false` | Show separator on stacked pane titles |
265| `workspace.styling.pane_mode_border_color` | string | `"#4A90E2"` | Pane mode border color (blue) |
266| `workspace.styling.tab_mode_border_color` | string | `"#FFA500"` | Tab mode border color (orange) |
267| `workspace.styling.transition_duration` | int | `120` | Border transition duration (ms) |
268| `workspace.styling.border_radius` | int | `0` | Border radius (px) |
269
270## Content Filtering
271
272| Key | Type | Default | Description |
273|-----|------|---------|-------------|
274| `content_filtering_whitelist` | array | See below | Domains to skip ad blocking |
275
276**Default whitelist:**
277```toml
278content_filtering_whitelist = [
279 "twitch.tv",
280 "passport.twitch.tv",
281 "gql.twitch.tv"
282]
283```
284
285## Environment Variables
286
287All config values can be overridden via environment variables with the prefix `DUMB_BROWSER_`:
288
289```bash
290# Database
291DUMB_BROWSER_DATABASE_PATH=/custom/path/db.sqlite
292
293# Rendering
294DUMBER_RENDERING_MODE=cpu
295DUMBER_DEFAULT_ZOOM=1.5
296
297# Video/Codec
298DUMBER_VIDEO_ACCELERATION_ENABLE=true
299LIBVA_DRIVER_NAME=iHD
300DUMBER_PREFERRED_CODECS=av1,vp9,h264
301```
302
303**Note:** Some video/codec env vars use `DUMBER_*` prefix and match GStreamer/VA-API conventions.