Dumber, fully unfeatured unbloated browser for tiling WMs
Dumber is a minimalist browser and launcher companion focused on speed and simplicity. It ships a built‑in WebKitGTK (GTK4) window for navigation and a CLI with dmenu‑style launcher integration (rofi, fuzzel).
- Native GUI via WebKitGTK 6 (GTK4, CGO) with an embedded homepage UI.
- CLI that parses URLs, supports search shortcuts (e.g.,
g:query), and integrates with rofi/dmenu.
- Persistent history and per‑domain zoom levels (SQLite, XDG locations).
- Configurable via
config.json and environment variables, with live reload.
Wayland‑First
- Dumb on purpose, designed for Wayland window managers (Sway, Hyprland, River, Niri, etc..) it's a tiny companion that interact nicely with your launcher.
- Uses a native Wayland WebKitGTK-6.0 window; no external browser required and no X11/XWayland dependency.
- Optimized for dmenu‑style launchers (rofi, fuzzel, wofi) and keyboard‑driven workflows.
Status
- Early development stage with regular releases. The workspace management system is fully functional and the browser works well for daily use. Expect some rough edges but core features are stable.
Features
- Complete workspace management: Zellij-inspired pane splitting with binary tree layout, stacked panes with title bars, focus tracking, and modal keyboard controls
- Multi-pane WebView architecture: Independent browsing sessions per pane with proper lifecycle management
- Advanced popup handling: Intelligent popup management for tiling WMs - OAuth flows, window.open(), and popup deduplication
- Window-level global shortcuts: Centralized shortcut handling to prevent conflicts between multiple WebView instances
- GPU rendering and hardware video acceleration: Automatic GPU detection with VA-API/VDPAU support
- Built-in ad blocker: UBlock-based content filtering (network blocking functional, cosmetic filtering in progress)
- Configurable color palettes: Customizable light and dark themes with semantic color tokens injected as CSS custom properties
- Terminal-style UI design: Monospace fonts, sharp corners, dashed borders with configurable appearance settings
- dmenu‑style launcher integration: rofi, fuzzel integration with favicon display, history and search shortcut suggestions
- Comprehensive keyboard controls: Complete keyboard-driven workflow with shortcuts and gestures
- Persistent history and zoom: SQLite-based history with configurable default zoom and per‑domain zoom persistence
- Fully configurable: Single config file with live reload and environment variable overrides
Controls & Shortcuts
Keyboard Shortcuts
Browser Controls
| Shortcut |
Action |
Notes |
| F12 |
Open Developer Tools |
WebKit inspector |
| Ctrl/Cmd+L |
Open Omnibox |
URL/search input with history |
| Ctrl/Cmd+F |
Find in Page |
Search text within current page |
| Ctrl/Cmd+= |
Zoom In |
Firefox-compatible zoom levels |
| Ctrl/Cmd++ |
Zoom In |
Alternative plus key |
| Ctrl/Cmd+- |
Zoom Out |
Works across keyboard layouts |
| Ctrl/Cmd+0 |
Reset Zoom |
Return to 100% zoom |
| Ctrl/Cmd+Shift+C |
Copy URL |
Copy current URL to clipboard with toast |
| Ctrl/Cmd+Shift+P |
Print Page |
Open native print dialog |
| Ctrl/Cmd+R / F5 |
Reload Page |
Refresh current page |
| Ctrl/Cmd+Shift+R |
Hard Reload |
Refresh ignoring cache |
| Ctrl+← / Ctrl+→ |
Navigate Back/Forward |
Browser history navigation |
Zellij-Inspired Pane Management
| Shortcut |
Action |
Notes |
| Ctrl/Cmd+P |
Enter Pane Mode |
Modal mode for pane operations |
| → / R (in pane mode) |
Split Right |
Create new pane to the right |
| ← / L (in pane mode) |
Split Left |
Create new pane to the left |
| ↑ / U (in pane mode) |
Split Up |
Create new pane above |
| ↓ / D (in pane mode) |
Split Down |
Create new pane below |
| S (in pane mode) |
Stack Pane |
Create stacked pane (Zellij-style) |
| X (in pane mode) |
Close Pane |
Close current pane |
| Enter (in pane mode) |
Confirm Action |
Confirm pane operation |
| Escape (in pane mode) |
Exit Pane Mode |
Return to normal navigation |
| Alt+Arrow Keys |
Navigate Panes |
Move focus between panes |
| Alt+Up/Down |
Navigate Stack |
Navigate between stacked panes |
Mouse Controls
| Action |
Result |
Notes |
| Ctrl+Scroll Up |
Zoom In |
Smooth zoom control |
| Ctrl+Scroll Down |
Zoom Out |
Smooth zoom control |
| Mouse Button 8 |
Navigate Back |
Side button (back) |
| Mouse Button 9 |
Navigate Forward |
Side button (forward) |
| Two-finger Swipe |
Back/Forward |
When supported by touchpad |
Omnibox/Find Mode (when active)
| Shortcut |
Action |
Notes |
| Escape |
Close overlay |
Exit omnibox or find mode |
| Enter |
Execute/Navigate |
Navigate to URL or jump to match |
| Shift+Enter |
Previous Match |
Find mode: go to previous match |
| Alt+Enter |
Center Match |
Find mode: center on match, keep open |
| ↑/↓ Arrow |
Navigate Results |
Browse suggestions/matches |
All zoom changes are automatically persisted per-domain and restored on next visit.
Quick Start
Prerequisites:
- Go 1.25+
- Node.js 20+ and npm (for building the embedded TypeScript frontend)
- For GUI build: WebKitGTK 6 and GTK4 dev packages (examples)
- Debian/Ubuntu:
libwebkitgtk-6.0-dev libgtk-4-dev build-essential
- Arch:
webkitgtk-6.0 gtk4 base-devel
Build options:
- GUI (default, recommended):
make build # builds frontend + Go with -tags=webkit_cgo
- Run:
./dist/dumber # opens the embedded homepage
- CLI‑only (no GUI, CGO disabled):
make build-no-gui
- Run:
./dist/dumber-no-gui version
Development:
make dev runs go run . (non‑CGO; GUI stubs log to console)
make test runs tests; make lint runs golangci‑lint
Install
Note: go install will not work for this project because the frontend assets must be built first and embedded into the binary. Use the build commands instead:
- GUI build (default, recommended):
- Ensure WebKit2GTK/GTK dev packages are installed (see prerequisites)
- Clone the repo and run
make build (builds frontend first, then Go with GUI support)
- The resulting
./dist/dumber binary includes the native GUI window
- CLI‑only (no native window):
- Clone the repo and run
make build-no-gui
- The resulting
./dist/dumber-no-gui binary runs CLI flows with GUI code stubbed
Usage
- Open a URL or search:
dumber browse https://example.com
dumber browse example.com # scheme auto‑added
dumber browse g:golang # Google search via shortcut
- Launch the GUI directly:
dumber # no args → opens GUI homepage
- Show version information:
dumber version # display version, commit, and build date
- Launcher integration (dmenu‑style examples):
- rofi:
dumber dmenu | rofi -dmenu -p "Browse: " | dumber dmenu --select
- fuzzel:
dumber dmenu | fuzzel --dmenu -p "Browse: " | dumber dmenu --select
- Manage browsing history:
dumber history # list recent history (default: 20 entries)
dumber history list -n 50 # list 50 recent entries
dumber history search golang # search history for "golang"
dumber history stats # show history statistics
dumber history clear # clear all history (with confirmation)
dumber history clear --force # clear all history (no confirmation)
- Clean up data and cache:
dumber purge # purge all data (with confirmation)
dumber purge --force # purge all data (no confirmation)
dumber purge -d -H -c # purge database and both caches
dumber purge --browser-data # purge WebKit data (cookies, etc.)
- Manage logs:
dumber logs list # list available log files
dumber logs tail # tail current log file
dumber logs clean # clean up old log files
You can invoke dmenu mode in two ways:
- Subcommand (recommended):
dumber dmenu … and dumber dmenu --select
- Root flag (generate options only):
dumber --dmenu
Note: The root flag path only generates options; for processing a selection (--select), use the dmenu subcommand as the receiving command.
In GUI mode the app serves an embedded homepage via dumb://homepage, and frontend assets under dumb://app/....
Pane Management (Zellij-Inspired)
Dumber features a Zellij-inspired pane management system that allows you to split your browser window into multiple panes, each running independent web sessions.
How it Works
- Enter Pane Mode: Press
Ctrl+P to enter pane mode (modal interface with timeout)
- Split or Stack Panes: Use arrow keys or letter shortcuts:
→ or R - Split right
← or L - Split left
↑ or U - Split up
↓ or D - Split down
S - Stack panes (Zellij-style, shows title bars for collapsed panes)
- Navigate: Use
Alt+Arrow Keys to move focus between split panes, or Alt+Up/Down to navigate within stacked panes
- Close: Press
X in pane mode to close the current pane
Configuration
The pane system is fully configurable via config.json:
"workspace": {
"enable_zellij_controls": true,
"pane_mode": {
"activation_shortcut": "cmdorctrl+p",
"timeout_ms": 3000,
"action_bindings": {
"arrowright": "split-right",
"r": "split-right",
"x": "close-pane",
// ... full key mappings
}
},
"popups": {
"placement": "right",
"open_in_new_pane": true
},
"styling": {
"border_width": 2,
"border_color": "@theme_selected_bg_color",
"transition_duration": 120
}
}
Configuration
Dumber follows the XDG Base Directory spec:
- Config:
~/.config/dumber/config.json
- Data:
~/.local/share/dumber
- State:
~/.local/state/dumber (default DB lives here)
A default config.json is created on first run. Config changes are watched and applied at runtime when possible.
Complete Configuration Reference
Database Configuration
"database": {
"path": "~/.local/state/dumber/history.db",
"max_connections": 1,
"max_idle_time": "5m0s",
"query_timeout": "30s"
}
History Management
"history": {
"max_entries": 10000,
"retention_period_days": 365,
"cleanup_interval_days": 1
}
Search Shortcuts
"search_shortcuts": {
"g": { "url": "https://www.google.com/search?q=%s", "description": "Google search" },
"gh": { "url": "https://github.com/search?q=%s", "description": "GitHub search" },
"yt": { "url": "https://www.youtube.com/results?search_query=%s", "description": "YouTube search" },
"w": { "url": "https://en.wikipedia.org/wiki/%s", "description": "Wikipedia search" },
"ddg": { "url": "https://duckduckgo.com/?q=%s", "description": "DuckDuckGo search" },
"so": { "url": "https://stackoverflow.com/search?q=%s", "description": "Stack Overflow search" },
"r": { "url": "https://www.reddit.com/search?q=%s", "description": "Reddit search" },
"npm": { "url": "https://www.npmjs.com/search?q=%s", "description": "npm package search" },
"go": { "url": "https://pkg.go.dev/search?q=%s", "description": "Go package search" },
"mdn": { "url": "https://developer.mozilla.org/en-US/search?q=%s", "description": "MDN Web Docs search" }
}
"dmenu": {
"max_history_items": 20,
"show_visit_count": true,
"show_last_visited": true,
"history_prefix": "🕒",
"shortcut_prefix": "🔍",
"url_prefix": "🌐",
"date_format": "2006-01-02 15:04",
"sort_by_visit_count": true
}
Logging Configuration
"logging": {
"level": "info",
"format": "text",
"filename": "",
"max_size": 100,
"max_backups": 3,
"max_age": 7,
"compress": true
}
Appearance Settings
"appearance": {
"sans_font": "Fira Sans",
"serif_font": "Fira Sans",
"monospace_font": "Fira Code",
"default_font_size": 16,
"default_zoom": 1.2,
"color_palette": {
"light": {
"background": "#ffffff",
"surface": "#f5f5f5",
"text": "#1a1a1a",
"text_muted": "#6b7280",
"accent": "#3b82f6",
"border": "#e5e7eb"
},
"dark": {
"background": "#0a0a0a",
"surface": "#1a1a1a",
"text": "#e5e7eb",
"text_muted": "#9ca3af",
"accent": "#60a5fa",
"border": "#374151"
}
}
}
Rendering Mode (GPU/CPU)
"rendering_mode": "auto"
auto: Detect GPU availability and use GPU when available (default)
gpu: Force GPU acceleration (Vulkan/OpenGL via GTK4)
cpu: Force software rendering
Environment Variables
All config values can be overridden with environment variables using the DUMB_BROWSER_ prefix:
# Database
DUMB_BROWSER_DATABASE_PATH="./browser.db"
DUMB_BROWSER_DATABASE_MAX_CONNECTIONS=5
# Rendering mode (special variable name)
DUMBER_RENDERING_MODE="gpu"
# Dmenu settings
DUMB_BROWSER_DMENU_MAX_HISTORY_ITEMS=50
DUMB_BROWSER_DMENU_SHOW_VISIT_COUNT=false
# Logging
DUMB_BROWSER_LOGGING_LEVEL="debug"
DUMB_BROWSER_LOGGING_FORMAT="json"
CLI Flags
The browse command supports additional runtime flags:
dumber browse --rendering-mode=gpu https://example.com
Building With WebKitGTK 6 (GTK4)
- The GUI requires building with
-tags=webkit_cgo and CGO enabled.
- Ensure WebKitGTK 6 and GTK4 dev headers are installed (see prerequisites).
- Make targets handle both frontend and Go build steps:
make build-gui (CGO enabled)
make build (CGO enabled by default in the Makefile’s main build)
Without the native tag, a stub backend is used: you can still run CLI flows and see logs, but no native window is displayed.
WebKitGTK uses GStreamer for media playback. Dumber includes automatic hardware video acceleration support that detects your GPU and configures the appropriate drivers.
Hardware Acceleration Features:
- Automatic GPU detection (AMD, NVIDIA, Intel)
- VA-API and VDPAU driver configuration
- Support for H.264, HEVC, VP9, and AV1 codecs
- Significantly reduced CPU usage during video streaming
Required packages:
- Arch Linux:
sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse
- Hardware accel:
gstreamer-vaapi mesa (AMD), libva-nvidia-driver (NVIDIA), libva-intel-driver intel-media-driver (Intel)
- Debian/Ubuntu:
sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-pipewire
- Hardware accel:
gstreamer1.0-vaapi va-driver-all (covers most GPUs)
Contribute
I will gladly accept contributions, especially related to UI/UX enhancements. Feel free to open an issue and let's discuss it!
Security & Privacy
- History and zoom settings are stored locally in SQLite under XDG state.
- The
tmp/ directory is ignored by Git and kept out of history.
Roadmap
- ✅ WebKitGTK 6 (GTK4) migration (GPU/Vulkan path complete)
- ✅ GPU rendering (Vulkan via GTK4 renderer) with graceful CPU fallback
- ✅ Zellij-inspired pane management with binary tree layout and keyboard-driven workflow
- 🚧 UBlock-based content filtering (early stage - network blocking works, cosmetic filtering needs work)
- Full Vim-style motion and keyboard navigation across pages and UI
- Tab management system (browser tabs in addition to panes)
- Performance work: faster startup, lower memory, snappier UI
- Other shiny things I'm not yet aware of
License
This project is licensed under the MIT License. See LICENSE for details.
source
1# Dumber, fully unfeatured unbloated browser for tiling WMs
2
3<p align="center">
4 <img src="assets/logo.svg" alt="Dumber Logo" width="256" height="256" />
5</p>
6
7Dumber is a minimalist browser and launcher companion focused on speed and simplicity. It ships a built‑in WebKitGTK (GTK4) window for navigation and a CLI with dmenu‑style launcher integration (rofi, fuzzel).
8
9- Native GUI via WebKitGTK 6 (GTK4, CGO) with an embedded homepage UI.
10- CLI that parses URLs, supports search shortcuts (e.g., `g:query`), and integrates with rofi/dmenu.
11- Persistent history and per‑domain zoom levels (SQLite, XDG locations).
12- Configurable via `config.json` and environment variables, with live reload.
13
14## Wayland‑First
15- Dumb on purpose, designed for Wayland window managers (Sway, Hyprland, River, Niri, etc..) it's a tiny companion that interact nicely with your launcher.
16- Uses a native Wayland WebKitGTK-6.0 window; no external browser required and no X11/XWayland dependency.
17- Optimized for dmenu‑style launchers (rofi, fuzzel, wofi) and keyboard‑driven workflows.
18
19## Status
20- Early development stage with regular releases. The workspace management system is fully functional and the browser works well for daily use. Expect some rough edges but core features are stable.
21
22## Features
23- **Complete workspace management**: Zellij-inspired pane splitting with binary tree layout, stacked panes with title bars, focus tracking, and modal keyboard controls
24- **Multi-pane WebView architecture**: Independent browsing sessions per pane with proper lifecycle management
25- **Advanced popup handling**: Intelligent popup management for tiling WMs - OAuth flows, window.open(), and popup deduplication
26- **Window-level global shortcuts**: Centralized shortcut handling to prevent conflicts between multiple WebView instances
27- **GPU rendering and hardware video acceleration**: Automatic GPU detection with VA-API/VDPAU support
28- **Built-in ad blocker**: UBlock-based content filtering (network blocking functional, cosmetic filtering in progress)
29- **Configurable color palettes**: Customizable light and dark themes with semantic color tokens injected as CSS custom properties
30- **Terminal-style UI design**: Monospace fonts, sharp corners, dashed borders with configurable appearance settings
31- **dmenu‑style launcher integration**: rofi, fuzzel integration with favicon display, history and search shortcut suggestions
32- **Comprehensive keyboard controls**: Complete keyboard-driven workflow with shortcuts and gestures
33- **Persistent history and zoom**: SQLite-based history with configurable default zoom and per‑domain zoom persistence
34- **Fully configurable**: Single config file with live reload and environment variable overrides
35
36## Controls & Shortcuts
37
38### Keyboard Shortcuts
39
40#### Browser Controls
41| Shortcut | Action | Notes |
42|----------|--------|-------|
43| **F12** | Open Developer Tools | WebKit inspector |
44| **Ctrl/Cmd+L** | Open Omnibox | URL/search input with history |
45| **Ctrl/Cmd+F** | Find in Page | Search text within current page |
46| **Ctrl/Cmd+=** | Zoom In | Firefox-compatible zoom levels |
47| **Ctrl/Cmd++** | Zoom In | Alternative plus key |
48| **Ctrl/Cmd+-** | Zoom Out | Works across keyboard layouts |
49| **Ctrl/Cmd+0** | Reset Zoom | Return to 100% zoom |
50| **Ctrl/Cmd+Shift+C** | Copy URL | Copy current URL to clipboard with toast |
51| **Ctrl/Cmd+Shift+P** | Print Page | Open native print dialog |
52| **Ctrl/Cmd+R** / **F5** | Reload Page | Refresh current page |
53| **Ctrl/Cmd+Shift+R** | Hard Reload | Refresh ignoring cache |
54| **Ctrl+←** / **Ctrl+→** | Navigate Back/Forward | Browser history navigation |
55
56#### Zellij-Inspired Pane Management
57| Shortcut | Action | Notes |
58|----------|--------|-------|
59| **Ctrl/Cmd+P** | Enter Pane Mode | Modal mode for pane operations |
60| **→** / **R** (in pane mode) | Split Right | Create new pane to the right |
61| **←** / **L** (in pane mode) | Split Left | Create new pane to the left |
62| **↑** / **U** (in pane mode) | Split Up | Create new pane above |
63| **↓** / **D** (in pane mode) | Split Down | Create new pane below |
64| **S** (in pane mode) | Stack Pane | Create stacked pane (Zellij-style) |
65| **X** (in pane mode) | Close Pane | Close current pane |
66| **Enter** (in pane mode) | Confirm Action | Confirm pane operation |
67| **Escape** (in pane mode) | Exit Pane Mode | Return to normal navigation |
68| **Alt+Arrow Keys** | Navigate Panes | Move focus between panes |
69| **Alt+Up/Down** | Navigate Stack | Navigate between stacked panes |
70
71### Mouse Controls
72| Action | Result | Notes |
73|--------|---------|-------|
74| **Ctrl+Scroll Up** | Zoom In | Smooth zoom control |
75| **Ctrl+Scroll Down** | Zoom Out | Smooth zoom control |
76| **Mouse Button 8** | Navigate Back | Side button (back) |
77| **Mouse Button 9** | Navigate Forward | Side button (forward) |
78| **Two-finger Swipe** | Back/Forward | When supported by touchpad |
79
80### Omnibox/Find Mode (when active)
81| Shortcut | Action | Notes |
82|----------|--------|-------|
83| **Escape** | Close overlay | Exit omnibox or find mode |
84| **Enter** | Execute/Navigate | Navigate to URL or jump to match |
85| **Shift+Enter** | Previous Match | Find mode: go to previous match |
86| **Alt+Enter** | Center Match | Find mode: center on match, keep open |
87| **↑/↓ Arrow** | Navigate Results | Browse suggestions/matches |
88
89All zoom changes are automatically persisted per-domain and restored on next visit.
90
91## Quick Start
92Prerequisites:
93- Go 1.25+
94- Node.js 20+ and npm (for building the embedded TypeScript frontend)
95- For GUI build: WebKitGTK 6 and GTK4 dev packages (examples)
96 - Debian/Ubuntu: `libwebkitgtk-6.0-dev libgtk-4-dev build-essential`
97 - Arch: `webkitgtk-6.0 gtk4 base-devel`
98
99Build options:
100- GUI (default, recommended):
101 - `make build` # builds frontend + Go with `-tags=webkit_cgo`
102 - Run: `./dist/dumber` # opens the embedded homepage
103- CLI‑only (no GUI, CGO disabled):
104 - `make build-no-gui`
105 - Run: `./dist/dumber-no-gui version`
106
107Development:
108- `make dev` runs `go run .` (non‑CGO; GUI stubs log to console)
109- `make test` runs tests; `make lint` runs golangci‑lint
110
111## Install
112**Note**: `go install` will not work for this project because the frontend assets must be built first and embedded into the binary. Use the build commands instead:
113
114- GUI build (default, recommended):
115 - Ensure WebKit2GTK/GTK dev packages are installed (see prerequisites)
116 - Clone the repo and run `make build` (builds frontend first, then Go with GUI support)
117 - The resulting `./dist/dumber` binary includes the native GUI window
118- CLI‑only (no native window):
119 - Clone the repo and run `make build-no-gui`
120 - The resulting `./dist/dumber-no-gui` binary runs CLI flows with GUI code stubbed
121
122## Usage
123- Open a URL or search:
124 - `dumber browse https://example.com`
125 - `dumber browse example.com` # scheme auto‑added
126 - `dumber browse g:golang` # Google search via shortcut
127- Launch the GUI directly:
128 - `dumber` # no args → opens GUI homepage
129- Show version information:
130 - `dumber version` # display version, commit, and build date
131- Launcher integration (dmenu‑style examples):
132 - rofi: `dumber dmenu | rofi -dmenu -p "Browse: " | dumber dmenu --select`
133 - fuzzel: `dumber dmenu | fuzzel --dmenu -p "Browse: " | dumber dmenu --select`
134- Manage browsing history:
135 - `dumber history` # list recent history (default: 20 entries)
136 - `dumber history list -n 50` # list 50 recent entries
137 - `dumber history search golang` # search history for "golang"
138 - `dumber history stats` # show history statistics
139 - `dumber history clear` # clear all history (with confirmation)
140 - `dumber history clear --force` # clear all history (no confirmation)
141- Clean up data and cache:
142 - `dumber purge` # purge all data (with confirmation)
143 - `dumber purge --force` # purge all data (no confirmation)
144 - `dumber purge -d -H -c` # purge database and both caches
145 - `dumber purge --browser-data` # purge WebKit data (cookies, etc.)
146- Manage logs:
147 - `dumber logs list` # list available log files
148 - `dumber logs tail` # tail current log file
149 - `dumber logs clean` # clean up old log files
150
151### Dmenu mode invocation
152You can invoke dmenu mode in two ways:
153- Subcommand (recommended): `dumber dmenu` … and `dumber dmenu --select`
154- Root flag (generate options only): `dumber --dmenu`
155
156Note: The root flag path only generates options; for processing a selection (`--select`), use the `dmenu` subcommand as the receiving command.
157
158In GUI mode the app serves an embedded homepage via `dumb://homepage`, and frontend assets under `dumb://app/...`.
159
160## Pane Management (Zellij-Inspired)
161
162Dumber features a Zellij-inspired pane management system that allows you to split your browser window into multiple panes, each running independent web sessions.
163
164### How it Works
1651. **Enter Pane Mode**: Press `Ctrl+P` to enter pane mode (modal interface with timeout)
1662. **Split or Stack Panes**: Use arrow keys or letter shortcuts:
167 - `→` or `R` - Split right
168 - `←` or `L` - Split left
169 - `↑` or `U` - Split up
170 - `↓` or `D` - Split down
171 - `S` - Stack panes (Zellij-style, shows title bars for collapsed panes)
1723. **Navigate**: Use `Alt+Arrow Keys` to move focus between split panes, or `Alt+Up/Down` to navigate within stacked panes
1734. **Close**: Press `X` in pane mode to close the current pane
174
175### Configuration
176The pane system is fully configurable via `config.json`:
177```json
178"workspace": {
179 "enable_zellij_controls": true,
180 "pane_mode": {
181 "activation_shortcut": "cmdorctrl+p",
182 "timeout_ms": 3000,
183 "action_bindings": {
184 "arrowright": "split-right",
185 "r": "split-right",
186 "x": "close-pane",
187 // ... full key mappings
188 }
189 },
190 "popups": {
191 "placement": "right",
192 "open_in_new_pane": true
193 },
194 "styling": {
195 "border_width": 2,
196 "border_color": "@theme_selected_bg_color",
197 "transition_duration": 120
198 }
199}
200```
201
202## Configuration
203
204Dumber follows the XDG Base Directory spec:
205- Config: `~/.config/dumber/config.json`
206- Data: `~/.local/share/dumber`
207- State: `~/.local/state/dumber` (default DB lives here)
208
209A default `config.json` is created on first run. Config changes are watched and applied at runtime when possible.
210
211### Complete Configuration Reference
212
213#### Database Configuration
214```json
215"database": {
216 "path": "~/.local/state/dumber/history.db",
217 "max_connections": 1,
218 "max_idle_time": "5m0s",
219 "query_timeout": "30s"
220}
221```
222
223#### History Management
224```json
225"history": {
226 "max_entries": 10000,
227 "retention_period_days": 365,
228 "cleanup_interval_days": 1
229}
230```
231
232#### Search Shortcuts
233```json
234"search_shortcuts": {
235 "g": { "url": "https://www.google.com/search?q=%s", "description": "Google search" },
236 "gh": { "url": "https://github.com/search?q=%s", "description": "GitHub search" },
237 "yt": { "url": "https://www.youtube.com/results?search_query=%s", "description": "YouTube search" },
238 "w": { "url": "https://en.wikipedia.org/wiki/%s", "description": "Wikipedia search" },
239 "ddg": { "url": "https://duckduckgo.com/?q=%s", "description": "DuckDuckGo search" },
240 "so": { "url": "https://stackoverflow.com/search?q=%s", "description": "Stack Overflow search" },
241 "r": { "url": "https://www.reddit.com/search?q=%s", "description": "Reddit search" },
242 "npm": { "url": "https://www.npmjs.com/search?q=%s", "description": "npm package search" },
243 "go": { "url": "https://pkg.go.dev/search?q=%s", "description": "Go package search" },
244 "mdn": { "url": "https://developer.mozilla.org/en-US/search?q=%s", "description": "MDN Web Docs search" }
245}
246```
247
248#### Dmenu Integration
249```json
250"dmenu": {
251 "max_history_items": 20,
252 "show_visit_count": true,
253 "show_last_visited": true,
254 "history_prefix": "🕒",
255 "shortcut_prefix": "🔍",
256 "url_prefix": "🌐",
257 "date_format": "2006-01-02 15:04",
258 "sort_by_visit_count": true
259}
260```
261
262#### Logging Configuration
263```json
264"logging": {
265 "level": "info",
266 "format": "text",
267 "filename": "",
268 "max_size": 100,
269 "max_backups": 3,
270 "max_age": 7,
271 "compress": true
272}
273```
274
275#### Appearance Settings
276```json
277"appearance": {
278 "sans_font": "Fira Sans",
279 "serif_font": "Fira Sans",
280 "monospace_font": "Fira Code",
281 "default_font_size": 16,
282 "default_zoom": 1.2,
283 "color_palette": {
284 "light": {
285 "background": "#ffffff",
286 "surface": "#f5f5f5",
287 "text": "#1a1a1a",
288 "text_muted": "#6b7280",
289 "accent": "#3b82f6",
290 "border": "#e5e7eb"
291 },
292 "dark": {
293 "background": "#0a0a0a",
294 "surface": "#1a1a1a",
295 "text": "#e5e7eb",
296 "text_muted": "#9ca3af",
297 "accent": "#60a5fa",
298 "border": "#374151"
299 }
300 }
301}
302```
303
304#### Rendering Mode (GPU/CPU)
305```json
306"rendering_mode": "auto"
307```
308- `auto`: Detect GPU availability and use GPU when available (default)
309- `gpu`: Force GPU acceleration (Vulkan/OpenGL via GTK4)
310- `cpu`: Force software rendering
311
312### Environment Variables
313All config values can be overridden with environment variables using the `DUMB_BROWSER_` prefix:
314
315```bash
316# Database
317DUMB_BROWSER_DATABASE_PATH="./browser.db"
318DUMB_BROWSER_DATABASE_MAX_CONNECTIONS=5
319
320# Rendering mode (special variable name)
321DUMBER_RENDERING_MODE="gpu"
322
323# Dmenu settings
324DUMB_BROWSER_DMENU_MAX_HISTORY_ITEMS=50
325DUMB_BROWSER_DMENU_SHOW_VISIT_COUNT=false
326
327# Logging
328DUMB_BROWSER_LOGGING_LEVEL="debug"
329DUMB_BROWSER_LOGGING_FORMAT="json"
330```
331
332### CLI Flags
333The browse command supports additional runtime flags:
334```bash
335dumber browse --rendering-mode=gpu https://example.com
336```
337
338
339## Building With WebKitGTK 6 (GTK4)
340- The GUI requires building with `-tags=webkit_cgo` and CGO enabled.
341- Ensure WebKitGTK 6 and GTK4 dev headers are installed (see prerequisites).
342- Make targets handle both frontend and Go build steps:
343 - `make build-gui` (CGO enabled)
344 - `make build` (CGO enabled by default in the Makefile’s main build)
345
346Without the native tag, a stub backend is used: you can still run CLI flows and see logs, but no native window is displayed.
347
348## Media (GStreamer) & Hardware Acceleration
349
350WebKitGTK uses GStreamer for media playback. Dumber includes automatic hardware video acceleration support that detects your GPU and configures the appropriate drivers.
351
352**Hardware Acceleration Features:**
353- Automatic GPU detection (AMD, NVIDIA, Intel)
354- VA-API and VDPAU driver configuration
355- Support for H.264, HEVC, VP9, and AV1 codecs
356- Significantly reduced CPU usage during video streaming
357
358**Required packages:**
359- Arch Linux:
360 - `sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse`
361 - Hardware accel: `gstreamer-vaapi mesa` (AMD), `libva-nvidia-driver` (NVIDIA), `libva-intel-driver intel-media-driver` (Intel)
362- Debian/Ubuntu:
363 - `sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-pipewire`
364 - Hardware accel: `gstreamer1.0-vaapi va-driver-all` (covers most GPUs)
365
366## Contribute
367I will gladly accept contributions, especially related to UI/UX enhancements. Feel free to open an issue and let's discuss it!
368
369## Security & Privacy
370- History and zoom settings are stored locally in SQLite under XDG state.
371- The `tmp/` directory is ignored by Git and kept out of history.
372
373## Roadmap
374- ✅ WebKitGTK 6 (GTK4) migration (GPU/Vulkan path complete)
375- ✅ GPU rendering (Vulkan via GTK4 renderer) with graceful CPU fallback
376- ✅ Zellij-inspired pane management with binary tree layout and keyboard-driven workflow
377- 🚧 UBlock-based content filtering (early stage - network blocking works, cosmetic filtering needs work)
378- Full Vim-style motion and keyboard navigation across pages and UI
379- Tab management system (browser tabs in addition to panes)
380- Performance work: faster startup, lower memory, snappier UI
381- Other shiny things I'm not yet aware of
382
383## License
384This project is licensed under the MIT License. See `LICENSE` for details.