feat(config): default to cef engine
- commit
- c66eabf173c38ac4e5aa44e47f5b27cc600a0bff
- author
- brice · · 2026-05-27 05:36 UTC
- committer
- brice · · 2026-05-27 05:38 UTC
- parent
- dbdbf6d
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
13 files · +55 -23
M CHANGELOG.md +17 -7
| @@ -6,21 +6,31 @@ All notable changes to this project will be documented in this file. | |||
| 6 | 6 | ||
| 7 | 7 | ### Added | |
| 8 | 8 | ||
| 9 | + | - **CEF as the default browser engine**: New installs and configs without an explicit engine now use CEF by default. WebKit remains available by setting `engine.type = "webkit"`. | |
| 10 | + | - **CEF browser backend**: CEF is now available as a full browser engine with audio output, shared downloads, context menus, file dialogs, popups, zoom, and system view support. | |
| 11 | + | - **System views rewrite**: The old Svelte `webui/` has been replaced by native/WASM-backed system views for config, history, and favorites. | |
| 9 | 12 | - **Standalone omnibox launcher**: `dumber omnibox` now opens the omnibox in a standalone window. | |
| 10 | - | - **CEF engine support**: The CEF engine is now available alongside WebKit, including audio output support. | |
| 11 | 13 | - **Fresh browser windows**: Browser launches can now open in dedicated fresh windows. | |
| 12 | - | - **Unified context menus**: Right-click menus now behave consistently across WebKit and CEF. | |
| 13 | - | - **Shared download handling**: Downloads now use the same handling in WebKit and CEF, with progress and completion toasts. | |
| 14 | + | - **GTK UI font setting**: GTK chrome now has its own configurable UI font. | |
| 14 | 15 | ||
| 15 | 16 | ### Changed | |
| 16 | 17 | ||
| 17 | - | - **Omnibox default order toggle**: You can now persist and switch the default history order. | |
| 18 | - | - **Omnibox most-visited window**: The most-visited view now uses a 30-day history window by default. | |
| 18 | + | - **CEF runtime integration**: CEF now uses `purego-cef2gtk`, a codec-enabled runtime path, deterministic runtime discovery, and XDG-scoped user data. | |
| 19 | + | - **CEF rendering defaults**: CEF uses a GPU-first Wayland render stack by default, with Vulkan/DMABUF presentation, EGL fallback, adaptive OSR frame rate, and fractional-scale handling. | |
| 20 | + | - **Unified browser plumbing**: Downloads, context menus, internal pages, favicons, clipboard handling, and browser launch flows now share more code across WebKit and CEF. | |
| 21 | + | - **Window-scoped tabs and browsing contexts**: Tab shortcuts, popup handling, OAuth windows, and native browser windows now track the owning window/context more consistently. | |
| 22 | + | - **Omnibox behavior**: The default order can be persisted, most-visited history uses a 30-day window, hover callbacks are lighter, and standalone launch behavior is more reliable. | |
| 23 | + | - **Logging cleanup**: Session log cleanup can cap log files by count as well as age. | |
| 24 | + | - **Tooling and dependencies**: Go/runtime dependencies, GitHub Actions, golangci-lint, PipeWire audio dependencies, and AUR metadata were refreshed. | |
| 19 | 25 | ||
| 20 | 26 | ### Fixed | |
| 21 | 27 | ||
| 22 | - | - **CEF storage location**: CEF user data now uses the XDG data directory. | |
| 23 | - | - **CEF clipboard and focus**: Clipboard and input focus handling in CEF is more reliable. | |
| 28 | + | - **CEF rendering stability**: Hardened OSR browser creation, live resize repainting, viewport sync, popup surfaces, and bounded size observation. | |
| 29 | + | - **CEF input and focus**: Improved clipboard, keyboard focus, tab shortcuts, global shortcut release behavior, gesture callback release, and ghost shortcut suppression. | |
| 30 | + | - **CEF file dialogs and local files**: Hardened GTK file-dialog callbacks, GIO cleanup, file-dialog edge cases, and zoom for local `file://` URLs. | |
| 31 | + | - **CEF popups and OAuth**: Improved popup lifecycle cleanup, native popup content widgets, pane-hosted popup fallback cleanup, and OAuth auto-close behavior. | |
| 32 | + | - **Desktop integration**: Browser MIME handler sync and browser launch error redaction are more reliable. | |
| 33 | + | - **Session and pane resilience**: Stale pane restore paths, nil workspace pane views, and popup restore cleanup are safer. | |
| 24 | 34 | ||
| 25 | 35 | ## [0.28.0] - 2026-03-27 | |
| 26 | 36 | ||
| @@ -6,21 +6,31 @@ All notable changes to this project will be documented in this file. | |||||
| 6 | 6 | ||||
| 7 | ### Added | 7 | ### Added | ||
| 8 | 8 | ||||
| 9 | + | - **CEF as the default browser engine**: New installs and configs without an explicit engine now use CEF by default. WebKit remains available by setting `engine.type = "webkit"`. | |||
| 10 | + | - **CEF browser backend**: CEF is now available as a full browser engine with audio output, shared downloads, context menus, file dialogs, popups, zoom, and system view support. | |||
| 11 | + | - **System views rewrite**: The old Svelte `webui/` has been replaced by native/WASM-backed system views for config, history, and favorites. | |||
| 9 | - **Standalone omnibox launcher**: `dumber omnibox` now opens the omnibox in a standalone window. | 12 | - **Standalone omnibox launcher**: `dumber omnibox` now opens the omnibox in a standalone window. | ||
| 10 | - | - **CEF engine support**: The CEF engine is now available alongside WebKit, including audio output support. | |||
| 11 | - **Fresh browser windows**: Browser launches can now open in dedicated fresh windows. | 13 | - **Fresh browser windows**: Browser launches can now open in dedicated fresh windows. | ||
| 12 | - | - **Unified context menus**: Right-click menus now behave consistently across WebKit and CEF. | 14 | + | - **GTK UI font setting**: GTK chrome now has its own configurable UI font. |
| 13 | - | - **Shared download handling**: Downloads now use the same handling in WebKit and CEF, with progress and completion toasts. | |||
| 14 | 15 | ||||
| 15 | ### Changed | 16 | ### Changed | ||
| 16 | 17 | ||||
| 17 | - | - **Omnibox default order toggle**: You can now persist and switch the default history order. | 18 | + | - **CEF runtime integration**: CEF now uses `purego-cef2gtk`, a codec-enabled runtime path, deterministic runtime discovery, and XDG-scoped user data. |
| 18 | - | - **Omnibox most-visited window**: The most-visited view now uses a 30-day history window by default. | 19 | + | - **CEF rendering defaults**: CEF uses a GPU-first Wayland render stack by default, with Vulkan/DMABUF presentation, EGL fallback, adaptive OSR frame rate, and fractional-scale handling. |
| 20 | + | - **Unified browser plumbing**: Downloads, context menus, internal pages, favicons, clipboard handling, and browser launch flows now share more code across WebKit and CEF. | |||
| 21 | + | - **Window-scoped tabs and browsing contexts**: Tab shortcuts, popup handling, OAuth windows, and native browser windows now track the owning window/context more consistently. | |||
| 22 | + | - **Omnibox behavior**: The default order can be persisted, most-visited history uses a 30-day window, hover callbacks are lighter, and standalone launch behavior is more reliable. | |||
| 23 | + | - **Logging cleanup**: Session log cleanup can cap log files by count as well as age. | |||
| 24 | + | - **Tooling and dependencies**: Go/runtime dependencies, GitHub Actions, golangci-lint, PipeWire audio dependencies, and AUR metadata were refreshed. | |||
| 19 | 25 | ||||
| 20 | ### Fixed | 26 | ### Fixed | ||
| 21 | 27 | ||||
| 22 | - | - **CEF storage location**: CEF user data now uses the XDG data directory. | 28 | + | - **CEF rendering stability**: Hardened OSR browser creation, live resize repainting, viewport sync, popup surfaces, and bounded size observation. |
| 23 | - | - **CEF clipboard and focus**: Clipboard and input focus handling in CEF is more reliable. | 29 | + | - **CEF input and focus**: Improved clipboard, keyboard focus, tab shortcuts, global shortcut release behavior, gesture callback release, and ghost shortcut suppression. |
| 30 | + | - **CEF file dialogs and local files**: Hardened GTK file-dialog callbacks, GIO cleanup, file-dialog edge cases, and zoom for local `file://` URLs. | |||
| 31 | + | - **CEF popups and OAuth**: Improved popup lifecycle cleanup, native popup content widgets, pane-hosted popup fallback cleanup, and OAuth auto-close behavior. | |||
| 32 | + | - **Desktop integration**: Browser MIME handler sync and browser launch error redaction are more reliable. | |||
| 33 | + | - **Session and pane resilience**: Stale pane restore paths, nil workspace pane views, and popup restore cleanup are safer. | |||
| 24 | 34 | ||||
| 25 | ## [0.28.0] - 2026-03-27 | 35 | ## [0.28.0] - 2026-03-27 | ||
| 26 | 36 | ||||
M README.md +11 -5
| @@ -65,7 +65,7 @@ flatpak run dev.bnema.Dumber browse | |||
| 65 | 65 | **Arch Linux:** | |
| 66 | 66 | ||
| 67 | 67 | ```bash | |
| 68 | - | sudo pacman -S webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va | |
| 68 | + | sudo pacman -S cef webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va | |
| 69 | 69 | ``` | |
| 70 | 70 | ||
| 71 | 71 | **Debian/Ubuntu:** | |
| @@ -76,15 +76,16 @@ sudo apt install libwebkitgtk-6.0-4 libgtk-4-1 gstreamer1.0-plugins-base gstream | |||
| 76 | 76 | ||
| 77 | 77 | > ⚠️ Ubuntu 24.04 ships GLib 2.80, but Dumber requires GLib 2.84+. Use Arch, Fedora 41+, or the Flatpak. | |
| 78 | 78 | ||
| 79 | - | ### CEF engine (optional) | |
| 79 | + | ### Browser engine | |
| 80 | 80 | ||
| 81 | - | Dumber supports a Chromium Embedded Framework engine as an alternative to WebKit. | |
| 82 | - | To use it on Arch: | |
| 81 | + | Dumber uses the Chromium Embedded Framework engine by default. On Arch, install the CEF runtime with: | |
| 83 | 82 | ||
| 84 | 83 | ```bash | |
| 85 | 84 | sudo pacman -S cef | |
| 86 | 85 | ``` | |
| 87 | 86 | ||
| 87 | + | For hardware video decoding, `cef-vaapi` is also available from the AUR as an optional CEF build. | |
| 88 | + | ||
| 88 | 89 | CEF runtime precedence is deterministic: `CEF_DIR` wins first, then `engine.cef.cef_dir`, then `/usr/lib/cef`, then `~/.local/share/cef`. | |
| 89 | 90 | Set `engine.cef.cef_dir` in config when `CEF_DIR` is unset: | |
| 90 | 91 | ||
| @@ -99,7 +100,12 @@ Or set the higher-precedence `CEF_DIR` environment variable: | |||
| 99 | 100 | CEF_DIR=/custom/path dumber browse | |
| 100 | 101 | ``` | |
| 101 | 102 | ||
| 102 | - | Then set `engine.type = "cef"` in your config. | |
| 103 | + | WebKit remains available as a fallback: | |
| 104 | + | ||
| 105 | + | ```toml | |
| 106 | + | [engine] | |
| 107 | + | type = "webkit" | |
| 108 | + | ``` | |
| 103 | 109 | ||
| 104 | 110 | CEF uses Dumber's GPU-first Wayland render stack by default: GDK DMABUF presentation with ANGLE/GSK Vulkan. For driver compatibility, switch to the EGL/OpenGL stack with `engine.cef.render_stack = "egl"`; the default is `"vulkan"`. | |
| 105 | 111 | ||
| @@ -65,7 +65,7 @@ flatpak run dev.bnema.Dumber browse | |||||
| 65 | **Arch Linux:** | 65 | **Arch Linux:** | ||
| 66 | 66 | ||||
| 67 | ```bash | 67 | ```bash | ||
| 68 | - | sudo pacman -S webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va | 68 | + | sudo pacman -S cef webkitgtk-6.0 gtk4 gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugin-va |
| 69 | ``` | 69 | ``` | ||
| 70 | 70 | ||||
| 71 | **Debian/Ubuntu:** | 71 | **Debian/Ubuntu:** | ||
| @@ -76,15 +76,16 @@ sudo apt install libwebkitgtk-6.0-4 libgtk-4-1 gstreamer1.0-plugins-base gstream | |||||
| 76 | 76 | ||||
| 77 | > ⚠️ Ubuntu 24.04 ships GLib 2.80, but Dumber requires GLib 2.84+. Use Arch, Fedora 41+, or the Flatpak. | 77 | > ⚠️ Ubuntu 24.04 ships GLib 2.80, but Dumber requires GLib 2.84+. Use Arch, Fedora 41+, or the Flatpak. | ||
| 78 | 78 | ||||
| 79 | - | ### CEF engine (optional) | 79 | + | ### Browser engine |
| 80 | 80 | ||||
| 81 | - | Dumber supports a Chromium Embedded Framework engine as an alternative to WebKit. | 81 | + | Dumber uses the Chromium Embedded Framework engine by default. On Arch, install the CEF runtime with: |
| 82 | - | To use it on Arch: | |||
| 83 | 82 | ||||
| 84 | ```bash | 83 | ```bash | ||
| 85 | sudo pacman -S cef | 84 | sudo pacman -S cef | ||
| 86 | ``` | 85 | ``` | ||
| 87 | 86 | ||||
| 87 | + | For hardware video decoding, `cef-vaapi` is also available from the AUR as an optional CEF build. | |||
| 88 | + | ||||
| 88 | CEF runtime precedence is deterministic: `CEF_DIR` wins first, then `engine.cef.cef_dir`, then `/usr/lib/cef`, then `~/.local/share/cef`. | 89 | CEF runtime precedence is deterministic: `CEF_DIR` wins first, then `engine.cef.cef_dir`, then `/usr/lib/cef`, then `~/.local/share/cef`. | ||
| 89 | Set `engine.cef.cef_dir` in config when `CEF_DIR` is unset: | 90 | Set `engine.cef.cef_dir` in config when `CEF_DIR` is unset: | ||
| 90 | 91 | ||||
| @@ -99,7 +100,12 @@ Or set the higher-precedence `CEF_DIR` environment variable: | |||||
| 99 | CEF_DIR=/custom/path dumber browse | 100 | CEF_DIR=/custom/path dumber browse | ||
| 100 | ``` | 101 | ``` | ||
| 101 | 102 | ||||
| 102 | - | Then set `engine.type = "cef"` in your config. | 103 | + | WebKit remains available as a fallback: |
| 104 | + | ||||
| 105 | + | ```toml | |||
| 106 | + | [engine] | |||
| 107 | + | type = "webkit" | |||
| 108 | + | ``` | |||
| 103 | 109 | ||||
| 104 | CEF uses Dumber's GPU-first Wayland render stack by default: GDK DMABUF presentation with ANGLE/GSK Vulkan. For driver compatibility, switch to the EGL/OpenGL stack with `engine.cef.render_stack = "egl"`; the default is `"vulkan"`. | 110 | CEF uses Dumber's GPU-first Wayland render stack by default: GDK DMABUF presentation with ANGLE/GSK Vulkan. For driver compatibility, switch to the EGL/OpenGL stack with `engine.cef.render_stack = "egl"`; the default is `"vulkan"`. | ||
| 105 | 111 | ||||
M aur/dumber-browser-git/.SRCINFO +2 -0
| @@ -9,6 +9,7 @@ pkgbase = dumber-browser-git | |||
| 9 | 9 | makedepends = git | |
| 10 | 10 | makedepends = brotli | |
| 11 | 11 | depends = gtk4 | |
| 12 | + | depends = cef | |
| 12 | 13 | depends = webkitgtk-6.0 | |
| 13 | 14 | optdepends = gst-plugins-base: Base media codecs | |
| 14 | 15 | optdepends = gst-plugins-good: Additional media codecs | |
| @@ -17,6 +18,7 @@ pkgbase = dumber-browser-git | |||
| 17 | 18 | optdepends = gst-libav: FFmpeg-based codecs | |
| 18 | 19 | optdepends = gst-plugin-pipewire: PipeWire audio support | |
| 19 | 20 | optdepends = gst-plugin-va: Hardware video decoding (VA-API stateless decoders) | |
| 21 | + | optdepends = cef-vaapi: Optional AUR CEF build with VA-API hardware video decoding support | |
| 20 | 22 | optdepends = pipewire: Audio/video routing | |
| 21 | 23 | optdepends = pipewire-pulse: PulseAudio replacement | |
| 22 | 24 | optdepends = mesa: VA-API driver for AMD GPUs | |
| @@ -9,6 +9,7 @@ pkgbase = dumber-browser-git | |||||
| 9 | makedepends = git | 9 | makedepends = git | ||
| 10 | makedepends = brotli | 10 | makedepends = brotli | ||
| 11 | depends = gtk4 | 11 | depends = gtk4 | ||
| 12 | + | depends = cef | |||
| 12 | depends = webkitgtk-6.0 | 13 | depends = webkitgtk-6.0 | ||
| 13 | optdepends = gst-plugins-base: Base media codecs | 14 | optdepends = gst-plugins-base: Base media codecs | ||
| 14 | optdepends = gst-plugins-good: Additional media codecs | 15 | optdepends = gst-plugins-good: Additional media codecs | ||
| @@ -17,6 +18,7 @@ pkgbase = dumber-browser-git | |||||
| 17 | optdepends = gst-libav: FFmpeg-based codecs | 18 | optdepends = gst-libav: FFmpeg-based codecs | ||
| 18 | optdepends = gst-plugin-pipewire: PipeWire audio support | 19 | optdepends = gst-plugin-pipewire: PipeWire audio support | ||
| 19 | optdepends = gst-plugin-va: Hardware video decoding (VA-API stateless decoders) | 20 | optdepends = gst-plugin-va: Hardware video decoding (VA-API stateless decoders) | ||
| 21 | + | optdepends = cef-vaapi: Optional AUR CEF build with VA-API hardware video decoding support | |||
| 20 | optdepends = pipewire: Audio/video routing | 22 | optdepends = pipewire: Audio/video routing | ||
| 21 | optdepends = pipewire-pulse: PulseAudio replacement | 23 | optdepends = pipewire-pulse: PulseAudio replacement | ||
| 22 | optdepends = mesa: VA-API driver for AMD GPUs | 24 | optdepends = mesa: VA-API driver for AMD GPUs | ||
M aur/dumber-browser-git/PKGBUILD +2 -1
| @@ -7,7 +7,7 @@ arch=('x86_64') | |||
| 7 | 7 | url="https://github.com/bnema/dumber" | |
| 8 | 8 | license=('MIT') | |
| 9 | 9 | makedepends=('go>=1.26' 'git' 'brotli') | |
| 10 | - | depends=('gtk4' 'webkitgtk-6.0') | |
| 10 | + | depends=('gtk4' 'cef' 'webkitgtk-6.0') | |
| 11 | 11 | optdepends=( | |
| 12 | 12 | 'gst-plugins-base: Base media codecs' | |
| 13 | 13 | 'gst-plugins-good: Additional media codecs' | |
| @@ -16,6 +16,7 @@ optdepends=( | |||
| 16 | 16 | 'gst-libav: FFmpeg-based codecs' | |
| 17 | 17 | 'gst-plugin-pipewire: PipeWire audio support' | |
| 18 | 18 | 'gst-plugin-va: Hardware video decoding (VA-API stateless decoders)' | |
| 19 | + | 'cef-vaapi: Optional AUR CEF build with VA-API hardware video decoding support' | |
| 19 | 20 | 'pipewire: Audio/video routing' | |
| 20 | 21 | 'pipewire-pulse: PulseAudio replacement' | |
| 21 | 22 | 'mesa: VA-API driver for AMD GPUs' | |
| @@ -7,7 +7,7 @@ arch=('x86_64') | |||||
| 7 | url="https://github.com/bnema/dumber" | 7 | url="https://github.com/bnema/dumber" | ||
| 8 | license=('MIT') | 8 | license=('MIT') | ||
| 9 | makedepends=('go>=1.26' 'git' 'brotli') | 9 | makedepends=('go>=1.26' 'git' 'brotli') | ||
| 10 | - | depends=('gtk4' 'webkitgtk-6.0') | 10 | + | depends=('gtk4' 'cef' 'webkitgtk-6.0') |
| 11 | optdepends=( | 11 | optdepends=( | ||
| 12 | 'gst-plugins-base: Base media codecs' | 12 | 'gst-plugins-base: Base media codecs' | ||
| 13 | 'gst-plugins-good: Additional media codecs' | 13 | 'gst-plugins-good: Additional media codecs' | ||
| @@ -16,6 +16,7 @@ optdepends=( | |||||
| 16 | 'gst-libav: FFmpeg-based codecs' | 16 | 'gst-libav: FFmpeg-based codecs' | ||
| 17 | 'gst-plugin-pipewire: PipeWire audio support' | 17 | 'gst-plugin-pipewire: PipeWire audio support' | ||
| 18 | 'gst-plugin-va: Hardware video decoding (VA-API stateless decoders)' | 18 | 'gst-plugin-va: Hardware video decoding (VA-API stateless decoders)' | ||
| 19 | + | 'cef-vaapi: Optional AUR CEF build with VA-API hardware video decoding support' | |||
| 19 | 'pipewire: Audio/video routing' | 20 | 'pipewire: Audio/video routing' | ||
| 20 | 'pipewire-pulse: PulseAudio replacement' | 21 | 'pipewire-pulse: PulseAudio replacement' | ||
| 21 | 'mesa: VA-API driver for AMD GPUs' | 22 | 'mesa: VA-API driver for AMD GPUs' | ||
M docs/config/index.md +1 -0
| @@ -189,6 +189,7 @@ border = "#363636" | |||
| 189 | 189 | | `rendering.show_fps` | bool | `false` | - | Show WebKit FPS counter (`WEBKIT_SHOW_FPS`) | | |
| 190 | 190 | | `rendering.sample_memory` | bool | `false` | - | Enable WebKit memory sampling (`WEBKIT_SAMPLE_MEMORY`) | | |
| 191 | 191 | | `rendering.debug_frames` | bool | `false` | - | Enable GTK frame timing debug (`GDK_DEBUG=frames`) | | |
| 192 | + | | `engine.type` | string | `"cef"` | `cef`, `webkit` | Browser engine. WebKit remains available as a fallback. | | |
| 192 | 193 | | `engine.cef.render_stack` | string | `"vulkan"` | `vulkan`, `egl` | CEF GPU render stack | | |
| 193 | 194 | | `engine.cef.adaptive_windowless_frame_rate` | bool | `true` | - | Enable adaptive CEF OSR FPS polling (only applies when `windowless_frame_rate = 0`) | | |
| 194 | 195 | | `engine.cef.windowless_frame_rate` | int32 | `0` | >= 0 | Explicit CEF OSR FPS cap; 0 uses adaptive mode if enabled, otherwise CEF default | | |
| @@ -189,6 +189,7 @@ border = "#363636" | |||||
| 189 | | `rendering.show_fps` | bool | `false` | - | Show WebKit FPS counter (`WEBKIT_SHOW_FPS`) | | 189 | | `rendering.show_fps` | bool | `false` | - | Show WebKit FPS counter (`WEBKIT_SHOW_FPS`) | | ||
| 190 | | `rendering.sample_memory` | bool | `false` | - | Enable WebKit memory sampling (`WEBKIT_SAMPLE_MEMORY`) | | 190 | | `rendering.sample_memory` | bool | `false` | - | Enable WebKit memory sampling (`WEBKIT_SAMPLE_MEMORY`) | | ||
| 191 | | `rendering.debug_frames` | bool | `false` | - | Enable GTK frame timing debug (`GDK_DEBUG=frames`) | | 191 | | `rendering.debug_frames` | bool | `false` | - | Enable GTK frame timing debug (`GDK_DEBUG=frames`) | | ||
| 192 | + | | `engine.type` | string | `"cef"` | `cef`, `webkit` | Browser engine. WebKit remains available as a fallback. | | |||
| 192 | | `engine.cef.render_stack` | string | `"vulkan"` | `vulkan`, `egl` | CEF GPU render stack | | 193 | | `engine.cef.render_stack` | string | `"vulkan"` | `vulkan`, `egl` | CEF GPU render stack | | ||
| 193 | | `engine.cef.adaptive_windowless_frame_rate` | bool | `true` | - | Enable adaptive CEF OSR FPS polling (only applies when `windowless_frame_rate = 0`) | | 194 | | `engine.cef.adaptive_windowless_frame_rate` | bool | `true` | - | Enable adaptive CEF OSR FPS polling (only applies when `windowless_frame_rate = 0`) | | ||
| 194 | | `engine.cef.windowless_frame_rate` | int32 | `0` | >= 0 | Explicit CEF OSR FPS cap; 0 uses adaptive mode if enabled, otherwise CEF default | | 195 | | `engine.cef.windowless_frame_rate` | int32 | `0` | >= 0 | Explicit CEF OSR FPS cap; 0 uses adaptive mode if enabled, otherwise CEF default | | ||
M docs/reference/configuration.md +1 -0
| @@ -59,6 +59,7 @@ | |||
| 59 | 59 | | `rendering.show_fps` | bool | `false` | | | |
| 60 | 60 | | `rendering.sample_memory` | bool | `false` | | | |
| 61 | 61 | | `rendering.debug_frames` | bool | `false` | | | |
| 62 | + | | `engine.type` | string | `cef` | `cef`, `webkit` | | |
| 62 | 63 | | `engine.cef.render_stack` | string | `vulkan` | `vulkan`, `egl` | | |
| 63 | 64 | | `engine.cef.adaptive_windowless_frame_rate` | bool | `true` | | | |
| 64 | 65 | | `engine.cef.windowless_frame_rate` | int32 | `0` | >= 0 | | |
| @@ -59,6 +59,7 @@ | |||||
| 59 | | `rendering.show_fps` | bool | `false` | | | 59 | | `rendering.show_fps` | bool | `false` | | | ||
| 60 | | `rendering.sample_memory` | bool | `false` | | | 60 | | `rendering.sample_memory` | bool | `false` | | | ||
| 61 | | `rendering.debug_frames` | bool | `false` | | | 61 | | `rendering.debug_frames` | bool | `false` | | | ||
| 62 | + | | `engine.type` | string | `cef` | `cef`, `webkit` | | |||
| 62 | | `engine.cef.render_stack` | string | `vulkan` | `vulkan`, `egl` | | 63 | | `engine.cef.render_stack` | string | `vulkan` | `vulkan`, `egl` | | ||
| 63 | | `engine.cef.adaptive_windowless_frame_rate` | bool | `true` | | | 64 | | `engine.cef.adaptive_windowless_frame_rate` | bool | `true` | | | ||
| 64 | | `engine.cef.windowless_frame_rate` | int32 | `0` | >= 0 | | 65 | | `engine.cef.windowless_frame_rate` | int32 | `0` | >= 0 | | ||
M docs/reference/dependencies.md +5 -3
| @@ -4,10 +4,10 @@ This page lists the system dependencies required to run Dumber on different Linu | |||
| 4 | 4 | ||
| 5 | 5 | ## Arch Linux | |
| 6 | 6 | ||
| 7 | - | ### Core GTK4 and WebKit | |
| 7 | + | ### Core GTK4, CEF, and WebKit fallback | |
| 8 | 8 | ||
| 9 | 9 | ```bash | |
| 10 | - | sudo pacman -S gtk4 webkitgtk-6.0 | |
| 10 | + | sudo pacman -S gtk4 cef webkitgtk-6.0 | |
| 11 | 11 | ``` | |
| 12 | 12 | ||
| 13 | 13 | ### VA-API (Hardware Video Acceleration) | |
| @@ -16,6 +16,8 @@ sudo pacman -S gtk4 webkitgtk-6.0 | |||
| 16 | 16 | sudo pacman -S libva libva-utils | |
| 17 | 17 | ``` | |
| 18 | 18 | ||
| 19 | + | For CEF hardware video decoding, `cef-vaapi` is available from the AUR as an optional CEF build. | |
| 20 | + | ||
| 19 | 21 | #### VA-API Drivers (install one based on GPU) | |
| 20 | 22 | ||
| 21 | 23 | **Intel (Broadwell and newer):** | |
| @@ -73,7 +75,7 @@ sudo pacman -S vulkan-tools # for vulkaninfo | |||
| 73 | 75 | ||
| 74 | 76 | ### CEF Wayland rendering | |
| 75 | 77 | ||
| 76 | - | When `engine.type = "cef"`, Dumber defaults to the GPU-first Wayland stack: GDK DMABUF presentation with ANGLE/GSK Vulkan. No launch wrapper or render environment variables are required for normal use. For driver compatibility, set `engine.cef.render_stack = "egl"` (or `DUMBER_ENGINE_CEF_RENDER_STACK=egl`) to use the GtkGLArea/EGL/OpenGL stack. | |
| 78 | + | CEF is Dumber's default engine. It uses the GPU-first Wayland stack: GDK DMABUF presentation with ANGLE/GSK Vulkan. No launch wrapper or render environment variables are required for normal use. For driver compatibility, set `engine.cef.render_stack = "egl"` (or `DUMBER_ENGINE_CEF_RENDER_STACK=egl`) to use the GtkGLArea/EGL/OpenGL stack. | |
| 77 | 79 | ||
| 78 | 80 | ## Debian/Ubuntu | |
| 79 | 81 | ||
| @@ -4,10 +4,10 @@ This page lists the system dependencies required to run Dumber on different Linu | |||||
| 4 | 4 | ||||
| 5 | ## Arch Linux | 5 | ## Arch Linux | ||
| 6 | 6 | ||||
| 7 | - | ### Core GTK4 and WebKit | 7 | + | ### Core GTK4, CEF, and WebKit fallback |
| 8 | 8 | ||||
| 9 | ```bash | 9 | ```bash | ||
| 10 | - | sudo pacman -S gtk4 webkitgtk-6.0 | 10 | + | sudo pacman -S gtk4 cef webkitgtk-6.0 |
| 11 | ``` | 11 | ``` | ||
| 12 | 12 | ||||
| 13 | ### VA-API (Hardware Video Acceleration) | 13 | ### VA-API (Hardware Video Acceleration) | ||
| @@ -16,6 +16,8 @@ sudo pacman -S gtk4 webkitgtk-6.0 | |||||
| 16 | sudo pacman -S libva libva-utils | 16 | sudo pacman -S libva libva-utils | ||
| 17 | ``` | 17 | ``` | ||
| 18 | 18 | ||||
| 19 | + | For CEF hardware video decoding, `cef-vaapi` is available from the AUR as an optional CEF build. | |||
| 20 | + | ||||
| 19 | #### VA-API Drivers (install one based on GPU) | 21 | #### VA-API Drivers (install one based on GPU) | ||
| 20 | 22 | ||||
| 21 | **Intel (Broadwell and newer):** | 23 | **Intel (Broadwell and newer):** | ||
| @@ -73,7 +75,7 @@ sudo pacman -S vulkan-tools # for vulkaninfo | |||||
| 73 | 75 | ||||
| 74 | ### CEF Wayland rendering | 76 | ### CEF Wayland rendering | ||
| 75 | 77 | ||||
| 76 | - | When `engine.type = "cef"`, Dumber defaults to the GPU-first Wayland stack: GDK DMABUF presentation with ANGLE/GSK Vulkan. No launch wrapper or render environment variables are required for normal use. For driver compatibility, set `engine.cef.render_stack = "egl"` (or `DUMBER_ENGINE_CEF_RENDER_STACK=egl`) to use the GtkGLArea/EGL/OpenGL stack. | 78 | + | CEF is Dumber's default engine. It uses the GPU-first Wayland stack: GDK DMABUF presentation with ANGLE/GSK Vulkan. No launch wrapper or render environment variables are required for normal use. For driver compatibility, set `engine.cef.render_stack = "egl"` (or `DUMBER_ENGINE_CEF_RENDER_STACK=egl`) to use the GtkGLArea/EGL/OpenGL stack. |
| 77 | 79 | ||||
| 78 | ## Debian/Ubuntu | 80 | ## Debian/Ubuntu | ||
| 79 | 81 | ||||
M internal/infrastructure/config/defaults.go +1 -1
| @@ -163,7 +163,7 @@ func DefaultConfig() *Config { | |||
| 163 | 163 | EnableDevTools: true, | |
| 164 | 164 | }, | |
| 165 | 165 | Engine: EngineConfig{ | |
| 166 | - | Type: "webkit", | |
| 166 | + | Type: EngineTypeCEF, | |
| 167 | 167 | Profile: ProfileDefault, | |
| 168 | 168 | PoolPrewarmCount: defaultWebViewPoolPrewarmCount, | |
| 169 | 169 | ZoomCacheSize: defaultZoomCacheSize, | |
| @@ -163,7 +163,7 @@ func DefaultConfig() *Config { | |||||
| 163 | EnableDevTools: true, | 163 | EnableDevTools: true, | ||
| 164 | }, | 164 | }, | ||
| 165 | Engine: EngineConfig{ | 165 | Engine: EngineConfig{ | ||
| 166 | - | Type: "webkit", | 166 | + | Type: EngineTypeCEF, |
| 167 | Profile: ProfileDefault, | 167 | Profile: ProfileDefault, | ||
| 168 | PoolPrewarmCount: defaultWebViewPoolPrewarmCount, | 168 | PoolPrewarmCount: defaultWebViewPoolPrewarmCount, | ||
| 169 | ZoomCacheSize: defaultZoomCacheSize, | 169 | ZoomCacheSize: defaultZoomCacheSize, | ||
M internal/infrastructure/config/defaults_test.go +1 -1
| @@ -15,7 +15,7 @@ func TestDefaultConfig_CoreDefaults(t *testing.T) { | |||
| 15 | 15 | assert.False(t, cfg.Media.ShowDiagnosticsOnStartup) | |
| 16 | 16 | ||
| 17 | 17 | // Engine defaults (replaces old Performance/Privacy sections) | |
| 18 | - | assert.Equal(t, "webkit", cfg.Engine.Type) | |
| 18 | + | assert.Equal(t, EngineTypeCEF, cfg.Engine.Type) | |
| 19 | 19 | assert.Equal(t, ProfileDefault, cfg.Engine.Profile) | |
| 20 | 20 | assert.Equal(t, CookiePolicyAlways, cfg.Engine.CookiePolicy) | |
| 21 | 21 | assert.Equal(t, CEFRenderStackVulkan, cfg.Engine.CEF.CEFRenderStack()) | |
| @@ -15,7 +15,7 @@ func TestDefaultConfig_CoreDefaults(t *testing.T) { | |||||
| 15 | assert.False(t, cfg.Media.ShowDiagnosticsOnStartup) | 15 | assert.False(t, cfg.Media.ShowDiagnosticsOnStartup) | ||
| 16 | 16 | ||||
| 17 | // Engine defaults (replaces old Performance/Privacy sections) | 17 | // Engine defaults (replaces old Performance/Privacy sections) | ||
| 18 | - | assert.Equal(t, "webkit", cfg.Engine.Type) | 18 | + | assert.Equal(t, EngineTypeCEF, cfg.Engine.Type) |
| 19 | assert.Equal(t, ProfileDefault, cfg.Engine.Profile) | 19 | assert.Equal(t, ProfileDefault, cfg.Engine.Profile) | ||
| 20 | assert.Equal(t, CookiePolicyAlways, cfg.Engine.CookiePolicy) | 20 | assert.Equal(t, CookiePolicyAlways, cfg.Engine.CookiePolicy) | ||
| 21 | assert.Equal(t, CEFRenderStackVulkan, cfg.Engine.CEF.CEFRenderStack()) | 21 | assert.Equal(t, CEFRenderStackVulkan, cfg.Engine.CEF.CEFRenderStack()) | ||
M internal/infrastructure/config/engine.go +2 -2
| @@ -27,12 +27,12 @@ type EngineConfig struct { | |||
| 27 | 27 | } | |
| 28 | 28 | ||
| 29 | 29 | // ResolveEngineType returns the effective engine type from config + env override. | |
| 30 | - | // It defaults to "webkit" when no type is configured, and allows DUMBER_ENGINE | |
| 30 | + | // It defaults to "cef" when no type is configured, and allows DUMBER_ENGINE | |
| 31 | 31 | // to override the configured value for smoke testing. | |
| 32 | 32 | func (e *EngineConfig) ResolveEngineType() string { | |
| 33 | 33 | engineType := e.Type | |
| 34 | 34 | if engineType == "" { | |
| 35 | - | engineType = EngineTypeWebKit | |
| 35 | + | engineType = EngineTypeCEF | |
| 36 | 36 | } | |
| 37 | 37 | if envEngine := os.Getenv("DUMBER_ENGINE"); envEngine != "" { | |
| 38 | 38 | engineType = envEngine | |
| @@ -27,12 +27,12 @@ type EngineConfig struct { | |||||
| 27 | } | 27 | } | ||
| 28 | 28 | ||||
| 29 | // ResolveEngineType returns the effective engine type from config + env override. | 29 | // ResolveEngineType returns the effective engine type from config + env override. | ||
| 30 | - | // It defaults to "webkit" when no type is configured, and allows DUMBER_ENGINE | 30 | + | // It defaults to "cef" when no type is configured, and allows DUMBER_ENGINE |
| 31 | // to override the configured value for smoke testing. | 31 | // to override the configured value for smoke testing. | ||
| 32 | func (e *EngineConfig) ResolveEngineType() string { | 32 | func (e *EngineConfig) ResolveEngineType() string { | ||
| 33 | engineType := e.Type | 33 | engineType := e.Type | ||
| 34 | if engineType == "" { | 34 | if engineType == "" { | ||
| 35 | - | engineType = EngineTypeWebKit | 35 | + | engineType = EngineTypeCEF |
| 36 | } | 36 | } | ||
| 37 | if envEngine := os.Getenv("DUMBER_ENGINE"); envEngine != "" { | 37 | if envEngine := os.Getenv("DUMBER_ENGINE"); envEngine != "" { | ||
| 38 | engineType = envEngine | 38 | engineType = envEngine | ||
M internal/infrastructure/config/engine_test.go +9 -0
| @@ -2,6 +2,15 @@ package config | |||
| 2 | 2 | ||
| 3 | 3 | import "testing" | |
| 4 | 4 | ||
| 5 | + | func TestResolveEngineTypeDefaultsToCEF(t *testing.T) { | |
| 6 | + | t.Parallel() | |
| 7 | + | ||
| 8 | + | cfg := EngineConfig{} | |
| 9 | + | if got := cfg.ResolveEngineType(); got != EngineTypeCEF { | |
| 10 | + | t.Fatalf("default engine type = %q, want %q", got, EngineTypeCEF) | |
| 11 | + | } | |
| 12 | + | } | |
| 13 | + | ||
| 5 | 14 | func TestCEFWindowlessFrameRateFallsBackToDefault(t *testing.T) { | |
| 6 | 15 | t.Parallel() | |
| 7 | 16 | ||
| @@ -2,6 +2,15 @@ package config | |||||
| 2 | 2 | ||||
| 3 | import "testing" | 3 | import "testing" | ||
| 4 | 4 | ||||
| 5 | + | func TestResolveEngineTypeDefaultsToCEF(t *testing.T) { | |||
| 6 | + | t.Parallel() | |||
| 7 | + | ||||
| 8 | + | cfg := EngineConfig{} | |||
| 9 | + | if got := cfg.ResolveEngineType(); got != EngineTypeCEF { | |||
| 10 | + | t.Fatalf("default engine type = %q, want %q", got, EngineTypeCEF) | |||
| 11 | + | } | |||
| 12 | + | } | |||
| 13 | + | ||||
| 5 | func TestCEFWindowlessFrameRateFallsBackToDefault(t *testing.T) { | 14 | func TestCEFWindowlessFrameRateFallsBackToDefault(t *testing.T) { | ||
| 6 | t.Parallel() | 15 | t.Parallel() | ||
| 7 | 16 | ||||
M internal/infrastructure/config/loader_test.go +1 -1
| @@ -12,7 +12,7 @@ func TestSetEngineDefaults(t *testing.T) { | |||
| 12 | 12 | mgr.setDefaults() | |
| 13 | 13 | ||
| 14 | 14 | // Universal engine fields | |
| 15 | - | assert.Equal(t, "webkit", mgr.viper.GetString("engine.type")) | |
| 15 | + | assert.Equal(t, EngineTypeCEF, mgr.viper.GetString("engine.type")) | |
| 16 | 16 | assert.Equal(t, "default", mgr.viper.GetString("engine.profile")) | |
| 17 | 17 | assert.Equal(t, "always", mgr.viper.GetString("engine.cookie_policy")) | |
| 18 | 18 | assert.Equal(t, 4, mgr.viper.GetInt("engine.pool_prewarm_count")) | |
| @@ -12,7 +12,7 @@ func TestSetEngineDefaults(t *testing.T) { | |||||
| 12 | mgr.setDefaults() | 12 | mgr.setDefaults() | ||
| 13 | 13 | ||||
| 14 | // Universal engine fields | 14 | // Universal engine fields | ||
| 15 | - | assert.Equal(t, "webkit", mgr.viper.GetString("engine.type")) | 15 | + | assert.Equal(t, EngineTypeCEF, mgr.viper.GetString("engine.type")) |
| 16 | assert.Equal(t, "default", mgr.viper.GetString("engine.profile")) | 16 | assert.Equal(t, "default", mgr.viper.GetString("engine.profile")) | ||
| 17 | assert.Equal(t, "always", mgr.viper.GetString("engine.cookie_policy")) | 17 | assert.Equal(t, "always", mgr.viper.GetString("engine.cookie_policy")) | ||
| 18 | assert.Equal(t, 4, mgr.viper.GetInt("engine.pool_prewarm_count")) | 18 | assert.Equal(t, 4, mgr.viper.GetInt("engine.pool_prewarm_count")) | ||
M internal/infrastructure/config/migrate_engine_test.go +2 -2
| @@ -81,7 +81,7 @@ func TestMigrateToEngineConfig_OldFormat(t *testing.T) { | |||
| 81 | 81 | engine, ok := engineAny.(map[string]any) | |
| 82 | 82 | require.True(t, ok, "engine must be a map") | |
| 83 | 83 | ||
| 84 | - | // engine.type defaults to "webkit" | |
| 84 | + | // legacy engine migration preserves WebKit because the old rendering/media sections are WebKit-specific | |
| 85 | 85 | assert.Equal(t, "webkit", engine["type"]) | |
| 86 | 86 | ||
| 87 | 87 | // [performance] -> [engine] universal fields | |
| @@ -280,5 +280,5 @@ show_fps = true | |||
| 280 | 280 | require.True(t, ok, "raw[\"engine\"] should exist") | |
| 281 | 281 | engine, ok := engineAny.(map[string]any) | |
| 282 | 282 | require.True(t, ok, "raw[\"engine\"] should be map[string]any, got %T", engineAny) | |
| 283 | - | assert.Equal(t, "webkit", engine["type"], "engine.type should default to webkit") | |
| 283 | + | assert.Equal(t, EngineTypeWebKit, engine["type"], "legacy engine migration should preserve WebKit") | |
| 284 | 284 | } | |
| @@ -81,7 +81,7 @@ func TestMigrateToEngineConfig_OldFormat(t *testing.T) { | |||||
| 81 | engine, ok := engineAny.(map[string]any) | 81 | engine, ok := engineAny.(map[string]any) | ||
| 82 | require.True(t, ok, "engine must be a map") | 82 | require.True(t, ok, "engine must be a map") | ||
| 83 | 83 | ||||
| 84 | - | // engine.type defaults to "webkit" | 84 | + | // legacy engine migration preserves WebKit because the old rendering/media sections are WebKit-specific |
| 85 | assert.Equal(t, "webkit", engine["type"]) | 85 | assert.Equal(t, "webkit", engine["type"]) | ||
| 86 | 86 | ||||
| 87 | // [performance] -> [engine] universal fields | 87 | // [performance] -> [engine] universal fields | ||
| @@ -280,5 +280,5 @@ show_fps = true | |||||
| 280 | require.True(t, ok, "raw[\"engine\"] should exist") | 280 | require.True(t, ok, "raw[\"engine\"] should exist") | ||
| 281 | engine, ok := engineAny.(map[string]any) | 281 | engine, ok := engineAny.(map[string]any) | ||
| 282 | require.True(t, ok, "raw[\"engine\"] should be map[string]any, got %T", engineAny) | 282 | require.True(t, ok, "raw[\"engine\"] should be map[string]any, got %T", engineAny) | ||
| 283 | - | assert.Equal(t, "webkit", engine["type"], "engine.type should default to webkit") | 283 | + | assert.Equal(t, EngineTypeWebKit, engine["type"], "legacy engine migration should preserve WebKit") |
| 284 | } | 284 | } | ||