v0.9.0 636c44c

README.md RawHistoryFolder

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

  • Very early stage, expect sharp edges and breaking changes, but it works well enough to browse and play with the launcher flows and the pane management system.

Features

  • Zellij-inspired pane management: Split browser into multiple panes with keyboard shortcuts (Ctrl+P to enter pane mode)
  • GPU Rendering and Hardware video acceleration
  • Built-in ad blocker (UBlock-based, work in progress)
  • dmenu‑style launcher integration (rofi, fuzzel) with history and shortcut suggestions
  • Keyboard and mouse controls: comprehensive shortcuts and gestures
  • Persistent history with search and stats
  • Per‑domain zoom persistence
  • One config file, fully customizable

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+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
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

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

Dmenu mode invocation

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

  1. Enter Pane Mode: Press Ctrl+P to enter pane mode (modal interface with timeout)
  2. Split Panes: Use arrow keys or letter shortcuts to split:
    • → or R - Split right
    • ← or L - Split left
    • ↑ or U - Split up
    • ↓ or D - Split down
  3. Navigate: Use Alt+Arrow Keys to move focus between panes
  4. Close: Press X in pane mode to close the current pane

Features

  • Binary tree layout: Panes are organized in a binary tree structure for optimal space usage
  • Focus management: Visual borders and hover-to-focus for intuitive navigation
  • Independent sessions: Each pane maintains its own browsing session, history, and zoom level
  • Popup handling: Configurable popup placement (new pane, same pane, etc.)
  • Keyboard-driven: All operations accessible via keyboard shortcuts

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 Integration

"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
}

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.

Media (GStreamer) & Hardware Acceleration

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 libva-mesa-driver (AMD), libva-vdpau-driver (NVIDIA), 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)

Theme and Runtime Updates

  • The homepage and pages respect your system’s light/dark preference.
  • The app updates color‑scheme live when your GTK theme changes (no relaunch needed).

Project Structure

  • main.go: Entry point with CLI/GUI routing
  • internal/app/cli: CLI application logic and Cobra commands
  • internal/app/browser: Browser application logic and WebKit integration
  • internal/cli: Cobra commands (browse, dmenu, version)
  • internal/config: Viper‑backed config, XDG helpers, defaults
  • internal/db: SQLite schema init and sqlc‑generated queries
  • internal/logging: Structured logging system with file rotation
  • services: Application services (parser/history/config/browser)
  • pkg/webkit: WebKit2GTK bindings (CGO and stub implementations)
  • pkg/clipboard: Cross-platform clipboard operations
  • frontend: TypeScript homepage UI bundled into the binary

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

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