CHANGELOG.md RawHistoryFolder

Changelog

All notable changes to this project will be documented in this file.

[Unreleased]

Added

  • Named browser windows: Added dumber browse --instance <name> to open or focus a stable named window in the current CEF profile host. Named windows share cookies, tokens, local storage, configuration, history, and favorites; use --profile for a separate persistent browser profile/host or --ephemeral for a temporary isolated profile/host.
  • Omnibox visual styles: Added configurable command, multiplexer, and minimal GTK treatments. The terminal-inspired command palette is the default.
  • Vim mode for keyboard-driven page navigation: Added configurable multi-key sequences for page scrolling, fast scrolling, page-input focus, and live heading navigation. Pressing Enter on a selected CEF heading opens its associated link before leaving Vim Mode. CEF accessibility data also provides the foundation for navigating structured page content such as headings, lists, paragraphs, and sections.
  • Native favorites sidebar: Added a keyboard-driven GTK sidebar toggled with Ctrl+B, including search, tag filtering, tag creation, favorite editing, shortcut assignment, deletion, and opening favorites in the current pane or a new split.
  • WebP favicon decoding: Added safe WebP decoding for sites that publish WebP favicons.

Changed

  • Omnibox borders: Outer borders scale with the configured UI size and remain more pronounced for the default command style.
  • Omnibox status indicators: The history-order control is now a passive status badge switched with Ctrl+R, and favorites use a terminal-style * marker.
  • Favorites organization: Favorites now use a tags-first model. Existing folder assignments are migrated into deterministic tags, with collision handling and folded-name uniqueness preserved during migration.
  • Page mode configuration: Page Mode is now called Vim Mode and uses the workspace.vim_mode configuration namespace for activation, timeouts, and action sequences. Existing page-mode bindings are migrated by the configuration loader.
  • Browsing-context routing: External links, floating panes, popups, and standalone omnibox launches now use explicit browsing-context ownership so they open in the appropriate pane or browser window.
  • Omnibox history window: Replaced omnibox.most_visited_days with omnibox.max_history_days. The window now applies to typed omnibox searches and to both empty-input lists (recent and most_visited), filtered in SQL before result limits. dumber config migrate renames the legacy key while preserving its value (including 0).
  • CEF presentation and lifecycle: Browser visibility, first-frame presentation, accessibility enablement, browser recreation, and PipeWire audio handoff now follow stricter lifecycle ownership and synchronization.
  • Dependencies and packaging: Updated the CEF/GTK bridge and PureGo dependencies, refreshed vendored build inputs, and synchronized CI, Flatpak, AUR, and release workflow metadata.

Fixed

  • Omnibox favorite selection: Selected favorite rows retain their yellow left indicator in every visual style.
  • Popup and floating-pane stability: Hardened deferred popup cleanup, failed popup creation, opener-capable fallback behavior, and pane/window rollback paths.
  • WebView resource cleanup: Fixed stale callback, timer, tick, split, hover-controller, and rebuilt-WebView ownership paths that could leak resources or act on detached views.
  • CEF rendering and input: Improved OSR input and clipboard handling, effective visibility transitions, canvas presentation, repeated GPU relaunch recovery, and runtime propagation to helper processes.
  • Omnibox and link handling: Fixed standalone links opening in the wrong context, stale entry-buffer reconciliation, external-pane chrome, and global shortcut ownership.
  • Vim input handling: Fixed ambiguous and modified-key sequence parsing, legacy binding collisions, detach cancellation, editable-focus transitions, and repeat/scroll scheduling.

Security

  • WebView bridge hardening: Tightened reviewed WebKit bridge paths and runtime/development boundary handling.

[0.30.0] - 2026-06-27

Added

  • CEF input tuning and touchpad navigation: Added CEF scroll sensitivity settings plus deliberate two-finger back/forward swipe navigation with edge detection, threshold controls, and an on-screen progress indicator.
  • Pane ejection to windows: Pane Mode can move the active pane into a new browser window with the eject-pane-to-window action.
  • Native history sidebar: Ctrl+H now toggles a GTK history sidebar with grouped history, search/filtering, paging, keyboard navigation, configurable width, and live refresh when history changes.
  • Favicon refresh and resolution pipeline: Favicons are discovered, converted, cached, refreshed, and resolved through a path-aware cache with safer fallback behavior.
  • Noctalia external theme integration: Dumber can follow Noctalia colors.json palettes with live reload, last-good fallback, and an advanced Dumber-specific JSON theme format.

Changed

  • Runtime configuration handling: Engine, privacy, CEF/WebKit tuning, and clipboard settings now flow through typed runtime snapshots so active and newly acquired browser views use current settings consistently.
  • History loading performance: History timelines use stable cursor pagination bounded by row count, improving large-history loading and “load more” behavior.
  • Navigation URL normalization: Omnibox, dmenu, tab, and pane navigation now share consistent handling for existing local paths and file:// URLs.
  • Packaging and release checks: AUR metadata now declares the CEF runtime dependency, make check verifies generated systemview assets, and GoReleaser validates the embedded compressed systemviews WASM before packaging.
  • Tooling and dependencies: Updated CEF bridge, Go dependencies, GitHub Actions, and pinned local lint/static analysis tooling.

Fixed

  • CEF rendering stability: CEF now respects effective HiDPI scale for zoom, keeps viewports synced during resize, and handles Vulkan/navigation handoff paths more reliably.
  • Browser resource cleanup: Closing tabs and windows now releases their WebViews through the normal lifecycle path, reducing leaked browser resources.
  • Idle inhibition cleanup: Fixed a portal signal cleanup race that could crash when idle-inhibitor connections were cleared.
  • Session and filter maintenance: Session cleanup now uses process liveness instead of ending unrelated active sessions, and content-filter updates better detect manifest changes while pruning obsolete cached parts.
  • Pane operation safety: Invalid split directions and failed pane moves are validated before mutating pane state.
  • Loading/error states: Failed main-frame navigations now leave loading skeletons and content state cleanly.
  • Updater resilience: Self-update checks retry transient request failures, including temporary DNS errors.
  • WebKit fallback stability: WebKit systemview message routing now snapshots base context safely under concurrent updates.

Security

  • External scheme launch hardening: External protocol redirects from page navigation no longer launch desktop handlers from untrusted paths or corrupt browser navigation state.
  • Sensitive URL redaction: Diagnostic logs redact URL paths, query strings, and fragments, and persistent log files/directories use user-private permissions.
  • Local boundary hardening: Filter downloads, manifest parsing, cache writes/lookups, systemview bridge access, and history query limits now enforce stricter path, size, trust, and validation boundaries.

[0.29.0] - 2026-05-27

Added

  • 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".
  • 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.
  • System views rewrite: The old Svelte webui/ has been replaced by native/WASM-backed system views for config, history, and favorites.
  • Standalone omnibox launcher: dumber omnibox now opens the omnibox in a standalone window.
  • Fresh browser windows: Browser launches can now open in dedicated fresh windows.
  • GTK UI font setting: GTK chrome now has its own configurable UI font.

Changed

  • CEF runtime integration: CEF now uses purego-cef2gtk, a codec-enabled runtime path, deterministic runtime discovery, and XDG-scoped user data.
  • 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.
  • Unified browser plumbing: Downloads, context menus, internal pages, favicons, clipboard handling, and browser launch flows now share more code across WebKit and CEF.
  • Window-scoped tabs and browsing contexts: Tab shortcuts, popup handling, OAuth windows, and native browser windows now track the owning window/context more consistently.
  • 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.
  • Logging cleanup: Session log cleanup can cap log files by count as well as age.
  • Tooling and dependencies: Go/runtime dependencies, GitHub Actions, golangci-lint, PipeWire audio dependencies, and AUR metadata were refreshed.

Fixed

  • CEF rendering stability: Hardened OSR browser creation, live resize repainting, viewport sync, popup surfaces, and bounded size observation.
  • CEF input and focus: Improved clipboard, keyboard focus, tab shortcuts, global shortcut release behavior, gesture callback release, and ghost shortcut suppression.
  • CEF file dialogs and local files: Hardened GTK file-dialog callbacks, GIO cleanup, file-dialog edge cases, and zoom for local file:// URLs.
  • CEF popups and OAuth: Improved popup lifecycle cleanup, native popup content widgets, pane-hosted popup fallback cleanup, and OAuth auto-close behavior.
  • Desktop integration: Browser MIME handler sync and browser launch error redaction are more reliable.
  • Session and pane resilience: Stale pane restore paths, nil workspace pane views, and popup restore cleanup are safer.

[0.28.0] - 2026-03-27

Added

  • Engine abstraction layer: Introduced a major architectural refactor that decouples the browser engine layer from the UI. The new Engine interface and supporting infrastructure make it possible to support alternative rendering engines beyond WebKit in the future. Users with custom configurations should run dumber config migrate to transition to the new engine configuration format ([engine]/[engine.webkit] structure). The migration is automatic and backwards-compatible.
  • Website data access permission: New permission dialog and system for controlling access to website persistent data. Users can now grant or deny individual websites access to cookies, localStorage, and other persistent storage.
  • Content blocker large filter set support: Filter sets exceeding WebKit's 150k rule limit are now properly handled by compiling each part file as a separate WebKit filter, enabling support for comprehensive filter lists. Filter file discovery is now dynamic via manifest instead of a hardcoded list.
  • Content blocker debug logging: Added load-failed signal logging to help diagnose content blocker and filter compilation issues.

Changed

  • Database backend modernization: Replaced the WASM-based ncruces/go-sqlite3 with native purego-sqlite via pure FFI (no WASM runtime, no CGO required). This simplifies the build process and improves startup performance by removing the SQLite WASM initialization precompile step.
  • Keyboard and input system overhaul: Complete rewrite of keyboard routing with native dead key and compose sequence support. The new unified key routing system properly handles accent input with bubble-phase handling and input method fallback, restricted to editable targets with accessibility fallback.
  • Omnibox ghostwriter reliability: Reimplemented the ghost text system to eliminate letter-eating on fast typing. Replaced the goroutine/token/coalescer machinery with synchronous ghost computation, a guard flag for programmatic SetText, debounced echo detection, and stale input checks.
  • Omnibox URL intent matching: Improved URL detection to prioritize URL-like input on Enter, normalize bare IPs to HTTP for local/tailnet services, and handle leading whitespace correctly. Explicit omnibox selections are now always honored over ghost input.
  • Permission system hardening: Strengthened permission origin handling to use the live page URI from the signal's WebView for all permission lookups. Exported metadata key constants replace raw string literals. Cookie policy default now correctly aligns with Epiphany ITP model.
  • GTK binding upgrades: Migrated from jwijenbergh/puregotk to bnema/puregotk with ebitengine/purego. Signal callbacks now receive *glib.Error instead of raw uintptr, providing actual error messages in load-failed and download-failed logs. Fixes g_object_new_with_properties use-after-free via []string keepalive.

Fixed

  • WebView accent picker: Fixed double-character input and focus loss in the WebView accent picker during rapid typing.
  • Async callback safety: Hardened async callbacks with URI validation and timer generation counters to prevent stale callbacks from executing on the wrong WebView.
  • Modal phase synchronization: Made setControllerPhase synchronous and dispatched modal timeouts via the GTK main thread to prevent race conditions.
  • Keyboard routing thread-safety: Resolved thread-safety issues and nil-guard checks in keyboard routing.
  • Application shortcuts restoration: App shortcuts are now restored when WebView has focus.
  • Favicon caching: Fixed stacked title bar favicons to populate from cache on stack creation, guarded against nil texture overwriting a good favicon, and prevented swap on pool reuse.
  • SIGABRT crash on permission requests: Fixed a crash that occurred when the permission-request signal was emitted during rapid pane teardown.
  • Panic logging in safeGLibType: Recovered panics are now logged instead of silently swallowed.

[0.27.2] - 2026-02-17

Changed

  • Toolchain compatibility updates: Bumped the project to Go 1.26, updated puregotk dependencies, and upgraded golangci-lint to v2.9.0 to keep CI aligned with the new Go version.
  • Maintenance: Internal refactor to OAuth popup timing.
  • README wording cleanup: Tightened README copy and standardized uBlock casing.
  • Repository hygiene: Removed an accidentally tracked plan file that is already covered by .gitignore.

Fixed

  • Floating pane Escape handling: Pressing Escape now hides the floating pane only when it is currently visible.
  • OAuth popups now close reliably after sign-in.
  • Auto-close only affects the OAuth window so other popups are not dismissed unexpectedly.

[0.27.1] - 2026-02-12

Fixed

  • Release CI hotfix: Removed invalid disable_immutable from GoReleaser config so release workflows run correctly.

Changed

  • Release workflow compatibility: Fixed Flatpak upload behavior for workflow_dispatch triggers.

[0.27.0] - 2026-02-12

Added

  • Unexpected-close crash reports: Automatically detects prior abrupt sessions on startup and generates per-session crash reports (JSON + Markdown) with metadata, core-dump diagnostics, and redacted log tails. Reports are capped at 20 to prevent unbounded disk growth.
  • dumber crashes CLI: New CLI surface to list, view, and extract GitHub issue payloads from crash reports (dumber crashes, dumber crashes show latest, dumber crashes issue latest).
  • Crash report UI notification: Startup toast guides users to run dumber crashes issue latest when unexpected-close reports are detected.
  • Unexpected-close GitHub issue template: Structured issue template for reporting crashes with crash report payload, context, and reproduction steps.
  • Session exit classification runbook and diagnostics docs: Added dedicated operational documentation for abrupt/clean exit classification and troubleshooting paths.
  • Session/bootstrap resilience coverage: Added tests and supporting logic for startup markers, WebKit stack bootstrap, and exit classification handling.
  • Omnibox async guard tests: Added focused tests for ghost text async/state safety and normalization behavior.
  • Floating pane (persistent overlay pane): Alt+F toggles a workspace floating pane that preserves its session state while hidden.
  • Floating pane profiles: Optional URL profiles under workspace.floating_pane.profiles with user-defined shortcut keys to open/focus named floating sessions.
  • Floating pane documentation: Added reference docs describing floating behavior, shortcuts, and configuration.
  • Installer prerelease/version selection: install.sh supports DUMBER_PRERELEASE=1 to install the latest prerelease and DUMBER_VERSION=<tag> to install a specific release.

Changed

  • WebKit/puregotk compatibility refresh: Updated bindings and call sites for github.com/bnema/puregotk-webkit v0.0.10 and latest puregotk replacement, including signal ID/type handling updates.
  • Dependencies updated: Bumped key runtime/developer dependencies, including go-sqlite3, bubbles, and related transitive modules.
  • Omnibox behavior tuning: Refined ghost suggestion ranking/selection behavior and dynamic result sizing tied to pane height.
  • Autocomplete architecture cleanup: Centralized completion flow and ghost positioning helpers for more consistent behavior across async paths.
  • Omnibox keyboard/navigation UX: Added Alt+h/j/k/l pane navigation while omnibox is open and improved chrome height scaling/debouncing on GTK main thread.
  • Config normalization hardening: Normalization now coerces invalid profile/appearance values to safe defaults.
  • Loading skeleton redesign: Reduced logo from 512px to 256px, added version label below a discrete 32px spinner. Sizes extracted to constants so tests use mock.Anything and don't break on dimension changes.
  • Aggressive WebView reuse policy: reusePolicyAggressive now actually differs from reusePolicySafe by allowing reuse regardless of navigation activity, relying on ResetForPoolReuse to clear state.
  • Multiple GUI instances: GTK app is now non-unique, allowing independent dumber launches in parallel.
  • Config schema/validation: Added workspace.floating_pane.* config keys to schema and validation, including URL/profile shortcut validation.
  • Config migration for shortcut actions: Migration now merges newly added workspace.shortcuts.actions.* defaults into existing user action maps without overwriting user-defined entries.

Fixed

  • Hover focus stealing from new split panes: New pane creation now locks hover focus until the user intentionally moves the mouse, replacing the 300ms time-based suppression that could expire before GTK layout completes. Synthetic enter events from widget rearrangement no longer steal focus from freshly created panes.
  • Stacked pane title desync on navigation: Titles in the stacked title bar now sync immediately on LoadCommitted and when switching panes, preventing stale titles after background navigation.
  • Session marker file accumulation: writeShutdownMarker now removes the matching startup marker (embedding its timestamp for classification), and a new sweepPairedMarkers sweep in background cleanup removes old marker trios past the configured age.
  • Retry delay exceeding max: retryDelayForAttempt now clamps the final delay (base + jitter) to retryMaxDelay so backoff never overshoots the hard cap.
  • Inconsistent WebView termination in pool: PrewarmFirst, PrewarmAsync, prewarmSync, and RefreshScripts now call DestroyWithPolicy(terminatePolicy) instead of bare Destroy(), matching Release behavior.
  • Pool metrics counted on failed creation: acquireCount, acquirePoolMisses, and acquireTotalNanos are now incremented only after createWebView succeeds.
  • Redundant crash page URI sanitization: Removed double sanitizeCrashPageOriginalURI call inside buildCrashPageHTML; the caller already sanitizes.
  • Racy skeleton version global: Replaced plain string with atomic.Value so concurrent reads/writes to skeletonVersion are safe.
  • Inline ghost suggestion stability: Reworked ghostwriter flow to keep suggestions selected (not auto-committed), with stronger token guards and stale-callback protection.
  • GTK thread-safety in omnibox: Removed unsafe off-main-thread widget reads in async flows.
  • Review follow-ups (Copilot/CodeRabbit): Fixed custom-scheme GET handling for empty WebKit methods, synchronized pool close/send paths, aligned WebKit signal ID storage types, and marshalled OAuth parent refresh reloads back to the GTK main loop.
  • Persistence/update safety edges: Enforced positive visit-count deltas in SQLite repos, removed redundant filter cache directory creation, canceled pending snapshot timer on SetReady, and made updater retry-loop exhaustion explicit.
  • Logging/dedup consistency: Unified abrupt-session marker stat warnings under structured session logging and reduced favicon warning dedup growth by using a global cache-dir warning key plus callback coverage tests.
  • Omnibox input/ghost correctness: Enforced minimum typed input before ghost suggestions, trimmed leading spaces before URL interpretation, deferred omnibox auto-open until layout is ready, and fixed width/layout edge-cases.
  • History/autocomplete edge-cases: Normalized FTS queries containing slashes and capped about:blank visit-count inflation.
  • Navigation/history robustness: Added pane history cleanup hooks, batched/capped visit increment fallback, and idempotent NavigateUseCase.Close().
  • WebView lifecycle/reset correctness: Reset pooled WebView transient state more thoroughly and improved callback/signal wiring consistency.
  • Navigation safety guards: Added CanGoBack protection in navigation policy handling and corrected back-forward-list signal disconnection target.
  • Crash handling and retry edge-cases: Hardened crash-page routing safety, updater retry semantics/documentation, and related infra error paths.
  • Filtering/snapshot/session reliability: Fixed race/error-handling paths in filtering updates, snapshot persistence, and session startup marker processing.
  • WebView pool shutdown race: Re-check closed flag after createWebView in Acquire to prevent leaking WebViews when pool closes during creation.
  • Updater transient error detection: Broadened isRetryableRequestError to detect ECONNRESET, ECONNREFUSED, ENETUNREACH, EHOSTUNREACH, and EADDRNOTAVAIL syscall errors, plus net.Error.Temporary() and url.Error wrappers.
  • Session lock probe accuracy: markAbruptExits now uses non-blocking flock instead of os.Stat, correctly distinguishing active sessions (lock held) from stale ones (lock acquirable) and skipping on permission/IO errors.
  • Crash page "Stay on this page" UX: Button no longer navigates to dumb://home/crash; it now stays on the crash page as its label suggests.
  • Visit increment fallback overflow: IncrementVisitCountBy now returns an error when delta exceeds the fallback cap instead of silently dropping increments.

Security

  • External scheme launch guard: Restricted external URL scheme launching to user-gesture initiated navigations.

[0.26.1] - 2026-01-25

Fixed

  • Popups not working in split panes: Fixed window.open() and target="_blank" links not functioning in split panes. Popup handling was not being set up for WebViews created via EnsureWebView.

Changed

  • WebView callback setup refactoring: Consolidated duplicate callback setup code into single setupWebViewCallbacks function. EnsureWebView now delegates to this function instead of inline setup. Made setupPopupHandling private since no external callers remain.

[0.26.0] - 2026-01-24

Added

  • Visual keybindings editor: New Keybindings tab in dumb://config allows editing all keyboard shortcuts via a visual UI. Supports key capture, reset to defaults, and per-binding reset. Fixes #123.
  • Keybindings hot reload: Changed keybindings take effect immediately without restarting the browser.
  • Ordered config file: Config file sections are now written in alphabetical order for better readability and deterministic output.
  • Inline ghost text autocompletion: Omnibox now shows inline ghost text suggestions from history as you type. Accept with Right Arrow (full) or Ctrl+Right (word). Properly aligned with entry text.
  • Omnibox click-outside-to-close: Omnibox automatically closes when clicking outside its bounds.
  • GTK/WebKit log capture: New logging.capture_gtk_webkit_logs config option to capture GTK and WebKit logs for debugging.
  • Startup performance tracing: Added startup trace logging for cold start performance analysis and optimization.

Changed

  • Simplified keybinding syntax: Keybindings now use symbol syntax ([, ], {, }) instead of verbose GTK names (bracketleft, braceleft). Fixes #122.
  • BREAKING: Global shortcuts config structure: workspace.shortcuts changed from individual string fields to unified Actions map with ActionBinding (keys + description). Existing custom shortcuts in config.toml will be replaced with defaults. Use the new Keybindings UI to reconfigure.
  • Keybindings clean architecture: Refactored keybindings handler to follow ports/adapters pattern. Business logic moved from handler to use cases, config access via gateway adapter instead of global singleton.
  • Deferred startup initialization: Non-critical initialization (WebView pool prewarm, etc.) now deferred until after first navigation starts for faster cold start.
  • Omnibox search ranking: Improved domain matching boost and FTS5 period handling for better search result relevance.

Upgrade Notes

Recommended: Delete your config.toml and restart dumber to regenerate a fresh config with the new keybinding structure and alphabetically sorted sections. Your settings will reset to defaults, but you can reconfigure keybindings via the new visual editor at dumb://config → Keybindings tab.

Fixed

  • Config save/read race condition: Fixed UI scale and other config values returning stale data after save. Implemented atomic file writes (temp file + rename) and skipNextReload flag to prevent fsnotify-triggered reload from overwriting correct in-memory config with stale viper cache.
  • WebUI lint warnings: Added ESLint Svelte plugin and resolved 33 lint errors and 14 any type warnings across all components. Created dumber.d.ts for proper TypeScript types for WebKit bridge communication.
  • Session snapshot FK constraint: Fixed SQLite foreign key constraint violation when snapshot service tried to save before session was persisted to database. Added ready flag and callback notification pattern.
  • Stacked pane index out of bounds: Fixed crash when domain model and UI got out of sync during stacked pane operations. Added bounds checking and proper rollback when UI updates fail.
  • Noisy gesture navigation logs: Mouse button back/forward navigation errors (expected when no history) now log at debug level instead of error level.
  • Omnibox ghost text race conditions: Fixed stale ghost text appearing due to race conditions. Query now passed through the entire autocomplete chain.
  • Omnibox ghost text clipping: Ghost text now properly clips to entry bounds and aligns vertically with input text.
  • Ghost text on history scroll: Disabled ghost text suggestions when scrolling through history with arrow keys after user has typed.
  • Popup WebView hierarchy: Fixed popup WebViews not being inserted into GTK hierarchy before create signal returns.
  • OAuth popup timeout: Added 30-second safety timeout for OAuth popup handling to prevent stuck popups.
  • External page background: Reset WebView background to white for external pages to prevent dark theme color bleeding into light-themed sites.
  • Localhost URL normalization: Fixed localhost URL handling and improved download handler architecture for cleaner code.
  • Svelte 5 Proxy serialization: Fixed keybinding bridge serialization to handle Svelte 5 Proxies and added conflict detection.

[0.25.0] - 2026-01-08

Added

  • File download handling: Downloads from websites now save to the user's download directory with toast notifications for start/complete/failed states. Configurable via downloads.path (defaults to $XDG_DOWNLOAD_DIR or ~/Downloads).
  • Print shortcut: Ctrl+Shift+P opens the print dialog for the current page. Fixes #99.

Changed

  • Flatpak files location: Moved flatpak-related files to flatpak/ directory. Fixes #101.
  • Navigation shortcuts: Ctrl+Left/Right now triggers back/forward navigation, Alt+Left/Right moves focus between panes. Fixes #98.
  • Update notification: Simplified update toaster message for AUR/Flatpak users - no longer shows "manual install required". Fixes #109.

Fixed

  • SPA mouse navigation: Fixed unreliable back/forward mouse button navigation in Single Page Applications. WebKit's BackForwardList doesn't track JavaScript History API (pushState/replaceState) navigation. Now uses JavaScript history.back()/history.forward() as fallback when WebKit native navigation is unavailable.
  • Accent picker freeze: Fixed UI freeze when selecting an accent by pressing Enter or Escape. The deadlock was caused by the callback (which calls Hide()) being invoked while holding the mutex that Hide() also needs to acquire.
  • Stacked pane title mismatch: Fixed title bar showing wrong page title after closing panes in a stack. Refactored stacked pane management to use proper use cases, ensuring domain model stays in sync with UI.
  • Flatpak favicons: Fixed favicons not displaying in omnibox for Flatpak installs by ensuring cache directory exists before saving. Fixes #105.
  • Flatpak desktop launcher: Fixed .desktop file not launching application from app launchers by adding locale environment variables. Fixes #104.
  • Flatpak update notifications: Skip GitHub update checks for Flatpak and AUR installs (use package manager instead). Fixes #107.
  • Active border with stacked panes: Hide active pane border when only one pane area is visible (stacked panes count as one). Fixes #108.
  • Setup command for AUR: dumber setup now detects AUR and Flatpak installations and locates the correct .desktop file. Fixes #102.

Removed

  • dev/ directory: Removed development scripts directory. Fixes #103.

[0.24.0] - 2026-01-06

Added

  • Auto-copy on selection: Text selected in web pages is automatically copied to the clipboard (like zellij/tmux). Shows brief "Copied to clipboard" toast notification. Configurable via clipboard.auto_copy_on_selection (default: true). Fixes #83.
  • Font availability detection: On first run, detects available system fonts using fontconfig (fc-list) and selects the best font from a fallback chain instead of hardcoding Fira Sans / Fira Code. Fallback chains: sans-serif (Fira Sans, Noto Sans, DejaVu Sans, Liberation Sans, FreeSans), serif (Noto Serif, DejaVu Serif, Liberation Serif, FreeSerif), monospace (Fira Code, JetBrains Mono, Noto Sans Mono, DejaVu Sans Mono, Liberation Mono, FreeMono). Falls back to generic CSS fonts if none available. Fixes #85.
  • Stacked pane close buttons: Close buttons in stacked pane title bars allow closing individual panes directly. Includes proper signal cleanup on removal.
  • AUR git package CI: Automated CI workflow to publish dumber-browser-git AUR package on push to main branch.

Changed

  • Flatpak runtime: Bumped to GNOME 49 runtime.
  • Focus method refactored: Focus() now delegates to ApplyFocusChange() to ensure stack index is updated when focusing stacked panes.

Fixed

  • Flatpak locale crash: Attempted fix for crash on systems with certain locale configurations by adding proper locale data to the Flatpak bundle.
  • Stacked pane vertical splits: Vertical splits from stacked panes now correctly split around the entire stack instead of just the active pane.
  • Pane border focus: Fixed stale border remaining on previously hovered pane when using keyboard navigation to switch focus. Fixes #89.
  • Geometric focus navigation: Fixed focus jumping to wrong pane when navigating left/right in complex layouts. Navigation now prioritizes panes at the same vertical level (for left/right) or horizontal level (for up/down).
  • Link status overlay auto-hide: Link URL overlay now automatically hides after 10 seconds of inactivity instead of staying visible indefinitely. Timer resets when hovering new links. Fixes #82.
  • Omnibox multi-word search: History search now matches all words in query (AND logic) and searches both URL and title fields. Prefix matching enabled (e.g., "git iss" matches "github.com/issues"). FTS5 special characters are now sanitized to prevent syntax errors. Results interleave URL and title matches for better balance. Fixes #87.

[0.23.2] - 2025-12-31

Added

  • AUR packaging support: Dumber is now available on the Arch User Repository (AUR).
    • dumber-browser-bin: Pre-built binary package from GitHub releases (recommended).
    • dumber-browser-git: Build from source, tracks latest git.
    • Install with yay -S dumber-browser-bin or paru -S dumber-browser-bin.
    • Automatic AUR updates via GitHub Actions (1 hour delay after Flatpak build for safety).
  • Pacman/AUR install detection: Self-updater is disabled when installed via pacman/AUR (uses pacman -Qo to detect package ownership). Shows specific message: "use your package manager instead".
  • Improved update error messages: Self-update now shows specific messages for Flatpak ("use 'flatpak update'") and pacman/AUR ("use your package manager") installs instead of generic "binary not writable" error.

[0.23.1] - 2025-12-30

Added

  • Flatpak packaging support: Dumber is now available as a Flatpak bundle for easy installation with all dependencies included.
    • dumber.flatpak bundle attached to each GitHub release.
    • Install with flatpak install --user dumber.flatpak.
    • Includes Wayland, GPU, audio, webcam, and PipeWire permissions.
    • Automatic builds via GitHub Actions on every release.
  • Flatpak runtime detection: Skip pkg-config runtime checks when running inside Flatpak sandbox (GNOME runtime provides all dependencies).
  • Self-updater disabled in Flatpak: Binary self-update is disabled when running as Flatpak (use Flatpak update mechanisms instead).

[0.23.0] - 2025-12-30

Added

  • macOS-style accent picker: Long-press (400ms) on keys with accent variants (e, a, o, u, i, c, n, s, y, z) shows a popup with accented character options. Select with number keys 1-9, arrow keys + Enter, or click. Works in omnibox, find bar (Ctrl+F), and web page inputs. Implements dead keys/compose sequence alternative for users who can't use system-level input methods.
  • Performance profiles (WebKit tuning presets): New performance.profile setting (default, lite, max, custom) plus WebUI support for selecting and editing performance tuning values.
  • dmenu history enhancements: New dumber dmenu --days N (time-window history) and --most-visited (sort by visit count).

Changed

  • Color scheme detection architecture: Refactored theme preference detection into a priority-based ColorSchemeResolver with multiple detectors (libadwaita/GTK/gsettings/env) and a change notification API for consistent dark-mode behavior.
  • dmenu history limiting: dmenu history limiting is now time-based (days) instead of a fixed max item count.
  • WebKit dependency: Bumped github.com/bnema/puregotk-webkit to v0.0.9.

Fixed

  • Dark mode detection on internal pages: Fixed dumb://home and other internal pages showing light theme despite system being in dark mode. Refactored color scheme detection to use a priority-based resolver with proper initialization ordering. The libadwaita detector (highest priority) is now correctly enabled only after adw.Init() completes, ensuring WebViews created during bootstrap get the correct theme preference.
  • External site form theming artifacts: Removed injected color-scheme overrides that caused odd styling in some forms/inputs on regular websites.
  • WebKit memory pressure stability: Fixed an assertion by applying strict memory thresholds before conservative thresholds when configuring WebKit’s memory pressure handlers.
  • Web process termination on perf tuning: Removed the “memory kill” threshold because it could terminate the web process immediately in some environments.
  • dumb:// scheme context mismatch: Fixed internal pages sometimes using a different WebKit context than expected by always using the default context.
  • Accent picker Escape behavior: Fixed cases where Escape wouldn’t dismiss the accent picker after mouse interaction by restoring focus appropriately.
  • dmenu history days edge case: Fixed dumber dmenu --days 0 to mean “all history”, and added validation for invalid day values.

[0.22.0] - 2025-12-28

Added

  • Omnibox bang shortcuts UI: Typing ! in the omnibox now shows all configured bangs (search shortcuts) with filtering and Enter-to-autocomplete, plus a header badge when a bang is recognized.
  • Loading skeleton with app logo: New panes show a centered 512x512 faded app logo with a spinner while loading, replacing the blank/white flash. Uses --muted theme color for the spinner.
  • App logo favicon for internal pages: dumb:// URLs now display the dumber logo as favicon in history, favorites, omnibox suggestions, and dmenu/rofi. WebUI and CLI tools share consistent branding.
  • Omnibox favorite indicator: History items that are also bookmarked now display a yellowish left border and subtle background tint in the omnibox. Uses parallel async loading to avoid blocking browser startup.
  • Mode indicator toaster: Visual notification showing current modal mode (PANE MODE, TAB MODE, SESSION MODE, RESIZE MODE) at bottom-left corner with mode-specific colors. Configurable via workspace.styling.mode_indicator_toaster_enabled (default: true).
  • Config migration system: Detects missing config keys when new settings are added in updates and provides tools to add them.
    • dumber config status: Shows config file path and number of new settings available.
    • dumber config migrate: Lists missing keys with types/defaults and adds them to config file.
    • GUI toast notification on startup when new settings are available (configurable via update.notify_on_new_settings).
  • CLI self-update command: New dumber update command to check for and install updates from the command line.
    • Interactive spinner animation during check and download phases.
    • --force / -f flag to skip version check and reinstall the current version.
    • Reuses existing auto-update infrastructure (check, download, stage, apply on exit).
    • Theme-aware styling consistent with other CLI commands.
  • Config open command: New dumber config open command to open the config file in your preferred editor. Uses $EDITOR, then $VISUAL, with fallback to nano/vim/vi.
  • Config schema command: New dumber config schema command that displays all configuration keys with their types, defaults, descriptions, and valid values. Supports --json flag for machine-readable output.
  • CLI gen-docs command: New dumber gen-docs command to generate documentation from CLI command definitions. Supports man pages (installed to ~/.local/share/man/man1/) and markdown formats. Use --format markdown for markdown output or --output for custom directory.
  • Move pane to tab: New pane-mode actions to move the active pane to another tab.
    • Ctrl+P → m: Opens a tab picker modal.
    • Ctrl+P → M: Moves the active pane to the next tab (creates a new tab if needed).
    • New config: workspace.switch_to_tab_on_move (default: true).

Changed

  • Cold start optimization: Reduced startup time by ~150ms (29% faster) through parallel initialization.
    • New internal/bootstrap package encapsulates all startup orchestration.
    • RunParallelInit() runs 5 goroutines concurrently: directory resolution, pkg-config check, GStreamer check, theme manager creation, and SQLite WASM pre-compilation.
    • WebView pool prewarming creates one WebView synchronously so first Acquire() is instant.
    • Async session cleanup: stale session marking runs in background, doesn't block startup.
    • StartupTimer logs timing for each bootstrap phase (parallel init, DB/WebKit, app creation).
    • Database initialization runs in background goroutine while WebKit stack initializes on main thread.
    • Database path now resolved via config.GetDatabaseFile() following clean architecture.
    • Added connection pool settings optimized for SQLite (SetMaxOpenConns(1), keep-alive).
    • Reduced mmap_size from 30GB to 256MB (reasonable for browser history DB).
    • Added PRAGMA foreign_keys = ON for referential integrity.
  • Startup deferrals: Runtime/media checks and SQLite WASM precompile now run after first paint, and DB initialization uses lazy repositories when auto-restore is off to cut cold-start latency further.
  • Console logging: Standardized console timestamps to HH:MM:SS across bootstrap and session logging.

Fixed

  • Omnibox favorite toggle reactivity: Fixed space key toggle in omnibox not updating UI reactively. Now properly toggles favorites (add if not favorite, remove if favorite) with immediate visual feedback (yellow indicator) and toast notifications. Business logic moved to ManageFavoritesUseCase.Toggle() for testability.
  • Config migration type matching: Fixed migration incorrectly matching keys of different types (e.g., _width int keys with _color string keys) during rename detection, preventing value swapping.
  • Config migrate removes deprecated settings: Fixed dumber config migrate not removing deprecated settings from the config file. Previously deprecated keys were preserved but unused; now they are properly deleted. Supports TOML, YAML, and JSON config formats.
  • Fullscreen video tab bar: Fixed tab bar remaining visible during fullscreen video playback. Now hides automatically when entering fullscreen and restores based on normal visibility logic when exiting.
  • Dark mode navigation flash: Fixed a brief white flash between the loading skeleton and page content when navigating in dark mode.
  • Progress bar stuck state: Added 30-second timeout to progress bar to auto-hide if page load stalls and never completes.
  • OAuth popup login: Fixed parent page going blank after OAuth popup closes (e.g., Google login on claude.ai, notion.com). Related WebViews share a web process with their parent; destroying the popup was terminating the shared process, killing the parent. Now skips TerminateWebProcess() for popup WebViews.
  • Startup: defer WebView pool prewarm until after initial tab creation to reduce cold-start navigation latency.
  • README CLI examples: updated to match current commands/flags (purge --force only, logs usage, sessions list --limit, removed deprecated --dmenu root flag).

[0.21.0] - 2025-12-26

Added

  • Configurable new-pane defaults: New workspace.new_pane_url (default: about:blank, supports dumb://) and omnibox.auto_open_on_new_pane (default: false).
  • Consume-or-expel panes (very alpha): Niri-style pane consume/expel operation to merge a leaf into a sibling stack or expel a stacked pane into a split. Default global shortcuts: Alt+[ / Alt+] (and Alt+Shift+[ / Alt+Shift+]).
  • Zellij-style pane resize mode: New modal resize mode (Ctrl+N) to adjust split sizes with keyboard (h/j/k/l or arrow keys, +/- smart resize). Shows a per-pane border indicator and keeps the timeout alive while you resize.
  • Mouse-driven pane resizing: Drag split dividers with the mouse; split ratios are persisted in session snapshots (rounded to 2 decimals) and restored on resurrection.
  • Dynamic window title: Window title now displays the active pane's page title in format <Page Title> - Dumber. Updates when switching tabs/panes or navigating. Truncated at 255 characters.
  • Link URL status overlay: Shows destination URL in bottom-left corner when hovering over links, images, or media elements. Standard browser UX pattern with 100ms show delay to avoid flicker and 150ms CSS fade transitions. Configurable via CSS.
  • Local file path support: dumber browse test.html now correctly opens local HTML files by converting existing file paths to file:// URLs. Supports absolute paths, relative paths, and ~/ home directory expansion.
  • Auto-update system: Automatic update checking and self-updating binary replacement following clean architecture.
    • Update check on startup: Async check against GitHub releases API (configurable via update.enable_on_startup, default: true).
    • Toast notifications: Non-intrusive auto-dismiss notifications for update availability.
    • Auto-download: Optional background download with binary staging (configurable via update.auto_download, default: false).
    • Binary self-update: Atomic binary replacement on clean exit with .old backup. Only works if binary is user-writable (e.g., ~/.local/bin/).
    • CLI update check: dumber about now displays update availability.
    • Version-less release archives: Goreleaser now produces dumber_linux_x86_64.tar.gz (version in directory inside) enabling stable GitHub /releases/latest/download/ URLs.
  • Session management & resurrection: Zellij-inspired session management system allowing users to save, list, and restore browser sessions.
    • Automatic session snapshots: Debounced state saving (configurable interval, default 5s) captures tabs, panes, splits, stacks, URLs, titles, and zoom levels.
    • Session Manager modal: Access via Ctrl+O → s/w or Ctrl+Shift+S to browse and restore sessions with inline preview of tabs and panes.
    • Session mode: New modal mode (Ctrl+O) with purple border indicator, similar to pane/tab modes.
    • CLI session commands: dumber sessions opens interactive TUI browser; dumber sessions list shows saved sessions; dumber sessions restore <id> resurrects a session in a new window; dumber sessions delete <id> removes a session.
    • Session purging: Integrated into dumber purge command for cleaning up old session data. Simplified UI with single "Sessions" toggle instead of individual selection.
    • Automatic session cleanup: Sessions are automatically cleaned up on startup based on max_exited_sessions (default: 50) and max_exited_session_age_days (default: 7 days).
    • Configuration options: session.auto_restore, session.snapshot_interval_ms, session.max_exited_sessions, session.max_exited_session_age_days, plus session mode shortcuts and styling.

Fixed

  • Alt/Ctrl+number shortcuts on non-QWERTY keyboards: Fixed Alt+1-9/0 tab switching and Ctrl+1-9/0 omnibox shortcuts not working on AZERTY, QWERTZ, Dvorak, and other non-QWERTY keyboard layouts. Uses hardware keycodes as fallback when keyval lookup fails, enabling shortcuts to work based on physical key position regardless of layout.
  • Idle inhibition leak on pane close: Fixed D-Bus idle inhibit request not being released when closing a pane/tab while in fullscreen or playing audio. The inhibition would remain active until the app exited. Now properly tracks fullscreen and audio state and releases inhibition before destroying WebView.
  • Audio-based idle inhibition: Extended idle inhibition to also activate when a page is playing audio (e.g., video/music playback), not just in fullscreen mode. Uses WebKit's notify::is-playing-audio signal. The inhibitor uses refcounting, so both fullscreen and audio can be active simultaneously.

[0.20.1] - 2025-12-25

Fixed

  • Stacked pane favicon and title updates: Fixed favicon and title not updating in stacked pane title bars by tracking pane IDs in StackedView and properly routing update events to the correct pane.
  • WebKit process leak on pane close: Fixed zombie WebKit web processes not being terminated when panes were closed. WebView.Destroy() now properly calls TerminateWebProcess() and unparents GTK widgets, freeing GPU resources (VA-API, DMA-BUF, GL contexts). This should significantly improve video playback stability and reduce memory usage when opening/closing many panes.
  • White flash on navigation: Eliminated white page flash when navigating in dark mode by setting WebView background color to match theme and hiding WebView until content commits.
  • Dark mode detection on websites: Fixed prefers-color-scheme: dark detection by improving matchMedia query normalization and adding proper event listener stubs. Sites like Reddit now correctly detect dark mode preference.
  • Alt+number tab switching: Fixed Alt+1-9 shortcuts not working when WebView has focus by using GtkShortcutController with global scope instead of EventControllerKey.
  • System locking during fullscreen video: Added idle inhibition via XDG Desktop Portal when WebView enters fullscreen mode. Prevents system from locking/sleeping during fullscreen video playback on Wayland (works with all compositors: GNOME, KDE, sway, hyprland, etc.).
  • Navigation performance: Significantly faster page navigation through multiple optimizations:
    • Async history recording via background worker (SQLite writes no longer block GTK main thread)
    • LRU cache for per-domain zoom levels (repeat visits skip database queries)
    • Async favicon preload (cache lookup doesn't block navigation start)
    • Progress callback throttling at ~60fps (reduces UI callback overhead)
    • Increased WebView pool prewarm from 2 to 4 for faster initial tab creation

Changed

  • Custom color picker and confirm dialogs: Replaced native GTK color picker and confirm dialogs with custom Svelte components using bits-ui AlertDialog. Fixes Wayland compatibility issues where native dialogs would not display properly (fixes #12).
  • GSK renderer default: Changed default from vulkan to auto to let GTK choose the best renderer and avoid potential DMA-BUF synchronization conflicts with WebKit.
  • Removed invalid GStreamer config: Removed video_buffer_size_mb and queue_buffer_time_sec config options as these were not valid GStreamer environment variables (they are element properties that cannot be set via env vars).

Added

  • Performance config section: New performance config section with zoom_cache_size (default: 256) and webview_pool_prewarm_count (default: 4) for tuning. Not exposed in UI but can be set in config file.
  • Clean-architecture rewrite (pure Go): Major refactor to a ports/adapters style architecture with explicit domain, application (use cases), infrastructure, and ui layers.
  • New CLI commands: doctor (runtime dependency checks), about (build info), setup (desktop integration), plus expanded purge with an interactive TUI.
  • WebUI config improvements: Search shortcut management (CRUD) and reset-to-defaults support.
  • Find-in-page: New find UI and shortcut handling.
  • Migrated GUI stack to puregotk + puregotk-webkit and disabled CGO for pure Go compilation.
  • Omnibox rewrite: Replaced injected Svelte/JS omnibox with a native GTK4 widget overlay.
  • Startup defers non-critical work, adds DNS prefetching and a warmed WebView pool for faster tab/pane creation.
  • SQLite WAL checkpoints happen less frequently to reduce contention.
  • Content filters skip caching invalid rules; EasyList parser prefers if-domain over unless-domain.
  • Workspace border overlays can now receive pointer input.
  • Session-based logging and session management for CLI/GUI runs.

[0.15.0] - 2025-11-29

Added

  • 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.
  • 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.
  • Configurable filter lists: New content_filtering.filter_lists config option. Defaults include EasyList, EasyPrivacy, and uBlock filters (annoyances, quick-fixes).
  • Demo video: Added feature showcase video to README (docs/media/dumber-demo.mp4).
  • 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.
  • 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.
  • Omnibox keyboard blocking: Prevent page scripts from stealing focus while omnibox is active.
  • Configurable border widths: Added pane_mode_border_width and tab_mode_border_width configuration options (default: 4px) for full border customization.
  • Content filter caching: Centralized content blocking service compiles filters once and caches them for instant reuse across all WebViews.
  • CLI purge enhancements: Separate --cookies and --history flags for granular data deletion.
  • URL normalization: Consistent URL storage across browser, CLI, and favicon services (strips trailing slashes, normalizes schemes).

Fixed

  • Filter compilation race condition: Fixed concurrent map crash when multiple filter lists compile simultaneously by using local converter instead of shared state.
  • 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.
  • 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.
  • Zoom toast suppression: Suppress zoom toast notifications during browser initialization to prevent UI flash.
  • Cosmetic filter injection: Inject rules immediately and fix selector normalization for better ad blocking.

Changed

  • Refactor keyboard blocking: Move logic to main-world.ts, reduce handler.go verbosity.
  • 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.
  • 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.
  • Remove Turnstile workaround: Removed temporary Cloudflare Turnstile CORS allowlist (no longer needed).

[0.14.1] - 2025-11-18

Added

  • 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.
  • 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).
  • 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.

Fixed

  • 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.
  • 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).
  • 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.
  • Video codec fallback: Unblocked VP8 codec to allow fallback for ad segments, preventing playback interruptions when ads use different codecs than main content.
  • Video buffering: Increased buffer sizes (64 MB, 20s) to handle bursty Twitch/AV1 segments and improve streaming reliability on variable bitrate platforms.

Changed

  • Console output cleanup: Disabled WebKit console.log() messages to stdout to prevent page script spam. DevTools console (F12) still shows all messages.
  • Content filtering configuration: Refactored content_filtering_whitelist into structured content_filtering config with enabled boolean and whitelist array for better organization.

[0.14.0] - 2025-11-18

Added

  • 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).
  • 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.
  • Click-to-activate stacked panes: Click on any collapsed title bar to instantly activate that pane. Uses GTK4 gesture clicks for native interaction feel.
  • Title bar visual separators: Subtle 1px borders between stacked title bars. Theme-aware colors automatically adjust for light/dark mode.
  • 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).
  • 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.
  • 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.).
  • 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.
  • 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.
  • 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").

Changed

  • 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.
  • 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.
  • Code cleanup: Removed dead code files and emojis from GUI modules
  • 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).
  • Omnibox spacing: Increased vertical spacing between suggestion items from 0.65rem to 0.85rem for better readability
  • Smart Escape key: First press clears input text, second press closes omnibox. Empty input closes immediately.

Fixed

  • Ctrl+Tab shortcuts: Fixed focus cycling behavior, now properly switches between tabs
  • Active tab visibility: Fixed identical styling - active tab now clearly visible with distinct gray shade
  • AZERTY keyboard support: Alt+number shortcuts now work on all keyboard layouts using hardware keycodes
  • Keyboard layout detection: Fixed always detecting "en" - now correctly detects fr/de/etc layouts
  • 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.
  • 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.
  • 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.
  • 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.
  • 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.

[0.13.0] - 2025-10-24

Added

  • Color scheme config: appearance.color_scheme setting to force dark/light theme ("prefer-dark", "prefer-light", "default")
  • DNS prefetch: Added capability to prefetch DNS for links to speed up future requests
  • Page cache (bfcache): Enabled WebKit back/forward cache for instant navigation
  • Smooth scrolling: Enabled WebKit smooth scrolling for better UX
  • JSON Schema: Auto-generated config schema for IDE autocompletion and validation
  • Parallel cache loading: Zoom, certificate, and fuzzy caches load concurrently at startup (<100ms target)
  • Certificate validation cache: In-memory cache for TLS certificate decisions with graceful shutdown flushing

Changed

  • Database performance: Enabled WAL mode with optimized PRAGMAs (64MB cache, memory-mapped I/O, 5s busy timeout) for 70k reads/sec, 3.6k writes/sec
  • Zoom performance: In-memory cache eliminates database reads during page transitions
  • History writes: Batched writes with background processor (flush every 5s or 50 items) to reduce I/O overhead
  • BREAKING: Keyboard shortcuts: All shortcuts now use ctrl+ instead of cmdorctrl+. Existing configs with cmdorctrl still work via backward compatibility. Delete ~/.config/dumber/config.json to regenerate with new defaults.
  • Cache management: Graceful cache flushing on shutdown prevents data loss; startup timing instrumentation with performance warnings

Fixed

  • Graceful shutdown deadlock: Resolved GTK main loop deadlock on Ctrl+Q by removing mutex locks and GTK calls after main loop exit
  • CSS provider error handling: Now properly handles errors from GTK CSS provider with logging
  • Cache operations: Added context timeouts to cache flush and history queue operations for graceful failure
  • Command typos now show proper error instead of opening in browser
  • History queue now uses buffered channel to prevent blocking on shutdown

[0.12.1] - 2025-10-18

Added

  • Favicon refactoring: WebKitGTK FaviconDatabase as single source of truth, removing fragile file-based cache and ico/bmp conversion dependencies
    • Native favicon detection and automatic PNG export at 32x32 for CLI (dmenu)
    • SVG favicon rasterization support
    • Async texture loading with callbacks for non-blocking UI updates
    • FaviconService handles favicon collection across all panes

Changed

  • Removed old favicon cache system (go-ico, go-bmp dependencies)
  • Simplified omnibox favicon handling: uses database favicon_url only

Fixed

  • Mouse button navigation: Added support for hardware mouse buttons 8/9 (back/forward)
  • Touchpad gestures: Two-finger horizontal swipe for back/forward navigation
  • Web app shortcuts: Ctrl+C, Ctrl+V, Ctrl+A now work in Gmail, VSCode web, etc.
  • Dark mode flash on startup: Set GTK dark theme preference and WebView background color before window/content creation
  • Cmd+Q and window close button now trigger graceful shutdown instead of killing the browser process
  • WebView cleanup: Properly destroy WebViews to prevent memory leaks and duplicate handler registrations when closing stacked panes
  • CLI help: Running dumber without arguments now shows available commands (use --gui or browse to launch GUI)

[0.12.0] - 2025-10-16

Added

  • Native favicon support: WebKit FaviconDatabase integration with automatic detection and caching for all panes
  • ENV=dev support to isolate test builds from production config/data in .dev/dumber/ directory
  • Content filtering whitelist config (Twitch enabled by default)
  • dumber config command to open config file in $VISUAL/$EDITOR or print path with --path
  • Native WebKit popup lifecycle: Implemented WebKit's create/ready-to-show/close signals for proper popup management, eliminating manual WebView creation that bypassed WebKit's internal architecture
  • Popup behavior configuration: Added popup_behavior config with four modes: split (default), stacked, tabbed, and windowed for user control over popup placement
  • Backend-driven pane mode: Complete rewrite of pane mode from JavaScript to Go backend with native keyboard handling. Ctrl+P enters mode, x/l/r/d/u/arrows for actions, Escape exits. Blocks all other keys during mode.
  • Pane mode visual border: Zellij-style border around workspace root when pane mode is active, replacing old toast notification system. Uses GTK margins with configurable pane_mode_border_color (defaults to #FFA500 orange). Window background color shows through margins to create visible border effect

Changed

  • Popup architecture refactoring: Removed ~280 lines of JavaScript window.open interception in favor of WebKit's native popup signals. Popups now follow WebKitGTK's expected lifecycle instead of being intercepted and manually created
  • GUI bootstrap refactoring: Extracted 400+ lines of common initialization logic into reusable bootstrap.ts module shared between injected pages and special schemes (homepage, etc.)
  • Workspace pane mode: Moved ~450 lines of JavaScript state machine to Go backend for more reliable keyboard handling and eliminated race conditions between webviews

Fixed

  • TLS certificate validation restored: Re-implemented persistent certificate error handling (broken during gotk4 migration)
    • Interactive three-option dialog: "Go Back", "Proceed Once (Unsafe)", and "Always Accept This Site"
    • SQLite-based hostname decision storage (hostname-only matching - GIO certificate properties are unstable)
    • Smart expiration: "Proceed Once" temporary (not stored), "Always Accept" persists for 30 days
    • Automatic cleanup of expired validations on application startup
    • Known issue: Accepted certificates not pre-loaded into WebKit session on startup - stored decisions only apply when TLS error occurs again
  • Content blocking restored: Re-implemented WebKit native ad/tracker blocking (broken during gotk4 migration) using UserContentFilterStore API
  • Script injection spam: Fixed 100+ duplicate "Sending color palettes" messages by injecting scripts only in top frame instead of all iframes
  • Favicon race conditions: Eliminated duplicate downloads and file handle errors via mutex protection and proper handler registration
  • Homepage theme switching: Fixed color palette application for proper light/dark mode transitions
  • Workspace pane borders: Hide active pane border when only one pane exists to match Zellij UX
  • Enabled missing WebKitGTK6 features: WebRTC, MediaSource, LocalStorage, WebAudio, MediaStream, Clipboard
  • Cosmetic filter duplicate injection in frames
  • Config file duplicate keys (snake_case/camelCase) by using Viper's SafeWriteConfigAs
  • Config not reading newly created default config file
  • Config writing to disk on every load/reload
  • Popup SIGSEGV crashes: Eliminated segmentation violations during popup lifecycle by respecting WebKit's signal-based popup management. Fixes OAuth popup crashes and GTK bloom filter corruption
  • GTK focus event duplicates: Added timestamp-based deduplication to prevent multiple focus enter/leave events in the same millisecond from WebKitGTK nested widgets
  • Popup close behavior: Fixed app exit when closing popups by excluding them from remaining pane count check
  • Pane mode border cleanup: Fixed border persisting after pane splits by saving container reference when applying margins. Ensures proper cleanup even when workspace tree structure changes during split operations
  • Stacked pane active border: Fixed active border incorrectly appearing on stacked pane containers instead of individual panes
  • Stacked pane creation: Fixed premature Realize() call causing widget lifecycle issues during stack creation
  • Browser exit on last pane close: Fixed browser not properly quitting when closing the last webview via Ctrl+P x by calling GTK main loop quit instead of window close
  • Zoom level persistence restored: Fixed per-domain zoom settings not being saved to database (broken during gotk4 migration). Added missing notify::zoom-level signal connection in setupEventHandlers to properly persist zoom changes

[0.11.0] - 2025-10-07

Added

  • Auto-open omnibox on blank panes: Omnibox automatically opens when a new pane is created with about:blank, providing immediate search/navigation access
  • Configurable default zoom: Added default_zoom config (defaults to 1.2/120%). Per-domain zoom still overrides this
  • Pin/favorite sites: Pin websites from history or quick access to prioritize them in "Jump back in" section. Uses localStorage persistence with star icons for pin/unpin actions
  • Zellij-style stacked panes: Added Ctrl+P → 's' to stack panes instead of splitting, with Alt+Up/Down navigation between stacked panes. Features collapsed page title bars showing for inactive panes and full WebView interaction for the active pane. Includes GTK4 CSS styling for proper visual feedback
  • Stacked pane favicons: Title bars display site favicons with async caching. Click title bars to switch between stacked panes
  • Color palette configuration: Light and dark color palettes now configurable in appearance config with semantic tokens (background, surface, text, muted, accent, border). Injected as CSS custom properties at document start
  • Search shortcut badges: Visual badges in omnibox input showing active shortcut prefix (e.g., "gh:", "npm:") with description labels
  • Search shortcuts API: Frontend bridge to fetch search shortcuts from backend /api/config endpoint with automatic normalization

Changed

  • Terminal-style UI theme: Monospace fonts (JetBrains Mono, Fira Code), sharp corners (no border-radius), dashed borders, adjusted shadows and spacing throughout omnibox components
  • History suggestions: Use favicon from database when available, omit automatic search shortcuts from suggestions (rely on explicit prefix commands)
  • Search shortcuts defaults: Updated defaults to include ddg, go, mdn, npm packages while reordering others
  • Chrome user agent: Updated to version 141.0.0.0 for better site compatibility
  • CSS color system: Removed hardcoded theme colors, now use dynamic CSS custom properties from Go-injected palette
  • History item layout: Removed "• domain" from titles, now highlight domain within the full URL using same color as title text
  • Quick access logic: Removed 20-item limit, now shows all sites with 2+ visits (pinned sites bypass visit requirement)
  • History pagination: Show 15 items initially (up from 10) with "Show N more" button
  • Homepage layout: Redesigned with improved visual hierarchy and dynamic color tokens
  • Favicon handlers: All webviews now register favicon change handlers for consistent caching across panes

Fixed

  • Mobile URL overflow: Fixed long URLs breaking layout on narrow screens by adding proper width constraints and CSS fixes
  • GTK shortcut GLib-CRITICAL error: Fixed NULL string assertion in shortcut callback system
  • SVG favicon handling: Skip SVG favicons to prevent conversion errors (no raster conversion dependencies)
  • Focus management architecture: Refactored workspace focus system from active field to currentlyFocused with dedicated FocusManager for improved reliability and consistency across pane operations
  • Stacked pane focus conflicts: Fixed focus stealing issues in stacked panes by implementing focus-aware navigation that preserves active pane when spawning siblings
  • WebView title updates: Enhanced webview title change handling to properly update stacked pane title bars in addition to database storage
  • GTK4 widget lifecycle: Improved widget parenting/unparenting operations with proper GTK4 validation and automatic cleanup to prevent critical warnings
  • Stacked pane close behavior: Fixed remaining pane becoming non-interactable (gray background) when closing stacked panes via Ctrl+W or Ctrl+P+X. Added proper widget visibility restoration and focus management during stack-to-regular conversion
  • Stacked pane title updates: Fixed collapsed panes not showing current page titles when switching between stacked panes. Now follows Zellij-style layout where hidden panes display their up-to-date page titles in title bars with correct positioning above and below the active pane

[0.10.0] - 2025-09-24

Added

  • Print functionality: Added Ctrl+Shift+P shortcut to open native print dialogs from any pane. Ctrl+P is blocked at WebKit level to prevent conflicts with pane mode shortcuts
  • WebKit native favicon detection: Implemented WebKit's built-in favicon database for automatic favicon detection and URI storage. Enhanced favicon support for all formats (PNG, SVG, ICO) without external dependencies

Changed

  • Homepage redesign: Brutal design with component-scoped styling, dynamic height matching, inline domain-URL layout with fade effects, and tighter spacing

Fixed

  • WebView teardown and memory management: Implemented comprehensive cleanup system to prevent crashes during WebView destruction. Added JavaScript teardown functionality with cleanup handlers for all event listeners, intervals, and global state. Enhanced pane cleanup with proper controller detachment and GTK widget detachment sequencing. Added WebView validity checks before JavaScript evaluation and improved workspace manager pane closing logic with better popup handling
  • Ctrl+W pane closing: Fixed Ctrl+W shortcut to properly close active panes including popups. Implemented active WebView detection and proper popup vs regular pane handling via OnWorkspaceMessage for consistent cleanup
  • WebView script injection segfault: Fixed segmentation violation when injecting JavaScript into destroyed WebViews during message handling. Added IsDestroyed() safety check to prevent GTK widget corruption
  • Alt+Arrow workspace navigation: Fixed Alt+Arrow keys not working for pane navigation after WebView focus changes. Implemented C-level to GTK4 shortcut bridge that ensures workspace navigation works consistently across all panes
  • Global shortcuts protection: Fixed window shortcuts (Ctrl+L, Ctrl+F, F12) not working in new panes due to overly aggressive webpage protection. Window shortcuts now properly bubble up to GTK while pane shortcuts remain blocked from webpages. Resolves omnibox and developer tools not responding to keyboard shortcuts in newly created panes
  • Omnibox keyboard event isolation: Fixed keyboard event leakage from omnibox to underlying webpages that caused unintended page actions (e.g., typing 's' in omnibox triggering GitHub search). Implemented WebKit-level main-world event blocking that activates when omnibox opens, preventing page JavaScript from receiving keyboard events while preserving native GTK shortcuts (Ctrl+L, Ctrl+F, etc.) and omnibox functionality
  • Active pane detection: Replaced complex pane ID abstraction with persistent webview IDs, fixing omnibox unresponsiveness after navigation. Omnibox now works immediately after page navigation without requiring mouse movement
  • Workspace architecture: Simplified focus tracking by removing URI change handlers and pane ID injection complexity, improving reliability and reducing codebase by 85 lines
  • WebView ID propagation: Added webview ID request/response mechanism for stub builds to ensure JavaScript side knows its webview ID for proper focus validation
  • Workspace theme integration: Fixed white borders on inactive panes by implementing dynamic border colors based on GTK theme preference (dark mode: #333333 borders, light mode: #dddddd borders)
  • GTK window background: Added theme-aware window and pane background colors to prevent white bleeding through transparent elements
  • Print dialog window handling: Fixed GTK window destroy errors during WebView cleanup by only destroying windows when CreateWindow was actually enabled
  • Modifier key logging noise: Filtered out Ctrl, Shift, Alt, and Super key presses from accelerator miss logging to reduce console spam

[0.9.0] - 2025-09-22

Added

  • Zellij-style workspace management: Complete pane splitting system with binary tree layout, focus tracking, and Zellij-inspired keybindings (Ctrl+P for pane mode, arrow keys for splits, 'x' to close)
  • Multi-pane WebView architecture: Container-based widget management with proper reparenting, lifecycle handling, and per-pane controllers
  • Window-level global shortcuts: Centralized shortcut handling to prevent conflicts between multiple WebView instances
  • Workspace configuration: New config section with Zellij controls toggle, pane mode bindings, tab shortcuts, and popup behavior settings
  • Configurable workspace styling: Pane border appearance (width, color, transition duration, radius) now customizable via config with proper viewport stability
  • Popup handling for tiling WM: Complete popup window support where popups open as workspace panes instead of floating windows, respecting tiling window manager design principles
  • Universal popup auto-close: Popup windows (OAuth, window.open(), etc.) automatically close when JavaScript calls window.close(), providing standard browser behavior adapted for workspace panes
  • Advanced popup deduplication system: Intelligent duplicate popup prevention with SHA256 fingerprinting and 200ms debounce window to eliminate popup spam
  • OAuth auto-close integration: RFC 6749 compliant OAuth callback detection with automatic popup closure for seamless authentication flows
  • Cross-WebView popup communication: localStorage-based parent-popup bridge enabling proper window.opener functionality in tiling workspace environment
  • WebView identity tracking: Unique WebView ID system for precise popup targeting and enhanced debugging capabilities

Improved

  • WebKit integration now forces GPU compositing by default while still honoring explicit config overrides.
  • Smooth scrolling is enabled (when supported) so wheel and gesture animations feel closer to Chromium/Firefox.
  • Title updates, zoom persistence, and domain zoom lookups are now done off the GTK main thread with results marshalled back safely, eliminating UI hitches during navigation.
  • Added optional DOM-level zoom (enabled by default) to avoid native viewport rescaling; falls back to WebKit zoom if the CSS path fails.
  • DOM zoom now seeds the saved level before the first paint and reuses it during document-start scripts, preventing pages from flashing back to 100%.
  • Native accelerator bridge debounces duplicate GTK key events earlier, so Ctrl±/Ctrl+0 only fires once per physical key press.
  • Omnibox-triggered navigations now reuse the navigation controller, so saved zoom levels are applied before first paint and redundant lookups are avoided.
  • Configuration loading writes the missing use_dom_zoom flag into existing config files so DOM zoom defaults persist without manual edits.
  • Omnibox UI now relies on shared Tailwind theme tokens and the injected color-scheme service for light/dark parity.
  • Omnibox overlay now self-heals if hostile pages remove the injected shadow host, ensuring Ctrl/Cmd+L works everywhere.
  • Navigation shortcuts changed from Alt+Arrow to Ctrl/Cmd+Arrow for better workspace compatibility.
  • GUI components now support workspace-aware focus management with pane-specific event handling.
  • Global zoom shortcuts: Unified zoom handling at window level (Ctrl+/=/0/-) ensuring zoom applies to currently active pane in multi-pane workspace
  • Workspace focus management: Enhanced focus throttling (100ms) and active state tracking to prevent infinite loops and conflicts between panes
  • Popup management: Intelligent popup vs tab detection based on window features, with improved auto-close logic for OAuth and login flows
  • Console logging: WebView ID context injection for better debugging and log correlation across multiple panes

Changed

  • Zoom shortcuts architecture: Moved from per-WebView registration to centralized window-level handling for consistency with other global shortcuts

[0.8.0] - 2025-09-17

Added

  • GTK color scheme bridge: Dedicated document-start module keeps WebKit theme in sync with GTK preferences and exposes unified runtime updater
  • Color scheme build pipeline: Separate Vite entry produces reusable color-scheme.js asset shared between native and injected contexts
  • Complete Svelte 5 GUI migration: Omnibox and find components migrated from raw JavaScript to modern Svelte 5 with runes
  • Tailwind CSS v4 integration: Unified design system with PostCSS and JIT compilation
  • TypeScript keyboard service: Centralized shortcut management with full type safety
  • Click-anywhere-to-close: Omnibox closes when clicking outside for better UX
  • Homepage Svelte 5 component: New standalone homepage with history display and keyboard shortcuts reference
  • Page generator system: Vite plugin for generating dumb:// protocol pages (homepage, config, about) with extensible architecture
  • History deletion API: New DELETE endpoint at /history/delete?id=N for removing individual history entries
  • Database migrations: Embedded migrations now run automatically at startup to keep sqlite schema in sync
  • Inline CSS type declarations: Ambient module definitions for raw CSS imports improve TypeScript ergonomics in injected bundles
  • Global Shadow DOM system: Unified shadow host utility for component isolation with shared ShadowRoot and CSS reset management
  • Unified page-world bridge: Integrated API bridge with event-driven communication between page-world and isolated-world contexts

Improved

  • Asset MIME detection: Expanded scheme handler lookup covers fonts, images, and JSON to prevent incorrect text/plain responses
  • Toast theming: Runtime theme observer syncs toast styling with the browser's dark mode state for consistent visuals
  • Shadow host styling: Injected GUI now adopts Tailwind design tokens inside the shared shadow root with automatic dark-mode mirroring
  • Omnibox/Find system: Complete migration from 500-line raw JavaScript to modular Svelte 5 components
  • Toast notifications: Migrated from raw JavaScript to Svelte 5 components with proper animations
  • GUI build pipeline: Vite-based bundling with hot reload and TypeScript support
  • Keyboard shortcuts: Fixed Ctrl+F not working by adding missing 'f' key to keyboard dispatcher
  • State management: Proper cleanup between omnibox and find modes prevents state conflicts
  • Homepage UX: Enhanced layout with 70/30 flex ratio, compact keyboard shortcuts table, and statistics display
  • Interactive delete: History entries show trash icon on hover with smooth fade-out animation on deletion
  • Top 5 most visited: New section displaying frequently accessed sites with visit counts
  • Performance: Instant shortcut response with pre-mounted DOM elements

Changed

  • Homepage icons: Replaced Lucide dependency with inline SVG/Unicode fallbacks to shrink bundle size while debugging upstream build issues
  • Major architecture shift: Removed HTTP API routes in favor of direct WebKit message bridge communication for better performance and reduced complexity
  • API token support: Added optional API security configuration with token-based authentication system
  • Shadow DOM improvements: Enhanced isolation with WeakSet tracking to prevent duplicate reset injection and global shadow host utility for component sharing
  • Message handler refactoring: Unified keyboard shortcut forwarding between native handlers and GUI components with DOM event bridge
  • Omnibox suggestions: Native Go-based suggestion computation with search shortcuts and history integration, eliminating HTTP fetch dependencies
  • Toast styling: Migrated from Tailwind CSS classes to inline styles within component scope for better Shadow DOM compatibility and isolation
  • JS to Svelte migration: Replaced legacy inline injected scripts (see pkg/webkit/ucm_js_cgo.go.deprecated) with structured Svelte components mounted via the shared shadow root.

Fixed

  • Service worker residue: Homepage clears stale caches and unregisters old service workers to avoid 404s for legacy _app assets
  • Keyboard debounce: Native accelerator bridge filters duplicate shortcut events within 120ms for DOM and CGO handlers
  • Ctrl+F shortcut: Added missing 'f' key case in keyboard_cgo.go dispatcher
  • Browser freeze: Removed infinite loop in mode switching reactive effects
  • State persistence: Proper cleanup when switching between Ctrl+L and Ctrl+F modes
  • Homepage protocol: Fixed dumb://homepage not working after GUI migration with proper Svelte 5 component and API integration
  • Omnibox positioning on homepage: Fixed omnibox stuck in top-left corner by isolating homepage CSS styles and strengthening omnibox positioning with explicit fixed positioning and CSS isolation
  • Find mode persistence: Fixed find view persisting after pressing Esc when reopening with Ctrl+L by ensuring toggle() resets mode to 'omnibox'
  • Favicon display: Fixed missing favicons in homepage history after Svelte 5 migration by adding FaviconURL field to API response and implementing proper fallback display logic
  • Homepage API communication: Migrated from HTTP fetch to WebKit message bridge for all homepage API calls (history, stats, search) with proper callback handling and timeout management
  • Omnibox accessibility: Added keyboard navigation support with Tab/Enter activation for suggestion items and proper ARIA attributes for screen readers
  • Omnibox suggestions race conditions: Fixed timing issues where suggestions arrived before API was ready by implementing pending suggestions queue and proper event bridging between page-world and isolated-world contexts

[0.7.0] - 2025-09-14

Added

  • Content blocking system: Native WebKit ad blocking with EasyList integration, cosmetic filtering, and filter cache management
  • Filter cache purging: New --filter-cache/-F flag in purge command
  • WebKit debug system: Comprehensive debugging support with configurable categories for troubleshooting WebKit internal errors
  • Enhanced error handling: Robust content filter injection with retry mechanisms and graceful fallbacks
  • Parallel compilation: Multi-core GCC compilation support for faster builds

Improved

  • Content filter timing: Optimized script injection timing to prevent interference with WebKit preconnect operations
  • Anti-breakage scriptlets: Safer JavaScript modifications that avoid WebKit internal conflicts
  • Build system: Added parallel compilation with automatic core detection and success indicators
  • Persistent TLS certificate validation system:
    • Three-option certificate dialog: "Go Back", "Proceed Once (Unsafe)", and "Always Accept This Site"
    • Database-backed certificate storage: SQLite-based persistence for user certificate decisions with SHA256 certificate hashing
    • Smart decision handling: Automatic application of stored decisions without repeated prompts
    • Temporary vs permanent choices: "Proceed Once" expires after 24 hours, "Always Accept" persists indefinitely
    • Seamless user experience: No more repetitive certificate warnings for trusted sites
  • Performance-optimized WebKit memory configuration system:
    • New WebkitMemoryConfig configuration section with performance-focused defaults for faster page loading
    • Aggressive caching strategy: web_browser cache model with page cache enabled for instant back/forward navigation
    • Balanced memory pressure management: Conservative (40%), strict (60%), and kill (80%) thresholds optimized for performance vs stability
    • Smart garbage collection: 2-minute JavaScript GC intervals with process recycling after 50 page loads
    • Reduced monitoring overhead: 45-second memory monitoring intervals to minimize performance impact
    • Environment variable overrides: All memory settings configurable via DUMBER_* environment variables (DUMBER_CACHE_MODEL, DUMBER_MEMORY_CONSERVATIVE, etc.)
  • Early crash handling initialization: Moved crash handler setup to application entry point for better crash recovery

Changed

  • Modernized GTK dialog system: Migrated from deprecated GTK 4.10 dialog functions to modern GtkAlertDialog API
    • Future-proof implementation: Eliminated all deprecation warnings by replacing gtk_message_dialog_* and gtk_dialog_* functions
    • Async-first architecture: Native async dialog handling with proper event loop integration
    • Improved accessibility: Better screen reader support and GTK4 theme integration
  • Major main.go refactoring: Massive code reduction from 1071 lines to 61 lines (~95% reduction)
    • Extracted browser application logic to dedicated internal/app/browser package for better separation of concerns
    • Streamlined entry point: Clean main function focusing only on CLI vs GUI mode detection and application bootstrapping
    • Improved maintainability: Modular architecture with clear responsibilities between CLI and browser components
  • Refactored memory configuration architecture:
    • Integrated WebKit memory settings into unified config system with Viper environment variable bindings
    • Eliminated redundant environment variable parsing in favor of centralized configuration management
    • Simplified webview initialization with direct config-to-WebKit conversion
  • Improved CLI logs command description: Enhanced help text for better user experience

[0.6.0] - 2025-09-12

Added

  • Smart AV1 codec negotiation system for YouTube high-resolution streaming:
    • Resolution-aware MediaCapabilities API reporting: Intelligent codec capability reporting based on video resolution, enabling YouTube to select optimal codecs for different quality levels
    • YouTube format manifest manipulation: Real-time format list reordering to prioritize AV1 for ≤1080p content while allowing VP9 fallback for higher resolutions
    • Graduated codec preference system: Smart localStorage preference (2048) instead of forced AV1 (8192), giving YouTube flexibility for optimal codec selection
    • 4K HDR 60fps AV1 support: Successfully enables YouTube delivery of premium quality 4K HDR content with AV1 codec, HDR10 (PQ) color space, and BT.2020 wide color gamut
    • Configurable AV1 resolution limits: New av1_max_resolution config option with environment variable support (DUMBER_AV1_MAX_RES)
    • Automatic codec fallback logic: Seamless VP9 fallback for resolutions where AV1 performance may be suboptimal
    • High bitrate streaming support: Enables premium quality streaming (650+ Mbps) with proper buffer management
    • Fixes previous limitation where forcing AV1 would cap YouTube playback at 1080p maximum
  • Page refresh functionality with standard keyboard shortcuts:
    • Ctrl+R / Cmd+R: Reload current page
    • Ctrl+Shift+R / Cmd+Shift+R: Hard reload (bypass cache)
    • F5: Alternative reload key
    • WebKit integration with proper webkit_web_view_reload() and webkit_web_view_reload_bypass_cache() calls
  • Twitch theater mode and fullscreen stability fix:
    • Complete removal of codec interference on Twitch: Eliminates aggressive codec control that caused theater mode and fullscreen freezing
    • Native Twitch codec selection: Allows Twitch to handle codec negotiation without browser intervention
    • Fixes theater mode freeze and fullscreen black screen issues on Twitch

Fixed

  • Zoom level toast no longer shows on every page navigation within the same domain:
    • Added smart detection to differentiate user-initiated vs programmatic zoom changes
    • Toast now only appears when manually adjusting zoom or entering a new domain
    • Prevents annoying notifications during regular browsing within the same site
  • Links with target="_blank" now load in current window instead of being ignored:
    • Added WebKit create signal handler to intercept new window requests
    • Redirects popup/new tab links to current window for seamless single-window browsing
    • Maintains user experience consistency in tab-less browser architecture

[0.5.0] - 2025-09-12

Added

  • Hardware video acceleration with automatic GPU detection:
    • Multi-vendor GPU detection (AMD, NVIDIA, Intel) using glxinfo, lspci, and sysfs
    • Automatic VA-API driver selection (radeonsi for AMD, vdpau for NVIDIA, iHD for Intel)
    • WebKitGTK integration with GStreamer hardware acceleration backends
    • Environment variable configuration support (LIBVA_DRIVER_NAME, GST_VAAPI_ALL_DRIVERS)
    • Legacy VA-API fallback mode for compatibility with older systems
    • Video decoding acceleration for H.264, HEVC, VP9, and AV1 codecs
    • Significantly reduced CPU usage during video streaming (Twitch, YouTube, etc.)
    • Smart conflict prevention between legacy and modern VA-API implementations
  • TLS certificate error handling with user confirmation dialog:
    • Comprehensive certificate information display (subject, issuer, validity dates)
    • Interactive warning dialog for untrusted certificate authorities
    • Certificate exception management with per-host persistence
    • Manual load triggering after user accepts certificate exceptions
    • Proper integration with WebKitGTK 6.0 network session API
  • Zoom level toast notifications:
    • Real-time zoom level display with format: "Zoom level: ±X% (Y%)"
    • Smart debouncing to prevent notification spam during rapid zoom changes
    • Automatic cleanup of stuck or colliding toast messages
    • 150ms debounce timer with 2-second display duration
    • Emergency cleanup function for orphaned toast elements
  • Comprehensive XDG-compliant logging system:
    • Complete application output capture (Go logs, fmt prints, WebKit C logs)
    • XDG Base Directory specification compliance (~/.local/state/dumber/logs/)
    • Automatic log rotation with size/age-based cleanup and compression
    • WebKit CGO log capture with GLib log handler integration
    • CLI log management commands (dumber logs list, logs tail, logs clean)
    • File-only logging for cache operations to prevent dmenu interference
    • Multi-output support with timestamped, tagged log entries
    • Configurable log levels, formats (text/JSON), and retention policies

Fixed

  • WebView background set to black to improve user experience during page loads
  • Multiple linting issues and code quality improvements (reduced from 211 to ~150 issues)
  • Omnibox responsive scaling and layout issues:
    • Fixed over-aggressive viewport scaling that made omnibox disproportionately large at high zoom levels
    • Resolved input field overflow extending beyond container boundaries
    • Improved box-sizing model to prevent layout issues
    • Added conditional separator display (hidden when no search results)
    • Omnibox now scales proportionally with webpage content across all zoom levels
  • Dmenu history favicon display:
    • Complete favicon caching system for fuzzel/dmenu integration with real website icons
    • ICO file support using go-ico library for perfect Windows icon conversion to PNG
    • Smart brightness detection and color inversion for dark theme visibility
    • All cached favicons normalized to consistent 32x32 PNG format for uniform display
    • Anti-aliasing preservation during color inversion to prevent edge noise and pixelation
    • Asynchronous favicon downloading and caching with 7-day freshness and 30-day cleanup
    • Fuzzel icon protocol integration (\0icon\x1f<path>) for native icon display
    • Favicon URLs extracted from webpage metadata and stored in database during navigation
    • Fallback system removed to ensure consistent sizing - shows real favicons or no icon
    • XDG Base Directory compliance for favicon cache storage

[0.4.0] - 2025-09-10

Added

  • High-performance fuzzy cache system for dmenu history:
    • Binary serialization with memory-mapped files for zero-copy access
    • Trigram indexing (3-character sequences) for fast candidate filtering
    • Prefix trie (compressed tree structure) for prefix matching
    • Pre-sorted entry indices for O(1) top entries retrieval
    • Smart cache invalidation with filesystem persistence and background refresh
    • Comprehensive fuzzy matching algorithms: Jaro-Winkler similarity, Levenshtein distance, tokenized matching
    • Weighted scoring system combining URL, title, recency, and visit count scores
    • XDG Base Directory Specification compliance (cache stored in state directory)
    • Atomic operations for concurrent access control
    • Dependency injection using interfaces and gomock for testing
  • Purge command for cleaning up dumber data and cache files:
    • Selective purging with flags: --database, --history-cache, --browser-cache, --browser-data, --state, --config
    • Clear distinction between history cache (dmenu fuzzy search) and browser cache (WebKit)
    • Browser data includes cookies, localStorage, sessionStorage
    • Confirmation prompt with --force flag to skip
    • Targets all data locations: SQLite database, WebKit cache/data, dmenu fuzzy cache, configuration files
  • Ctrl+Shift+C keyboard shortcut to copy current URL to clipboard:
    • Cross-platform clipboard support with wl-copy (Wayland) and xclip (X11) fallback
    • Reusable toast notification system for user feedback
    • Injectable JavaScript component for consistent styling across all websites
    • Native backend integration for reliable clipboard access

Changed

  • Dmenu performance dramatically improved: 200ms → 4ms (98% faster)
  • GetTopEntries optimized from O(n log n) to O(1) using pre-sorted indices
  • Cache build time reduced to ~300μs for typical history datasets

Fixed

  • Dark theme detection now properly reads GNOME desktop interface color-scheme setting (org.gnome.desktop.interface color-scheme) instead of only checking gtk-application-prefer-dark-theme
  • Eliminated O(n log n) sorting bottleneck on every dmenu call
  • Memory-efficient compact entry storage with minimal footprint
  • Concurrent cache access with proper read/write locking
  • Process no longer hangs when closing window with Cmd+Q or window close button - implemented proper GTK4 close-request signal handling and OS signal handling for graceful shutdown

[0.3.0] - 2025-01-11

Added

  • WebKit memory controls (opt‑in):
    • Env vars to tune memory/perf trade‑offs without code changes:
      • DUMBER_CACHE_MODEL, DUMBER_ENABLE_PAGE_CACHE
      • DUMBER_ENABLE_MEMORY_MONITORING, DUMBER_MEMORY_LIMIT_MB, DUMBER_MEMORY_POLL_INTERVAL
      • DUMBER_MEMORY_CONSERVATIVE, DUMBER_MEMORY_STRICT, DUMBER_MEMORY_KILL
      • DUMBER_GC_INTERVAL, DUMBER_RECYCLE_THRESHOLD
    • Version‑guarded CGO wrappers for memory pressure and GC hooks; safe no‑ops on unsupported WebKitGTK builds.
  • Find in page (Ctrl/Cmd+F):
    • Omnibox refactored into a reusable component with dedicated "find" mode.
    • Highlighting: yellow for all matches; active match in orange for clarity.
    • Match list with context (right side stops at nearest punctuation: . , ; : -).
    • Navigation UX:
      • ArrowUp/Down move selection and scroll the overlay list (page scroll disabled while open).
      • Enter centers on the active match and closes; Shift+Enter goes to previous; Alt+Enter centers without closing.
      • Hover focuses input and selects list items; click outside closes the overlay.
      • Faded overlay with subtle blur when reviewing matches; opacity restores on input focus/typing.
    • Programmatic API: OpenFind(initial), FindQuery(q), CloseFind() on WebView.

Changed

  • Performance‑first defaults retained:
    • Cache model set to “WebBrowser”, page cache enabled, DevTools available.
    • No implicit memory pressure or GC enabled by default; all memory tuning is opt‑in.

Removed

  • Deprecated offline app‑cache calls eliminated (no‑ops) to avoid warnings and brittle builds.

Fixed

  • Homepage Recent History layout:
    • Show single-line entries as “{Title} – {Domain} – {URL}”.
    • Truncate long URLs with a gradient fade; prevent horizontal overflow.
    • Adjusted styling so URL is darker for readability.
  • Search shortcuts and config interop:
    • Backend SearchShortcut now serializes url/description with JSON tags.
    • Frontend normalizes field casing and extracts base URLs, handling %s and {query} templates.
    • Omnibox shortcut parsing now URL-encodes queries and supports %s placeholders.
  • Input and navigation reliability (GTK4/WebKitGTK 6):
    • Capture-phase key controller to ensure accelerators fire consistently.
    • Do not consume normal left/right clicks; only mouse buttons 8/9 trigger back/forward.
    • Added Alt+ArrowLeft/Right navigation and enabled two-finger swipe back/forward when supported.
    • Added Ctrl+scroll zoom in/out; refined accelerator matching so Ctrl− works across layouts.
    • Removed layout-specific hacks; added diagnostic logs for raw minus key events.
  • Zoom persistence:
    • Added WebView zoom-changed hook; save per-domain zoom to SQLite on every change.
    • Log on successful save: “saved X.XX for domain.tld” and on load: “loaded X.XX for domain.tld”.
    • Load and log initial zoom level on startup and on every navigation.
  • Build/dev ergonomics:
    • Makefile loads .env.local; supports overriding GOMODCACHE, GOCACHE, GOTMPDIR for sandboxed builds.
  • WebKit CGO hardening and API compatibility:
    • Apply memory pressure settings to WebKitNetworkSession (correct signature) when enabled.
    • Guarded C wrappers remove deprecation warnings across header variants; builds succeed on WebKitGTK 6.

[0.2.0] - 2025-09-10

Added

  • WebKitGTK 6 (GTK4) migration for the built‑in browser window:
    • WebView constructed via g_object_new(WEBKIT_TYPE_WEB_VIEW, …) with a fresh WebKitUserContentManager.
    • WebKitNetworkSession with persistent cookies (SQLite) and cache directories.
  • Native UCM messaging restored via script-message-received::dumber (JSCValue*), removing the JS fallback bridge.
  • Rendering mode controls:
    • CLI flag --rendering-mode=auto|gpu|cpu and DUMBER_RENDERING_MODE env.
    • In‑app status endpoint dumb://homepage/api/rendering/status.
  • Native zoom shortcuts at the WebKit layer (Ctrl/Cmd+=, +, −, 0) and GTK4 input controllers for keyboard/mouse.
  • AZERTY keyboard fix: treat underscore as minus for zoom‑out.
  • Runtime theme synchronization: watch GTK gtk-application-prefer-dark-theme and update page color‑scheme live.
  • Makefile target check-webkit to print pkg-config versions of GTK4/WebKitGTK 6.0/JSC 6.0.
  • Documentation updates:
    • README now targets WebKitGTK 6 (GTK4) and lists GStreamer package requirements for Arch and Debian/Ubuntu.
    • CLAUDE notes updated with migration status, GPU/Vulkan path, runtime theme sync, and persistence.

Changed

  • Build flags and includes now target webkitgtk-6.0, gtk4, and javascriptcoregtk-6.0.
  • GTK4 APIs for windowing and event handling (GtkEventController, GtkGestureClick) replace GTK3/GdkEvent paths.

Removed

  • Legacy WebKit2GTK constructors and container APIs.
  • JavaScript fallback for UCM message bridging.

Fixed

  • Header/enum compatibility for hardware acceleration policy and cookie policy across WebKit header variants.
  • Linker error for on_theme_changed and gpointer usage in signal connections.
  • Crashy paths mitigated by default “media safe” startup (can be disabled via DUMBER_MEDIA_SAFE=0).

Notes

  • GPU rendering path leverages GTK4’s renderer (Vulkan/OpenGL). Mode auto uses GPU when available and falls back gracefully to CPU.
  • WebKitGTK relies on GStreamer; install recommended packages for audio/video (see README).

[0.1.0] - 2025-09-09

Added

  • Initial project scaffolding, build system, and dependencies.
  • Unified CLI + GUI architecture with search shortcuts and fuzzy parsing.
  • Wails v3‑alpha browser integration (early phase).
  • Global keyboard controls with script injection (zoom/devtools, etc.).
  • Native WebKit2GTK backend migration:
    • Custom dumb:// scheme and /api endpoints: /config, /history/recent, /history/search, /history/stats.
    • UserContentManager omnibox injection and theme initialization.
    • Persistent WebsiteDataManager with cookies.sqlite; per‑domain zoom and title persistence.
    • Keyboard/mouse accelerators (including mouse back/forward); debounced triggers.
    • Homepage switched to first‑party API fetches; removed @wailsio/runtime usage.
  • Documentation and licensing: README enhancements and LICENSE added.

Changed

  • Replaced Wails runtime with native WebKit2GTK CGO bindings and homepage API.
  • Improved asset resolution and logging for the dumb://homepage scheme.

Fixed

  • Eliminated duplicate accelerator triggers via debouncing.
  • Corrected asset resolution and URL normalization in scheme handler.
source
1# Changelog
2
3All notable changes to this project will be documented in this file.
4
5## [Unreleased]
6
7### Added
8
9- **Named browser windows**: Added `dumber browse --instance <name>` to open or focus a stable named window in the current CEF profile host. Named windows share cookies, tokens, local storage, configuration, history, and favorites; use `--profile` for a separate persistent browser profile/host or `--ephemeral` for a temporary isolated profile/host.
10- **Omnibox visual styles**: Added configurable `command`, `multiplexer`, and `minimal` GTK treatments. The terminal-inspired `command` palette is the default.
11- **Vim mode for keyboard-driven page navigation**: Added configurable multi-key sequences for page scrolling, fast scrolling, page-input focus, and live heading navigation. Pressing `Enter` on a selected CEF heading opens its associated link before leaving Vim Mode. CEF accessibility data also provides the foundation for navigating structured page content such as headings, lists, paragraphs, and sections.
12- **Native favorites sidebar**: Added a keyboard-driven GTK sidebar toggled with `Ctrl+B`, including search, tag filtering, tag creation, favorite editing, shortcut assignment, deletion, and opening favorites in the current pane or a new split.
13- **WebP favicon decoding**: Added safe WebP decoding for sites that publish WebP favicons.
14
15### Changed
16
17- **Omnibox borders**: Outer borders scale with the configured UI size and remain more pronounced for the default `command` style.
18- **Omnibox status indicators**: The history-order control is now a passive status badge switched with `Ctrl+R`, and favorites use a terminal-style `*` marker.
19- **Favorites organization**: Favorites now use a tags-first model. Existing folder assignments are migrated into deterministic tags, with collision handling and folded-name uniqueness preserved during migration.
20- **Page mode configuration**: Page Mode is now called Vim Mode and uses the `workspace.vim_mode` configuration namespace for activation, timeouts, and action sequences. Existing page-mode bindings are migrated by the configuration loader.
21- **Browsing-context routing**: External links, floating panes, popups, and standalone omnibox launches now use explicit browsing-context ownership so they open in the appropriate pane or browser window.
22- **Omnibox history window**: Replaced `omnibox.most_visited_days` with `omnibox.max_history_days`. The window now applies to typed omnibox searches and to both empty-input lists (`recent` and `most_visited`), filtered in SQL before result limits. `dumber config migrate` renames the legacy key while preserving its value (including `0`).
23- **CEF presentation and lifecycle**: Browser visibility, first-frame presentation, accessibility enablement, browser recreation, and PipeWire audio handoff now follow stricter lifecycle ownership and synchronization.
24- **Dependencies and packaging**: Updated the CEF/GTK bridge and PureGo dependencies, refreshed vendored build inputs, and synchronized CI, Flatpak, AUR, and release workflow metadata.
25
26### Fixed
27
28- **Omnibox favorite selection**: Selected favorite rows retain their yellow left indicator in every visual style.
29- **Popup and floating-pane stability**: Hardened deferred popup cleanup, failed popup creation, opener-capable fallback behavior, and pane/window rollback paths.
30- **WebView resource cleanup**: Fixed stale callback, timer, tick, split, hover-controller, and rebuilt-WebView ownership paths that could leak resources or act on detached views.
31- **CEF rendering and input**: Improved OSR input and clipboard handling, effective visibility transitions, canvas presentation, repeated GPU relaunch recovery, and runtime propagation to helper processes.
32- **Omnibox and link handling**: Fixed standalone links opening in the wrong context, stale entry-buffer reconciliation, external-pane chrome, and global shortcut ownership.
33- **Vim input handling**: Fixed ambiguous and modified-key sequence parsing, legacy binding collisions, detach cancellation, editable-focus transitions, and repeat/scroll scheduling.
34
35### Security
36
37- **WebView bridge hardening**: Tightened reviewed WebKit bridge paths and runtime/development boundary handling.
38
39## [0.30.0] - 2026-06-27
40
41### Added
42
43- **CEF input tuning and touchpad navigation**: Added CEF scroll sensitivity settings plus deliberate two-finger back/forward swipe navigation with edge detection, threshold controls, and an on-screen progress indicator.
44- **Pane ejection to windows**: Pane Mode can move the active pane into a new browser window with the `eject-pane-to-window` action.
45- **Native history sidebar**: `Ctrl+H` now toggles a GTK history sidebar with grouped history, search/filtering, paging, keyboard navigation, configurable width, and live refresh when history changes.
46- **Favicon refresh and resolution pipeline**: Favicons are discovered, converted, cached, refreshed, and resolved through a path-aware cache with safer fallback behavior.
47- **Noctalia external theme integration**: Dumber can follow Noctalia `colors.json` palettes with live reload, last-good fallback, and an advanced Dumber-specific JSON theme format.
48
49### Changed
50
51- **Runtime configuration handling**: Engine, privacy, CEF/WebKit tuning, and clipboard settings now flow through typed runtime snapshots so active and newly acquired browser views use current settings consistently.
52- **History loading performance**: History timelines use stable cursor pagination bounded by row count, improving large-history loading and “load more” behavior.
53- **Navigation URL normalization**: Omnibox, dmenu, tab, and pane navigation now share consistent handling for existing local paths and `file://` URLs.
54- **Packaging and release checks**: AUR metadata now declares the CEF runtime dependency, `make check` verifies generated systemview assets, and GoReleaser validates the embedded compressed systemviews WASM before packaging.
55- **Tooling and dependencies**: Updated CEF bridge, Go dependencies, GitHub Actions, and pinned local lint/static analysis tooling.
56
57### Fixed
58
59- **CEF rendering stability**: CEF now respects effective HiDPI scale for zoom, keeps viewports synced during resize, and handles Vulkan/navigation handoff paths more reliably.
60- **Browser resource cleanup**: Closing tabs and windows now releases their WebViews through the normal lifecycle path, reducing leaked browser resources.
61- **Idle inhibition cleanup**: Fixed a portal signal cleanup race that could crash when idle-inhibitor connections were cleared.
62- **Session and filter maintenance**: Session cleanup now uses process liveness instead of ending unrelated active sessions, and content-filter updates better detect manifest changes while pruning obsolete cached parts.
63- **Pane operation safety**: Invalid split directions and failed pane moves are validated before mutating pane state.
64- **Loading/error states**: Failed main-frame navigations now leave loading skeletons and content state cleanly.
65- **Updater resilience**: Self-update checks retry transient request failures, including temporary DNS errors.
66- **WebKit fallback stability**: WebKit systemview message routing now snapshots base context safely under concurrent updates.
67
68### Security
69
70- **External scheme launch hardening**: External protocol redirects from page navigation no longer launch desktop handlers from untrusted paths or corrupt browser navigation state.
71- **Sensitive URL redaction**: Diagnostic logs redact URL paths, query strings, and fragments, and persistent log files/directories use user-private permissions.
72- **Local boundary hardening**: Filter downloads, manifest parsing, cache writes/lookups, systemview bridge access, and history query limits now enforce stricter path, size, trust, and validation boundaries.
73
74## [0.29.0] - 2026-05-27
75
76### Added
77
78- **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"`.
79- **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.
80- **System views rewrite**: The old Svelte `webui/` has been replaced by native/WASM-backed system views for config, history, and favorites.
81- **Standalone omnibox launcher**: `dumber omnibox` now opens the omnibox in a standalone window.
82- **Fresh browser windows**: Browser launches can now open in dedicated fresh windows.
83- **GTK UI font setting**: GTK chrome now has its own configurable UI font.
84
85### Changed
86
87- **CEF runtime integration**: CEF now uses `purego-cef2gtk`, a codec-enabled runtime path, deterministic runtime discovery, and XDG-scoped user data.
88- **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.
89- **Unified browser plumbing**: Downloads, context menus, internal pages, favicons, clipboard handling, and browser launch flows now share more code across WebKit and CEF.
90- **Window-scoped tabs and browsing contexts**: Tab shortcuts, popup handling, OAuth windows, and native browser windows now track the owning window/context more consistently.
91- **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.
92- **Logging cleanup**: Session log cleanup can cap log files by count as well as age.
93- **Tooling and dependencies**: Go/runtime dependencies, GitHub Actions, golangci-lint, PipeWire audio dependencies, and AUR metadata were refreshed.
94
95### Fixed
96
97- **CEF rendering stability**: Hardened OSR browser creation, live resize repainting, viewport sync, popup surfaces, and bounded size observation.
98- **CEF input and focus**: Improved clipboard, keyboard focus, tab shortcuts, global shortcut release behavior, gesture callback release, and ghost shortcut suppression.
99- **CEF file dialogs and local files**: Hardened GTK file-dialog callbacks, GIO cleanup, file-dialog edge cases, and zoom for local `file://` URLs.
100- **CEF popups and OAuth**: Improved popup lifecycle cleanup, native popup content widgets, pane-hosted popup fallback cleanup, and OAuth auto-close behavior.
101- **Desktop integration**: Browser MIME handler sync and browser launch error redaction are more reliable.
102- **Session and pane resilience**: Stale pane restore paths, nil workspace pane views, and popup restore cleanup are safer.
103
104## [0.28.0] - 2026-03-27
105
106### Added
107
108- **Engine abstraction layer**: Introduced a major architectural refactor that decouples the browser engine layer from the UI. The new `Engine` interface and supporting infrastructure make it possible to support alternative rendering engines beyond WebKit in the future. Users with custom configurations should run `dumber config migrate` to transition to the new engine configuration format (`[engine]/[engine.webkit]` structure). The migration is automatic and backwards-compatible.
109- **Website data access permission**: New permission dialog and system for controlling access to website persistent data. Users can now grant or deny individual websites access to cookies, localStorage, and other persistent storage.
110- **Content blocker large filter set support**: Filter sets exceeding WebKit's 150k rule limit are now properly handled by compiling each part file as a separate WebKit filter, enabling support for comprehensive filter lists. Filter file discovery is now dynamic via manifest instead of a hardcoded list.
111- **Content blocker debug logging**: Added load-failed signal logging to help diagnose content blocker and filter compilation issues.
112
113### Changed
114
115- **Database backend modernization**: Replaced the WASM-based `ncruces/go-sqlite3` with native `purego-sqlite` via pure FFI (no WASM runtime, no CGO required). This simplifies the build process and improves startup performance by removing the SQLite WASM initialization precompile step.
116- **Keyboard and input system overhaul**: Complete rewrite of keyboard routing with native dead key and compose sequence support. The new unified key routing system properly handles accent input with bubble-phase handling and input method fallback, restricted to editable targets with accessibility fallback.
117- **Omnibox ghostwriter reliability**: Reimplemented the ghost text system to eliminate letter-eating on fast typing. Replaced the goroutine/token/coalescer machinery with synchronous ghost computation, a guard flag for programmatic `SetText`, debounced echo detection, and stale input checks.
118- **Omnibox URL intent matching**: Improved URL detection to prioritize URL-like input on Enter, normalize bare IPs to HTTP for local/tailnet services, and handle leading whitespace correctly. Explicit omnibox selections are now always honored over ghost input.
119- **Permission system hardening**: Strengthened permission origin handling to use the live page URI from the signal's WebView for all permission lookups. Exported metadata key constants replace raw string literals. Cookie policy default now correctly aligns with Epiphany ITP model.
120- **GTK binding upgrades**: Migrated from `jwijenbergh/puregotk` to `bnema/puregotk` with `ebitengine/purego`. Signal callbacks now receive `*glib.Error` instead of raw `uintptr`, providing actual error messages in load-failed and download-failed logs. Fixes `g_object_new_with_properties` use-after-free via `[]string` keepalive.
121
122### Fixed
123
124- **WebView accent picker**: Fixed double-character input and focus loss in the WebView accent picker during rapid typing.
125- **Async callback safety**: Hardened async callbacks with URI validation and timer generation counters to prevent stale callbacks from executing on the wrong WebView.
126- **Modal phase synchronization**: Made `setControllerPhase` synchronous and dispatched modal timeouts via the GTK main thread to prevent race conditions.
127- **Keyboard routing thread-safety**: Resolved thread-safety issues and nil-guard checks in keyboard routing.
128- **Application shortcuts restoration**: App shortcuts are now restored when WebView has focus.
129- **Favicon caching**: Fixed stacked title bar favicons to populate from cache on stack creation, guarded against nil texture overwriting a good favicon, and prevented swap on pool reuse.
130- **SIGABRT crash on permission requests**: Fixed a crash that occurred when the permission-request signal was emitted during rapid pane teardown.
131- **Panic logging in safeGLibType**: Recovered panics are now logged instead of silently swallowed.
132
133## [0.27.2] - 2026-02-17
134
135### Changed
136
137- **Toolchain compatibility updates**: Bumped the project to Go 1.26, updated puregotk dependencies, and upgraded golangci-lint to v2.9.0 to keep CI aligned with the new Go version.
138- **Maintenance**: Internal refactor to OAuth popup timing.
139- **README wording cleanup**: Tightened README copy and standardized uBlock casing.
140- **Repository hygiene**: Removed an accidentally tracked plan file that is already covered by `.gitignore`.
141
142### Fixed
143
144- **Floating pane Escape handling**: Pressing `Escape` now hides the floating pane only when it is currently visible.
145- **OAuth popups now close reliably after sign-in**.
146- **Auto-close only affects the OAuth window** so other popups are not dismissed unexpectedly.
147
148## [0.27.1] - 2026-02-12
149
150### Fixed
151
152- **Release CI hotfix**: Removed invalid `disable_immutable` from GoReleaser config so release workflows run correctly.
153
154### Changed
155
156- **Release workflow compatibility**: Fixed Flatpak upload behavior for `workflow_dispatch` triggers.
157
158## [0.27.0] - 2026-02-12
159
160### Added
161
162- **Unexpected-close crash reports**: Automatically detects prior abrupt sessions on startup and generates per-session crash reports (JSON + Markdown) with metadata, core-dump diagnostics, and redacted log tails. Reports are capped at 20 to prevent unbounded disk growth.
163- **`dumber crashes` CLI**: New CLI surface to list, view, and extract GitHub issue payloads from crash reports (`dumber crashes`, `dumber crashes show latest`, `dumber crashes issue latest`).
164- **Crash report UI notification**: Startup toast guides users to run `dumber crashes issue latest` when unexpected-close reports are detected.
165- **Unexpected-close GitHub issue template**: Structured issue template for reporting crashes with crash report payload, context, and reproduction steps.
166- **Session exit classification runbook and diagnostics docs**: Added dedicated operational documentation for abrupt/clean exit classification and troubleshooting paths.
167- **Session/bootstrap resilience coverage**: Added tests and supporting logic for startup markers, WebKit stack bootstrap, and exit classification handling.
168- **Omnibox async guard tests**: Added focused tests for ghost text async/state safety and normalization behavior.
169- **Floating pane (persistent overlay pane)**: `Alt+F` toggles a workspace floating pane that preserves its session state while hidden.
170- **Floating pane profiles**: Optional URL profiles under `workspace.floating_pane.profiles` with user-defined shortcut keys to open/focus named floating sessions.
171- **Floating pane documentation**: Added reference docs describing floating behavior, shortcuts, and configuration.
172- **Installer prerelease/version selection**: `install.sh` supports `DUMBER_PRERELEASE=1` to install the latest prerelease and `DUMBER_VERSION=<tag>` to install a specific release.
173
174### Changed
175
176- **WebKit/puregotk compatibility refresh**: Updated bindings and call sites for `github.com/bnema/puregotk-webkit v0.0.10` and latest puregotk replacement, including signal ID/type handling updates.
177- **Dependencies updated**: Bumped key runtime/developer dependencies, including `go-sqlite3`, `bubbles`, and related transitive modules.
178- **Omnibox behavior tuning**: Refined ghost suggestion ranking/selection behavior and dynamic result sizing tied to pane height.
179- **Autocomplete architecture cleanup**: Centralized completion flow and ghost positioning helpers for more consistent behavior across async paths.
180- **Omnibox keyboard/navigation UX**: Added `Alt+h/j/k/l` pane navigation while omnibox is open and improved chrome height scaling/debouncing on GTK main thread.
181- **Config normalization hardening**: Normalization now coerces invalid profile/appearance values to safe defaults.
182- **Loading skeleton redesign**: Reduced logo from 512px to 256px, added version label below a discrete 32px spinner. Sizes extracted to constants so tests use `mock.Anything` and don't break on dimension changes.
183- **Aggressive WebView reuse policy**: `reusePolicyAggressive` now actually differs from `reusePolicySafe` by allowing reuse regardless of navigation activity, relying on `ResetForPoolReuse` to clear state.
184- **Multiple GUI instances**: GTK app is now non-unique, allowing independent `dumber` launches in parallel.
185- **Config schema/validation**: Added `workspace.floating_pane.*` config keys to schema and validation, including URL/profile shortcut validation.
186- **Config migration for shortcut actions**: Migration now merges newly added `workspace.shortcuts.actions.*` defaults into existing user action maps without overwriting user-defined entries.
187
188### Fixed
189
190- **Hover focus stealing from new split panes**: New pane creation now locks hover focus until the user intentionally moves the mouse, replacing the 300ms time-based suppression that could expire before GTK layout completes. Synthetic enter events from widget rearrangement no longer steal focus from freshly created panes.
191- **Stacked pane title desync on navigation**: Titles in the stacked title bar now sync immediately on `LoadCommitted` and when switching panes, preventing stale titles after background navigation.
192- **Session marker file accumulation**: `writeShutdownMarker` now removes the matching startup marker (embedding its timestamp for classification), and a new `sweepPairedMarkers` sweep in background cleanup removes old marker trios past the configured age.
193- **Retry delay exceeding max**: `retryDelayForAttempt` now clamps the final delay (base + jitter) to `retryMaxDelay` so backoff never overshoots the hard cap.
194- **Inconsistent WebView termination in pool**: `PrewarmFirst`, `PrewarmAsync`, `prewarmSync`, and `RefreshScripts` now call `DestroyWithPolicy(terminatePolicy)` instead of bare `Destroy()`, matching `Release` behavior.
195- **Pool metrics counted on failed creation**: `acquireCount`, `acquirePoolMisses`, and `acquireTotalNanos` are now incremented only after `createWebView` succeeds.
196- **Redundant crash page URI sanitization**: Removed double `sanitizeCrashPageOriginalURI` call inside `buildCrashPageHTML`; the caller already sanitizes.
197- **Racy skeleton version global**: Replaced plain `string` with `atomic.Value` so concurrent reads/writes to `skeletonVersion` are safe.
198- **Inline ghost suggestion stability**: Reworked ghostwriter flow to keep suggestions selected (not auto-committed), with stronger token guards and stale-callback protection.
199- **GTK thread-safety in omnibox**: Removed unsafe off-main-thread widget reads in async flows.
200- **Review follow-ups (Copilot/CodeRabbit)**: Fixed custom-scheme GET handling for empty WebKit methods, synchronized pool close/send paths, aligned WebKit signal ID storage types, and marshalled OAuth parent refresh reloads back to the GTK main loop.
201- **Persistence/update safety edges**: Enforced positive visit-count deltas in SQLite repos, removed redundant filter cache directory creation, canceled pending snapshot timer on `SetReady`, and made updater retry-loop exhaustion explicit.
202- **Logging/dedup consistency**: Unified abrupt-session marker stat warnings under structured session logging and reduced favicon warning dedup growth by using a global cache-dir warning key plus callback coverage tests.
203- **Omnibox input/ghost correctness**: Enforced minimum typed input before ghost suggestions, trimmed leading spaces before URL interpretation, deferred omnibox auto-open until layout is ready, and fixed width/layout edge-cases.
204- **History/autocomplete edge-cases**: Normalized FTS queries containing slashes and capped `about:blank` visit-count inflation.
205- **Navigation/history robustness**: Added pane history cleanup hooks, batched/capped visit increment fallback, and idempotent `NavigateUseCase.Close()`.
206- **WebView lifecycle/reset correctness**: Reset pooled WebView transient state more thoroughly and improved callback/signal wiring consistency.
207- **Navigation safety guards**: Added `CanGoBack` protection in navigation policy handling and corrected back-forward-list signal disconnection target.
208- **Crash handling and retry edge-cases**: Hardened crash-page routing safety, updater retry semantics/documentation, and related infra error paths.
209- **Filtering/snapshot/session reliability**: Fixed race/error-handling paths in filtering updates, snapshot persistence, and session startup marker processing.
210- **WebView pool shutdown race**: Re-check `closed` flag after `createWebView` in `Acquire` to prevent leaking WebViews when pool closes during creation.
211- **Updater transient error detection**: Broadened `isRetryableRequestError` to detect `ECONNRESET`, `ECONNREFUSED`, `ENETUNREACH`, `EHOSTUNREACH`, and `EADDRNOTAVAIL` syscall errors, plus `net.Error.Temporary()` and `url.Error` wrappers.
212- **Session lock probe accuracy**: `markAbruptExits` now uses non-blocking flock instead of `os.Stat`, correctly distinguishing active sessions (lock held) from stale ones (lock acquirable) and skipping on permission/IO errors.
213- **Crash page "Stay on this page" UX**: Button no longer navigates to `dumb://home/crash`; it now stays on the crash page as its label suggests.
214- **Visit increment fallback overflow**: `IncrementVisitCountBy` now returns an error when delta exceeds the fallback cap instead of silently dropping increments.
215
216### Security
217
218- **External scheme launch guard**: Restricted external URL scheme launching to user-gesture initiated navigations.
219
220## [0.26.1] - 2026-01-25
221
222### Fixed
223- **Popups not working in split panes**: Fixed `window.open()` and `target="_blank"` links not functioning in split panes. Popup handling was not being set up for WebViews created via `EnsureWebView`.
224
225### Changed
226- **WebView callback setup refactoring**: Consolidated duplicate callback setup code into single `setupWebViewCallbacks` function. `EnsureWebView` now delegates to this function instead of inline setup. Made `setupPopupHandling` private since no external callers remain.
227
228## [0.26.0] - 2026-01-24
229
230### Added
231- **Visual keybindings editor**: New Keybindings tab in `dumb://config` allows editing all keyboard shortcuts via a visual UI. Supports key capture, reset to defaults, and per-binding reset. Fixes #123.
232- **Keybindings hot reload**: Changed keybindings take effect immediately without restarting the browser.
233- **Ordered config file**: Config file sections are now written in alphabetical order for better readability and deterministic output.
234- **Inline ghost text autocompletion**: Omnibox now shows inline ghost text suggestions from history as you type. Accept with Right Arrow (full) or Ctrl+Right (word). Properly aligned with entry text.
235- **Omnibox click-outside-to-close**: Omnibox automatically closes when clicking outside its bounds.
236- **GTK/WebKit log capture**: New `logging.capture_gtk_webkit_logs` config option to capture GTK and WebKit logs for debugging.
237- **Startup performance tracing**: Added startup trace logging for cold start performance analysis and optimization.
238
239### Changed
240- **Simplified keybinding syntax**: Keybindings now use symbol syntax (`[`, `]`, `{`, `}`) instead of verbose GTK names (`bracketleft`, `braceleft`). Fixes #122.
241- **BREAKING: Global shortcuts config structure**: `workspace.shortcuts` changed from individual string fields to unified `Actions` map with `ActionBinding` (keys + description). Existing custom shortcuts in config.toml will be replaced with defaults. Use the new Keybindings UI to reconfigure.
242- **Keybindings clean architecture**: Refactored keybindings handler to follow ports/adapters pattern. Business logic moved from handler to use cases, config access via gateway adapter instead of global singleton.
243- **Deferred startup initialization**: Non-critical initialization (WebView pool prewarm, etc.) now deferred until after first navigation starts for faster cold start.
244- **Omnibox search ranking**: Improved domain matching boost and FTS5 period handling for better search result relevance.
245
246### Upgrade Notes
247> **Recommended**: Delete your `config.toml` and restart dumber to regenerate a fresh config with the new keybinding structure and alphabetically sorted sections. Your settings will reset to defaults, but you can reconfigure keybindings via the new visual editor at `dumb://config` → Keybindings tab.
248
249### Fixed
250- **Config save/read race condition**: Fixed UI scale and other config values returning stale data after save. Implemented atomic file writes (temp file + rename) and `skipNextReload` flag to prevent fsnotify-triggered reload from overwriting correct in-memory config with stale viper cache.
251- **WebUI lint warnings**: Added ESLint Svelte plugin and resolved 33 lint errors and 14 `any` type warnings across all components. Created `dumber.d.ts` for proper TypeScript types for WebKit bridge communication.
252- **Session snapshot FK constraint**: Fixed SQLite foreign key constraint violation when snapshot service tried to save before session was persisted to database. Added ready flag and callback notification pattern.
253- **Stacked pane index out of bounds**: Fixed crash when domain model and UI got out of sync during stacked pane operations. Added bounds checking and proper rollback when UI updates fail.
254- **Noisy gesture navigation logs**: Mouse button back/forward navigation errors (expected when no history) now log at debug level instead of error level.
255- **Omnibox ghost text race conditions**: Fixed stale ghost text appearing due to race conditions. Query now passed through the entire autocomplete chain.
256- **Omnibox ghost text clipping**: Ghost text now properly clips to entry bounds and aligns vertically with input text.
257- **Ghost text on history scroll**: Disabled ghost text suggestions when scrolling through history with arrow keys after user has typed.
258- **Popup WebView hierarchy**: Fixed popup WebViews not being inserted into GTK hierarchy before create signal returns.
259- **OAuth popup timeout**: Added 30-second safety timeout for OAuth popup handling to prevent stuck popups.
260- **External page background**: Reset WebView background to white for external pages to prevent dark theme color bleeding into light-themed sites.
261- **Localhost URL normalization**: Fixed localhost URL handling and improved download handler architecture for cleaner code.
262- **Svelte 5 Proxy serialization**: Fixed keybinding bridge serialization to handle Svelte 5 Proxies and added conflict detection.
263
264## [0.25.0] - 2026-01-08
265
266### Added
267- **File download handling**: Downloads from websites now save to the user's download directory with toast notifications for start/complete/failed states. Configurable via `downloads.path` (defaults to `$XDG_DOWNLOAD_DIR` or `~/Downloads`).
268- **Print shortcut**: `Ctrl+Shift+P` opens the print dialog for the current page. Fixes #99.
269
270### Changed
271- **Flatpak files location**: Moved flatpak-related files to `flatpak/` directory. Fixes #101.
272- **Navigation shortcuts**: `Ctrl+Left/Right` now triggers back/forward navigation, `Alt+Left/Right` moves focus between panes. Fixes #98.
273- **Update notification**: Simplified update toaster message for AUR/Flatpak users - no longer shows "manual install required". Fixes #109.
274
275### Fixed
276- **SPA mouse navigation**: Fixed unreliable back/forward mouse button navigation in Single Page Applications. WebKit's `BackForwardList` doesn't track JavaScript History API (`pushState`/`replaceState`) navigation. Now uses JavaScript `history.back()`/`history.forward()` as fallback when WebKit native navigation is unavailable.
277- **Accent picker freeze**: Fixed UI freeze when selecting an accent by pressing Enter or Escape. The deadlock was caused by the callback (which calls `Hide()`) being invoked while holding the mutex that `Hide()` also needs to acquire.
278- **Stacked pane title mismatch**: Fixed title bar showing wrong page title after closing panes in a stack. Refactored stacked pane management to use proper use cases, ensuring domain model stays in sync with UI.
279- **Flatpak favicons**: Fixed favicons not displaying in omnibox for Flatpak installs by ensuring cache directory exists before saving. Fixes #105.
280- **Flatpak desktop launcher**: Fixed .desktop file not launching application from app launchers by adding locale environment variables. Fixes #104.
281- **Flatpak update notifications**: Skip GitHub update checks for Flatpak and AUR installs (use package manager instead). Fixes #107.
282- **Active border with stacked panes**: Hide active pane border when only one pane area is visible (stacked panes count as one). Fixes #108.
283- **Setup command for AUR**: `dumber setup` now detects AUR and Flatpak installations and locates the correct .desktop file. Fixes #102.
284
285### Removed
286- **dev/ directory**: Removed development scripts directory. Fixes #103.
287
288## [0.24.0] - 2026-01-06
289
290### Added
291- **Auto-copy on selection**: Text selected in web pages is automatically copied to the clipboard (like zellij/tmux). Shows brief "Copied to clipboard" toast notification. Configurable via `clipboard.auto_copy_on_selection` (default: true). Fixes #83.
292- **Font availability detection**: On first run, detects available system fonts using fontconfig (`fc-list`) and selects the best font from a fallback chain instead of hardcoding `Fira Sans` / `Fira Code`. Fallback chains: sans-serif (Fira Sans, Noto Sans, DejaVu Sans, Liberation Sans, FreeSans), serif (Noto Serif, DejaVu Serif, Liberation Serif, FreeSerif), monospace (Fira Code, JetBrains Mono, Noto Sans Mono, DejaVu Sans Mono, Liberation Mono, FreeMono). Falls back to generic CSS fonts if none available. Fixes #85.
293- **Stacked pane close buttons**: Close buttons in stacked pane title bars allow closing individual panes directly. Includes proper signal cleanup on removal.
294- **AUR git package CI**: Automated CI workflow to publish `dumber-browser-git` AUR package on push to main branch.
295
296### Changed
297- **Flatpak runtime**: Bumped to GNOME 49 runtime.
298- **Focus method refactored**: `Focus()` now delegates to `ApplyFocusChange()` to ensure stack index is updated when focusing stacked panes.
299
300### Fixed
301- **Flatpak locale crash**: Attempted fix for crash on systems with certain locale configurations by adding proper locale data to the Flatpak bundle.
302- **Stacked pane vertical splits**: Vertical splits from stacked panes now correctly split around the entire stack instead of just the active pane.
303- **Pane border focus**: Fixed stale border remaining on previously hovered pane when using keyboard navigation to switch focus. Fixes #89.
304- **Geometric focus navigation**: Fixed focus jumping to wrong pane when navigating left/right in complex layouts. Navigation now prioritizes panes at the same vertical level (for left/right) or horizontal level (for up/down).
305- **Link status overlay auto-hide**: Link URL overlay now automatically hides after 10 seconds of inactivity instead of staying visible indefinitely. Timer resets when hovering new links. Fixes #82.
306- **Omnibox multi-word search**: History search now matches all words in query (AND logic) and searches both URL and title fields. Prefix matching enabled (e.g., "git iss" matches "github.com/issues"). FTS5 special characters are now sanitized to prevent syntax errors. Results interleave URL and title matches for better balance. Fixes #87.
307
308## [0.23.2] - 2025-12-31
309
310### Added
311- **AUR packaging support**: Dumber is now available on the Arch User Repository (AUR).
312  - `dumber-browser-bin`: Pre-built binary package from GitHub releases (recommended).
313  - `dumber-browser-git`: Build from source, tracks latest git.
314  - Install with `yay -S dumber-browser-bin` or `paru -S dumber-browser-bin`.
315  - Automatic AUR updates via GitHub Actions (1 hour delay after Flatpak build for safety).
316- **Pacman/AUR install detection**: Self-updater is disabled when installed via pacman/AUR (uses `pacman -Qo` to detect package ownership). Shows specific message: "use your package manager instead".
317- **Improved update error messages**: Self-update now shows specific messages for Flatpak ("use 'flatpak update'") and pacman/AUR ("use your package manager") installs instead of generic "binary not writable" error.
318
319## [0.23.1] - 2025-12-30
320
321### Added
322- **Flatpak packaging support**: Dumber is now available as a Flatpak bundle for easy installation with all dependencies included.
323  - `dumber.flatpak` bundle attached to each GitHub release.
324  - Install with `flatpak install --user dumber.flatpak`.
325  - Includes Wayland, GPU, audio, webcam, and PipeWire permissions.
326  - Automatic builds via GitHub Actions on every release.
327- **Flatpak runtime detection**: Skip pkg-config runtime checks when running inside Flatpak sandbox (GNOME runtime provides all dependencies).
328- **Self-updater disabled in Flatpak**: Binary self-update is disabled when running as Flatpak (use Flatpak update mechanisms instead).
329
330## [0.23.0] - 2025-12-30
331
332### Added
333- **macOS-style accent picker**: Long-press (400ms) on keys with accent variants (e, a, o, u, i, c, n, s, y, z) shows a popup with accented character options. Select with number keys 1-9, arrow keys + Enter, or click. Works in omnibox, find bar (Ctrl+F), and web page inputs. Implements dead keys/compose sequence alternative for users who can't use system-level input methods.
334- **Performance profiles (WebKit tuning presets)**: New `performance.profile` setting (`default`, `lite`, `max`, `custom`) plus WebUI support for selecting and editing performance tuning values.
335- **dmenu history enhancements**: New `dumber dmenu --days N` (time-window history) and `--most-visited` (sort by visit count).
336
337### Changed
338- **Color scheme detection architecture**: Refactored theme preference detection into a priority-based `ColorSchemeResolver` with multiple detectors (libadwaita/GTK/gsettings/env) and a change notification API for consistent dark-mode behavior.
339- **dmenu history limiting**: dmenu history limiting is now time-based (days) instead of a fixed max item count.
340- **WebKit dependency**: Bumped `github.com/bnema/puregotk-webkit` to `v0.0.9`.
341
342### Fixed
343- **Dark mode detection on internal pages**: Fixed `dumb://home` and other internal pages showing light theme despite system being in dark mode. Refactored color scheme detection to use a priority-based resolver with proper initialization ordering. The libadwaita detector (highest priority) is now correctly enabled only after `adw.Init()` completes, ensuring WebViews created during bootstrap get the correct theme preference.
344- **External site form theming artifacts**: Removed injected `color-scheme` overrides that caused odd styling in some forms/inputs on regular websites.
345- **WebKit memory pressure stability**: Fixed an assertion by applying strict memory thresholds before conservative thresholds when configuring WebKit’s memory pressure handlers.
346- **Web process termination on perf tuning**: Removed the “memory kill” threshold because it could terminate the web process immediately in some environments.
347- **`dumb://` scheme context mismatch**: Fixed internal pages sometimes using a different WebKit context than expected by always using the default context.
348- **Accent picker Escape behavior**: Fixed cases where Escape wouldn’t dismiss the accent picker after mouse interaction by restoring focus appropriately.
349- **dmenu history days edge case**: Fixed `dumber dmenu --days 0` to mean “all history”, and added validation for invalid day values.
350
351## [0.22.0] - 2025-12-28
352
353### Added
354- **Omnibox bang shortcuts UI**: Typing `!` in the omnibox now shows all configured bangs (search shortcuts) with filtering and Enter-to-autocomplete, plus a header badge when a bang is recognized.
355- **Loading skeleton with app logo**: New panes show a centered 512x512 faded app logo with a spinner while loading, replacing the blank/white flash. Uses `--muted` theme color for the spinner.
356- **App logo favicon for internal pages**: `dumb://` URLs now display the dumber logo as favicon in history, favorites, omnibox suggestions, and dmenu/rofi. WebUI and CLI tools share consistent branding.
357- **Omnibox favorite indicator**: History items that are also bookmarked now display a yellowish left border and subtle background tint in the omnibox. Uses parallel async loading to avoid blocking browser startup.
358- **Mode indicator toaster**: Visual notification showing current modal mode (PANE MODE, TAB MODE, SESSION MODE, RESIZE MODE) at bottom-left corner with mode-specific colors. Configurable via `workspace.styling.mode_indicator_toaster_enabled` (default: true).
359- **Config migration system**: Detects missing config keys when new settings are added in updates and provides tools to add them.
360  - `dumber config status`: Shows config file path and number of new settings available.
361  - `dumber config migrate`: Lists missing keys with types/defaults and adds them to config file.
362  - GUI toast notification on startup when new settings are available (configurable via `update.notify_on_new_settings`).
363- **CLI self-update command**: New `dumber update` command to check for and install updates from the command line.
364  - Interactive spinner animation during check and download phases.
365  - `--force` / `-f` flag to skip version check and reinstall the current version.
366  - Reuses existing auto-update infrastructure (check, download, stage, apply on exit).
367  - Theme-aware styling consistent with other CLI commands.
368- **Config open command**: New `dumber config open` command to open the config file in your preferred editor. Uses `$EDITOR`, then `$VISUAL`, with fallback to nano/vim/vi.
369- **Config schema command**: New `dumber config schema` command that displays all configuration keys with their types, defaults, descriptions, and valid values. Supports `--json` flag for machine-readable output.
370- **CLI gen-docs command**: New `dumber gen-docs` command to generate documentation from CLI command definitions. Supports man pages (installed to `~/.local/share/man/man1/`) and markdown formats. Use `--format markdown` for markdown output or `--output` for custom directory.
371- **Move pane to tab**: New pane-mode actions to move the active pane to another tab.
372  - `Ctrl+P → m`: Opens a tab picker modal.
373  - `Ctrl+P → M`: Moves the active pane to the next tab (creates a new tab if needed).
374  - New config: `workspace.switch_to_tab_on_move` (default: true).
375
376### Changed
377- **Cold start optimization**: Reduced startup time by ~150ms (29% faster) through parallel initialization.
378  - New `internal/bootstrap` package encapsulates all startup orchestration.
379  - `RunParallelInit()` runs 5 goroutines concurrently: directory resolution, pkg-config check, GStreamer check, theme manager creation, and SQLite WASM pre-compilation.
380  - WebView pool prewarming creates one WebView synchronously so first `Acquire()` is instant.
381  - Async session cleanup: stale session marking runs in background, doesn't block startup.
382  - `StartupTimer` logs timing for each bootstrap phase (parallel init, DB/WebKit, app creation).
383  - Database initialization runs in background goroutine while WebKit stack initializes on main thread.
384  - Database path now resolved via `config.GetDatabaseFile()` following clean architecture.
385  - Added connection pool settings optimized for SQLite (`SetMaxOpenConns(1)`, keep-alive).
386  - Reduced `mmap_size` from 30GB to 256MB (reasonable for browser history DB).
387  - Added `PRAGMA foreign_keys = ON` for referential integrity.
388- **Startup deferrals**: Runtime/media checks and SQLite WASM precompile now run after first paint, and DB initialization uses lazy repositories when auto-restore is off to cut cold-start latency further.
389- **Console logging**: Standardized console timestamps to `HH:MM:SS` across bootstrap and session logging.
390
391### Fixed
392- **Omnibox favorite toggle reactivity**: Fixed space key toggle in omnibox not updating UI reactively. Now properly toggles favorites (add if not favorite, remove if favorite) with immediate visual feedback (yellow indicator) and toast notifications. Business logic moved to `ManageFavoritesUseCase.Toggle()` for testability.
393- **Config migration type matching**: Fixed migration incorrectly matching keys of different types (e.g., `_width` int keys with `_color` string keys) during rename detection, preventing value swapping.
394- **Config migrate removes deprecated settings**: Fixed `dumber config migrate` not removing deprecated settings from the config file. Previously deprecated keys were preserved but unused; now they are properly deleted. Supports TOML, YAML, and JSON config formats.
395- **Fullscreen video tab bar**: Fixed tab bar remaining visible during fullscreen video playback. Now hides automatically when entering fullscreen and restores based on normal visibility logic when exiting.
396- **Dark mode navigation flash**: Fixed a brief white flash between the loading skeleton and page content when navigating in dark mode.
397- **Progress bar stuck state**: Added 30-second timeout to progress bar to auto-hide if page load stalls and never completes.
398- **OAuth popup login**: Fixed parent page going blank after OAuth popup closes (e.g., Google login on claude.ai, notion.com). Related WebViews share a web process with their parent; destroying the popup was terminating the shared process, killing the parent. Now skips `TerminateWebProcess()` for popup WebViews.
399- Startup: defer WebView pool prewarm until after initial tab creation to reduce cold-start navigation latency.
400- README CLI examples: updated to match current commands/flags (`purge --force` only, `logs` usage, `sessions list --limit`, removed deprecated `--dmenu` root flag).
401
402## [0.21.0] - 2025-12-26
403
404### Added
405- **Configurable new-pane defaults**: New `workspace.new_pane_url` (default: `about:blank`, supports `dumb://`) and `omnibox.auto_open_on_new_pane` (default: false).
406- **Consume-or-expel panes (very alpha)**: Niri-style pane consume/expel operation to merge a leaf into a sibling stack or expel a stacked pane into a split. Default global shortcuts: `Alt+[` / `Alt+]` (and `Alt+Shift+[` / `Alt+Shift+]`).
407- **Zellij-style pane resize mode**: New modal resize mode (`Ctrl+N`) to adjust split sizes with keyboard (`h/j/k/l` or arrow keys, `+/-` smart resize). Shows a per-pane border indicator and keeps the timeout alive while you resize.
408- **Mouse-driven pane resizing**: Drag split dividers with the mouse; split ratios are persisted in session snapshots (rounded to 2 decimals) and restored on resurrection.
409- **Dynamic window title**: Window title now displays the active pane's page title in format `<Page Title> - Dumber`. Updates when switching tabs/panes or navigating. Truncated at 255 characters.
410- **Link URL status overlay**: Shows destination URL in bottom-left corner when hovering over links, images, or media elements. Standard browser UX pattern with 100ms show delay to avoid flicker and 150ms CSS fade transitions. Configurable via CSS.
411- **Local file path support**: `dumber browse test.html` now correctly opens local HTML files by converting existing file paths to `file://` URLs. Supports absolute paths, relative paths, and `~/` home directory expansion.
412- **Auto-update system**: Automatic update checking and self-updating binary replacement following clean architecture.
413  - **Update check on startup**: Async check against GitHub releases API (configurable via `update.enable_on_startup`, default: true).
414  - **Toast notifications**: Non-intrusive auto-dismiss notifications for update availability.
415  - **Auto-download**: Optional background download with binary staging (configurable via `update.auto_download`, default: false).
416  - **Binary self-update**: Atomic binary replacement on clean exit with `.old` backup. Only works if binary is user-writable (e.g., `~/.local/bin/`).
417  - **CLI update check**: `dumber about` now displays update availability.
418  - **Version-less release archives**: Goreleaser now produces `dumber_linux_x86_64.tar.gz` (version in directory inside) enabling stable GitHub `/releases/latest/download/` URLs.
419- **Session management & resurrection**: Zellij-inspired session management system allowing users to save, list, and restore browser sessions.
420  - **Automatic session snapshots**: Debounced state saving (configurable interval, default 5s) captures tabs, panes, splits, stacks, URLs, titles, and zoom levels.
421  - **Session Manager modal**: Access via `Ctrl+O → s/w` or `Ctrl+Shift+S` to browse and restore sessions with inline preview of tabs and panes.
422  - **Session mode**: New modal mode (`Ctrl+O`) with purple border indicator, similar to pane/tab modes.
423  - **CLI session commands**: `dumber sessions` opens interactive TUI browser; `dumber sessions list` shows saved sessions; `dumber sessions restore <id>` resurrects a session in a new window; `dumber sessions delete <id>` removes a session.
424  - **Session purging**: Integrated into `dumber purge` command for cleaning up old session data. Simplified UI with single "Sessions" toggle instead of individual selection.
425  - **Automatic session cleanup**: Sessions are automatically cleaned up on startup based on `max_exited_sessions` (default: 50) and `max_exited_session_age_days` (default: 7 days).
426  - **Configuration options**: `session.auto_restore`, `session.snapshot_interval_ms`, `session.max_exited_sessions`, `session.max_exited_session_age_days`, plus session mode shortcuts and styling.
427
428### Fixed
429- **Alt/Ctrl+number shortcuts on non-QWERTY keyboards**: Fixed Alt+1-9/0 tab switching and Ctrl+1-9/0 omnibox shortcuts not working on AZERTY, QWERTZ, Dvorak, and other non-QWERTY keyboard layouts. Uses hardware keycodes as fallback when keyval lookup fails, enabling shortcuts to work based on physical key position regardless of layout.
430- **Idle inhibition leak on pane close**: Fixed D-Bus idle inhibit request not being released when closing a pane/tab while in fullscreen or playing audio. The inhibition would remain active until the app exited. Now properly tracks fullscreen and audio state and releases inhibition before destroying WebView.
431- **Audio-based idle inhibition**: Extended idle inhibition to also activate when a page is playing audio (e.g., video/music playback), not just in fullscreen mode. Uses WebKit's `notify::is-playing-audio` signal. The inhibitor uses refcounting, so both fullscreen and audio can be active simultaneously.
432
433## [0.20.1] - 2025-12-25
434
435### Fixed
436- **Stacked pane favicon and title updates**: Fixed favicon and title not updating in stacked pane title bars by tracking pane IDs in StackedView and properly routing update events to the correct pane.
437- **WebKit process leak on pane close**: Fixed zombie WebKit web processes not being terminated when panes were closed. `WebView.Destroy()` now properly calls `TerminateWebProcess()` and unparents GTK widgets, freeing GPU resources (VA-API, DMA-BUF, GL contexts). This should significantly improve video playback stability and reduce memory usage when opening/closing many panes.
438- **White flash on navigation**: Eliminated white page flash when navigating in dark mode by setting WebView background color to match theme and hiding WebView until content commits.
439- **Dark mode detection on websites**: Fixed `prefers-color-scheme: dark` detection by improving matchMedia query normalization and adding proper event listener stubs. Sites like Reddit now correctly detect dark mode preference.
440- **Alt+number tab switching**: Fixed Alt+1-9 shortcuts not working when WebView has focus by using GtkShortcutController with global scope instead of EventControllerKey.
441- **System locking during fullscreen video**: Added idle inhibition via XDG Desktop Portal when WebView enters fullscreen mode. Prevents system from locking/sleeping during fullscreen video playback on Wayland (works with all compositors: GNOME, KDE, sway, hyprland, etc.).
442- **Navigation performance**: Significantly faster page navigation through multiple optimizations:
443  - Async history recording via background worker (SQLite writes no longer block GTK main thread)
444  - LRU cache for per-domain zoom levels (repeat visits skip database queries)
445  - Async favicon preload (cache lookup doesn't block navigation start)
446  - Progress callback throttling at ~60fps (reduces UI callback overhead)
447  - Increased WebView pool prewarm from 2 to 4 for faster initial tab creation
448
449### Changed
450- **Custom color picker and confirm dialogs**: Replaced native GTK color picker and confirm dialogs with custom Svelte components using bits-ui AlertDialog. Fixes Wayland compatibility issues where native dialogs would not display properly (fixes #12).
451- **GSK renderer default**: Changed default from `vulkan` to `auto` to let GTK choose the best renderer and avoid potential DMA-BUF synchronization conflicts with WebKit.
452- **Removed invalid GStreamer config**: Removed `video_buffer_size_mb` and `queue_buffer_time_sec` config options as these were not valid GStreamer environment variables (they are element properties that cannot be set via env vars).
453
454### Added
455- **Performance config section**: New `performance` config section with `zoom_cache_size` (default: 256) and `webview_pool_prewarm_count` (default: 4) for tuning. Not exposed in UI but can be set in config file.
456- **Clean-architecture rewrite (pure Go)**: Major refactor to a ports/adapters style architecture with explicit `domain`, `application` (use cases), `infrastructure`, and `ui` layers.
457- **New CLI commands**: `doctor` (runtime dependency checks), `about` (build info), `setup` (desktop integration), plus expanded `purge` with an interactive TUI.
458- **WebUI config improvements**: Search shortcut management (CRUD) and reset-to-defaults support.
459- **Find-in-page**: New find UI and shortcut handling.
460- Migrated GUI stack to `puregotk` + `puregotk-webkit` and disabled CGO for pure Go compilation.
461- **Omnibox rewrite**: Replaced injected Svelte/JS omnibox with a native GTK4 widget overlay.
462- Startup defers non-critical work, adds DNS prefetching and a warmed WebView pool for faster tab/pane creation.
463- SQLite WAL checkpoints happen less frequently to reduce contention.
464- Content filters skip caching invalid rules; EasyList parser prefers if-domain over unless-domain.
465- Workspace border overlays can now receive pointer input.
466- Session-based logging and session management for CLI/GUI runs.
467
468## [0.15.0] - 2025-11-29
469
470### Added
471- **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.
472- **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.
473- **Configurable filter lists**: New `content_filtering.filter_lists` config option. Defaults include EasyList, EasyPrivacy, and uBlock filters (annoyances, quick-fixes).
474- **Demo video**: Added feature showcase video to README (docs/media/dumber-demo.mp4).
475- **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.
476- **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.
477- **Omnibox keyboard blocking**: Prevent page scripts from stealing focus while omnibox is active.
478- **Configurable border widths**: Added `pane_mode_border_width` and `tab_mode_border_width` configuration options (default: 4px) for full border customization.
479- **Content filter caching**: Centralized content blocking service compiles filters once and caches them for instant reuse across all WebViews.
480- **CLI purge enhancements**: Separate `--cookies` and `--history` flags for granular data deletion.
481- **URL normalization**: Consistent URL storage across browser, CLI, and favicon services (strips trailing slashes, normalizes schemes).
482
483### Fixed
484- **Filter compilation race condition**: Fixed concurrent map crash when multiple filter lists compile simultaneously by using local converter instead of shared state.
485- **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.
486- **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.
487- **Zoom toast suppression**: Suppress zoom toast notifications during browser initialization to prevent UI flash.
488- **Cosmetic filter injection**: Inject rules immediately and fix selector normalization for better ad blocking.
489
490### Changed
491- **Refactor keyboard blocking**: Move logic to main-world.ts, reduce handler.go verbosity.
492- **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.
493- **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.
494- **Remove Turnstile workaround**: Removed temporary Cloudflare Turnstile CORS allowlist (no longer needed).
495
496## [0.14.1] - 2025-11-18
497
498### Added
499- **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.
500- **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).
501- **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.
502
503### Fixed
504- **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.
505- **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).
506- **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.
507- **Video codec fallback**: Unblocked VP8 codec to allow fallback for ad segments, preventing playback interruptions when ads use different codecs than main content.
508- **Video buffering**: Increased buffer sizes (64 MB, 20s) to handle bursty Twitch/AV1 segments and improve streaming reliability on variable bitrate platforms.
509
510### Changed
511- **Console output cleanup**: Disabled WebKit console.log() messages to stdout to prevent page script spam. DevTools console (F12) still shows all messages.
512- **Content filtering configuration**: Refactored `content_filtering_whitelist` into structured `content_filtering` config with `enabled` boolean and `whitelist` array for better organization.
513
514## [0.14.0] - 2025-11-18
515
516### Added
517- **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).
518- **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.
519- **Click-to-activate stacked panes**: Click on any collapsed title bar to instantly activate that pane. Uses GTK4 gesture clicks for native interaction feel.
520- **Title bar visual separators**: Subtle 1px borders between stacked title bars. Theme-aware colors automatically adjust for light/dark mode.
521- **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).
522- **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.
523- **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.).
524- **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.
525- **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.
526- **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"`).
527
528### Changed
529- **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.
530- **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.
531- **Code cleanup**: Removed dead code files and emojis from GUI modules
532- **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).
533- **Omnibox spacing**: Increased vertical spacing between suggestion items from 0.65rem to 0.85rem for better readability
534- **Smart Escape key**: First press clears input text, second press closes omnibox. Empty input closes immediately.
535
536### Fixed
537- **Ctrl+Tab shortcuts**: Fixed focus cycling behavior, now properly switches between tabs
538- **Active tab visibility**: Fixed identical styling - active tab now clearly visible with distinct gray shade
539- **AZERTY keyboard support**: Alt+number shortcuts now work on all keyboard layouts using hardware keycodes
540- **Keyboard layout detection**: Fixed always detecting "en" - now correctly detects fr/de/etc layouts
541- **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.
542- **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`.
543- **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.
544- **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.
545- **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.
546
547## [0.13.0] - 2025-10-24
548
549### Added
550- **Color scheme config**: `appearance.color_scheme` setting to force dark/light theme (`"prefer-dark"`, `"prefer-light"`, `"default"`)
551- **DNS prefetch**: Added capability to prefetch DNS for links to speed up future requests
552- **Page cache (bfcache)**: Enabled WebKit back/forward cache for instant navigation
553- **Smooth scrolling**: Enabled WebKit smooth scrolling for better UX
554- **JSON Schema**: Auto-generated config schema for IDE autocompletion and validation
555- **Parallel cache loading**: Zoom, certificate, and fuzzy caches load concurrently at startup (<100ms target)
556- **Certificate validation cache**: In-memory cache for TLS certificate decisions with graceful shutdown flushing
557
558### Changed
559- **Database performance**: Enabled WAL mode with optimized PRAGMAs (64MB cache, memory-mapped I/O, 5s busy timeout) for 70k reads/sec, 3.6k writes/sec
560- **Zoom performance**: In-memory cache eliminates database reads during page transitions
561- **History writes**: Batched writes with background processor (flush every 5s or 50 items) to reduce I/O overhead
562- **BREAKING: Keyboard shortcuts**: All shortcuts now use `ctrl+` instead of `cmdorctrl+`. Existing configs with `cmdorctrl` still work via backward compatibility. Delete `~/.config/dumber/config.json` to regenerate with new defaults.
563- **Cache management**: Graceful cache flushing on shutdown prevents data loss; startup timing instrumentation with performance warnings
564
565### Fixed
566- **Graceful shutdown deadlock**: Resolved GTK main loop deadlock on Ctrl+Q by removing mutex locks and GTK calls after main loop exit
567- **CSS provider error handling**: Now properly handles errors from GTK CSS provider with logging
568- **Cache operations**: Added context timeouts to cache flush and history queue operations for graceful failure
569- Command typos now show proper error instead of opening in browser
570- History queue now uses buffered channel to prevent blocking on shutdown
571
572## [0.12.1] - 2025-10-18
573
574### Added
575- **Favicon refactoring**: WebKitGTK FaviconDatabase as single source of truth, removing fragile file-based cache and ico/bmp conversion dependencies
576  - Native favicon detection and automatic PNG export at 32x32 for CLI (dmenu)
577  - SVG favicon rasterization support
578  - Async texture loading with callbacks for non-blocking UI updates
579  - FaviconService handles favicon collection across all panes
580
581### Changed
582- Removed old favicon cache system (go-ico, go-bmp dependencies)
583- Simplified omnibox favicon handling: uses database favicon_url only
584
585### Fixed
586- Mouse button navigation: Added support for hardware mouse buttons 8/9 (back/forward)
587- Touchpad gestures: Two-finger horizontal swipe for back/forward navigation
588- Web app shortcuts: Ctrl+C, Ctrl+V, Ctrl+A now work in Gmail, VSCode web, etc.
589- Dark mode flash on startup: Set GTK dark theme preference and WebView background color before window/content creation
590- Cmd+Q and window close button now trigger graceful shutdown instead of killing the browser process
591- WebView cleanup: Properly destroy WebViews to prevent memory leaks and duplicate handler registrations when closing stacked panes
592- CLI help: Running `dumber` without arguments now shows available commands (use `--gui` or `browse` to launch GUI)
593
594## [0.12.0] - 2025-10-16
595
596### Added
597- **Native favicon support**: WebKit FaviconDatabase integration with automatic detection and caching for all panes
598- ENV=dev support to isolate test builds from production config/data in .dev/dumber/ directory
599- Content filtering whitelist config (Twitch enabled by default)
600- `dumber config` command to open config file in $VISUAL/$EDITOR or print path with `--path`
601- **Native WebKit popup lifecycle**: Implemented WebKit's create/ready-to-show/close signals for proper popup management, eliminating manual WebView creation that bypassed WebKit's internal architecture
602- **Popup behavior configuration**: Added `popup_behavior` config with four modes: `split` (default), `stacked`, `tabbed`, and `windowed` for user control over popup placement
603- **Backend-driven pane mode**: Complete rewrite of pane mode from JavaScript to Go backend with native keyboard handling. Ctrl+P enters mode, x/l/r/d/u/arrows for actions, Escape exits. Blocks all other keys during mode.
604- **Pane mode visual border**: Zellij-style border around workspace root when pane mode is active, replacing old toast notification system. Uses GTK margins with configurable `pane_mode_border_color` (defaults to #FFA500 orange). Window background color shows through margins to create visible border effect
605
606### Changed
607- **Popup architecture refactoring**: Removed ~280 lines of JavaScript window.open interception in favor of WebKit's native popup signals. Popups now follow WebKitGTK's expected lifecycle instead of being intercepted and manually created
608- **GUI bootstrap refactoring**: Extracted 400+ lines of common initialization logic into reusable bootstrap.ts module shared between injected pages and special schemes (homepage, etc.)
609- **Workspace pane mode**: Moved ~450 lines of JavaScript state machine to Go backend for more reliable keyboard handling and eliminated race conditions between webviews
610
611### Fixed
612- **TLS certificate validation restored**: Re-implemented persistent certificate error handling (broken during gotk4 migration)
613  - Interactive three-option dialog: "Go Back", "Proceed Once (Unsafe)", and "Always Accept This Site"
614  - SQLite-based hostname decision storage (hostname-only matching - GIO certificate properties are unstable)
615  - Smart expiration: "Proceed Once" temporary (not stored), "Always Accept" persists for 30 days
616  - Automatic cleanup of expired validations on application startup
617  - **Known issue**: Accepted certificates not pre-loaded into WebKit session on startup - stored decisions only apply when TLS error occurs again
618- **Content blocking restored**: Re-implemented WebKit native ad/tracker blocking (broken during gotk4 migration) using UserContentFilterStore API
619- **Script injection spam**: Fixed 100+ duplicate "Sending color palettes" messages by injecting scripts only in top frame instead of all iframes
620- **Favicon race conditions**: Eliminated duplicate downloads and file handle errors via mutex protection and proper handler registration
621- **Homepage theme switching**: Fixed color palette application for proper light/dark mode transitions
622- **Workspace pane borders**: Hide active pane border when only one pane exists to match Zellij UX
623- Enabled missing WebKitGTK6 features: WebRTC, MediaSource, LocalStorage, WebAudio, MediaStream, Clipboard
624- Cosmetic filter duplicate injection in frames
625- Config file duplicate keys (snake_case/camelCase) by using Viper's SafeWriteConfigAs
626- Config not reading newly created default config file
627- Config writing to disk on every load/reload
628- **Popup SIGSEGV crashes**: Eliminated segmentation violations during popup lifecycle by respecting WebKit's signal-based popup management. Fixes OAuth popup crashes and GTK bloom filter corruption
629- **GTK focus event duplicates**: Added timestamp-based deduplication to prevent multiple focus enter/leave events in the same millisecond from WebKitGTK nested widgets
630- **Popup close behavior**: Fixed app exit when closing popups by excluding them from remaining pane count check
631- **Pane mode border cleanup**: Fixed border persisting after pane splits by saving container reference when applying margins. Ensures proper cleanup even when workspace tree structure changes during split operations
632- **Stacked pane active border**: Fixed active border incorrectly appearing on stacked pane containers instead of individual panes
633- **Stacked pane creation**: Fixed premature Realize() call causing widget lifecycle issues during stack creation
634- **Browser exit on last pane close**: Fixed browser not properly quitting when closing the last webview via Ctrl+P x by calling GTK main loop quit instead of window close
635- **Zoom level persistence restored**: Fixed per-domain zoom settings not being saved to database (broken during gotk4 migration). Added missing `notify::zoom-level` signal connection in setupEventHandlers to properly persist zoom changes
636
637## [0.11.0] - 2025-10-07
638
639### Added
640- **Auto-open omnibox on blank panes**: Omnibox automatically opens when a new pane is created with about:blank, providing immediate search/navigation access
641- **Configurable default zoom**: Added `default_zoom` config (defaults to 1.2/120%). Per-domain zoom still overrides this
642- **Pin/favorite sites**: Pin websites from history or quick access to prioritize them in "Jump back in" section. Uses localStorage persistence with star icons for pin/unpin actions
643- **Zellij-style stacked panes**: Added Ctrl+P → 's' to stack panes instead of splitting, with Alt+Up/Down navigation between stacked panes. Features collapsed page title bars showing  for inactive panes and full WebView interaction for the active pane. Includes GTK4 CSS styling for proper visual feedback
644- **Stacked pane favicons**: Title bars display site favicons with async caching. Click title bars to switch between stacked panes
645- **Color palette configuration**: Light and dark color palettes now configurable in `appearance` config with semantic tokens (background, surface, text, muted, accent, border). Injected as CSS custom properties at document start
646- **Search shortcut badges**: Visual badges in omnibox input showing active shortcut prefix (e.g., "gh:", "npm:") with description labels
647- **Search shortcuts API**: Frontend bridge to fetch search shortcuts from backend `/api/config` endpoint with automatic normalization
648
649### Changed
650- **Terminal-style UI theme**: Monospace fonts (JetBrains Mono, Fira Code), sharp corners (no border-radius), dashed borders, adjusted shadows and spacing throughout omnibox components
651- **History suggestions**: Use favicon from database when available, omit automatic search shortcuts from suggestions (rely on explicit prefix commands)
652- **Search shortcuts defaults**: Updated defaults to include ddg, go, mdn, npm packages while reordering others
653- **Chrome user agent**: Updated to version 141.0.0.0 for better site compatibility
654- **CSS color system**: Removed hardcoded theme colors, now use dynamic CSS custom properties from Go-injected palette
655- **History item layout**: Removed "• domain" from titles, now highlight domain within the full URL using same color as title text
656- **Quick access logic**: Removed 20-item limit, now shows all sites with 2+ visits (pinned sites bypass visit requirement)
657- **History pagination**: Show 15 items initially (up from 10) with "Show N more" button
658- **Homepage layout**: Redesigned with improved visual hierarchy and dynamic color tokens
659- **Favicon handlers**: All webviews now register favicon change handlers for consistent caching across panes
660
661### Fixed
662- **Mobile URL overflow**: Fixed long URLs breaking layout on narrow screens by adding proper width constraints and CSS fixes
663- **GTK shortcut GLib-CRITICAL error**: Fixed NULL string assertion in shortcut callback system
664- **SVG favicon handling**: Skip SVG favicons to prevent conversion errors (no raster conversion dependencies)
665- **Focus management architecture**: Refactored workspace focus system from `active` field to `currentlyFocused` with dedicated FocusManager for improved reliability and consistency across pane operations
666- **Stacked pane focus conflicts**: Fixed focus stealing issues in stacked panes by implementing focus-aware navigation that preserves active pane when spawning siblings
667- **WebView title updates**: Enhanced webview title change handling to properly update stacked pane title bars in addition to database storage
668- **GTK4 widget lifecycle**: Improved widget parenting/unparenting operations with proper GTK4 validation and automatic cleanup to prevent critical warnings
669- **Stacked pane close behavior**: Fixed remaining pane becoming non-interactable (gray background) when closing stacked panes via Ctrl+W or Ctrl+P+X. Added proper widget visibility restoration and focus management during stack-to-regular conversion
670- **Stacked pane title updates**: Fixed collapsed panes not showing current page titles when switching between stacked panes. Now follows Zellij-style layout where hidden panes display their up-to-date page titles in title bars with correct positioning above and below the active pane
671
672## [0.10.0] - 2025-09-24
673
674### Added
675- **Print functionality**: Added Ctrl+Shift+P shortcut to open native print dialogs from any pane. Ctrl+P is blocked at WebKit level to prevent conflicts with pane mode shortcuts
676- **WebKit native favicon detection**: Implemented WebKit's built-in favicon database for automatic favicon detection and URI storage. Enhanced favicon support for all formats (PNG, SVG, ICO) without external dependencies
677
678### Changed
679- **Homepage redesign**: Brutal design with component-scoped styling, dynamic height matching, inline domain-URL layout with fade effects, and tighter spacing
680
681### Fixed
682- **WebView teardown and memory management**: Implemented comprehensive cleanup system to prevent crashes during WebView destruction. Added JavaScript teardown functionality with cleanup handlers for all event listeners, intervals, and global state. Enhanced pane cleanup with proper controller detachment and GTK widget detachment sequencing. Added WebView validity checks before JavaScript evaluation and improved workspace manager pane closing logic with better popup handling
683- **Ctrl+W pane closing**: Fixed Ctrl+W shortcut to properly close active panes including popups. Implemented active WebView detection and proper popup vs regular pane handling via OnWorkspaceMessage for consistent cleanup
684- **WebView script injection segfault**: Fixed segmentation violation when injecting JavaScript into destroyed WebViews during message handling. Added IsDestroyed() safety check to prevent GTK widget corruption
685- **Alt+Arrow workspace navigation**: Fixed Alt+Arrow keys not working for pane navigation after WebView focus changes. Implemented C-level to GTK4 shortcut bridge that ensures workspace navigation works consistently across all panes
686- **Global shortcuts protection**: Fixed window shortcuts (Ctrl+L, Ctrl+F, F12) not working in new panes due to overly aggressive webpage protection. Window shortcuts now properly bubble up to GTK while pane shortcuts remain blocked from webpages. Resolves omnibox and developer tools not responding to keyboard shortcuts in newly created panes
687- **Omnibox keyboard event isolation**: Fixed keyboard event leakage from omnibox to underlying webpages that caused unintended page actions (e.g., typing 's' in omnibox triggering GitHub search). Implemented WebKit-level main-world event blocking that activates when omnibox opens, preventing page JavaScript from receiving keyboard events while preserving native GTK shortcuts (Ctrl+L, Ctrl+F, etc.) and omnibox functionality
688- **Active pane detection**: Replaced complex pane ID abstraction with persistent webview IDs, fixing omnibox unresponsiveness after navigation. Omnibox now works immediately after page navigation without requiring mouse movement
689- **Workspace architecture**: Simplified focus tracking by removing URI change handlers and pane ID injection complexity, improving reliability and reducing codebase by 85 lines
690- **WebView ID propagation**: Added webview ID request/response mechanism for stub builds to ensure JavaScript side knows its webview ID for proper focus validation
691- **Workspace theme integration**: Fixed white borders on inactive panes by implementing dynamic border colors based on GTK theme preference (dark mode: #333333 borders, light mode: #dddddd borders)
692- **GTK window background**: Added theme-aware window and pane background colors to prevent white bleeding through transparent elements
693- **Print dialog window handling**: Fixed GTK window destroy errors during WebView cleanup by only destroying windows when CreateWindow was actually enabled
694- **Modifier key logging noise**: Filtered out Ctrl, Shift, Alt, and Super key presses from accelerator miss logging to reduce console spam
695
696## [0.9.0] - 2025-09-22
697
698### Added
699- **Zellij-style workspace management**: Complete pane splitting system with binary tree layout, focus tracking, and Zellij-inspired keybindings (Ctrl+P for pane mode, arrow keys for splits, 'x' to close)
700- **Multi-pane WebView architecture**: Container-based widget management with proper reparenting, lifecycle handling, and per-pane controllers
701- **Window-level global shortcuts**: Centralized shortcut handling to prevent conflicts between multiple WebView instances
702- **Workspace configuration**: New config section with Zellij controls toggle, pane mode bindings, tab shortcuts, and popup behavior settings
703- **Configurable workspace styling**: Pane border appearance (width, color, transition duration, radius) now customizable via config with proper viewport stability
704- **Popup handling for tiling WM**: Complete popup window support where popups open as workspace panes instead of floating windows, respecting tiling window manager design principles
705- **Universal popup auto-close**: Popup windows (OAuth, window.open(), etc.) automatically close when JavaScript calls window.close(), providing standard browser behavior adapted for workspace panes
706- **Advanced popup deduplication system**: Intelligent duplicate popup prevention with SHA256 fingerprinting and 200ms debounce window to eliminate popup spam
707- **OAuth auto-close integration**: RFC 6749 compliant OAuth callback detection with automatic popup closure for seamless authentication flows
708- **Cross-WebView popup communication**: localStorage-based parent-popup bridge enabling proper `window.opener` functionality in tiling workspace environment
709- **WebView identity tracking**: Unique WebView ID system for precise popup targeting and enhanced debugging capabilities
710
711### Improved
712- WebKit integration now forces GPU compositing by default while still honoring explicit config overrides.
713- Smooth scrolling is enabled (when supported) so wheel and gesture animations feel closer to Chromium/Firefox.
714- Title updates, zoom persistence, and domain zoom lookups are now done off the GTK main thread with results marshalled back safely, eliminating UI hitches during navigation.
715- Added optional DOM-level zoom (enabled by default) to avoid native viewport rescaling; falls back to WebKit zoom if the CSS path fails.
716- DOM zoom now seeds the saved level before the first paint and reuses it during document-start scripts, preventing pages from flashing back to 100%.
717- Native accelerator bridge debounces duplicate GTK key events earlier, so Ctrl±/Ctrl+0 only fires once per physical key press.
718- Omnibox-triggered navigations now reuse the navigation controller, so saved zoom levels are applied before first paint and redundant lookups are avoided.
719- Configuration loading writes the missing `use_dom_zoom` flag into existing config files so DOM zoom defaults persist without manual edits.
720- Omnibox UI now relies on shared Tailwind theme tokens and the injected color-scheme service for light/dark parity.
721- Omnibox overlay now self-heals if hostile pages remove the injected shadow host, ensuring Ctrl/Cmd+L works everywhere.
722- Navigation shortcuts changed from Alt+Arrow to Ctrl/Cmd+Arrow for better workspace compatibility.
723- GUI components now support workspace-aware focus management with pane-specific event handling.
724- **Global zoom shortcuts**: Unified zoom handling at window level (Ctrl+/=/0/-) ensuring zoom applies to currently active pane in multi-pane workspace
725- **Workspace focus management**: Enhanced focus throttling (100ms) and active state tracking to prevent infinite loops and conflicts between panes
726- **Popup management**: Intelligent popup vs tab detection based on window features, with improved auto-close logic for OAuth and login flows
727- **Console logging**: WebView ID context injection for better debugging and log correlation across multiple panes
728
729### Changed
730- **Zoom shortcuts architecture**: Moved from per-WebView registration to centralized window-level handling for consistency with other global shortcuts
731
732## [0.8.0] - 2025-09-17
733
734### Added
735- **GTK color scheme bridge**: Dedicated document-start module keeps WebKit theme in sync with GTK preferences and exposes unified runtime updater
736- **Color scheme build pipeline**: Separate Vite entry produces reusable `color-scheme.js` asset shared between native and injected contexts
737- **Complete Svelte 5 GUI migration**: Omnibox and find components migrated from raw JavaScript to modern Svelte 5 with runes
738- **Tailwind CSS v4 integration**: Unified design system with PostCSS and JIT compilation
739- **TypeScript keyboard service**: Centralized shortcut management with full type safety
740- **Click-anywhere-to-close**: Omnibox closes when clicking outside for better UX
741- **Homepage Svelte 5 component**: New standalone homepage with history display and keyboard shortcuts reference
742- **Page generator system**: Vite plugin for generating dumb:// protocol pages (homepage, config, about) with extensible architecture
743- **History deletion API**: New DELETE endpoint at `/history/delete?id=N` for removing individual history entries
744- **Database migrations**: Embedded migrations now run automatically at startup to keep sqlite schema in sync
745- **Inline CSS type declarations**: Ambient module definitions for raw CSS imports improve TypeScript ergonomics in injected bundles
746- **Global Shadow DOM system**: Unified shadow host utility for component isolation with shared ShadowRoot and CSS reset management
747- **Unified page-world bridge**: Integrated API bridge with event-driven communication between page-world and isolated-world contexts
748
749### Improved
750- **Asset MIME detection**: Expanded scheme handler lookup covers fonts, images, and JSON to prevent incorrect `text/plain` responses
751- **Toast theming**: Runtime theme observer syncs toast styling with the browser's dark mode state for consistent visuals
752- **Shadow host styling**: Injected GUI now adopts Tailwind design tokens inside the shared shadow root with automatic dark-mode mirroring
753- **Omnibox/Find system**: Complete migration from 500-line raw JavaScript to modular Svelte 5 components
754- **Toast notifications**: Migrated from raw JavaScript to Svelte 5 components with proper animations
755- **GUI build pipeline**: Vite-based bundling with hot reload and TypeScript support
756- **Keyboard shortcuts**: Fixed Ctrl+F not working by adding missing 'f' key to keyboard dispatcher
757- **State management**: Proper cleanup between omnibox and find modes prevents state conflicts
758- **Homepage UX**: Enhanced layout with 70/30 flex ratio, compact keyboard shortcuts table, and statistics display
759- **Interactive delete**: History entries show trash icon on hover with smooth fade-out animation on deletion
760- **Top 5 most visited**: New section displaying frequently accessed sites with visit counts
761- **Performance**: Instant shortcut response with pre-mounted DOM elements
762
763### Changed
764- **Homepage icons**: Replaced Lucide dependency with inline SVG/Unicode fallbacks to shrink bundle size while debugging upstream build issues
765- **Major architecture shift**: Removed HTTP API routes in favor of direct WebKit message bridge communication for better performance and reduced complexity
766- **API token support**: Added optional API security configuration with token-based authentication system
767- **Shadow DOM improvements**: Enhanced isolation with WeakSet tracking to prevent duplicate reset injection and global shadow host utility for component sharing
768- **Message handler refactoring**: Unified keyboard shortcut forwarding between native handlers and GUI components with DOM event bridge
769- **Omnibox suggestions**: Native Go-based suggestion computation with search shortcuts and history integration, eliminating HTTP fetch dependencies
770- **Toast styling**: Migrated from Tailwind CSS classes to inline styles within component scope for better Shadow DOM compatibility and isolation
771- **JS to Svelte migration**: Replaced legacy inline injected scripts (see `pkg/webkit/ucm_js_cgo.go.deprecated`) with structured Svelte components mounted via the shared shadow root.
772
773### Fixed
774- **Service worker residue**: Homepage clears stale caches and unregisters old service workers to avoid 404s for legacy `_app` assets
775- **Keyboard debounce**: Native accelerator bridge filters duplicate shortcut events within 120ms for DOM and CGO handlers
776- **Ctrl+F shortcut**: Added missing 'f' key case in keyboard_cgo.go dispatcher
777- **Browser freeze**: Removed infinite loop in mode switching reactive effects
778- **State persistence**: Proper cleanup when switching between Ctrl+L and Ctrl+F modes
779- **Homepage protocol**: Fixed dumb://homepage not working after GUI migration with proper Svelte 5 component and API integration
780- **Omnibox positioning on homepage**: Fixed omnibox stuck in top-left corner by isolating homepage CSS styles and strengthening omnibox positioning with explicit fixed positioning and CSS isolation
781- **Find mode persistence**: Fixed find view persisting after pressing Esc when reopening with Ctrl+L by ensuring toggle() resets mode to 'omnibox'
782- **Favicon display**: Fixed missing favicons in homepage history after Svelte 5 migration by adding FaviconURL field to API response and implementing proper fallback display logic
783- **Homepage API communication**: Migrated from HTTP fetch to WebKit message bridge for all homepage API calls (history, stats, search) with proper callback handling and timeout management
784- **Omnibox accessibility**: Added keyboard navigation support with Tab/Enter activation for suggestion items and proper ARIA attributes for screen readers
785- **Omnibox suggestions race conditions**: Fixed timing issues where suggestions arrived before API was ready by implementing pending suggestions queue and proper event bridging between page-world and isolated-world contexts
786
787## [0.7.0] - 2025-09-14
788
789### Added
790- **Content blocking system**: Native WebKit ad blocking with EasyList integration, cosmetic filtering, and filter cache management
791- **Filter cache purging**: New `--filter-cache/-F` flag in purge command
792- **WebKit debug system**: Comprehensive debugging support with configurable categories for troubleshooting WebKit internal errors
793- **Enhanced error handling**: Robust content filter injection with retry mechanisms and graceful fallbacks
794- **Parallel compilation**: Multi-core GCC compilation support for faster builds
795
796### Improved
797- **Content filter timing**: Optimized script injection timing to prevent interference with WebKit preconnect operations
798- **Anti-breakage scriptlets**: Safer JavaScript modifications that avoid WebKit internal conflicts
799- **Build system**: Added parallel compilation with automatic core detection and success indicators
800- **Persistent TLS certificate validation system**:
801  - **Three-option certificate dialog**: "Go Back", "Proceed Once (Unsafe)", and "Always Accept This Site"
802  - **Database-backed certificate storage**: SQLite-based persistence for user certificate decisions with SHA256 certificate hashing
803  - **Smart decision handling**: Automatic application of stored decisions without repeated prompts
804  - **Temporary vs permanent choices**: "Proceed Once" expires after 24 hours, "Always Accept" persists indefinitely
805  - **Seamless user experience**: No more repetitive certificate warnings for trusted sites
806- **Performance-optimized WebKit memory configuration system**:
807  - **New `WebkitMemoryConfig`** configuration section with performance-focused defaults for faster page loading
808  - **Aggressive caching strategy**: `web_browser` cache model with page cache enabled for instant back/forward navigation
809  - **Balanced memory pressure management**: Conservative (40%), strict (60%), and kill (80%) thresholds optimized for performance vs stability
810  - **Smart garbage collection**: 2-minute JavaScript GC intervals with process recycling after 50 page loads
811  - **Reduced monitoring overhead**: 45-second memory monitoring intervals to minimize performance impact
812  - **Environment variable overrides**: All memory settings configurable via `DUMBER_*` environment variables (`DUMBER_CACHE_MODEL`, `DUMBER_MEMORY_CONSERVATIVE`, etc.)
813- **Early crash handling initialization**: Moved crash handler setup to application entry point for better crash recovery
814
815### Changed
816- **Modernized GTK dialog system**: Migrated from deprecated GTK 4.10 dialog functions to modern `GtkAlertDialog` API
817  - **Future-proof implementation**: Eliminated all deprecation warnings by replacing `gtk_message_dialog_*` and `gtk_dialog_*` functions
818  - **Async-first architecture**: Native async dialog handling with proper event loop integration
819  - **Improved accessibility**: Better screen reader support and GTK4 theme integration
820- **Major main.go refactoring**: Massive code reduction from 1071 lines to 61 lines (~95% reduction)
821  - **Extracted browser application logic** to dedicated `internal/app/browser` package for better separation of concerns
822  - **Streamlined entry point**: Clean main function focusing only on CLI vs GUI mode detection and application bootstrapping
823  - **Improved maintainability**: Modular architecture with clear responsibilities between CLI and browser components
824- **Refactored memory configuration architecture**:
825  - Integrated WebKit memory settings into unified config system with Viper environment variable bindings
826  - Eliminated redundant environment variable parsing in favor of centralized configuration management
827  - Simplified webview initialization with direct config-to-WebKit conversion
828- **Improved CLI logs command description**: Enhanced help text for better user experience
829
830## [0.6.0] - 2025-09-12
831
832### Added
833- **Smart AV1 codec negotiation system for YouTube high-resolution streaming**:
834  - **Resolution-aware MediaCapabilities API reporting**: Intelligent codec capability reporting based on video resolution, enabling YouTube to select optimal codecs for different quality levels
835  - **YouTube format manifest manipulation**: Real-time format list reordering to prioritize AV1 for ≤1080p content while allowing VP9 fallback for higher resolutions
836  - **Graduated codec preference system**: Smart localStorage preference (`2048`) instead of forced AV1 (`8192`), giving YouTube flexibility for optimal codec selection
837  - **4K HDR 60fps AV1 support**: Successfully enables YouTube delivery of premium quality 4K HDR content with AV1 codec, HDR10 (PQ) color space, and BT.2020 wide color gamut
838  - **Configurable AV1 resolution limits**: New `av1_max_resolution` config option with environment variable support (`DUMBER_AV1_MAX_RES`)
839  - **Automatic codec fallback logic**: Seamless VP9 fallback for resolutions where AV1 performance may be suboptimal
840  - **High bitrate streaming support**: Enables premium quality streaming (650+ Mbps) with proper buffer management
841  - Fixes previous limitation where forcing AV1 would cap YouTube playback at 1080p maximum
842- Page refresh functionality with standard keyboard shortcuts:
843  - **Ctrl+R** / **Cmd+R**: Reload current page
844  - **Ctrl+Shift+R** / **Cmd+Shift+R**: Hard reload (bypass cache)
845  - **F5**: Alternative reload key
846  - WebKit integration with proper `webkit_web_view_reload()` and `webkit_web_view_reload_bypass_cache()` calls
847- **Twitch theater mode and fullscreen stability fix**:
848  - **Complete removal of codec interference on Twitch**: Eliminates aggressive codec control that caused theater mode and fullscreen freezing
849  - **Native Twitch codec selection**: Allows Twitch to handle codec negotiation without browser intervention
850  - Fixes theater mode freeze and fullscreen black screen issues on Twitch
851
852### Fixed
853- Zoom level toast no longer shows on every page navigation within the same domain:
854  - Added smart detection to differentiate user-initiated vs programmatic zoom changes
855  - Toast now only appears when manually adjusting zoom or entering a new domain
856  - Prevents annoying notifications during regular browsing within the same site
857- Links with `target="_blank"` now load in current window instead of being ignored:
858  - Added WebKit `create` signal handler to intercept new window requests
859  - Redirects popup/new tab links to current window for seamless single-window browsing
860  - Maintains user experience consistency in tab-less browser architecture
861
862## [0.5.0] - 2025-09-12
863
864### Added
865- Hardware video acceleration with automatic GPU detection:
866  - Multi-vendor GPU detection (AMD, NVIDIA, Intel) using glxinfo, lspci, and sysfs
867  - Automatic VA-API driver selection (radeonsi for AMD, vdpau for NVIDIA, iHD for Intel)
868  - WebKitGTK integration with GStreamer hardware acceleration backends
869  - Environment variable configuration support (LIBVA_DRIVER_NAME, GST_VAAPI_ALL_DRIVERS)
870  - Legacy VA-API fallback mode for compatibility with older systems
871  - Video decoding acceleration for H.264, HEVC, VP9, and AV1 codecs
872  - Significantly reduced CPU usage during video streaming (Twitch, YouTube, etc.)
873  - Smart conflict prevention between legacy and modern VA-API implementations
874- TLS certificate error handling with user confirmation dialog:
875  - Comprehensive certificate information display (subject, issuer, validity dates)
876  - Interactive warning dialog for untrusted certificate authorities
877  - Certificate exception management with per-host persistence
878  - Manual load triggering after user accepts certificate exceptions
879  - Proper integration with WebKitGTK 6.0 network session API
880- Zoom level toast notifications:
881  - Real-time zoom level display with format: "Zoom level: ±X% (Y%)"
882  - Smart debouncing to prevent notification spam during rapid zoom changes
883  - Automatic cleanup of stuck or colliding toast messages
884  - 150ms debounce timer with 2-second display duration
885  - Emergency cleanup function for orphaned toast elements
886- Comprehensive XDG-compliant logging system:
887  - Complete application output capture (Go logs, fmt prints, WebKit C logs)
888  - XDG Base Directory specification compliance (`~/.local/state/dumber/logs/`)
889  - Automatic log rotation with size/age-based cleanup and compression
890  - WebKit CGO log capture with GLib log handler integration
891  - CLI log management commands (`dumber logs list`, `logs tail`, `logs clean`)
892  - File-only logging for cache operations to prevent dmenu interference
893  - Multi-output support with timestamped, tagged log entries
894  - Configurable log levels, formats (text/JSON), and retention policies
895
896### Fixed
897- WebView background set to black to improve user experience during page loads
898- Multiple linting issues and code quality improvements (reduced from 211 to ~150 issues)
899- Omnibox responsive scaling and layout issues:
900  - Fixed over-aggressive viewport scaling that made omnibox disproportionately large at high zoom levels
901  - Resolved input field overflow extending beyond container boundaries
902  - Improved box-sizing model to prevent layout issues
903  - Added conditional separator display (hidden when no search results)
904  - Omnibox now scales proportionally with webpage content across all zoom levels
905- Dmenu history favicon display:
906  - Complete favicon caching system for fuzzel/dmenu integration with real website icons
907  - ICO file support using go-ico library for perfect Windows icon conversion to PNG
908  - Smart brightness detection and color inversion for dark theme visibility
909  - All cached favicons normalized to consistent 32x32 PNG format for uniform display
910  - Anti-aliasing preservation during color inversion to prevent edge noise and pixelation
911  - Asynchronous favicon downloading and caching with 7-day freshness and 30-day cleanup
912  - Fuzzel icon protocol integration (`\0icon\x1f<path>`) for native icon display
913  - Favicon URLs extracted from webpage metadata and stored in database during navigation
914  - Fallback system removed to ensure consistent sizing - shows real favicons or no icon
915  - XDG Base Directory compliance for favicon cache storage
916
917## [0.4.0] - 2025-09-10
918
919### Added
920- High-performance fuzzy cache system for dmenu history:
921  - Binary serialization with memory-mapped files for zero-copy access
922  - Trigram indexing (3-character sequences) for fast candidate filtering  
923  - Prefix trie (compressed tree structure) for prefix matching
924  - Pre-sorted entry indices for O(1) top entries retrieval
925  - Smart cache invalidation with filesystem persistence and background refresh
926  - Comprehensive fuzzy matching algorithms: Jaro-Winkler similarity, Levenshtein distance, tokenized matching
927  - Weighted scoring system combining URL, title, recency, and visit count scores
928  - XDG Base Directory Specification compliance (cache stored in state directory)
929  - Atomic operations for concurrent access control
930  - Dependency injection using interfaces and gomock for testing
931- Purge command for cleaning up dumber data and cache files:
932  - Selective purging with flags: `--database`, `--history-cache`, `--browser-cache`, `--browser-data`, `--state`, `--config`
933  - Clear distinction between history cache (dmenu fuzzy search) and browser cache (WebKit)
934  - Browser data includes cookies, localStorage, sessionStorage
935  - Confirmation prompt with `--force` flag to skip
936  - Targets all data locations: SQLite database, WebKit cache/data, dmenu fuzzy cache, configuration files
937- Ctrl+Shift+C keyboard shortcut to copy current URL to clipboard:
938  - Cross-platform clipboard support with wl-copy (Wayland) and xclip (X11) fallback
939  - Reusable toast notification system for user feedback
940  - Injectable JavaScript component for consistent styling across all websites
941  - Native backend integration for reliable clipboard access
942
943### Changed
944- Dmenu performance dramatically improved: 200ms → 4ms (98% faster)
945- GetTopEntries optimized from O(n log n) to O(1) using pre-sorted indices
946- Cache build time reduced to ~300μs for typical history datasets
947
948### Fixed
949- Dark theme detection now properly reads GNOME desktop interface color-scheme setting (`org.gnome.desktop.interface color-scheme`) instead of only checking `gtk-application-prefer-dark-theme`
950- Eliminated O(n log n) sorting bottleneck on every dmenu call
951- Memory-efficient compact entry storage with minimal footprint
952- Concurrent cache access with proper read/write locking
953- Process no longer hangs when closing window with Cmd+Q or window close button - implemented proper GTK4 `close-request` signal handling and OS signal handling for graceful shutdown
954
955## [0.3.0] - 2025-01-11
956
957### Added
958- WebKit memory controls (opt‑in):
959  - Env vars to tune memory/perf trade‑offs without code changes:
960    - `DUMBER_CACHE_MODEL`, `DUMBER_ENABLE_PAGE_CACHE`
961    - `DUMBER_ENABLE_MEMORY_MONITORING`, `DUMBER_MEMORY_LIMIT_MB`, `DUMBER_MEMORY_POLL_INTERVAL`
962    - `DUMBER_MEMORY_CONSERVATIVE`, `DUMBER_MEMORY_STRICT`, `DUMBER_MEMORY_KILL`
963    - `DUMBER_GC_INTERVAL`, `DUMBER_RECYCLE_THRESHOLD`
964  - Version‑guarded CGO wrappers for memory pressure and GC hooks; safe no‑ops on unsupported WebKitGTK builds.
965 - Find in page (Ctrl/Cmd+F):
966   - Omnibox refactored into a reusable component with dedicated "find" mode.
967   - Highlighting: yellow for all matches; active match in orange for clarity.
968   - Match list with context (right side stops at nearest punctuation: . , ; : -).
969   - Navigation UX:
970     - ArrowUp/Down move selection and scroll the overlay list (page scroll disabled while open).
971     - Enter centers on the active match and closes; Shift+Enter goes to previous; Alt+Enter centers without closing.
972     - Hover focuses input and selects list items; click outside closes the overlay.
973     - Faded overlay with subtle blur when reviewing matches; opacity restores on input focus/typing.
974   - Programmatic API: `OpenFind(initial)`, `FindQuery(q)`, `CloseFind()` on `WebView`.
975
976### Changed
977- Performance‑first defaults retained:
978  - Cache model set to “WebBrowser”, page cache enabled, DevTools available.
979  - No implicit memory pressure or GC enabled by default; all memory tuning is opt‑in.
980
981### Removed
982- Deprecated offline app‑cache calls eliminated (no‑ops) to avoid warnings and brittle builds.
983
984### Fixed
985- Homepage Recent History layout:
986  - Show single-line entries as “{Title} – {Domain} – {URL}”.
987  - Truncate long URLs with a gradient fade; prevent horizontal overflow.
988  - Adjusted styling so URL is darker for readability.
989- Search shortcuts and config interop:
990  - Backend SearchShortcut now serializes `url`/`description` with JSON tags.
991  - Frontend normalizes field casing and extracts base URLs, handling `%s` and `{query}` templates.
992  - Omnibox shortcut parsing now URL-encodes queries and supports `%s` placeholders.
993- Input and navigation reliability (GTK4/WebKitGTK 6):
994  - Capture-phase key controller to ensure accelerators fire consistently.
995  - Do not consume normal left/right clicks; only mouse buttons 8/9 trigger back/forward.
996  - Added Alt+ArrowLeft/Right navigation and enabled two-finger swipe back/forward when supported.
997  - Added Ctrl+scroll zoom in/out; refined accelerator matching so Ctrl− works across layouts.
998  - Removed layout-specific hacks; added diagnostic logs for raw minus key events.
999- Zoom persistence:
1000  - Added WebView zoom-changed hook; save per-domain zoom to SQLite on every change.
1001  - Log on successful save: “saved X.XX for domain.tld” and on load: “loaded X.XX for domain.tld”.
1002  - Load and log initial zoom level on startup and on every navigation.
1003- Build/dev ergonomics:
1004  - Makefile loads `.env.local`; supports overriding `GOMODCACHE`, `GOCACHE`, `GOTMPDIR` for sandboxed builds.
1005 - WebKit CGO hardening and API compatibility:
1006   - Apply memory pressure settings to `WebKitNetworkSession` (correct signature) when enabled.
1007   - Guarded C wrappers remove deprecation warnings across header variants; builds succeed on WebKitGTK 6.
1008
1009## [0.2.0] - 2025-09-10
1010
1011### Added
1012- WebKitGTK 6 (GTK4) migration for the built‑in browser window:
1013  - WebView constructed via `g_object_new(WEBKIT_TYPE_WEB_VIEW, …)` with a fresh `WebKitUserContentManager`.
1014  - `WebKitNetworkSession` with persistent cookies (SQLite) and cache directories.
1015- Native UCM messaging restored via `script-message-received::dumber` (JSCValue*), removing the JS fallback bridge.
1016- Rendering mode controls:
1017  - CLI flag `--rendering-mode=auto|gpu|cpu` and `DUMBER_RENDERING_MODE` env.
1018  - In‑app status endpoint `dumb://homepage/api/rendering/status`.
1019- Native zoom shortcuts at the WebKit layer (Ctrl/Cmd+=, +, −, 0) and GTK4 input controllers for keyboard/mouse.
1020- AZERTY keyboard fix: treat underscore as minus for zoom‑out.
1021- Runtime theme synchronization: watch GTK `gtk-application-prefer-dark-theme` and update page color‑scheme live.
1022- Makefile target `check-webkit` to print `pkg-config` versions of GTK4/WebKitGTK 6.0/JSC 6.0.
1023- Documentation updates:
1024  - README now targets WebKitGTK 6 (GTK4) and lists GStreamer package requirements for Arch and Debian/Ubuntu.
1025  - CLAUDE notes updated with migration status, GPU/Vulkan path, runtime theme sync, and persistence.
1026
1027### Changed
1028- Build flags and includes now target `webkitgtk-6.0`, `gtk4`, and `javascriptcoregtk-6.0`.
1029- GTK4 APIs for windowing and event handling (GtkEventController, GtkGestureClick) replace GTK3/GdkEvent paths.
1030
1031### Removed
1032- Legacy WebKit2GTK constructors and container APIs.
1033- JavaScript fallback for UCM message bridging.
1034
1035### Fixed
1036- Header/enum compatibility for hardware acceleration policy and cookie policy across WebKit header variants.
1037- Linker error for `on_theme_changed` and gpointer usage in signal connections.
1038- Crashy paths mitigated by default “media safe” startup (can be disabled via `DUMBER_MEDIA_SAFE=0`).
1039
1040### Notes
1041- GPU rendering path leverages GTK4’s renderer (Vulkan/OpenGL). Mode `auto` uses GPU when available and falls back gracefully to CPU.
1042- WebKitGTK relies on GStreamer; install recommended packages for audio/video (see README).
1043
1044## [0.1.0] - 2025-09-09
1045
1046### Added
1047- Initial project scaffolding, build system, and dependencies.
1048- Unified CLI + GUI architecture with search shortcuts and fuzzy parsing.
1049- Wails v3‑alpha browser integration (early phase).
1050- Global keyboard controls with script injection (zoom/devtools, etc.).
1051- Native WebKit2GTK backend migration:
1052  - Custom `dumb://` scheme and `/api` endpoints: `/config`, `/history/recent`, `/history/search`, `/history/stats`.
1053  - UserContentManager omnibox injection and theme initialization.
1054  - Persistent WebsiteDataManager with cookies.sqlite; per‑domain zoom and title persistence.
1055  - Keyboard/mouse accelerators (including mouse back/forward); debounced triggers.
1056  - Homepage switched to first‑party API fetches; removed @wailsio/runtime usage.
1057- Documentation and licensing: README enhancements and LICENSE added.
1058
1059### Changed
1060- Replaced Wails runtime with native WebKit2GTK CGO bindings and homepage API.
1061- Improved asset resolution and logging for the `dumb://homepage` scheme.
1062
1063### Fixed
1064- Eliminated duplicate accelerator triggers via debouncing.
1065- Corrected asset resolution and URL normalization in scheme handler.

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