detached 4015f5d

Merge pull request #146 from bnema/feat/install-script

feat: add install script and restructure documentation
commit
4015f5d6b24746f9474d0a9ddfb61f97ac015235
author
bnema · · 2026-01-24 20:14 UTC
committer
GitHub · · 2026-01-24 20:14 UTC
merge of
ae3a77a + e644af2 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
14 files · +917 -456
M README.md +64 -365
@@ -1,355 +1,88 @@
1-# Dumber, fully unfeatured unbloated browser for tiling WMs
1+# Dumber
22
3-<p align="center">
4- <img src="assets/logo.svg" alt="Dumber Logo" width="256" height="256" />
5-</p>
3+[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
64
5+A TTY-inspired browser multiplexer for tiling window managers.
76
8-https://github.com/user-attachments/assets/394f5f7e-a475-42da-b483-5a58b2ea2f51
7+- Website: [dumber.bnema.dev](https://dumber.bnema.dev)
8+- Documentation: [dumber.bnema.dev/docs](https://dumber.bnema.dev/docs)
99
10+---
1011
12+## What is Dumber?
1113
12-A dumb browser that works like your favorite terminal multiplexer.
14+Dumber is a Wayland-native browser that works like your terminal multiplexer. Tabs hold workspaces. Workspaces hold panes. Panes split and stack like Zellij. Everything is keyboard-driven.
1315
14-## Features
15-- **Wayland native**: No X11/XWayland dependency, works with Sway, Hyprland, River, Niri, etc.
16-- **Tabs and workspaces**: Each tab holds a workspace with split or stacked panes.
17-- **Keyboard-driven**: Keyboard workflow inspired by Zellij.
18-- **Smart popup handling**: OAuth flows, window.open(), and popup deduplication for tiling WMs.
19-- **GPU rendering**: Hardware video acceleration with automatic VA-API/VDPAU detection.
20-- **Built-in ad blocking**: UBlock-based network + cosmetic filtering.
21-- **Launcher integration**: dmenu-style with rofi/fuzzel support, shows favicons and history.
22-- **Search shortcuts**: Quick search via bangs (e.g., `!g golang` for Google, `!gi cats` for Google Images).
23-- **Customizable themes**: Light and dark palettes with semantic color tokens.
24-- **Persistent storage**: SQLite for history, favorites, per-domain zoom levels, and sessions.
25-- **Live configuration**: Single config file with hot reload when possible.
26-- **Session management**: Zellij-style session save/restore with automatic snapshots and resurrection.
16+No bloat. No Chrome. No Electron.
2717
28-## Status
29-Dumber is almost feature-complete. Next steps will focus on stability, performance, and bug fixing.
18+**Features:**
19+- Zellij-style panes with modal keyboard navigation
20+- Wayland native (Sway, Hyprland, River, Niri)
21+- Session resurrection with auto-snapshots
22+- Built-in ad blocking (UBlock-based)
23+- GPU accelerated video (VA-API/VDPAU)
24+- Launcher integration (rofi/fuzzel/dmenu)
25+- Search bangs (!g, !gi, !ddg)
26+- Single config.toml with hot reload
3027
31-Core features work well for daily use but expect some rough edges. Some features are still alpha/experimental (notably consume-or-expel panes) and may change behavior between releases.
28+## Documentation
29+
30+Full documentation is available at **[dumber.bnema.dev](https://dumber.bnema.dev)**
31+
32+- [Documentation](https://dumber.bnema.dev/docs) - Installation, configuration, CLI reference
33+- [Keybindings](https://dumber.bnema.dev/docs/reference/keybindings) - Keyboard shortcuts
3234
3335 ## Quick Start
3436
3537 ```bash
36-# Download and install
37-wget https://github.com/bnema/dumber/releases/latest/download/dumber_linux_x86_64.tar.gz
38-tar -xzf dumber_linux_x86_64.tar.gz
39-mkdir -p ~/.local/bin && install -m 755 dumber_*/dumber ~/.local/bin/
38+# Install
39+curl -fsSL https://dumber.bnema.dev/install | sh
4040
41-# Run
42-dumber browse https://example.com
41+# Launch
42+dumber browse
4343 ```
4444
45-See [Install](#install) for AUR, Flatpak, building from source, and runtime dependencies.
46-
47-## Controls & Shortcuts
48-
49-### Keyboard Shortcuts
50-
51-#### Browser Controls
52-| Shortcut | Action | Notes |
53-|----------|--------|-------|
54-| **F12** | Open Developer Tools | WebKit inspector |
55-| **Ctrl+L** | Open Omnibox | URL/search input with history |
56-| **Ctrl+F** | Find in Page | Search text within current page |
57-| **Ctrl+=** | Zoom In | Firefox-compatible zoom levels |
58-| **Ctrl++** | Zoom In | Alternative plus key |
59-| **Ctrl+-** | Zoom Out | Works across keyboard layouts |
60-| **Ctrl+0** | Reset Zoom | Return to 100% zoom |
61-| **Ctrl+Shift+C** | Copy URL | Copy current URL to clipboard with toast |
62-| **Ctrl+Shift+P** | Print Page | Open native print dialog |
63-| **Ctrl+R** / **F5** | Reload Page | Refresh current page |
64-| **Ctrl+Shift+R** | Hard Reload | Refresh ignoring cache |
65-| **Ctrl+←** / **Ctrl+→** | Navigate Back/Forward | Browser history navigation |
66-
67-#### Tab Management
68-| Shortcut | Action | Notes |
69-|----------|--------|-------|
70-| **Ctrl+T** | Enter Tab Mode | Modal mode for tab operations |
71-| **Ctrl+Tab** | Next Tab | Quick tab switching |
72-| **Ctrl+Shift+Tab** | Previous Tab | Quick tab switching |
73-| **Ctrl+W** | Close Tab | Close current tab |
74-| **N** / **C** (in tab mode) | New Tab | Create new tab |
75-| **X** (in tab mode) | Close Tab | Close current tab |
76-| **L** / **Tab** (in tab mode) | Next Tab | Navigate to next tab |
77-| **H** / **Shift+Tab** (in tab mode) | Previous Tab | Navigate to previous tab |
78-| **Escape** (in tab mode) | Exit Tab Mode | Return to normal navigation |
79-
80-#### Pane Management
81-| Shortcut | Action | Notes |
82-|----------|--------|-------|
83-| **Ctrl+P** | Enter Pane Mode | Modal mode for pane operations |
84-| **→** / **R** (in pane mode) | Split Right | Create new pane to the right |
85-| **←** / **L** (in pane mode) | Split Left | Create new pane to the left |
86-| **↑** / **U** (in pane mode) | Split Up | Create new pane above |
87-| **↓** / **D** (in pane mode) | Split Down | Create new pane below |
88-| **S** (in pane mode) | Stack Pane | Create stacked pane (Zellij-style) |
89-| **X** (in pane mode) | Close Pane | Close current pane |
90-| **m** (in pane mode) | Move Pane To Tab | Opens a tab picker modal |
91-| **M** (in pane mode) | Move Pane To Next Tab | Moves to the next tab, creates new tab if needed |
92-| **Enter** (in pane mode) | Confirm Action | Confirm pane operation |
93-| **Escape** (in pane mode) | Exit Pane Mode | Return to normal navigation |
94-| **Alt+Arrow Keys** | Navigate Panes | Move focus between panes |
95-| **Alt+Up/Down** | Navigate Stack | Navigate between stacked panes |
96-| **Alt+[** / **Alt+]** | Consume / Expel Pane | Experimental (alpha): merge into sibling stack, or expel out of stack |
97-| **Alt+Shift+[** / **Alt+Shift+]** | Consume / Expel Pane (Vertical) | Experimental (alpha): up/down variants |
98-
99-#### Resize Mode
100-| Shortcut | Action | Notes |
101-|----------|--------|-------|
102-| **Ctrl+N** | Enter Resize Mode | Modal mode for pane resizing |
103-| **←/↓/↑/→** / **h/j/k/l** (in resize mode) | Move Divider | Resizes the nearest split by moving the divider |
104-| **H/J/K/L** (in resize mode) | Move Divider (Inverse) | Inverts the direction |
105-| **+ / -** (in resize mode) | Smart Resize | Grow/shrink the active pane (best-effort) |
106-| **Enter** (in resize mode) | Confirm | Exit resize mode |
107-| **Escape** (in resize mode) | Cancel | Exit resize mode |
108-
109-#### Session Management
110-| Shortcut | Action | Notes |
111-|----------|--------|-------|
112-| **Ctrl+O** | Enter Session Mode | Modal mode for session operations |
113-| **Ctrl+Shift+S** | Open Session Manager | Direct access to session browser |
114-| **S** / **W** (in session mode) | Open Session Manager | Browse and restore sessions |
115-| **Escape** (in session mode) | Exit Session Mode | Return to normal navigation |
116-
117-### Mouse Controls
118-| Action | Result | Notes |
119-|--------|---------|-------|
120-| **Drag pane divider** | Resize panes | Updates split ratio and persists in session snapshots |
121-| **Ctrl+Scroll Up** | Zoom In | Smooth zoom control |
122-| **Ctrl+Scroll Down** | Zoom Out | Smooth zoom control |
123-| **Mouse Button 8** | Navigate Back | Side button (back) |
124-| **Mouse Button 9** | Navigate Forward | Side button (forward) |
125-| **Two-finger Swipe** | Back/Forward | When supported by touchpad |
126-
127-### Omnibox/Find Mode (when active)
128-| Shortcut | Action | Notes |
129-|----------|--------|-------|
130-| **Escape** | Close/Clear | Clear input if text present, close if empty |
131-| **Enter** | Execute/Navigate | Navigate to URL or jump to match |
132-| **Shift+Enter** | Previous Match | Find mode: go to previous match |
133-| **Alt+Enter** | Center Match | Find mode: center on match, keep open |
134-| **Tab** | Toggle View | Omnibox mode: switch between history and favorites |
135-| **Space** | Toggle Favorite | Omnibox mode: favorite/unfavorite selected item |
136-| **Ctrl+1-9, 0** | Quick Navigate | Jump to result by number (1-10) |
137-| **↑/↓ Arrow** | Navigate Results | Browse suggestions/matches |
138-| **Hold key 400ms** | Accent Picker | Shows accented variants in any text input (e.g., hold 'e' for è, é, ê, ë) |
139-
140-All zoom changes are automatically persisted per-domain and restored on next visit.
141-
142-## Install
143-
144-### Pre-built Binaries (Recommended)
145-
146-Pre-built binaries are available for Linux (x86_64/amd64) in the [releases page](https://github.com/bnema/dumber/releases). See [Quick Start](#quick-start) for installation instructions.
147-
14845 ### Arch Linux (AUR)
14946
150-Dumber is available on the [Arch User Repository (AUR)](https://aur.archlinux.org/packages?K=dumber-browser):
151-
15247 ```bash
153-# Binary package (pre-built, recommended - fastest install)
154-yay -S dumber-browser-bin
155-
156-# Or build from source (latest git - bleeding edge)
157-yay -S dumber-browser-git
48+yay -S dumber-browser-bin # Pre-built binary
49+yay -S dumber-browser-git # Build from source
15850 ```
15951
160-Both packages install to `/usr/bin/dumber` and include desktop integration. The binary package downloads pre-built releases from GitHub, while the git package builds from the latest source code.
161-
162-> **Note:** When installed via AUR, the self-updater is automatically disabled. Use `yay -Syu` or your preferred AUR helper to update.
163-
16452 ### Flatpak
16553
166-A Flatpak bundle is available in each release. This is the easiest way to install Dumber with all dependencies included:
167-
16854 ```bash
169-# Download the Flatpak bundle from the latest release
17055 wget https://github.com/bnema/dumber/releases/latest/download/dumber.flatpak
171-
172-# Install it (user-level, no root required)
17356 flatpak install --user dumber.flatpak
174-
175-# Run it
17657 flatpak run dev.bnema.Dumber browse
17758 ```
17859
179-To uninstall:
180-```bash
181-flatpak uninstall --user dev.bnema.Dumber
182-```
183-
18460 ### Dependencies
18561
186-Required for both pre-built binaries and source builds:
187-
18862 **Arch Linux:**
189-```bash
190-# Core WebKitGTK 6.0 and GTK4
191-sudo pacman -S webkitgtk-6.0 gtk4
19263
193-# GStreamer for media playback
194-sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse
195-
196-# Hardware video decoding (required for YouTube, Twitch, etc.)
197-sudo pacman -S gst-plugin-va
198-
199-# VA-API drivers (choose based on your GPU)
200-# AMD: sudo pacman -S mesa
201-# NVIDIA: sudo pacman -S libva-nvidia-driver
202-# Intel: sudo pacman -S libva-intel-driver intel-media-driver
64+```bash
65+sudo pacman -S webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va
20366 ```
20467
20568 **Debian/Ubuntu:**
20669
207-> ⚠️ **Note:** Ubuntu 24.04 LTS ships with GLib 2.80, but this project requires GLib 2.84+ due to newer GTK/WebKitGTK runtime requirements. Use Arch Linux, Fedora 41+, or another distribution with recent GLib packages.
208-
20970 ```bash
210-# Core WebKitGTK and GTK4
211-sudo apt install libwebkitgtk-6.0-4 libgtk-4-1
212-
213-# GStreamer for media playback
214-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
215-
216-# Hardware video decoding (gst-plugins-bad includes VA stateless decoders)
217-# VA-API drivers
218-sudo apt install va-driver-all
71+sudo apt install libwebkitgtk-6.0-4 libgtk-4-1 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad
21972 ```
22073
221-### Build From Source
74+> ⚠️ Ubuntu 24.04 ships GLib 2.80, but Dumber requires GLib 2.84+. Use Arch, Fedora 41+, or the Flatpak.
22275
223-**Note**: `go install` will not work for this project because the frontend assets must be built first and embedded into the binary.
76+## Keyboard-Driven
22477
225-**Prerequisites:**
226-- Go 1.25+
227-- Node.js 20+ and npm (for building the embedded TypeScript frontend)
228-- WebKitGTK 6 and GTK4 dev packages:
229- - Minimum runtime versions: WebKitGTK 6.0 >= `2.50`, GTK4 >= `4.20`, GLib >= `2.84`
230- - Debian/Ubuntu: `libwebkitgtk-6.0-dev libgtk-4-dev build-essential`
231- - Arch: `webkitgtk-6.0 gtk4 base-devel`
232- - Verify your system with: `dumber doctor` (or configure `runtime.prefix` for `/opt` installs)
233-
234-**Build options:**
235-- GUI build (default, recommended):
236- - Clone the repo and run `make build` (builds frontend first, then Go with GUI support)
237- - The resulting `./dist/dumber` binary includes the native GUI window
238-- CLI‑only (no native window):
239- - Clone the repo and run `make build-no-gui`
240- - The resulting `./dist/dumber-no-gui` binary runs CLI flows with GUI code stubbed
241-
242-## Usage
243-- Open a URL, local file, or search:
244- - `dumber browse https://example.com`
245- - `dumber browse example.com` # scheme auto‑added
246- - `dumber browse ./test.html` # local file path (converted to file://)
247- - `dumber browse dumb://home` # built-in home page (stats, shortcuts, etc.)
248- - `dumber browse "!g golang"` # search via bang shortcut
249-- Show version information:
250- - `dumber about` # version, commit, and build date
251-- Check for and install updates:
252- - `dumber update` # check and install if available
253- - `dumber update --force` # force reinstall (skips version check)
254-- Launcher integration (dmenu‑style examples with favicon support):
255- - rofi: `dumber dmenu | rofi -dmenu -show-icons -p "🔍 " | dumber dmenu --select`
256- - fuzzel: `dumber dmenu | fuzzel --dmenu -p "🔍 " | dumber dmenu --select`
257- - `dumber dmenu --interactive` # built-in TUI fuzzy finder
258- - `dumber dmenu --days 7` # show history from last 7 days (default: 30)
259- - `dumber dmenu --most-visited` # sort by visit count instead of recency
260-- Manage browsing history:
261- - `dumber history` # interactive history browser (timeline tabs + fuzzy search)
262- - `dumber history --json` # output recent entries as JSON
263- - `dumber history --json --max 50` # limit JSON output to N entries
264- - `dumber history stats` # show history statistics
265- - `dumber history clear` # interactive time-range cleanup
266-- Clean up data:
267- - `dumber purge` # interactive selection (TUI)
268- - `dumber purge --force` # remove everything (no prompts)
269-- Manage configuration:
270- - `dumber config status` # show config path and migration availability
271- - `dumber config migrate` # add missing default settings to config
272- - `dumber config migrate --yes` # skip confirmation prompt
273-- Manage sessions:
274- - `dumber sessions` # interactive session browser (TUI)
275- - `dumber sessions list` # list saved sessions
276- - `dumber sessions list --json` # output sessions as JSON
277- - `dumber sessions list --limit 50` # limit number of sessions shown
278- - `dumber sessions restore <id>` # restore a session in a new window
279- - `dumber sessions delete <id>` # delete a saved session
280-- Manage logs:
281- - `dumber logs` # list sessions with log files
282- - `dumber logs <session>` # show logs for a session (full ID or unique suffix)
283- - `dumber logs -f <session>` # follow logs in real time
284- - `dumber logs -n 200 <session>` # show last N lines
285- - `dumber logs clear` # clean up old log files
286- - `dumber logs clear --all` # remove all log files
287-- Generate documentation:
288- - `dumber gen-docs` # install man pages to ~/.local/share/man/man1/
289- - `dumber gen-docs --format markdown` # generate markdown docs to ./docs/
290- - `dumber gen-docs --output ./man` # generate to custom directory
291-
292-### Dmenu mode invocation
293-You can invoke dmenu mode in two ways:
294-- Piped launcher (generate options): `dumber dmenu`
295-- Receive selection from stdin: `dumber dmenu --select`
296-
297-For a built-in fuzzy finder UI, use: `dumber dmenu --interactive`
298-
299-In GUI mode the app serves an embedded home page via `dumb://home`, and frontend assets under `dumb://app/...`.
300-
301-There is also a WIP config UI at `dumb://config` for viewing/applying settings with live reload.
302-
303-## Tab Management
304-
305-Each tab holds its own workspace. Each workspace can contain multiple panes (split or stacked). Switch between tabs to switch between independent workspaces.
306-
307-### How it Works
308-1. **Enter Tab Mode**: Press `Ctrl+T` to enter tab mode (modal interface with timeout)
309-2. **Create/Close Tabs**: Use keyboard shortcuts:
310- - `N` or `C` - New tab
311- - `X` - Close current tab
312-3. **Navigate**: Use `Ctrl+Tab` / `Ctrl+Shift+Tab` for quick tab switching, or `L`/`H` in tab mode
313-4. **Exit**: Press `Escape` to exit tab mode or wait for timeout
314-
315-
316-
317-## Pane Management
318-
319-Split your browser window into multiple panes, each running independent web sessions.
320-
321-### How it Works
322-1. **Enter Pane Mode**: Press `Ctrl+P` to enter pane mode (modal interface with timeout)
323-2. **Split or Stack Panes**: Use arrow keys or letter shortcuts:
324- - `→` or `R` - Split right
325- - `←` or `L` - Split left
326- - `↑` or `U` - Split up
327- - `↓` or `D` - Split down
328- - `S` - Stack panes (Zellij-style, shows title bars for collapsed panes)
329-3. **Navigate**: Use `Alt+Arrow Keys` to move focus between split panes, or `Alt+Up/Down` to navigate within stacked panes
330-4. **Close**: Press `X` in pane mode to close the current pane
331-
332-## Session Management
333-
334-Dumber automatically saves your browser session (tabs, panes, split ratios, URLs) and allows you to restore previous sessions.
335-
336-### How it Works
337-1. **Automatic Snapshots**: Session state is saved automatically (debounced, every 5s by default) and on graceful shutdown
338-2. **Session Manager**: Press `Ctrl+O → s` or `Ctrl+Shift+S` to open the session manager modal
339-3. **Browse Sessions**: View active and exited sessions with tab/pane previews
340-4. **Restore**: Select an exited session to restore it in a new browser window
341-5. **CLI Access**: Use `dumber sessions` for an interactive TUI, or `dumber sessions list/restore/delete` for scripting
342-
343-
344-
345-## Configuration
346-
347-Configuration file: `~/.config/dumber/config.toml` (supports TOML, JSON, YAML)
348-
349-A default config is created on first run. Changes are applied automatically (hot reload). Override any setting with `DUMB_BROWSER_*` or `DUMBER_*` environment variables.
350-
351-**Full documentation**: [docs/CONFIG.md](docs/CONFIG.md) - Complete reference for all settings, workspace controls, shortcuts, styling, and more.
78+Four modal modes. Enter a mode, take action, escape out. Vim and Zellij users will feel right at home.
35279
80+| Mode | Key | Actions |
81+|------|-----|---------|
82+| Pane | `Ctrl+P` | Split · Stack · Close · Move |
83+| Tab | `Ctrl+T` | New · Close · Switch · Rename |
84+| Resize | `Ctrl+N` | Grow · Shrink · hjkl/arrows |
85+| Session | `Ctrl+O` | Save · Restore · Browse |
35386
35487 ## Development
35588
@@ -357,72 +90,38 @@ Dumber uses pure-Go bindings (no CGO) but requires GTK4/WebKitGTK runtime librar
35790
35891 ### Environment
35992
360-Set `ENV=dev` to use a local `.dev/dumber/` directory for config, data, state, and cache instead of XDG paths. Useful for testing without affecting your real browser data.
93+Set `ENV=dev` to use `.dev/dumber/` for config/data instead of XDG paths.
94+
95+### Build From Source
96+
97+**Prerequisites:**
98+- Go 1.25+
99+- Node.js 20+ (for frontend assets)
100+- WebKitGTK 6.0 and GTK4 dev packages
101+
102+```bash
103+git clone https://github.com/bnema/dumber
104+cd dumber
105+make build
106+./dist/dumber browse
107+```
361108
362109 ### Make Targets
363110
364111 | Target | Description |
365112 |--------|-------------|
366-| `make build` | Build frontend + binary (recommended) |
367-| `make build-quick` | Build binary only (faster for backend work) |
368-| `make build-frontend` | Build webui pages (homepage, error, config) |
113+| `make build` | Build frontend + binary |
114+| `make build-quick` | Build binary only (skip frontend) |
369115 | `make dev` | Run with `go run` |
370116 | `make test` | Run tests |
371-| `make test-race` | Run tests with race detection |
372-| `make test-cover` | Run tests with coverage report |
373117 | `make lint` | Run golangci-lint |
374-| `make lint-fix` | Run golangci-lint with auto-fix |
375-| `make fmt` | Format Go code |
376-| `make generate` | Generate SQLC code |
377-| `make mocks` | Generate mock implementations |
378-| `make install-tools` | Install dev tools (sqlc, golangci-lint) |
379-| `make check` | Verify tools, build, and tests work |
380-| `make clean` | Remove build artifacts |
381-
382-### Flatpak
383-
384-| Target | Description |
385-|--------|-------------|
386-| `make flatpak-deps` | Install Flatpak build dependencies |
387118 | `make flatpak-build` | Build Flatpak bundle |
388-| `make flatpak-install` | Install Flatpak locally for testing |
389-| `make flatpak-run` | Run the installed Flatpak |
390-| `make flatpak-clean` | Clean Flatpak build artifacts |
391-
392-### Release
393-
394-| Target | Description |
395-|--------|-------------|
396-| `make release-snapshot` | Build snapshot with goreleaser |
397-| `make release` | Create full release with goreleaser |
398119
399-## Media (GStreamer) & Hardware Acceleration
120+## Community
400121
401-WebKitGTK uses GStreamer for media playback. Dumber includes automatic hardware video acceleration support that detects your GPU and configures the appropriate drivers.
402-
403-**Hardware Acceleration Features:**
404-- Automatic GPU detection (AMD, NVIDIA, Intel)
405-- VA-API and VDPAU driver configuration
406-- Support for H.264, HEVC, VP9, and AV1 codecs
407-- Significantly reduced CPU usage during video streaming
408-
409-**Required packages:**
410-- Arch Linux:
411- - `sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse`
412- - Hardware decoding: `gst-plugin-va` (stateless VA decoders - required for WebKitGTK)
413- - VA-API drivers: `mesa` (AMD), `libva-nvidia-driver` (NVIDIA), `libva-intel-driver intel-media-driver` (Intel)
414-- Debian/Ubuntu:
415- - `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`
416- - Hardware decoding: `gstreamer1.0-plugins-bad` includes VA stateless decoders
417- - VA-API drivers: `va-driver-all` (covers most GPUs)
418-
419-## References
420-- puregotk: https://github.com/jwijenbergh/puregotk
421-- puregotk-webkit: https://github.com/bnema/puregotk-webkit
422-- ublock-webkit-filters (filter list releases): https://github.com/bnema/ublock-webkit-filters
423-
424-## Contribute
425-I will gladly accept contributions, especially related to UI/UX enhancements. Feel free to open an issue and let's discuss it!
122+- [Report bugs](https://github.com/bnema/dumber/issues)
123+- [Releases](https://github.com/bnema/dumber/releases)
426124
427125 ## License
428-This project is licensed under the MIT License. See `LICENSE` for details.
126+
127+MIT - See `LICENSE` for details.
@@ -1,355 +1,88 @@
1-# Dumber, fully unfeatured unbloated browser for tiling WMs1+# Dumber
2 2
3-<p align="center">3+[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
4- <img src="assets/logo.svg" alt="Dumber Logo" width="256" height="256" />
5-</p>
6 4
5+A TTY-inspired browser multiplexer for tiling window managers.
7 6
8-https://github.com/user-attachments/assets/394f5f7e-a475-42da-b483-5a58b2ea2f517+- Website: [dumber.bnema.dev](https://dumber.bnema.dev)
8+- Documentation: [dumber.bnema.dev/docs](https://dumber.bnema.dev/docs)
9 9
10+---
10 11
12+## What is Dumber?
11 13
12-A dumb browser that works like your favorite terminal multiplexer.14+Dumber is a Wayland-native browser that works like your terminal multiplexer. Tabs hold workspaces. Workspaces hold panes. Panes split and stack like Zellij. Everything is keyboard-driven.
13 15
14-## Features16+No bloat. No Chrome. No Electron.
15-- **Wayland native**: No X11/XWayland dependency, works with Sway, Hyprland, River, Niri, etc.
16-- **Tabs and workspaces**: Each tab holds a workspace with split or stacked panes.
17-- **Keyboard-driven**: Keyboard workflow inspired by Zellij.
18-- **Smart popup handling**: OAuth flows, window.open(), and popup deduplication for tiling WMs.
19-- **GPU rendering**: Hardware video acceleration with automatic VA-API/VDPAU detection.
20-- **Built-in ad blocking**: UBlock-based network + cosmetic filtering.
21-- **Launcher integration**: dmenu-style with rofi/fuzzel support, shows favicons and history.
22-- **Search shortcuts**: Quick search via bangs (e.g., `!g golang` for Google, `!gi cats` for Google Images).
23-- **Customizable themes**: Light and dark palettes with semantic color tokens.
24-- **Persistent storage**: SQLite for history, favorites, per-domain zoom levels, and sessions.
25-- **Live configuration**: Single config file with hot reload when possible.
26-- **Session management**: Zellij-style session save/restore with automatic snapshots and resurrection.
27 17
28-## Status18+**Features:**
29-Dumber is almost feature-complete. Next steps will focus on stability, performance, and bug fixing.19+- Zellij-style panes with modal keyboard navigation
20+- Wayland native (Sway, Hyprland, River, Niri)
21+- Session resurrection with auto-snapshots
22+- Built-in ad blocking (UBlock-based)
23+- GPU accelerated video (VA-API/VDPAU)
24+- Launcher integration (rofi/fuzzel/dmenu)
25+- Search bangs (!g, !gi, !ddg)
26+- Single config.toml with hot reload
30 27
31-Core features work well for daily use but expect some rough edges. Some features are still alpha/experimental (notably consume-or-expel panes) and may change behavior between releases.28+## Documentation
29+
30+Full documentation is available at **[dumber.bnema.dev](https://dumber.bnema.dev)**
31+
32+- [Documentation](https://dumber.bnema.dev/docs) - Installation, configuration, CLI reference
33+- [Keybindings](https://dumber.bnema.dev/docs/reference/keybindings) - Keyboard shortcuts
32 34
33 ## Quick Start35 ## Quick Start
34 36
35 ```bash37 ```bash
36-# Download and install38+# Install
37-wget https://github.com/bnema/dumber/releases/latest/download/dumber_linux_x86_64.tar.gz39+curl -fsSL https://dumber.bnema.dev/install | sh
38-tar -xzf dumber_linux_x86_64.tar.gz
39-mkdir -p ~/.local/bin && install -m 755 dumber_*/dumber ~/.local/bin/
40 40
41-# Run41+# Launch
42-dumber browse https://example.com42+dumber browse
43 ```43 ```
44 44
45-See [Install](#install) for AUR, Flatpak, building from source, and runtime dependencies.
46-
47-## Controls & Shortcuts
48-
49-### Keyboard Shortcuts
50-
51-#### Browser Controls
52-| Shortcut | Action | Notes |
53-|----------|--------|-------|
54-| **F12** | Open Developer Tools | WebKit inspector |
55-| **Ctrl+L** | Open Omnibox | URL/search input with history |
56-| **Ctrl+F** | Find in Page | Search text within current page |
57-| **Ctrl+=** | Zoom In | Firefox-compatible zoom levels |
58-| **Ctrl++** | Zoom In | Alternative plus key |
59-| **Ctrl+-** | Zoom Out | Works across keyboard layouts |
60-| **Ctrl+0** | Reset Zoom | Return to 100% zoom |
61-| **Ctrl+Shift+C** | Copy URL | Copy current URL to clipboard with toast |
62-| **Ctrl+Shift+P** | Print Page | Open native print dialog |
63-| **Ctrl+R** / **F5** | Reload Page | Refresh current page |
64-| **Ctrl+Shift+R** | Hard Reload | Refresh ignoring cache |
65-| **Ctrl+←** / **Ctrl+→** | Navigate Back/Forward | Browser history navigation |
66-
67-#### Tab Management
68-| Shortcut | Action | Notes |
69-|----------|--------|-------|
70-| **Ctrl+T** | Enter Tab Mode | Modal mode for tab operations |
71-| **Ctrl+Tab** | Next Tab | Quick tab switching |
72-| **Ctrl+Shift+Tab** | Previous Tab | Quick tab switching |
73-| **Ctrl+W** | Close Tab | Close current tab |
74-| **N** / **C** (in tab mode) | New Tab | Create new tab |
75-| **X** (in tab mode) | Close Tab | Close current tab |
76-| **L** / **Tab** (in tab mode) | Next Tab | Navigate to next tab |
77-| **H** / **Shift+Tab** (in tab mode) | Previous Tab | Navigate to previous tab |
78-| **Escape** (in tab mode) | Exit Tab Mode | Return to normal navigation |
79-
80-#### Pane Management
81-| Shortcut | Action | Notes |
82-|----------|--------|-------|
83-| **Ctrl+P** | Enter Pane Mode | Modal mode for pane operations |
84-| **→** / **R** (in pane mode) | Split Right | Create new pane to the right |
85-| **←** / **L** (in pane mode) | Split Left | Create new pane to the left |
86-| **↑** / **U** (in pane mode) | Split Up | Create new pane above |
87-| **↓** / **D** (in pane mode) | Split Down | Create new pane below |
88-| **S** (in pane mode) | Stack Pane | Create stacked pane (Zellij-style) |
89-| **X** (in pane mode) | Close Pane | Close current pane |
90-| **m** (in pane mode) | Move Pane To Tab | Opens a tab picker modal |
91-| **M** (in pane mode) | Move Pane To Next Tab | Moves to the next tab, creates new tab if needed |
92-| **Enter** (in pane mode) | Confirm Action | Confirm pane operation |
93-| **Escape** (in pane mode) | Exit Pane Mode | Return to normal navigation |
94-| **Alt+Arrow Keys** | Navigate Panes | Move focus between panes |
95-| **Alt+Up/Down** | Navigate Stack | Navigate between stacked panes |
96-| **Alt+[** / **Alt+]** | Consume / Expel Pane | Experimental (alpha): merge into sibling stack, or expel out of stack |
97-| **Alt+Shift+[** / **Alt+Shift+]** | Consume / Expel Pane (Vertical) | Experimental (alpha): up/down variants |
98-
99-#### Resize Mode
100-| Shortcut | Action | Notes |
101-|----------|--------|-------|
102-| **Ctrl+N** | Enter Resize Mode | Modal mode for pane resizing |
103-| **←/↓/↑/→** / **h/j/k/l** (in resize mode) | Move Divider | Resizes the nearest split by moving the divider |
104-| **H/J/K/L** (in resize mode) | Move Divider (Inverse) | Inverts the direction |
105-| **+ / -** (in resize mode) | Smart Resize | Grow/shrink the active pane (best-effort) |
106-| **Enter** (in resize mode) | Confirm | Exit resize mode |
107-| **Escape** (in resize mode) | Cancel | Exit resize mode |
108-
109-#### Session Management
110-| Shortcut | Action | Notes |
111-|----------|--------|-------|
112-| **Ctrl+O** | Enter Session Mode | Modal mode for session operations |
113-| **Ctrl+Shift+S** | Open Session Manager | Direct access to session browser |
114-| **S** / **W** (in session mode) | Open Session Manager | Browse and restore sessions |
115-| **Escape** (in session mode) | Exit Session Mode | Return to normal navigation |
116-
117-### Mouse Controls
118-| Action | Result | Notes |
119-|--------|---------|-------|
120-| **Drag pane divider** | Resize panes | Updates split ratio and persists in session snapshots |
121-| **Ctrl+Scroll Up** | Zoom In | Smooth zoom control |
122-| **Ctrl+Scroll Down** | Zoom Out | Smooth zoom control |
123-| **Mouse Button 8** | Navigate Back | Side button (back) |
124-| **Mouse Button 9** | Navigate Forward | Side button (forward) |
125-| **Two-finger Swipe** | Back/Forward | When supported by touchpad |
126-
127-### Omnibox/Find Mode (when active)
128-| Shortcut | Action | Notes |
129-|----------|--------|-------|
130-| **Escape** | Close/Clear | Clear input if text present, close if empty |
131-| **Enter** | Execute/Navigate | Navigate to URL or jump to match |
132-| **Shift+Enter** | Previous Match | Find mode: go to previous match |
133-| **Alt+Enter** | Center Match | Find mode: center on match, keep open |
134-| **Tab** | Toggle View | Omnibox mode: switch between history and favorites |
135-| **Space** | Toggle Favorite | Omnibox mode: favorite/unfavorite selected item |
136-| **Ctrl+1-9, 0** | Quick Navigate | Jump to result by number (1-10) |
137-| **↑/↓ Arrow** | Navigate Results | Browse suggestions/matches |
138-| **Hold key 400ms** | Accent Picker | Shows accented variants in any text input (e.g., hold 'e' for è, é, ê, ë) |
139-
140-All zoom changes are automatically persisted per-domain and restored on next visit.
141-
142-## Install
143-
144-### Pre-built Binaries (Recommended)
145-
146-Pre-built binaries are available for Linux (x86_64/amd64) in the [releases page](https://github.com/bnema/dumber/releases). See [Quick Start](#quick-start) for installation instructions.
147-
148 ### Arch Linux (AUR)45 ### Arch Linux (AUR)
149 46
150-Dumber is available on the [Arch User Repository (AUR)](https://aur.archlinux.org/packages?K=dumber-browser):
151-
152 ```bash47 ```bash
153-# Binary package (pre-built, recommended - fastest install)48+yay -S dumber-browser-bin # Pre-built binary
154-yay -S dumber-browser-bin49+yay -S dumber-browser-git # Build from source
155-
156-# Or build from source (latest git - bleeding edge)
157-yay -S dumber-browser-git
158 ```50 ```
159 51
160-Both packages install to `/usr/bin/dumber` and include desktop integration. The binary package downloads pre-built releases from GitHub, while the git package builds from the latest source code.
161-
162-> **Note:** When installed via AUR, the self-updater is automatically disabled. Use `yay -Syu` or your preferred AUR helper to update.
163-
164 ### Flatpak52 ### Flatpak
165 53
166-A Flatpak bundle is available in each release. This is the easiest way to install Dumber with all dependencies included:
167-
168 ```bash54 ```bash
169-# Download the Flatpak bundle from the latest release
170 wget https://github.com/bnema/dumber/releases/latest/download/dumber.flatpak55 wget https://github.com/bnema/dumber/releases/latest/download/dumber.flatpak
171-
172-# Install it (user-level, no root required)
173 flatpak install --user dumber.flatpak56 flatpak install --user dumber.flatpak
174-
175-# Run it
176 flatpak run dev.bnema.Dumber browse57 flatpak run dev.bnema.Dumber browse
177 ```58 ```
178 59
179-To uninstall:
180-```bash
181-flatpak uninstall --user dev.bnema.Dumber
182-```
183-
184 ### Dependencies60 ### Dependencies
185 61
186-Required for both pre-built binaries and source builds:
187-
188 **Arch Linux:**62 **Arch Linux:**
189-```bash
190-# Core WebKitGTK 6.0 and GTK4
191-sudo pacman -S webkitgtk-6.0 gtk4
192 63
193-# GStreamer for media playback64+```bash
194-sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse65+sudo pacman -S webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va
195-
196-# Hardware video decoding (required for YouTube, Twitch, etc.)
197-sudo pacman -S gst-plugin-va
198-
199-# VA-API drivers (choose based on your GPU)
200-# AMD: sudo pacman -S mesa
201-# NVIDIA: sudo pacman -S libva-nvidia-driver
202-# Intel: sudo pacman -S libva-intel-driver intel-media-driver
203 ```66 ```
204 67
205 **Debian/Ubuntu:**68 **Debian/Ubuntu:**
206 69
207-> ⚠️ **Note:** Ubuntu 24.04 LTS ships with GLib 2.80, but this project requires GLib 2.84+ due to newer GTK/WebKitGTK runtime requirements. Use Arch Linux, Fedora 41+, or another distribution with recent GLib packages.
208-
209 ```bash70 ```bash
210-# Core WebKitGTK and GTK471+sudo apt install libwebkitgtk-6.0-4 libgtk-4-1 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad
211-sudo apt install libwebkitgtk-6.0-4 libgtk-4-1
212-
213-# GStreamer for media playback
214-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
215-
216-# Hardware video decoding (gst-plugins-bad includes VA stateless decoders)
217-# VA-API drivers
218-sudo apt install va-driver-all
219 ```72 ```
220 73
221-### Build From Source74+> ⚠️ Ubuntu 24.04 ships GLib 2.80, but Dumber requires GLib 2.84+. Use Arch, Fedora 41+, or the Flatpak.
222 75
223-**Note**: `go install` will not work for this project because the frontend assets must be built first and embedded into the binary.76+## Keyboard-Driven
224 77
225-**Prerequisites:**78+Four modal modes. Enter a mode, take action, escape out. Vim and Zellij users will feel right at home.
226-- Go 1.25+
227-- Node.js 20+ and npm (for building the embedded TypeScript frontend)
228-- WebKitGTK 6 and GTK4 dev packages:
229- - Minimum runtime versions: WebKitGTK 6.0 >= `2.50`, GTK4 >= `4.20`, GLib >= `2.84`
230- - Debian/Ubuntu: `libwebkitgtk-6.0-dev libgtk-4-dev build-essential`
231- - Arch: `webkitgtk-6.0 gtk4 base-devel`
232- - Verify your system with: `dumber doctor` (or configure `runtime.prefix` for `/opt` installs)
233-
234-**Build options:**
235-- GUI build (default, recommended):
236- - Clone the repo and run `make build` (builds frontend first, then Go with GUI support)
237- - The resulting `./dist/dumber` binary includes the native GUI window
238-- CLI‑only (no native window):
239- - Clone the repo and run `make build-no-gui`
240- - The resulting `./dist/dumber-no-gui` binary runs CLI flows with GUI code stubbed
241-
242-## Usage
243-- Open a URL, local file, or search:
244- - `dumber browse https://example.com`
245- - `dumber browse example.com` # scheme auto‑added
246- - `dumber browse ./test.html` # local file path (converted to file://)
247- - `dumber browse dumb://home` # built-in home page (stats, shortcuts, etc.)
248- - `dumber browse "!g golang"` # search via bang shortcut
249-- Show version information:
250- - `dumber about` # version, commit, and build date
251-- Check for and install updates:
252- - `dumber update` # check and install if available
253- - `dumber update --force` # force reinstall (skips version check)
254-- Launcher integration (dmenu‑style examples with favicon support):
255- - rofi: `dumber dmenu | rofi -dmenu -show-icons -p "🔍 " | dumber dmenu --select`
256- - fuzzel: `dumber dmenu | fuzzel --dmenu -p "🔍 " | dumber dmenu --select`
257- - `dumber dmenu --interactive` # built-in TUI fuzzy finder
258- - `dumber dmenu --days 7` # show history from last 7 days (default: 30)
259- - `dumber dmenu --most-visited` # sort by visit count instead of recency
260-- Manage browsing history:
261- - `dumber history` # interactive history browser (timeline tabs + fuzzy search)
262- - `dumber history --json` # output recent entries as JSON
263- - `dumber history --json --max 50` # limit JSON output to N entries
264- - `dumber history stats` # show history statistics
265- - `dumber history clear` # interactive time-range cleanup
266-- Clean up data:
267- - `dumber purge` # interactive selection (TUI)
268- - `dumber purge --force` # remove everything (no prompts)
269-- Manage configuration:
270- - `dumber config status` # show config path and migration availability
271- - `dumber config migrate` # add missing default settings to config
272- - `dumber config migrate --yes` # skip confirmation prompt
273-- Manage sessions:
274- - `dumber sessions` # interactive session browser (TUI)
275- - `dumber sessions list` # list saved sessions
276- - `dumber sessions list --json` # output sessions as JSON
277- - `dumber sessions list --limit 50` # limit number of sessions shown
278- - `dumber sessions restore <id>` # restore a session in a new window
279- - `dumber sessions delete <id>` # delete a saved session
280-- Manage logs:
281- - `dumber logs` # list sessions with log files
282- - `dumber logs <session>` # show logs for a session (full ID or unique suffix)
283- - `dumber logs -f <session>` # follow logs in real time
284- - `dumber logs -n 200 <session>` # show last N lines
285- - `dumber logs clear` # clean up old log files
286- - `dumber logs clear --all` # remove all log files
287-- Generate documentation:
288- - `dumber gen-docs` # install man pages to ~/.local/share/man/man1/
289- - `dumber gen-docs --format markdown` # generate markdown docs to ./docs/
290- - `dumber gen-docs --output ./man` # generate to custom directory
291-
292-### Dmenu mode invocation
293-You can invoke dmenu mode in two ways:
294-- Piped launcher (generate options): `dumber dmenu`
295-- Receive selection from stdin: `dumber dmenu --select`
296-
297-For a built-in fuzzy finder UI, use: `dumber dmenu --interactive`
298-
299-In GUI mode the app serves an embedded home page via `dumb://home`, and frontend assets under `dumb://app/...`.
300-
301-There is also a WIP config UI at `dumb://config` for viewing/applying settings with live reload.
302-
303-## Tab Management
304-
305-Each tab holds its own workspace. Each workspace can contain multiple panes (split or stacked). Switch between tabs to switch between independent workspaces.
306-
307-### How it Works
308-1. **Enter Tab Mode**: Press `Ctrl+T` to enter tab mode (modal interface with timeout)
309-2. **Create/Close Tabs**: Use keyboard shortcuts:
310- - `N` or `C` - New tab
311- - `X` - Close current tab
312-3. **Navigate**: Use `Ctrl+Tab` / `Ctrl+Shift+Tab` for quick tab switching, or `L`/`H` in tab mode
313-4. **Exit**: Press `Escape` to exit tab mode or wait for timeout
314-
315-
316-
317-## Pane Management
318-
319-Split your browser window into multiple panes, each running independent web sessions.
320-
321-### How it Works
322-1. **Enter Pane Mode**: Press `Ctrl+P` to enter pane mode (modal interface with timeout)
323-2. **Split or Stack Panes**: Use arrow keys or letter shortcuts:
324- - `→` or `R` - Split right
325- - `←` or `L` - Split left
326- - `↑` or `U` - Split up
327- - `↓` or `D` - Split down
328- - `S` - Stack panes (Zellij-style, shows title bars for collapsed panes)
329-3. **Navigate**: Use `Alt+Arrow Keys` to move focus between split panes, or `Alt+Up/Down` to navigate within stacked panes
330-4. **Close**: Press `X` in pane mode to close the current pane
331-
332-## Session Management
333-
334-Dumber automatically saves your browser session (tabs, panes, split ratios, URLs) and allows you to restore previous sessions.
335-
336-### How it Works
337-1. **Automatic Snapshots**: Session state is saved automatically (debounced, every 5s by default) and on graceful shutdown
338-2. **Session Manager**: Press `Ctrl+O → s` or `Ctrl+Shift+S` to open the session manager modal
339-3. **Browse Sessions**: View active and exited sessions with tab/pane previews
340-4. **Restore**: Select an exited session to restore it in a new browser window
341-5. **CLI Access**: Use `dumber sessions` for an interactive TUI, or `dumber sessions list/restore/delete` for scripting
342-
343-
344-
345-## Configuration
346-
347-Configuration file: `~/.config/dumber/config.toml` (supports TOML, JSON, YAML)
348-
349-A default config is created on first run. Changes are applied automatically (hot reload). Override any setting with `DUMB_BROWSER_*` or `DUMBER_*` environment variables.
350-
351-**Full documentation**: [docs/CONFIG.md](docs/CONFIG.md) - Complete reference for all settings, workspace controls, shortcuts, styling, and more.
352 79
80+| Mode | Key | Actions |
81+|------|-----|---------|
82+| Pane | `Ctrl+P` | Split · Stack · Close · Move |
83+| Tab | `Ctrl+T` | New · Close · Switch · Rename |
84+| Resize | `Ctrl+N` | Grow · Shrink · hjkl/arrows |
85+| Session | `Ctrl+O` | Save · Restore · Browse |
353 86
354 ## Development87 ## Development
355 88
@@ -357,72 +90,38 @@ Dumber uses pure-Go bindings (no CGO) but requires GTK4/WebKitGTK runtime librar
357 90
358 ### Environment91 ### Environment
359 92
360-Set `ENV=dev` to use a local `.dev/dumber/` directory for config, data, state, and cache instead of XDG paths. Useful for testing without affecting your real browser data.93+Set `ENV=dev` to use `.dev/dumber/` for config/data instead of XDG paths.
94+
95+### Build From Source
96+
97+**Prerequisites:**
98+- Go 1.25+
99+- Node.js 20+ (for frontend assets)
100+- WebKitGTK 6.0 and GTK4 dev packages
101+
102+```bash
103+git clone https://github.com/bnema/dumber
104+cd dumber
105+make build
106+./dist/dumber browse
107+```
361 108
362 ### Make Targets109 ### Make Targets
363 110
364 | Target | Description |111 | Target | Description |
365 |--------|-------------|112 |--------|-------------|
366-| `make build` | Build frontend + binary (recommended) |113+| `make build` | Build frontend + binary |
367-| `make build-quick` | Build binary only (faster for backend work) |114+| `make build-quick` | Build binary only (skip frontend) |
368-| `make build-frontend` | Build webui pages (homepage, error, config) |
369 | `make dev` | Run with `go run` |115 | `make dev` | Run with `go run` |
370 | `make test` | Run tests |116 | `make test` | Run tests |
371-| `make test-race` | Run tests with race detection |
372-| `make test-cover` | Run tests with coverage report |
373 | `make lint` | Run golangci-lint |117 | `make lint` | Run golangci-lint |
374-| `make lint-fix` | Run golangci-lint with auto-fix |
375-| `make fmt` | Format Go code |
376-| `make generate` | Generate SQLC code |
377-| `make mocks` | Generate mock implementations |
378-| `make install-tools` | Install dev tools (sqlc, golangci-lint) |
379-| `make check` | Verify tools, build, and tests work |
380-| `make clean` | Remove build artifacts |
381-
382-### Flatpak
383-
384-| Target | Description |
385-|--------|-------------|
386-| `make flatpak-deps` | Install Flatpak build dependencies |
387 | `make flatpak-build` | Build Flatpak bundle |118 | `make flatpak-build` | Build Flatpak bundle |
388-| `make flatpak-install` | Install Flatpak locally for testing |
389-| `make flatpak-run` | Run the installed Flatpak |
390-| `make flatpak-clean` | Clean Flatpak build artifacts |
391-
392-### Release
393-
394-| Target | Description |
395-|--------|-------------|
396-| `make release-snapshot` | Build snapshot with goreleaser |
397-| `make release` | Create full release with goreleaser |
398 119
399-## Media (GStreamer) & Hardware Acceleration120+## Community
400 121
401-WebKitGTK uses GStreamer for media playback. Dumber includes automatic hardware video acceleration support that detects your GPU and configures the appropriate drivers.122+- [Report bugs](https://github.com/bnema/dumber/issues)
402-123+- [Releases](https://github.com/bnema/dumber/releases)
403-**Hardware Acceleration Features:**
404-- Automatic GPU detection (AMD, NVIDIA, Intel)
405-- VA-API and VDPAU driver configuration
406-- Support for H.264, HEVC, VP9, and AV1 codecs
407-- Significantly reduced CPU usage during video streaming
408-
409-**Required packages:**
410-- Arch Linux:
411- - `sudo pacman -S gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav gst-plugin-pipewire pipewire pipewire-pulse`
412- - Hardware decoding: `gst-plugin-va` (stateless VA decoders - required for WebKitGTK)
413- - VA-API drivers: `mesa` (AMD), `libva-nvidia-driver` (NVIDIA), `libva-intel-driver intel-media-driver` (Intel)
414-- Debian/Ubuntu:
415- - `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`
416- - Hardware decoding: `gstreamer1.0-plugins-bad` includes VA stateless decoders
417- - VA-API drivers: `va-driver-all` (covers most GPUs)
418-
419-## References
420-- puregotk: https://github.com/jwijenbergh/puregotk
421-- puregotk-webkit: https://github.com/bnema/puregotk-webkit
422-- ublock-webkit-filters (filter list releases): https://github.com/bnema/ublock-webkit-filters
423-
424-## Contribute
425-I will gladly accept contributions, especially related to UI/UX enhancements. Feel free to open an issue and let's discuss it!
426 124
427 ## License125 ## License
428-This project is licensed under the MIT License. See `LICENSE` for details.126+
127+MIT - See `LICENSE` for details.
A docs/cli/index.md +222 -0
@@ -0,0 +1,222 @@
1+# CLI Commands
2+
3+Dumber provides commands for browser management, history, sessions, and diagnostics.
4+
5+## Commands
6+
7+| Command | Description |
8+|---------|-------------|
9+| `dumber browse` | Launch the graphical browser |
10+| `dumber dmenu` | Launcher integration for rofi/fuzzel |
11+| `dumber history` | Browse and manage history |
12+| `dumber sessions` | Manage browser sessions |
13+| `dumber config` | Manage configuration |
14+| `dumber doctor` | Check runtime requirements |
15+| `dumber setup` | Setup desktop integration |
16+| `dumber update` | Check for and install updates |
17+| `dumber logs` | View application logs |
18+| `dumber purge` | Remove data and configuration |
19+| `dumber about` | Show version information |
20+| `dumber completion` | Generate shell completions |
21+
22+## Command Reference
23+
24+### browse
25+
26+Launch the graphical browser.
27+
28+```bash
29+dumber browse [url]
30+```
31+
32+### dmenu
33+
34+Launcher integration for rofi/fuzzel.
35+
36+```bash
37+dumber dmenu [flags]
38+```
39+
40+| Flag | Short | Description |
41+|------|-------|-------------|
42+| `--interactive` | `-i` | Use interactive TUI mode |
43+| `--select` | | Process selection from stdin |
44+| `--days` | | Number of days of history to show |
45+| `--most-visited` | `-m` | Sort by visit count instead of recency |
46+
47+**Examples:**
48+```bash
49+dumber dmenu | rofi -dmenu -show-icons | dumber dmenu --select
50+dumber dmenu | fuzzel --dmenu | dumber dmenu --select
51+dumber dmenu --interactive
52+dumber dmenu --days 7 --most-visited
53+```
54+
55+### history
56+
57+Browse and manage history.
58+
59+```bash
60+dumber history [flags]
61+dumber history stats
62+dumber history clear
63+```
64+
65+| Flag | Description |
66+|------|-------------|
67+| `--json` | Output as JSON |
68+| `--max` | Maximum entries to show (default: 50) |
69+
70+**Subcommands:**
71+- `stats` - Show history statistics
72+- `clear` - Interactive history cleanup
73+
74+### sessions
75+
76+Manage browser sessions.
77+
78+```bash
79+dumber sessions
80+dumber sessions list [flags]
81+dumber sessions restore <session-id>
82+dumber sessions delete <session-id>
83+```
84+
85+**Subcommands:**
86+
87+| Subcommand | Description |
88+|------------|-------------|
89+| `list` | List saved sessions |
90+| `restore <id>` | Restore a saved session |
91+| `delete <id>` | Delete a saved session |
92+
93+**list flags:**
94+
95+| Flag | Description |
96+|------|-------------|
97+| `--json` | Output as JSON |
98+| `--limit` | Maximum sessions to show (default: 20) |
99+
100+### config
101+
102+Manage configuration.
103+
104+```bash
105+dumber config open
106+dumber config status
107+dumber config migrate [flags]
108+dumber config schema [flags]
109+```
110+
111+**Subcommands:**
112+
113+| Subcommand | Description |
114+|------------|-------------|
115+| `open` | Open config file in editor |
116+| `status` | Show config status and migration availability |
117+| `migrate` | Add missing default settings |
118+| `schema` | Show all config keys with types and values |
119+
120+**migrate flags:**
121+
122+| Flag | Short | Description |
123+|------|-------|-------------|
124+| `--yes` | `-y` | Skip confirmation prompt |
125+
126+**schema flags:**
127+
128+| Flag | Description |
129+|------|-------------|
130+| `--json` | Output as JSON |
131+
132+### doctor
133+
134+Check runtime requirements and diagnose issues.
135+
136+```bash
137+dumber doctor [flags]
138+```
139+
140+| Flag | Description |
141+|------|-------------|
142+| `--runtime` | Only run runtime checks (GTK4/WebKitGTK) |
143+| `--media` | Only run media checks (GStreamer/VA-API) |
144+
145+### setup
146+
147+Setup desktop integration.
148+
149+```bash
150+dumber setup install
151+dumber setup default
152+```
153+
154+| Subcommand | Description |
155+|------------|-------------|
156+| `install` | Install desktop file to ~/.local/share/applications/ |
157+| `default` | Set dumber as the default web browser |
158+
159+### update
160+
161+Check for and install updates.
162+
163+```bash
164+dumber update [flags]
165+```
166+
167+| Flag | Short | Description |
168+|------|-------|-------------|
169+| `--force` | `-f` | Force reinstall (skips version check) |
170+
171+### logs
172+
173+View application logs.
174+
175+```bash
176+dumber logs [session]
177+dumber logs clear [flags]
178+```
179+
180+| Flag | Short | Description |
181+|------|-------|-------------|
182+| `--follow` | `-f` | Follow log output in real-time |
183+| `--lines` | `-n` | Number of lines to show (default: 50) |
184+
185+**Subcommands:**
186+
187+| Subcommand | Description |
188+|------------|-------------|
189+| `clear` | Clear old log files |
190+
191+**clear flags:**
192+
193+| Flag | Description |
194+|------|-------------|
195+| `--all` | Remove all session logs |
196+
197+### purge
198+
199+Remove dumber data and configuration.
200+
201+```bash
202+dumber purge
203+```
204+
205+### about
206+
207+Show version and build information.
208+
209+```bash
210+dumber about
211+```
212+
213+## Environment Variables
214+
215+Configuration can be overridden via environment variables:
216+
217+```bash
218+DUMBER_LOG_LEVEL=debug dumber browse
219+DUMBER_RENDERING_MODE=cpu dumber browse
220+```
221+
222+Pattern: `DUMBER_SECTION_KEY` (uppercase, underscores)
@@ -0,0 +1,222 @@
1+# CLI Commands
2+
3+Dumber provides commands for browser management, history, sessions, and diagnostics.
4+
5+## Commands
6+
7+| Command | Description |
8+|---------|-------------|
9+| `dumber browse` | Launch the graphical browser |
10+| `dumber dmenu` | Launcher integration for rofi/fuzzel |
11+| `dumber history` | Browse and manage history |
12+| `dumber sessions` | Manage browser sessions |
13+| `dumber config` | Manage configuration |
14+| `dumber doctor` | Check runtime requirements |
15+| `dumber setup` | Setup desktop integration |
16+| `dumber update` | Check for and install updates |
17+| `dumber logs` | View application logs |
18+| `dumber purge` | Remove data and configuration |
19+| `dumber about` | Show version information |
20+| `dumber completion` | Generate shell completions |
21+
22+## Command Reference
23+
24+### browse
25+
26+Launch the graphical browser.
27+
28+```bash
29+dumber browse [url]
30+```
31+
32+### dmenu
33+
34+Launcher integration for rofi/fuzzel.
35+
36+```bash
37+dumber dmenu [flags]
38+```
39+
40+| Flag | Short | Description |
41+|------|-------|-------------|
42+| `--interactive` | `-i` | Use interactive TUI mode |
43+| `--select` | | Process selection from stdin |
44+| `--days` | | Number of days of history to show |
45+| `--most-visited` | `-m` | Sort by visit count instead of recency |
46+
47+**Examples:**
48+```bash
49+dumber dmenu | rofi -dmenu -show-icons | dumber dmenu --select
50+dumber dmenu | fuzzel --dmenu | dumber dmenu --select
51+dumber dmenu --interactive
52+dumber dmenu --days 7 --most-visited
53+```
54+
55+### history
56+
57+Browse and manage history.
58+
59+```bash
60+dumber history [flags]
61+dumber history stats
62+dumber history clear
63+```
64+
65+| Flag | Description |
66+|------|-------------|
67+| `--json` | Output as JSON |
68+| `--max` | Maximum entries to show (default: 50) |
69+
70+**Subcommands:**
71+- `stats` - Show history statistics
72+- `clear` - Interactive history cleanup
73+
74+### sessions
75+
76+Manage browser sessions.
77+
78+```bash
79+dumber sessions
80+dumber sessions list [flags]
81+dumber sessions restore <session-id>
82+dumber sessions delete <session-id>
83+```
84+
85+**Subcommands:**
86+
87+| Subcommand | Description |
88+|------------|-------------|
89+| `list` | List saved sessions |
90+| `restore <id>` | Restore a saved session |
91+| `delete <id>` | Delete a saved session |
92+
93+**list flags:**
94+
95+| Flag | Description |
96+|------|-------------|
97+| `--json` | Output as JSON |
98+| `--limit` | Maximum sessions to show (default: 20) |
99+
100+### config
101+
102+Manage configuration.
103+
104+```bash
105+dumber config open
106+dumber config status
107+dumber config migrate [flags]
108+dumber config schema [flags]
109+```
110+
111+**Subcommands:**
112+
113+| Subcommand | Description |
114+|------------|-------------|
115+| `open` | Open config file in editor |
116+| `status` | Show config status and migration availability |
117+| `migrate` | Add missing default settings |
118+| `schema` | Show all config keys with types and values |
119+
120+**migrate flags:**
121+
122+| Flag | Short | Description |
123+|------|-------|-------------|
124+| `--yes` | `-y` | Skip confirmation prompt |
125+
126+**schema flags:**
127+
128+| Flag | Description |
129+|------|-------------|
130+| `--json` | Output as JSON |
131+
132+### doctor
133+
134+Check runtime requirements and diagnose issues.
135+
136+```bash
137+dumber doctor [flags]
138+```
139+
140+| Flag | Description |
141+|------|-------------|
142+| `--runtime` | Only run runtime checks (GTK4/WebKitGTK) |
143+| `--media` | Only run media checks (GStreamer/VA-API) |
144+
145+### setup
146+
147+Setup desktop integration.
148+
149+```bash
150+dumber setup install
151+dumber setup default
152+```
153+
154+| Subcommand | Description |
155+|------------|-------------|
156+| `install` | Install desktop file to ~/.local/share/applications/ |
157+| `default` | Set dumber as the default web browser |
158+
159+### update
160+
161+Check for and install updates.
162+
163+```bash
164+dumber update [flags]
165+```
166+
167+| Flag | Short | Description |
168+|------|-------|-------------|
169+| `--force` | `-f` | Force reinstall (skips version check) |
170+
171+### logs
172+
173+View application logs.
174+
175+```bash
176+dumber logs [session]
177+dumber logs clear [flags]
178+```
179+
180+| Flag | Short | Description |
181+|------|-------|-------------|
182+| `--follow` | `-f` | Follow log output in real-time |
183+| `--lines` | `-n` | Number of lines to show (default: 50) |
184+
185+**Subcommands:**
186+
187+| Subcommand | Description |
188+|------------|-------------|
189+| `clear` | Clear old log files |
190+
191+**clear flags:**
192+
193+| Flag | Description |
194+|------|-------------|
195+| `--all` | Remove all session logs |
196+
197+### purge
198+
199+Remove dumber data and configuration.
200+
201+```bash
202+dumber purge
203+```
204+
205+### about
206+
207+Show version and build information.
208+
209+```bash
210+dumber about
211+```
212+
213+## Environment Variables
214+
215+Configuration can be overridden via environment variables:
216+
217+```bash
218+DUMBER_LOG_LEVEL=debug dumber browse
219+DUMBER_RENDERING_MODE=cpu dumber browse
220+```
221+
222+Pattern: `DUMBER_SECTION_KEY` (uppercase, underscores)
R docs/CONFIG.md → docs/config/index.md +2 -14 renamed, 97% similar
@@ -1,19 +1,7 @@
1-# Configuration Reference
1+# Configuration Guide
22
3-**Primary format**: TOML (recommended)
43 **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-
10-TOML 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-
16-You can still use JSON or YAML if you prefer - dumber automatically detects the format.
4+**Formats**: TOML (recommended), JSON, YAML
175
186 ## Database
197
@@ -1,19 +1,7 @@
1-# Configuration Reference1+# Configuration Guide
2 2
3-**Primary format**: TOML (recommended)
4 **Location**: `~/.config/dumber/config.toml`3 **Location**: `~/.config/dumber/config.toml`
5-**Also supports**: JSON (`.json`) and YAML (`.yaml`)4+**Formats**: TOML (recommended), JSON, YAML
6-**JSON Schema**: `~/.config/dumber/config.schema.json` (auto-generated for JSON format)
7-
8-## Why TOML?
9-
10-TOML 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-
16-You can still use JSON or YAML if you prefer - dumber automatically detects the format.
17 5
18 ## Database6 ## Database
19 7
A docs/config/reference.md +121 -0
@@ -0,0 +1,121 @@
1+# Configuration Reference
2+
3+| Key | Type | Default | Valid Values |
4+|-----|------|---------|--------------|
5+| `database.path` | string | `~/.local/share/dumber/dumber.db` | |
6+| `history.max_entries` | int | `10000` | > 0 |
7+| `history.retention_period_days` | int | `365` | > 0 |
8+| `history.cleanup_interval_days` | int | `1` | > 0 |
9+| `default_search_engine` | string | `https://duckduckgo.com/?q=%s` | URL with `%s` |
10+| `search_shortcuts.<name>.url` | string | | URL with `%s` |
11+| `search_shortcuts.<name>.description` | string | | |
12+| `dmenu.max_history_days` | int | `30` | >= 0 |
13+| `dmenu.show_visit_count` | bool | `true` | |
14+| `dmenu.show_last_visited` | bool | `true` | |
15+| `dmenu.history_prefix` | string | `🕒` | |
16+| `dmenu.shortcut_prefix` | string | `🔍` | |
17+| `dmenu.url_prefix` | string | `🌐` | |
18+| `dmenu.date_format` | string | `2006-01-02 15:04` | Go time format |
19+| `dmenu.sort_by_visit_count` | bool | `true` | |
20+| `omnibox.initial_behavior` | string | `recent` | `recent`, `most_visited`, `none` |
21+| `omnibox.auto_open_on_new_pane` | bool | `false` | |
22+| `logging.level` | string | `info` | `debug`, `info`, `warn`, `error` |
23+| `logging.format` | string | `text` | `text`, `json` |
24+| `logging.max_age` | int | `7` | >= 0 |
25+| `logging.log_dir` | string | `~/.local/state/dumber/logs/` | |
26+| `logging.enable_file_log` | bool | `true` | |
27+| `logging.capture_console` | bool | `false` | |
28+| `logging.capture_gtk_webkit_logs` | bool | `false` | |
29+| `appearance.sans_font` | string | `Fira Sans` | |
30+| `appearance.serif_font` | string | `Fira Sans` | |
31+| `appearance.monospace_font` | string | `Fira Code` | |
32+| `appearance.default_font_size` | int | `16` | |
33+| `appearance.color_scheme` | string | `default` | `prefer-dark`, `prefer-light`, `default` |
34+| `appearance.light_palette.background` | string | `#f8f8f8` | |
35+| `appearance.light_palette.surface` | string | `#f2f2f2` | |
36+| `appearance.light_palette.surface_variant` | string | `#ececec` | |
37+| `appearance.light_palette.text` | string | `#1a1a1a` | |
38+| `appearance.light_palette.muted` | string | `#6e6e6e` | |
39+| `appearance.light_palette.accent` | string | `#404040` | |
40+| `appearance.light_palette.border` | string | `#d2d2d2` | |
41+| `appearance.dark_palette.background` | string | `#0e0e0e` | |
42+| `appearance.dark_palette.surface` | string | `#1a1a1a` | |
43+| `appearance.dark_palette.surface_variant` | string | `#141414` | |
44+| `appearance.dark_palette.text` | string | `#e4e4e4` | |
45+| `appearance.dark_palette.muted` | string | `#848484` | |
46+| `appearance.dark_palette.accent` | string | `#a8a8a8` | |
47+| `appearance.dark_palette.border` | string | `#363636` | |
48+| `debug.enable_devtools` | bool | `true` | |
49+| `rendering.mode` | string | `gpu` | `auto`, `gpu`, `cpu` |
50+| `rendering.disable_dmabuf_renderer` | bool | `false` | |
51+| `rendering.force_compositing_mode` | bool | `false` | |
52+| `rendering.disable_compositing_mode` | bool | `false` | |
53+| `rendering.gsk_renderer` | string | `auto` | `auto`, `opengl`, `vulkan`, `cairo` |
54+| `rendering.disable_mipmaps` | bool | `false` | |
55+| `rendering.prefer_gl` | bool | `false` | |
56+| `rendering.draw_compositing_indicators` | bool | `false` | |
57+| `rendering.show_fps` | bool | `false` | |
58+| `rendering.sample_memory` | bool | `false` | |
59+| `rendering.debug_frames` | bool | `false` | |
60+| `default_ui_scale` | float | `1.0` | > 0 |
61+| `default_webpage_zoom` | float | `1.2` | > 0 |
62+| `workspace.new_pane_url` | string | `about:blank` | |
63+| `workspace.switch_to_tab_on_move` | bool | `true` | |
64+| `workspace.pane_mode.activation_shortcut` | string | `ctrl+p` | |
65+| `workspace.pane_mode.timeout_ms` | int | `3000` | |
66+| `workspace.tab_mode.activation_shortcut` | string | `ctrl+t` | |
67+| `workspace.tab_mode.timeout_ms` | int | `3000` | |
68+| `workspace.resize_mode.activation_shortcut` | string | `ctrl+n` | |
69+| `workspace.resize_mode.timeout_ms` | int | `3000` | |
70+| `workspace.resize_mode.step_percent` | float | `5.0` | |
71+| `workspace.resize_mode.min_pane_percent` | float | `10.0` | |
72+| `workspace.popups.behavior` | string | `split` | `split`, `stacked`, `tabbed`, `windowed` |
73+| `workspace.popups.placement` | string | `right` | `right`, `left`, `top`, `bottom` |
74+| `workspace.popups.open_in_new_pane` | bool | `true` | |
75+| `workspace.popups.follow_pane_context` | bool | `true` | |
76+| `workspace.popups.blank_target_behavior` | string | `pane` | `pane`, `tab` |
77+| `workspace.popups.enable_smart_detection` | bool | `true` | |
78+| `workspace.popups.oauth_auto_close` | bool | `true` | |
79+| `workspace.styling.border_width` | int | `1` | |
80+| `workspace.styling.border_color` | string | `@theme_selected_bg_color` | |
81+| `workspace.styling.mode_border_width` | int | `4` | |
82+| `workspace.styling.pane_mode_color` | string | `#4A90E2` | |
83+| `workspace.styling.tab_mode_color` | string | `#FFA500` | |
84+| `workspace.styling.session_mode_color` | string | `#9B59B6` | |
85+| `workspace.styling.resize_mode_color` | string | `#00D4AA` | |
86+| `workspace.styling.mode_indicator_toaster_enabled` | bool | `true` | |
87+| `workspace.styling.transition_duration` | int | `120` | |
88+| `session.auto_restore` | bool | `false` | |
89+| `session.snapshot_interval_ms` | int | `5000` | |
90+| `session.max_exited_sessions` | int | `50` | |
91+| `session.max_exited_session_age_days` | int | `7` | |
92+| `session.session_mode.activation_shortcut` | string | `ctrl+o` | |
93+| `session.session_mode.timeout_ms` | int | `3000` | |
94+| `media.hardware_decoding` | string | `auto` | `auto`, `force`, `disable` |
95+| `media.prefer_av1` | bool | `false` | |
96+| `media.show_diagnostics` | bool | `false` | |
97+| `media.force_vsync` | bool | `false` | |
98+| `media.gl_rendering_mode` | string | `auto` | `auto`, `gles2`, `gl3`, `none` |
99+| `media.gstreamer_debug_level` | int | `0` | 0-5 |
100+| `runtime.prefix` | string | `` | |
101+| `clipboard.auto_copy_on_selection` | bool | `true` | |
102+| `content_filtering.enabled` | bool | `true` | |
103+| `content_filtering.auto_update` | bool | `true` | |
104+| `update.enable_on_startup` | bool | `true` | |
105+| `update.auto_download` | bool | `false` | |
106+| `update.notify_on_new_settings` | bool | `true` | |
107+| `performance.profile` | string | `default` | `default`, `lite`, `max`, `custom` |
108+| `performance.skia_cpu_painting_threads` | int | `0` | |
109+| `performance.skia_gpu_painting_threads` | int | `-1` | |
110+| `performance.skia_enable_cpu_rendering` | bool | `false` | |
111+| `performance.web_process_memory_limit_mb` | int | `0` | |
112+| `performance.web_process_memory_poll_interval_sec` | float | `0` | |
113+| `performance.web_process_memory_conservative_threshold` | float | `0` | |
114+| `performance.web_process_memory_strict_threshold` | float | `0` | |
115+| `performance.network_process_memory_limit_mb` | int | `0` | |
116+| `performance.network_process_memory_poll_interval_sec` | float | `0` | |
117+| `performance.network_process_memory_conservative_threshold` | float | `0` | |
118+| `performance.network_process_memory_strict_threshold` | float | `0` | |
119+| `performance.webview_pool_prewarm_count` | int | `4` | |
120+| `performance.zoom_cache_size` | int | `256` | |
121+| `downloads.path` | string | `` | |
@@ -0,0 +1,121 @@
1+# Configuration Reference
2+
3+| Key | Type | Default | Valid Values |
4+|-----|------|---------|--------------|
5+| `database.path` | string | `~/.local/share/dumber/dumber.db` | |
6+| `history.max_entries` | int | `10000` | > 0 |
7+| `history.retention_period_days` | int | `365` | > 0 |
8+| `history.cleanup_interval_days` | int | `1` | > 0 |
9+| `default_search_engine` | string | `https://duckduckgo.com/?q=%s` | URL with `%s` |
10+| `search_shortcuts.<name>.url` | string | | URL with `%s` |
11+| `search_shortcuts.<name>.description` | string | | |
12+| `dmenu.max_history_days` | int | `30` | >= 0 |
13+| `dmenu.show_visit_count` | bool | `true` | |
14+| `dmenu.show_last_visited` | bool | `true` | |
15+| `dmenu.history_prefix` | string | `🕒` | |
16+| `dmenu.shortcut_prefix` | string | `🔍` | |
17+| `dmenu.url_prefix` | string | `🌐` | |
18+| `dmenu.date_format` | string | `2006-01-02 15:04` | Go time format |
19+| `dmenu.sort_by_visit_count` | bool | `true` | |
20+| `omnibox.initial_behavior` | string | `recent` | `recent`, `most_visited`, `none` |
21+| `omnibox.auto_open_on_new_pane` | bool | `false` | |
22+| `logging.level` | string | `info` | `debug`, `info`, `warn`, `error` |
23+| `logging.format` | string | `text` | `text`, `json` |
24+| `logging.max_age` | int | `7` | >= 0 |
25+| `logging.log_dir` | string | `~/.local/state/dumber/logs/` | |
26+| `logging.enable_file_log` | bool | `true` | |
27+| `logging.capture_console` | bool | `false` | |
28+| `logging.capture_gtk_webkit_logs` | bool | `false` | |
29+| `appearance.sans_font` | string | `Fira Sans` | |
30+| `appearance.serif_font` | string | `Fira Sans` | |
31+| `appearance.monospace_font` | string | `Fira Code` | |
32+| `appearance.default_font_size` | int | `16` | |
33+| `appearance.color_scheme` | string | `default` | `prefer-dark`, `prefer-light`, `default` |
34+| `appearance.light_palette.background` | string | `#f8f8f8` | |
35+| `appearance.light_palette.surface` | string | `#f2f2f2` | |
36+| `appearance.light_palette.surface_variant` | string | `#ececec` | |
37+| `appearance.light_palette.text` | string | `#1a1a1a` | |
38+| `appearance.light_palette.muted` | string | `#6e6e6e` | |
39+| `appearance.light_palette.accent` | string | `#404040` | |
40+| `appearance.light_palette.border` | string | `#d2d2d2` | |
41+| `appearance.dark_palette.background` | string | `#0e0e0e` | |
42+| `appearance.dark_palette.surface` | string | `#1a1a1a` | |
43+| `appearance.dark_palette.surface_variant` | string | `#141414` | |
44+| `appearance.dark_palette.text` | string | `#e4e4e4` | |
45+| `appearance.dark_palette.muted` | string | `#848484` | |
46+| `appearance.dark_palette.accent` | string | `#a8a8a8` | |
47+| `appearance.dark_palette.border` | string | `#363636` | |
48+| `debug.enable_devtools` | bool | `true` | |
49+| `rendering.mode` | string | `gpu` | `auto`, `gpu`, `cpu` |
50+| `rendering.disable_dmabuf_renderer` | bool | `false` | |
51+| `rendering.force_compositing_mode` | bool | `false` | |
52+| `rendering.disable_compositing_mode` | bool | `false` | |
53+| `rendering.gsk_renderer` | string | `auto` | `auto`, `opengl`, `vulkan`, `cairo` |
54+| `rendering.disable_mipmaps` | bool | `false` | |
55+| `rendering.prefer_gl` | bool | `false` | |
56+| `rendering.draw_compositing_indicators` | bool | `false` | |
57+| `rendering.show_fps` | bool | `false` | |
58+| `rendering.sample_memory` | bool | `false` | |
59+| `rendering.debug_frames` | bool | `false` | |
60+| `default_ui_scale` | float | `1.0` | > 0 |
61+| `default_webpage_zoom` | float | `1.2` | > 0 |
62+| `workspace.new_pane_url` | string | `about:blank` | |
63+| `workspace.switch_to_tab_on_move` | bool | `true` | |
64+| `workspace.pane_mode.activation_shortcut` | string | `ctrl+p` | |
65+| `workspace.pane_mode.timeout_ms` | int | `3000` | |
66+| `workspace.tab_mode.activation_shortcut` | string | `ctrl+t` | |
67+| `workspace.tab_mode.timeout_ms` | int | `3000` | |
68+| `workspace.resize_mode.activation_shortcut` | string | `ctrl+n` | |
69+| `workspace.resize_mode.timeout_ms` | int | `3000` | |
70+| `workspace.resize_mode.step_percent` | float | `5.0` | |
71+| `workspace.resize_mode.min_pane_percent` | float | `10.0` | |
72+| `workspace.popups.behavior` | string | `split` | `split`, `stacked`, `tabbed`, `windowed` |
73+| `workspace.popups.placement` | string | `right` | `right`, `left`, `top`, `bottom` |
74+| `workspace.popups.open_in_new_pane` | bool | `true` | |
75+| `workspace.popups.follow_pane_context` | bool | `true` | |
76+| `workspace.popups.blank_target_behavior` | string | `pane` | `pane`, `tab` |
77+| `workspace.popups.enable_smart_detection` | bool | `true` | |
78+| `workspace.popups.oauth_auto_close` | bool | `true` | |
79+| `workspace.styling.border_width` | int | `1` | |
80+| `workspace.styling.border_color` | string | `@theme_selected_bg_color` | |
81+| `workspace.styling.mode_border_width` | int | `4` | |
82+| `workspace.styling.pane_mode_color` | string | `#4A90E2` | |
83+| `workspace.styling.tab_mode_color` | string | `#FFA500` | |
84+| `workspace.styling.session_mode_color` | string | `#9B59B6` | |
85+| `workspace.styling.resize_mode_color` | string | `#00D4AA` | |
86+| `workspace.styling.mode_indicator_toaster_enabled` | bool | `true` | |
87+| `workspace.styling.transition_duration` | int | `120` | |
88+| `session.auto_restore` | bool | `false` | |
89+| `session.snapshot_interval_ms` | int | `5000` | |
90+| `session.max_exited_sessions` | int | `50` | |
91+| `session.max_exited_session_age_days` | int | `7` | |
92+| `session.session_mode.activation_shortcut` | string | `ctrl+o` | |
93+| `session.session_mode.timeout_ms` | int | `3000` | |
94+| `media.hardware_decoding` | string | `auto` | `auto`, `force`, `disable` |
95+| `media.prefer_av1` | bool | `false` | |
96+| `media.show_diagnostics` | bool | `false` | |
97+| `media.force_vsync` | bool | `false` | |
98+| `media.gl_rendering_mode` | string | `auto` | `auto`, `gles2`, `gl3`, `none` |
99+| `media.gstreamer_debug_level` | int | `0` | 0-5 |
100+| `runtime.prefix` | string | `` | |
101+| `clipboard.auto_copy_on_selection` | bool | `true` | |
102+| `content_filtering.enabled` | bool | `true` | |
103+| `content_filtering.auto_update` | bool | `true` | |
104+| `update.enable_on_startup` | bool | `true` | |
105+| `update.auto_download` | bool | `false` | |
106+| `update.notify_on_new_settings` | bool | `true` | |
107+| `performance.profile` | string | `default` | `default`, `lite`, `max`, `custom` |
108+| `performance.skia_cpu_painting_threads` | int | `0` | |
109+| `performance.skia_gpu_painting_threads` | int | `-1` | |
110+| `performance.skia_enable_cpu_rendering` | bool | `false` | |
111+| `performance.web_process_memory_limit_mb` | int | `0` | |
112+| `performance.web_process_memory_poll_interval_sec` | float | `0` | |
113+| `performance.web_process_memory_conservative_threshold` | float | `0` | |
114+| `performance.web_process_memory_strict_threshold` | float | `0` | |
115+| `performance.network_process_memory_limit_mb` | int | `0` | |
116+| `performance.network_process_memory_poll_interval_sec` | float | `0` | |
117+| `performance.network_process_memory_conservative_threshold` | float | `0` | |
118+| `performance.network_process_memory_strict_threshold` | float | `0` | |
119+| `performance.webview_pool_prewarm_count` | int | `4` | |
120+| `performance.zoom_cache_size` | int | `256` | |
121+| `downloads.path` | string | `` | |
A docs/getting-started.md +60 -0
@@ -0,0 +1,60 @@
1+# Getting Started
2+
3+## Launch the Browser
4+
5+```bash
6+dumber browse
7+```
8+
9+Or use the desktop entry after running `dumber setup`.
10+
11+## Basic Navigation
12+
13+Dumber uses modal keybindings inspired by Zellij:
14+
15+| Mode | Activation | Purpose |
16+|------|------------|---------|
17+| Pane Mode | `Ctrl+P` | Split, close, focus panes |
18+| Tab Mode | `Ctrl+T` | Create, close, switch tabs |
19+| Resize Mode | `Ctrl+N` | Resize pane splits |
20+| Session Mode | `Ctrl+O` | Session management |
21+
22+Press `Escape` or `Enter` to exit any mode.
23+
24+## Pane Mode Quick Reference
25+
26+1. Press `Ctrl+P` to enter pane mode
27+2. Use arrow keys or `hjkl` to split in that direction
28+3. `Shift+arrows` to focus adjacent panes
29+4. `X` to close current pane
30+
31+## Omnibox
32+
33+Press `Ctrl+L` to open the omnibox for:
34+- URL navigation
35+- Search (uses default search engine)
36+- Bang shortcuts (`!g query` for Google, `!gh query` for GitHub)
37+
38+## Configuration
39+
40+Edit `~/.config/dumber/config.toml` or use:
41+
42+```bash
43+dumber config open
44+```
45+
46+See [Configuration](./config/index.md) for all options.
47+
48+## Launcher Integration
49+
50+Use with rofi or fuzzel:
51+
52+```bash
53+dumber dmenu | rofi -dmenu -show-icons | dumber dmenu --select
54+```
55+
56+## Next Steps
57+
58+- [Configuration Reference](./config/reference.md) - All settings
59+- [Keybindings](./reference/keybindings.md) - Full keyboard shortcuts
60+- [CLI Commands](./cli/index.md) - Command-line tools
@@ -0,0 +1,60 @@
1+# Getting Started
2+
3+## Launch the Browser
4+
5+```bash
6+dumber browse
7+```
8+
9+Or use the desktop entry after running `dumber setup`.
10+
11+## Basic Navigation
12+
13+Dumber uses modal keybindings inspired by Zellij:
14+
15+| Mode | Activation | Purpose |
16+|------|------------|---------|
17+| Pane Mode | `Ctrl+P` | Split, close, focus panes |
18+| Tab Mode | `Ctrl+T` | Create, close, switch tabs |
19+| Resize Mode | `Ctrl+N` | Resize pane splits |
20+| Session Mode | `Ctrl+O` | Session management |
21+
22+Press `Escape` or `Enter` to exit any mode.
23+
24+## Pane Mode Quick Reference
25+
26+1. Press `Ctrl+P` to enter pane mode
27+2. Use arrow keys or `hjkl` to split in that direction
28+3. `Shift+arrows` to focus adjacent panes
29+4. `X` to close current pane
30+
31+## Omnibox
32+
33+Press `Ctrl+L` to open the omnibox for:
34+- URL navigation
35+- Search (uses default search engine)
36+- Bang shortcuts (`!g query` for Google, `!gh query` for GitHub)
37+
38+## Configuration
39+
40+Edit `~/.config/dumber/config.toml` or use:
41+
42+```bash
43+dumber config open
44+```
45+
46+See [Configuration](./config/index.md) for all options.
47+
48+## Launcher Integration
49+
50+Use with rofi or fuzzel:
51+
52+```bash
53+dumber dmenu | rofi -dmenu -show-icons | dumber dmenu --select
54+```
55+
56+## Next Steps
57+
58+- [Configuration Reference](./config/reference.md) - All settings
59+- [Keybindings](./reference/keybindings.md) - Full keyboard shortcuts
60+- [CLI Commands](./cli/index.md) - Command-line tools
A docs/index.md +41 -0
@@ -0,0 +1,41 @@
1+# Dumber Documentation
2+
3+Dumber is a keyboard-driven browser for tiling window managers, built with GTK4 and WebKitGTK.
4+
5+## What is Dumber?
6+
7+A browser designed for Wayland compositors that works like your favorite terminal multiplexer:
8+
9+- **Tiling Panes** - Split, stack, and organize pages like Zellij/tmux
10+- **Modal Keybindings** - Keyboard-driven workflow with mode indicators
11+- **Session Management** - Auto-save and restore workspaces
12+- **Built-in Ad Blocking** - UBlock-based network + cosmetic filtering
13+- **Launcher Integration** - Rofi/fuzzel with favicons and history
14+- **GPU Rendering** - Automatic VA-API detection for video playback
15+
16+## Quick Navigation
17+
18+### Getting Started
19+
20+- [Installation](./installation.md) - Install via script, Flatpak, or from source
21+- [Getting Started](./getting-started.md) - First steps after installation
22+
23+### Configuration
24+
25+- [Configuration Overview](./config/index.md) - All configuration options
26+- [Configuration Reference](./config/reference.md) - Quick reference table
27+
28+### CLI Reference
29+
30+- [CLI Commands](./cli/index.md) - All available commands
31+
32+### Reference
33+
34+- [Keybindings](./reference/keybindings.md) - Keyboard shortcuts reference
35+- [Troubleshooting](./reference/troubleshooting.md) - Common issues and solutions
36+
37+## Requirements
38+
39+- Linux with Wayland (Sway, Hyprland, River, Niri, etc.)
40+- GTK4 and WebKitGTK 2.42+
41+- GStreamer (for media playback)
@@ -0,0 +1,41 @@
1+# Dumber Documentation
2+
3+Dumber is a keyboard-driven browser for tiling window managers, built with GTK4 and WebKitGTK.
4+
5+## What is Dumber?
6+
7+A browser designed for Wayland compositors that works like your favorite terminal multiplexer:
8+
9+- **Tiling Panes** - Split, stack, and organize pages like Zellij/tmux
10+- **Modal Keybindings** - Keyboard-driven workflow with mode indicators
11+- **Session Management** - Auto-save and restore workspaces
12+- **Built-in Ad Blocking** - UBlock-based network + cosmetic filtering
13+- **Launcher Integration** - Rofi/fuzzel with favicons and history
14+- **GPU Rendering** - Automatic VA-API detection for video playback
15+
16+## Quick Navigation
17+
18+### Getting Started
19+
20+- [Installation](./installation.md) - Install via script, Flatpak, or from source
21+- [Getting Started](./getting-started.md) - First steps after installation
22+
23+### Configuration
24+
25+- [Configuration Overview](./config/index.md) - All configuration options
26+- [Configuration Reference](./config/reference.md) - Quick reference table
27+
28+### CLI Reference
29+
30+- [CLI Commands](./cli/index.md) - All available commands
31+
32+### Reference
33+
34+- [Keybindings](./reference/keybindings.md) - Keyboard shortcuts reference
35+- [Troubleshooting](./reference/troubleshooting.md) - Common issues and solutions
36+
37+## Requirements
38+
39+- Linux with Wayland (Sway, Hyprland, River, Niri, etc.)
40+- GTK4 and WebKitGTK 2.42+
41+- GStreamer (for media playback)
A docs/installation.md +53 -0
@@ -0,0 +1,53 @@
1+# Installation
2+
3+## Quick Install (Linux x86_64)
4+
5+```bash
6+curl -fsSL https://dumber.bnema.dev/install | bash
7+```
8+
9+Installs to `~/.local/bin` if available, otherwise `/usr/local/bin` (requires sudo).
10+
11+## Flatpak
12+
13+```bash
14+# From Flathub (when available)
15+flatpak install flathub dev.bnema.Dumber
16+
17+# Or from release
18+flatpak install dumber.flatpak
19+```
20+
21+## From Source
22+
23+```bash
24+git clone https://github.com/bnema/dumber
25+cd dumber
26+go build -o dumber ./cmd/dumber
27+```
28+
29+### Build Dependencies
30+
31+- Go 1.25+
32+- GTK4 development libraries
33+- WebKitGTK 2.42+ development libraries
34+- GStreamer development libraries
35+
36+## Post-Install
37+
38+Run the setup wizard to configure desktop integration:
39+
40+```bash
41+dumber setup
42+```
43+
44+This creates:
45+- Desktop entry (`~/.local/share/applications/`)
46+- Default configuration (`~/.config/dumber/config.toml`)
47+
48+## Verify Installation
49+
50+```bash
51+dumber about
52+dumber doctor
53+```
@@ -0,0 +1,53 @@
1+# Installation
2+
3+## Quick Install (Linux x86_64)
4+
5+```bash
6+curl -fsSL https://dumber.bnema.dev/install | bash
7+```
8+
9+Installs to `~/.local/bin` if available, otherwise `/usr/local/bin` (requires sudo).
10+
11+## Flatpak
12+
13+```bash
14+# From Flathub (when available)
15+flatpak install flathub dev.bnema.Dumber
16+
17+# Or from release
18+flatpak install dumber.flatpak
19+```
20+
21+## From Source
22+
23+```bash
24+git clone https://github.com/bnema/dumber
25+cd dumber
26+go build -o dumber ./cmd/dumber
27+```
28+
29+### Build Dependencies
30+
31+- Go 1.25+
32+- GTK4 development libraries
33+- WebKitGTK 2.42+ development libraries
34+- GStreamer development libraries
35+
36+## Post-Install
37+
38+Run the setup wizard to configure desktop integration:
39+
40+```bash
41+dumber setup
42+```
43+
44+This creates:
45+- Desktop entry (`~/.local/share/applications/`)
46+- Default configuration (`~/.config/dumber/config.toml`)
47+
48+## Verify Installation
49+
50+```bash
51+dumber about
52+dumber doctor
53+```
A docs/reference/index.md +11 -0
@@ -0,0 +1,11 @@
1+# Reference
2+
3+## Quick Links
4+
5+- [Keybindings](./keybindings.md) - All keyboard shortcuts
6+- [Troubleshooting](./troubleshooting.md) - Common issues and solutions
7+
8+## Related
9+
10+- [Configuration Reference](../config/reference.md) - All config keys
11+- [CLI Commands](../cli/index.md) - Command-line interface
@@ -0,0 +1,11 @@
1+# Reference
2+
3+## Quick Links
4+
5+- [Keybindings](./keybindings.md) - All keyboard shortcuts
6+- [Troubleshooting](./troubleshooting.md) - Common issues and solutions
7+
8+## Related
9+
10+- [Configuration Reference](../config/reference.md) - All config keys
11+- [CLI Commands](../cli/index.md) - Command-line interface
A docs/reference/keybindings.md +103 -0
@@ -0,0 +1,103 @@
1+# Keybindings
2+
3+Dumber uses modal keybindings inspired by Zellij. Press a mode activation key, then use action keys within that mode.
4+
5+## Mode Activation
6+
7+| Mode | Key | Purpose |
8+|------|-----|---------|
9+| Pane Mode | `Ctrl+P` | Split, close, focus panes |
10+| Tab Mode | `Ctrl+T` | Create, close, switch tabs |
11+| Resize Mode | `Ctrl+N` | Resize pane splits |
12+| Session Mode | `Ctrl+O` | Session management |
13+
14+Press `Escape` or `Enter` to exit any mode.
15+
16+## Pane Mode (`Ctrl+P`)
17+
18+| Action | Keys |
19+|--------|------|
20+| Split right | `→`, `R` |
21+| Split left | `←`, `L` |
22+| Split up | `↑`, `U` |
23+| Split down | `↓`, `D` |
24+| Stack pane | `S` |
25+| Close pane | `X` |
26+| Move to tab | `M` |
27+| Move to next tab | `Shift+M` |
28+| Focus right | `Shift+→`, `Shift+L` |
29+| Focus left | `Shift+←`, `Shift+H` |
30+| Focus up | `Shift+↑`, `Shift+K` |
31+| Focus down | `Shift+↓`, `Shift+J` |
32+| Consume/expel left | `[` |
33+| Consume/expel right | `]` |
34+| Consume/expel up | `{` |
35+| Consume/expel down | `}` |
36+| Confirm | `Enter` |
37+| Cancel | `Escape` |
38+
39+## Tab Mode (`Ctrl+T`)
40+
41+| Action | Keys |
42+|--------|------|
43+| New tab | `N`, `C` |
44+| Close tab | `X` |
45+| Next tab | `L`, `Tab` |
46+| Previous tab | `H`, `Shift+Tab` |
47+| Rename tab | `R` |
48+| Confirm | `Enter` |
49+| Cancel | `Escape` |
50+
51+## Resize Mode (`Ctrl+N`)
52+
53+| Action | Keys |
54+|--------|------|
55+| Increase left | `H`, `←` |
56+| Increase down | `J`, `↓` |
57+| Increase up | `K`, `↑` |
58+| Increase right | `L`, `→` |
59+| Decrease left | `Shift+H` |
60+| Decrease down | `Shift+J` |
61+| Decrease up | `Shift+K` |
62+| Decrease right | `Shift+L` |
63+| Increase (smart) | `+`, `=` |
64+| Decrease (smart) | `-` |
65+| Confirm | `Enter` |
66+| Cancel | `Escape` |
67+
68+## Session Mode (`Ctrl+O`)
69+
70+| Action | Keys |
71+|--------|------|
72+| Session manager | `S`, `W` |
73+| Confirm | `Enter` |
74+| Cancel | `Escape` |
75+
76+## Global Shortcuts
77+
78+These work outside modal modes:
79+
80+| Action | Keys |
81+|--------|------|
82+| Close pane | `Ctrl+W` |
83+| Next tab | `Ctrl+Tab` |
84+| Previous tab | `Ctrl+Shift+Tab` |
85+| Consume/expel left | `Alt+[` |
86+| Consume/expel right | `Alt+]` |
87+| Consume/expel up | `Alt+{` |
88+| Consume/expel down | `Alt+}` |
89+
90+## Customization
91+
92+All keybindings can be customized in `~/.config/dumber/config.toml`:
93+
94+```toml
95+[workspace.pane_mode.actions]
96+split-right = ["arrowright", "r"]
97+close-pane = ["x", "q"]
98+
99+[workspace.shortcuts.actions.close_pane]
100+keys = ["ctrl+w"]
101+```
102+
103+See [Configuration](../config/index.md) for full details.
@@ -0,0 +1,103 @@
1+# Keybindings
2+
3+Dumber uses modal keybindings inspired by Zellij. Press a mode activation key, then use action keys within that mode.
4+
5+## Mode Activation
6+
7+| Mode | Key | Purpose |
8+|------|-----|---------|
9+| Pane Mode | `Ctrl+P` | Split, close, focus panes |
10+| Tab Mode | `Ctrl+T` | Create, close, switch tabs |
11+| Resize Mode | `Ctrl+N` | Resize pane splits |
12+| Session Mode | `Ctrl+O` | Session management |
13+
14+Press `Escape` or `Enter` to exit any mode.
15+
16+## Pane Mode (`Ctrl+P`)
17+
18+| Action | Keys |
19+|--------|------|
20+| Split right | `→`, `R` |
21+| Split left | `←`, `L` |
22+| Split up | `↑`, `U` |
23+| Split down | `↓`, `D` |
24+| Stack pane | `S` |
25+| Close pane | `X` |
26+| Move to tab | `M` |
27+| Move to next tab | `Shift+M` |
28+| Focus right | `Shift+→`, `Shift+L` |
29+| Focus left | `Shift+←`, `Shift+H` |
30+| Focus up | `Shift+↑`, `Shift+K` |
31+| Focus down | `Shift+↓`, `Shift+J` |
32+| Consume/expel left | `[` |
33+| Consume/expel right | `]` |
34+| Consume/expel up | `{` |
35+| Consume/expel down | `}` |
36+| Confirm | `Enter` |
37+| Cancel | `Escape` |
38+
39+## Tab Mode (`Ctrl+T`)
40+
41+| Action | Keys |
42+|--------|------|
43+| New tab | `N`, `C` |
44+| Close tab | `X` |
45+| Next tab | `L`, `Tab` |
46+| Previous tab | `H`, `Shift+Tab` |
47+| Rename tab | `R` |
48+| Confirm | `Enter` |
49+| Cancel | `Escape` |
50+
51+## Resize Mode (`Ctrl+N`)
52+
53+| Action | Keys |
54+|--------|------|
55+| Increase left | `H`, `←` |
56+| Increase down | `J`, `↓` |
57+| Increase up | `K`, `↑` |
58+| Increase right | `L`, `→` |
59+| Decrease left | `Shift+H` |
60+| Decrease down | `Shift+J` |
61+| Decrease up | `Shift+K` |
62+| Decrease right | `Shift+L` |
63+| Increase (smart) | `+`, `=` |
64+| Decrease (smart) | `-` |
65+| Confirm | `Enter` |
66+| Cancel | `Escape` |
67+
68+## Session Mode (`Ctrl+O`)
69+
70+| Action | Keys |
71+|--------|------|
72+| Session manager | `S`, `W` |
73+| Confirm | `Enter` |
74+| Cancel | `Escape` |
75+
76+## Global Shortcuts
77+
78+These work outside modal modes:
79+
80+| Action | Keys |
81+|--------|------|
82+| Close pane | `Ctrl+W` |
83+| Next tab | `Ctrl+Tab` |
84+| Previous tab | `Ctrl+Shift+Tab` |
85+| Consume/expel left | `Alt+[` |
86+| Consume/expel right | `Alt+]` |
87+| Consume/expel up | `Alt+{` |
88+| Consume/expel down | `Alt+}` |
89+
90+## Customization
91+
92+All keybindings can be customized in `~/.config/dumber/config.toml`:
93+
94+```toml
95+[workspace.pane_mode.actions]
96+split-right = ["arrowright", "r"]
97+close-pane = ["x", "q"]
98+
99+[workspace.shortcuts.actions.close_pane]
100+keys = ["ctrl+w"]
101+```
102+
103+See [Configuration](../config/index.md) for full details.
A docs/reference/troubleshooting.md +132 -0
@@ -0,0 +1,132 @@
1+# Troubleshooting
2+
3+## Diagnostics
4+
5+Run the doctor command to check your system:
6+
7+```bash
8+dumber doctor # Full check
9+dumber doctor --runtime # GTK4/WebKitGTK only
10+dumber doctor --media # GStreamer/VA-API only
11+```
12+
13+## Common Issues
14+
15+### Browser won't start
16+
17+**Symptoms:** Error about missing libraries or GTK/WebKitGTK version
18+
19+**Solution:**
20+1. Run `dumber doctor --runtime`
21+2. Install missing dependencies:
22+ - Arch: `pacman -S webkitgtk-6.0 gtk4`
23+ - Fedora: `dnf install webkitgtk6.0 gtk4`
24+ - Ubuntu: `apt install libwebkitgtk-6.0-4 libgtk-4-1`
25+
26+### Video playback issues
27+
28+**Symptoms:** Videos don't play, high CPU usage, or Error #4000 on Twitch
29+
30+**Solution:**
31+1. Run `dumber doctor --media`
32+2. Check hardware decoding:
33+ ```toml
34+ # ~/.config/dumber/config.toml
35+ [media]
36+ hardware_decoding = "auto" # Try "disable" if issues persist
37+ ```
38+3. Install VA-API drivers:
39+ - AMD: `libva-mesa-driver`
40+ - Intel: `intel-media-driver`
41+ - NVIDIA: `libva-nvidia-driver`
42+
43+### Screen flickering on Wayland
44+
45+**Symptoms:** Flicker when scrolling or rendering
46+
47+**Solution:**
48+```toml
49+[rendering]
50+disable_dmabuf_renderer = true
51+```
52+
53+### Fonts look wrong
54+
55+**Symptoms:** Missing characters, wrong font rendering
56+
57+**Solution:**
58+```toml
59+[appearance]
60+sans_font = "Your Preferred Font"
61+monospace_font = "Your Mono Font"
62+default_font_size = 16
63+```
64+
65+### High memory usage
66+
67+**Symptoms:** Browser uses too much RAM
68+
69+**Solution:**
70+```toml
71+[performance]
72+profile = "lite" # Reduces resource usage
73+```
74+
75+### Session not restoring
76+
77+**Symptoms:** Previous tabs/panes don't restore on startup
78+
79+**Solution:**
80+1. Check session auto-restore:
81+ ```toml
82+ [session]
83+ auto_restore = true
84+ ```
85+2. List sessions: `dumber sessions list`
86+3. Manually restore: `dumber sessions restore <id>`
87+
88+### Launcher integration not working
89+
90+**Symptoms:** Rofi/fuzzel doesn't show history or icons
91+
92+**Solution:**
93+1. Ensure PNG favicons are cached:
94+ ```bash
95+ dumber dmenu | head -5 # Should show entries with icon paths
96+ ```
97+2. Check rofi/fuzzel supports icons:
98+ ```bash
99+ dumber dmenu | rofi -dmenu -show-icons
100+ ```
101+
102+## Logs
103+
104+View application logs for debugging:
105+
106+```bash
107+dumber logs # List sessions
108+dumber logs <session-id> # View specific session
109+dumber logs -f <id> # Follow in real-time
110+```
111+
112+## Reset Configuration
113+
114+If config is corrupted:
115+
116+```bash
117+mv ~/.config/dumber/config.toml ~/.config/dumber/config.toml.bak
118+dumber browse # Creates new default config
119+```
120+
121+## Complete Reset
122+
123+Remove all data and start fresh:
124+
125+```bash
126+dumber purge
127+```
128+
129+## Getting Help
130+
131+- Check logs: `dumber logs`
132+- [GitHub Issues](https://github.com/bnema/dumber/issues)
@@ -0,0 +1,132 @@
1+# Troubleshooting
2+
3+## Diagnostics
4+
5+Run the doctor command to check your system:
6+
7+```bash
8+dumber doctor # Full check
9+dumber doctor --runtime # GTK4/WebKitGTK only
10+dumber doctor --media # GStreamer/VA-API only
11+```
12+
13+## Common Issues
14+
15+### Browser won't start
16+
17+**Symptoms:** Error about missing libraries or GTK/WebKitGTK version
18+
19+**Solution:**
20+1. Run `dumber doctor --runtime`
21+2. Install missing dependencies:
22+ - Arch: `pacman -S webkitgtk-6.0 gtk4`
23+ - Fedora: `dnf install webkitgtk6.0 gtk4`
24+ - Ubuntu: `apt install libwebkitgtk-6.0-4 libgtk-4-1`
25+
26+### Video playback issues
27+
28+**Symptoms:** Videos don't play, high CPU usage, or Error #4000 on Twitch
29+
30+**Solution:**
31+1. Run `dumber doctor --media`
32+2. Check hardware decoding:
33+ ```toml
34+ # ~/.config/dumber/config.toml
35+ [media]
36+ hardware_decoding = "auto" # Try "disable" if issues persist
37+ ```
38+3. Install VA-API drivers:
39+ - AMD: `libva-mesa-driver`
40+ - Intel: `intel-media-driver`
41+ - NVIDIA: `libva-nvidia-driver`
42+
43+### Screen flickering on Wayland
44+
45+**Symptoms:** Flicker when scrolling or rendering
46+
47+**Solution:**
48+```toml
49+[rendering]
50+disable_dmabuf_renderer = true
51+```
52+
53+### Fonts look wrong
54+
55+**Symptoms:** Missing characters, wrong font rendering
56+
57+**Solution:**
58+```toml
59+[appearance]
60+sans_font = "Your Preferred Font"
61+monospace_font = "Your Mono Font"
62+default_font_size = 16
63+```
64+
65+### High memory usage
66+
67+**Symptoms:** Browser uses too much RAM
68+
69+**Solution:**
70+```toml
71+[performance]
72+profile = "lite" # Reduces resource usage
73+```
74+
75+### Session not restoring
76+
77+**Symptoms:** Previous tabs/panes don't restore on startup
78+
79+**Solution:**
80+1. Check session auto-restore:
81+ ```toml
82+ [session]
83+ auto_restore = true
84+ ```
85+2. List sessions: `dumber sessions list`
86+3. Manually restore: `dumber sessions restore <id>`
87+
88+### Launcher integration not working
89+
90+**Symptoms:** Rofi/fuzzel doesn't show history or icons
91+
92+**Solution:**
93+1. Ensure PNG favicons are cached:
94+ ```bash
95+ dumber dmenu | head -5 # Should show entries with icon paths
96+ ```
97+2. Check rofi/fuzzel supports icons:
98+ ```bash
99+ dumber dmenu | rofi -dmenu -show-icons
100+ ```
101+
102+## Logs
103+
104+View application logs for debugging:
105+
106+```bash
107+dumber logs # List sessions
108+dumber logs <session-id> # View specific session
109+dumber logs -f <id> # Follow in real-time
110+```
111+
112+## Reset Configuration
113+
114+If config is corrupted:
115+
116+```bash
117+mv ~/.config/dumber/config.toml ~/.config/dumber/config.toml.bak
118+dumber browse # Creates new default config
119+```
120+
121+## Complete Reset
122+
123+Remove all data and start fresh:
124+
125+```bash
126+dumber purge
127+```
128+
129+## Getting Help
130+
131+- Check logs: `dumber logs`
132+- [GitHub Issues](https://github.com/bnema/dumber/issues)
D docs/v0.14.0-release-notes.md +0 -33
@@ -1,33 +0,0 @@
1-## [0.14.0] - 2025-11-18
2-
3-### Added
4-- **Zellij-style tab system**: Each tab contains an independent workspace with panes, splits, and stacks. `Ctrl+T` enters tab mode with modal keyboard control (`n`=new, `x`=close, `l/h`=navigate). `Alt+1-9/0` for direct tab switching. `Ctrl+Tab`/`Ctrl+Shift+Tab` for next/previous tab. Tab bar auto-hides with single tab. Orange border indicator (distinct from blue pane mode).
5-- **International keyboard layout support**: Hardware keycode-based shortcuts for `Alt+number` keys work across all keyboard layouts (QWERTY, AZERTY, QWERTZ, etc.). Physical key position used instead of character mapping.
6-- **Click-to-activate stacked panes**: Click on any collapsed title bar to instantly activate that pane. Uses GTK4 gesture clicks for native interaction feel.
7-- **Title bar visual separators**: Subtle 1px borders between stacked title bars. Theme-aware colors automatically adjust for light/dark mode.
8-- **UI scaling for title bars**: New `workspace.styling.ui_scale` config option (default: 1.0). Scales font size, padding, height, and favicon size. Range: 0.5 to 3.0 (e.g., 1.2 = 120% size).
9-- **Favorites system**: Full favorites management with keyboard controls and persistent storage. Press `Tab` to switch between History and Favorites views. Press `Space` to add/remove items. Yellow border indicates favorited items in History view. View mode persists across sessions. Database-backed with RAM-first caching for performance.
10-- **Omnibox quick navigation**: Press `Ctrl+1` through `Ctrl+9` to instantly navigate to the first 9 results, or `Ctrl+0` for the 10th. Works in both History and Favorites views. Visual number hints appear on each item. Keyboard layout independent (works on QWERTY, AZERTY, QWERTZ, etc.).
11-- **Middle-click and Ctrl+click link handling**: Links can now be opened in new workspace panes using standard browser gestures (middle-click or Ctrl+left-click). New panes split in the configured direction (default: right) and respect `workspace.popups.placement` configuration. Implemented via WebKit's `decide-policy` signal to intercept navigation actions before they occur.
12-- **Configurable pane border styling**: Added `workspace.styling.inactive_border_width`, `workspace.styling.inactive_border_color`, and `workspace.styling.show_stacked_title_border` config options. Active and inactive borders default to 1px to prevent layout shift, with only color changing on focus. Borders use GTK theme variables by default and support smooth CSS transitions.
13-- **Configurable default search engine**: Added `default_search_engine` config option with explicit URL template format. DuckDuckGo is now the default (was Google). Users can set any search engine with `%s` placeholder (e.g., `default_search_engine = "https://duckduckgo.com/?q=%s"`).
14-
15-### Changed
16-- **Target="_blank" and gesture link behavior**: Links with `target="_blank"`, Ctrl+click, and middle-click now open in stacked panes mode by default instead of split-right. New config option `workspace.popups.blank_target_behavior` (values: "split", "stacked", "tabbed") controls this behavior separately from JavaScript popups. Prevents browser exit when closing parent pane by marking _blank panes as popup-type.
17-- **Config format**: TOML is now the default format (JSON/YAML still supported). Action bindings inverted to `action→keys` structure for maintainability with O(1) runtime lookup. Added comprehensive validation.
18-- **Code cleanup**: Removed dead code files and emojis from GUI modules
19-- **Bridge architecture**: Unified main-world to isolated-world bridge system with comprehensive documentation. Single dispatcher for all window function bridges (omnibox, favorites, toasts). Better separation between CustomEvents (shared between worlds) and window functions (require bridging).
20-- **Omnibox spacing**: Increased vertical spacing between suggestion items from 0.65rem to 0.85rem for better readability
21-- **Smart Escape key**: First press clears input text, second press closes omnibox. Empty input closes immediately.
22-
23-### Fixed
24-- **Ctrl+Tab shortcuts**: Fixed focus cycling behavior, now properly switches between tabs
25-- **Active tab visibility**: Fixed identical styling - active tab now clearly visible with distinct gray shade
26-- **AZERTY keyboard support**: Alt+number shortcuts now work on all keyboard layouts using hardware keycodes
27-- **Keyboard layout detection**: Fixed always detecting "en" - now correctly detects fr/de/etc layouts
28-- **Zoom visual glitch**: Fixed zoom level for next page being applied before navigation completed, causing visible zoom change on current page. Zoom now applies on load-committed event instead of URI change.
29-- **Toast notifications**: Fixed toast notifications not appearing for copy URL (Ctrl+Shift+C) and clipboard operations. Event name was `dumber:showToast` but ToastContainer listens for `dumber:toast`.
30-- **Page reload shortcuts**: Restored `Ctrl+R`, `Ctrl+Shift+R`, `F5`, and `Ctrl+F5` shortcuts. They were registered but not actually wired to the window-level handler.
31-- **Bootstrap initialization**: Fixed omnibox component not mounting due to invalid toast function check in isolated world. Toast functions now bridge correctly via CustomEvents, allowing omnibox to initialize properly.
32-- **Empty state display**: History view now hides empty state when input is empty, showing it only when user has typed and no results are found. Favorites view always shows empty state with helpful hints.
33-
@@ -1,33 +0,0 @@
1-## [0.14.0] - 2025-11-18
2-
3-### Added
4-- **Zellij-style tab system**: Each tab contains an independent workspace with panes, splits, and stacks. `Ctrl+T` enters tab mode with modal keyboard control (`n`=new, `x`=close, `l/h`=navigate). `Alt+1-9/0` for direct tab switching. `Ctrl+Tab`/`Ctrl+Shift+Tab` for next/previous tab. Tab bar auto-hides with single tab. Orange border indicator (distinct from blue pane mode).
5-- **International keyboard layout support**: Hardware keycode-based shortcuts for `Alt+number` keys work across all keyboard layouts (QWERTY, AZERTY, QWERTZ, etc.). Physical key position used instead of character mapping.
6-- **Click-to-activate stacked panes**: Click on any collapsed title bar to instantly activate that pane. Uses GTK4 gesture clicks for native interaction feel.
7-- **Title bar visual separators**: Subtle 1px borders between stacked title bars. Theme-aware colors automatically adjust for light/dark mode.
8-- **UI scaling for title bars**: New `workspace.styling.ui_scale` config option (default: 1.0). Scales font size, padding, height, and favicon size. Range: 0.5 to 3.0 (e.g., 1.2 = 120% size).
9-- **Favorites system**: Full favorites management with keyboard controls and persistent storage. Press `Tab` to switch between History and Favorites views. Press `Space` to add/remove items. Yellow border indicates favorited items in History view. View mode persists across sessions. Database-backed with RAM-first caching for performance.
10-- **Omnibox quick navigation**: Press `Ctrl+1` through `Ctrl+9` to instantly navigate to the first 9 results, or `Ctrl+0` for the 10th. Works in both History and Favorites views. Visual number hints appear on each item. Keyboard layout independent (works on QWERTY, AZERTY, QWERTZ, etc.).
11-- **Middle-click and Ctrl+click link handling**: Links can now be opened in new workspace panes using standard browser gestures (middle-click or Ctrl+left-click). New panes split in the configured direction (default: right) and respect `workspace.popups.placement` configuration. Implemented via WebKit's `decide-policy` signal to intercept navigation actions before they occur.
12-- **Configurable pane border styling**: Added `workspace.styling.inactive_border_width`, `workspace.styling.inactive_border_color`, and `workspace.styling.show_stacked_title_border` config options. Active and inactive borders default to 1px to prevent layout shift, with only color changing on focus. Borders use GTK theme variables by default and support smooth CSS transitions.
13-- **Configurable default search engine**: Added `default_search_engine` config option with explicit URL template format. DuckDuckGo is now the default (was Google). Users can set any search engine with `%s` placeholder (e.g., `default_search_engine = "https://duckduckgo.com/?q=%s"`).
14-
15-### Changed
16-- **Target="_blank" and gesture link behavior**: Links with `target="_blank"`, Ctrl+click, and middle-click now open in stacked panes mode by default instead of split-right. New config option `workspace.popups.blank_target_behavior` (values: "split", "stacked", "tabbed") controls this behavior separately from JavaScript popups. Prevents browser exit when closing parent pane by marking _blank panes as popup-type.
17-- **Config format**: TOML is now the default format (JSON/YAML still supported). Action bindings inverted to `action→keys` structure for maintainability with O(1) runtime lookup. Added comprehensive validation.
18-- **Code cleanup**: Removed dead code files and emojis from GUI modules
19-- **Bridge architecture**: Unified main-world to isolated-world bridge system with comprehensive documentation. Single dispatcher for all window function bridges (omnibox, favorites, toasts). Better separation between CustomEvents (shared between worlds) and window functions (require bridging).
20-- **Omnibox spacing**: Increased vertical spacing between suggestion items from 0.65rem to 0.85rem for better readability
21-- **Smart Escape key**: First press clears input text, second press closes omnibox. Empty input closes immediately.
22-
23-### Fixed
24-- **Ctrl+Tab shortcuts**: Fixed focus cycling behavior, now properly switches between tabs
25-- **Active tab visibility**: Fixed identical styling - active tab now clearly visible with distinct gray shade
26-- **AZERTY keyboard support**: Alt+number shortcuts now work on all keyboard layouts using hardware keycodes
27-- **Keyboard layout detection**: Fixed always detecting "en" - now correctly detects fr/de/etc layouts
28-- **Zoom visual glitch**: Fixed zoom level for next page being applied before navigation completed, causing visible zoom change on current page. Zoom now applies on load-committed event instead of URI change.
29-- **Toast notifications**: Fixed toast notifications not appearing for copy URL (Ctrl+Shift+C) and clipboard operations. Event name was `dumber:showToast` but ToastContainer listens for `dumber:toast`.
30-- **Page reload shortcuts**: Restored `Ctrl+R`, `Ctrl+Shift+R`, `F5`, and `Ctrl+F5` shortcuts. They were registered but not actually wired to the window-level handler.
31-- **Bootstrap initialization**: Fixed omnibox component not mounting due to invalid toast function check in isolated world. Toast functions now bridge correctly via CustomEvents, allowing omnibox to initialize properly.
32-- **Empty state display**: History view now hides empty state when input is empty, showing it only when user has typed and no results are found. Favorites view always shows empty state with helpful hints.
33-
D docs/v0.14.1-release-notes.md +0 -17
@@ -1,17 +0,0 @@
1-## [0.14.1] - 2025-11-18
2-
3-### Added
4-- **Inline tab rename**: Press `Alt+T` then `r` to rename tabs directly in the tab bar. Enter saves, Escape cancels. Tab buttons temporarily allow focus during rename, then restore original focus behavior to prevent interfering with WebView keyboard input.
5-- **Cloudflare Turnstile CAPTCHA support**: Temporary CORS allowlist workaround for `challenges.cloudflare.com` to bypass WebKit's incomplete COEP credentialless implementation. Allows Turnstile-protected sites to function properly. Configurable via `enable_turnstile_workaround` (default: true).
6-- **Global content filtering toggle**: New `content_filtering.enabled` config option to completely disable ad blocking when needed. Whitelist system remains available for granular control. Defaults to enabled for backward compatibility.
7-
8-### Fixed
9-- **Search shortcut placeholders**: Support both `{query}` and `%s` placeholder formats in search shortcuts, allowing users to use either style. Also fixed domain-only URLs (e.g., "github.com") being incorrectly treated as search queries.
10-- **OAuth popup handling**: Fixed OAuth popups not functioning in stacked panes and split operations by ensuring `setupPopupHandling()` is called in all pane creation code paths (finalizeStackCreation, CloseStackedPane, splitNode).
11-- **WebView ID message parsing**: Fixed JSON unmarshaling errors when frontend sends numeric webviewId values instead of strings. Message handler now gracefully normalizes both string and numeric webviewId formats with fallback parsing logic.
12-- **Video codec fallback**: Unblocked VP8 codec to allow fallback for ad segments, preventing playback interruptions when ads use different codecs than main content.
13-- **Video buffering**: Increased buffer sizes (64 MB, 20s) to handle bursty Twitch/AV1 segments and improve streaming reliability on variable bitrate platforms.
14-
15-### Changed
16-- **Console output cleanup**: Disabled WebKit console.log() messages to stdout to prevent page script spam. DevTools console (F12) still shows all messages.
17-- **Content filtering configuration**: Refactored `content_filtering_whitelist` into structured `content_filtering` config with `enabled` boolean and `whitelist` array for better organization.
@@ -1,17 +0,0 @@
1-## [0.14.1] - 2025-11-18
2-
3-### Added
4-- **Inline tab rename**: Press `Alt+T` then `r` to rename tabs directly in the tab bar. Enter saves, Escape cancels. Tab buttons temporarily allow focus during rename, then restore original focus behavior to prevent interfering with WebView keyboard input.
5-- **Cloudflare Turnstile CAPTCHA support**: Temporary CORS allowlist workaround for `challenges.cloudflare.com` to bypass WebKit's incomplete COEP credentialless implementation. Allows Turnstile-protected sites to function properly. Configurable via `enable_turnstile_workaround` (default: true).
6-- **Global content filtering toggle**: New `content_filtering.enabled` config option to completely disable ad blocking when needed. Whitelist system remains available for granular control. Defaults to enabled for backward compatibility.
7-
8-### Fixed
9-- **Search shortcut placeholders**: Support both `{query}` and `%s` placeholder formats in search shortcuts, allowing users to use either style. Also fixed domain-only URLs (e.g., "github.com") being incorrectly treated as search queries.
10-- **OAuth popup handling**: Fixed OAuth popups not functioning in stacked panes and split operations by ensuring `setupPopupHandling()` is called in all pane creation code paths (finalizeStackCreation, CloseStackedPane, splitNode).
11-- **WebView ID message parsing**: Fixed JSON unmarshaling errors when frontend sends numeric webviewId values instead of strings. Message handler now gracefully normalizes both string and numeric webviewId formats with fallback parsing logic.
12-- **Video codec fallback**: Unblocked VP8 codec to allow fallback for ad segments, preventing playback interruptions when ads use different codecs than main content.
13-- **Video buffering**: Increased buffer sizes (64 MB, 20s) to handle bursty Twitch/AV1 segments and improve streaming reliability on variable bitrate platforms.
14-
15-### Changed
16-- **Console output cleanup**: Disabled WebKit console.log() messages to stdout to prevent page script spam. DevTools console (F12) still shows all messages.
17-- **Content filtering configuration**: Refactored `content_filtering_whitelist` into structured `content_filtering` config with `enabled` boolean and `whitelist` array for better organization.
D docs/v0.15.0-release-notes.md +0 -27
@@ -1,27 +0,0 @@
1-## [0.15.0] - 2025-11-29
2-
3-### Added
4-- **Inline URL suggestions**: Fish/zsh-style ghost text completion in omnibox. As you type, shows grayed-out URL completion from history. Accept with Right Arrow (full) or Ctrl+Right (word). Ctrl+Y also accepts full suggestion. Uses trie-based prefix search with debounced queries for smooth typing.
5-- **Filter list auto-update**: Async version checking using HTTP HEAD request with ETag. 2-minute startup delay, skips if checked within 24 hours. Stores version per filter list.
6-- **Configurable filter lists**: New `content_filtering.filter_lists` config option. Defaults include EasyList, EasyPrivacy, and uBlock filters (annoyances, quick-fixes).
7-- **Demo video**: Added feature showcase video to README (docs/media/dumber-demo.mp4).
8-- **Page load progress bar**: Thin animated indicator at window bottom showing web page loading progress. Tracks WebView load events with gradient animation, auto-hides when complete.
9-- **Omnibox initial history display**: Configurable behavior when opening empty omnibox via `omnibox.initial_behavior` ("recent", "most_visited", "none"). Shows initial history on open and when input is cleared. Default: recent visits.
10-- **Omnibox keyboard blocking**: Prevent page scripts from stealing focus while omnibox is active.
11-- **Configurable border widths**: Added `pane_mode_border_width` and `tab_mode_border_width` configuration options (default: 4px) for full border customization.
12-- **Content filter caching**: Centralized content blocking service compiles filters once and caches them for instant reuse across all WebViews.
13-- **CLI purge enhancements**: Separate `--cookies` and `--history` flags for granular data deletion.
14-- **URL normalization**: Consistent URL storage across browser, CLI, and favicon services (strips trailing slashes, normalizes schemes).
15-
16-### Fixed
17-- **Filter compilation race condition**: Fixed concurrent map crash when multiple filter lists compile simultaneously by using local converter instead of shared state.
18-- **Omnibox search performance**: Debounce search with 2-character minimum threshold to prevent UI freeze on first keystroke. Applies to both URL/history search and find-in-page modes.
19-- **Omnibox flash on load**: Load the injected GUI bundle at document-start and initialize the omnibox as soon as DOM is ready, ensuring it is ready without briefly flashing during page startup or new pane creation.
20-- **Zoom toast suppression**: Suppress zoom toast notifications during browser initialization to prevent UI flash.
21-- **Cosmetic filter injection**: Inject rules immediately and fix selector normalization for better ad blocking.
22-
23-### Changed
24-- **Refactor keyboard blocking**: Move logic to main-world.ts, reduce handler.go verbosity.
25-- **Border overlay architecture**: All borders (active pane, pane mode, tab mode) now use GTK overlay pattern preventing layout shifts when borders appear/disappear. Removed inactive border styling - only active panes show borders.
26-- **Simplified border configuration**: Removed `inactive_border_width`, `inactive_border_color`, `show_stacked_title_border`, and `border_radius` config options. All borders are now overlay-based with no layout impact.
27-- **Remove Turnstile workaround**: Removed temporary Cloudflare Turnstile CORS allowlist (no longer needed).
@@ -1,27 +0,0 @@
1-## [0.15.0] - 2025-11-29
2-
3-### Added
4-- **Inline URL suggestions**: Fish/zsh-style ghost text completion in omnibox. As you type, shows grayed-out URL completion from history. Accept with Right Arrow (full) or Ctrl+Right (word). Ctrl+Y also accepts full suggestion. Uses trie-based prefix search with debounced queries for smooth typing.
5-- **Filter list auto-update**: Async version checking using HTTP HEAD request with ETag. 2-minute startup delay, skips if checked within 24 hours. Stores version per filter list.
6-- **Configurable filter lists**: New `content_filtering.filter_lists` config option. Defaults include EasyList, EasyPrivacy, and uBlock filters (annoyances, quick-fixes).
7-- **Demo video**: Added feature showcase video to README (docs/media/dumber-demo.mp4).
8-- **Page load progress bar**: Thin animated indicator at window bottom showing web page loading progress. Tracks WebView load events with gradient animation, auto-hides when complete.
9-- **Omnibox initial history display**: Configurable behavior when opening empty omnibox via `omnibox.initial_behavior` ("recent", "most_visited", "none"). Shows initial history on open and when input is cleared. Default: recent visits.
10-- **Omnibox keyboard blocking**: Prevent page scripts from stealing focus while omnibox is active.
11-- **Configurable border widths**: Added `pane_mode_border_width` and `tab_mode_border_width` configuration options (default: 4px) for full border customization.
12-- **Content filter caching**: Centralized content blocking service compiles filters once and caches them for instant reuse across all WebViews.
13-- **CLI purge enhancements**: Separate `--cookies` and `--history` flags for granular data deletion.
14-- **URL normalization**: Consistent URL storage across browser, CLI, and favicon services (strips trailing slashes, normalizes schemes).
15-
16-### Fixed
17-- **Filter compilation race condition**: Fixed concurrent map crash when multiple filter lists compile simultaneously by using local converter instead of shared state.
18-- **Omnibox search performance**: Debounce search with 2-character minimum threshold to prevent UI freeze on first keystroke. Applies to both URL/history search and find-in-page modes.
19-- **Omnibox flash on load**: Load the injected GUI bundle at document-start and initialize the omnibox as soon as DOM is ready, ensuring it is ready without briefly flashing during page startup or new pane creation.
20-- **Zoom toast suppression**: Suppress zoom toast notifications during browser initialization to prevent UI flash.
21-- **Cosmetic filter injection**: Inject rules immediately and fix selector normalization for better ad blocking.
22-
23-### Changed
24-- **Refactor keyboard blocking**: Move logic to main-world.ts, reduce handler.go verbosity.
25-- **Border overlay architecture**: All borders (active pane, pane mode, tab mode) now use GTK overlay pattern preventing layout shifts when borders appear/disappear. Removed inactive border styling - only active panes show borders.
26-- **Simplified border configuration**: Removed `inactive_border_width`, `inactive_border_color`, `show_stacked_title_border`, and `border_radius` config options. All borders are now overlay-based with no layout impact.
27-- **Remove Turnstile workaround**: Removed temporary Cloudflare Turnstile CORS allowlist (no longer needed).
A install.sh +108 -0
@@ -0,0 +1,108 @@
1+#!/bin/sh
2+set -e
3+
4+# Dumber installer script
5+# Usage: curl -fsSL https://dumber.bnema.dev/install | sh
6+
7+REPO="bnema/dumber"
8+
9+# Prefer ~/.local/bin if it exists and is in PATH, otherwise /usr/local/bin
10+if [ -d "$HOME/.local/bin" ]; then
11+ INSTALL_DIR="$HOME/.local/bin"
12+ case ":$PATH:" in
13+ *":$HOME/.local/bin:"*) ;;
14+ *) echo "Warning: $HOME/.local/bin is not in your PATH" ;;
15+ esac
16+else
17+ INSTALL_DIR="/usr/local/bin"
18+fi
19+
20+echo "Installing Dumber..."
21+
22+# Check OS
23+OS=$(uname -s | tr '[:upper:]' '[:lower:]')
24+if [ "$OS" != "linux" ]; then
25+ echo "Error: Only Linux is supported. Detected: $OS"
26+ exit 1
27+fi
28+
29+# Check architecture
30+ARCH=$(uname -m)
31+if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "amd64" ]; then
32+ echo "Error: Only x86_64 is supported. Detected: $ARCH"
33+ exit 1
34+fi
35+
36+echo "Detected: linux/x86_64"
37+
38+TARBALL="dumber_linux_x86_64.tar.gz"
39+DOWNLOAD_URL="https://github.com/${REPO}/releases/latest/download/${TARBALL}"
40+
41+# Create temporary directory
42+TMP_DIR=$(mktemp -d)
43+trap 'rm -rf "$TMP_DIR"' EXIT
44+
45+# Download checksums file
46+CHECKSUMS_URL="https://github.com/${REPO}/releases/latest/download/checksums.txt"
47+echo "Downloading checksums..."
48+if ! curl -fsSL "$CHECKSUMS_URL" -o "$TMP_DIR/checksums.txt"; then
49+ echo "Error: Failed to download checksums file"
50+ exit 1
51+fi
52+
53+echo "Downloading ${TARBALL}..."
54+if ! curl -fsSL "$DOWNLOAD_URL" -o "$TMP_DIR/$TARBALL"; then
55+ echo "Error: Failed to download ${TARBALL}"
56+ exit 1
57+fi
58+
59+# Verify checksum
60+echo "Verifying checksum..."
61+EXPECTED_CHECKSUM=$(grep -E "[[:space:]]${TARBALL}\$" "$TMP_DIR/checksums.txt" | awk '{print $1}')
62+if [ -z "$EXPECTED_CHECKSUM" ]; then
63+ echo "Error: Could not find checksum for ${TARBALL}"
64+ exit 1
65+fi
66+
67+if command -v sha256sum >/dev/null 2>&1; then
68+ ACTUAL_CHECKSUM=$(sha256sum "$TMP_DIR/$TARBALL" | awk '{print $1}')
69+else
70+ echo "Error: sha256sum not found"
71+ exit 1
72+fi
73+
74+if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
75+ echo "Error: Checksum verification failed!"
76+ echo "Expected: $EXPECTED_CHECKSUM"
77+ echo "Actual: $ACTUAL_CHECKSUM"
78+ exit 1
79+fi
80+echo "Checksum verified."
81+
82+echo "Extracting..."
83+tar -xzf "$TMP_DIR/$TARBALL" -C "$TMP_DIR"
84+
85+# Find the dumber binary (handles versioned subdirectory)
86+BINARY=$(find "$TMP_DIR" -name "dumber" -type f -executable | head -1)
87+if [ -z "$BINARY" ]; then
88+ echo "Error: Could not find dumber binary in archive"
89+ exit 1
90+fi
91+
92+echo "Installing to ${INSTALL_DIR}..."
93+if [ -w "$INSTALL_DIR" ]; then
94+ mv "$BINARY" "$INSTALL_DIR/dumber"
95+else
96+ echo "sudo required to install to ${INSTALL_DIR}"
97+ sudo mv "$BINARY" "$INSTALL_DIR/dumber"
98+fi
99+
100+# Verify installation
101+if command -v dumber >/dev/null 2>&1; then
102+ echo ""
103+ echo "Dumber installed successfully!"
104+ dumber about
105+else
106+ echo ""
107+ echo "Installation complete. Add ${INSTALL_DIR} to your PATH if needed."
108+fi
@@ -0,0 +1,108 @@
1+#!/bin/sh
2+set -e
3+
4+# Dumber installer script
5+# Usage: curl -fsSL https://dumber.bnema.dev/install | sh
6+
7+REPO="bnema/dumber"
8+
9+# Prefer ~/.local/bin if it exists and is in PATH, otherwise /usr/local/bin
10+if [ -d "$HOME/.local/bin" ]; then
11+ INSTALL_DIR="$HOME/.local/bin"
12+ case ":$PATH:" in
13+ *":$HOME/.local/bin:"*) ;;
14+ *) echo "Warning: $HOME/.local/bin is not in your PATH" ;;
15+ esac
16+else
17+ INSTALL_DIR="/usr/local/bin"
18+fi
19+
20+echo "Installing Dumber..."
21+
22+# Check OS
23+OS=$(uname -s | tr '[:upper:]' '[:lower:]')
24+if [ "$OS" != "linux" ]; then
25+ echo "Error: Only Linux is supported. Detected: $OS"
26+ exit 1
27+fi
28+
29+# Check architecture
30+ARCH=$(uname -m)
31+if [ "$ARCH" != "x86_64" ] && [ "$ARCH" != "amd64" ]; then
32+ echo "Error: Only x86_64 is supported. Detected: $ARCH"
33+ exit 1
34+fi
35+
36+echo "Detected: linux/x86_64"
37+
38+TARBALL="dumber_linux_x86_64.tar.gz"
39+DOWNLOAD_URL="https://github.com/${REPO}/releases/latest/download/${TARBALL}"
40+
41+# Create temporary directory
42+TMP_DIR=$(mktemp -d)
43+trap 'rm -rf "$TMP_DIR"' EXIT
44+
45+# Download checksums file
46+CHECKSUMS_URL="https://github.com/${REPO}/releases/latest/download/checksums.txt"
47+echo "Downloading checksums..."
48+if ! curl -fsSL "$CHECKSUMS_URL" -o "$TMP_DIR/checksums.txt"; then
49+ echo "Error: Failed to download checksums file"
50+ exit 1
51+fi
52+
53+echo "Downloading ${TARBALL}..."
54+if ! curl -fsSL "$DOWNLOAD_URL" -o "$TMP_DIR/$TARBALL"; then
55+ echo "Error: Failed to download ${TARBALL}"
56+ exit 1
57+fi
58+
59+# Verify checksum
60+echo "Verifying checksum..."
61+EXPECTED_CHECKSUM=$(grep -E "[[:space:]]${TARBALL}\$" "$TMP_DIR/checksums.txt" | awk '{print $1}')
62+if [ -z "$EXPECTED_CHECKSUM" ]; then
63+ echo "Error: Could not find checksum for ${TARBALL}"
64+ exit 1
65+fi
66+
67+if command -v sha256sum >/dev/null 2>&1; then
68+ ACTUAL_CHECKSUM=$(sha256sum "$TMP_DIR/$TARBALL" | awk '{print $1}')
69+else
70+ echo "Error: sha256sum not found"
71+ exit 1
72+fi
73+
74+if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]; then
75+ echo "Error: Checksum verification failed!"
76+ echo "Expected: $EXPECTED_CHECKSUM"
77+ echo "Actual: $ACTUAL_CHECKSUM"
78+ exit 1
79+fi
80+echo "Checksum verified."
81+
82+echo "Extracting..."
83+tar -xzf "$TMP_DIR/$TARBALL" -C "$TMP_DIR"
84+
85+# Find the dumber binary (handles versioned subdirectory)
86+BINARY=$(find "$TMP_DIR" -name "dumber" -type f -executable | head -1)
87+if [ -z "$BINARY" ]; then
88+ echo "Error: Could not find dumber binary in archive"
89+ exit 1
90+fi
91+
92+echo "Installing to ${INSTALL_DIR}..."
93+if [ -w "$INSTALL_DIR" ]; then
94+ mv "$BINARY" "$INSTALL_DIR/dumber"
95+else
96+ echo "sudo required to install to ${INSTALL_DIR}"
97+ sudo mv "$BINARY" "$INSTALL_DIR/dumber"
98+fi
99+
100+# Verify installation
101+if command -v dumber >/dev/null 2>&1; then
102+ echo ""
103+ echo "Dumber installed successfully!"
104+ dumber about
105+else
106+ echo ""
107+ echo "Installation complete. Add ${INSTALL_DIR} to your PATH if needed."
108+fi

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