LibWebView+UI: Add browsing history and rich address bar autocomplete#8933
LibWebView+UI: Add browsing history and rich address bar autocomplete#8933awesomekling wants to merge 10 commits intoLadybirdBrowser:masterfrom
Conversation
98775f7 to
591d9dd
Compare
trflynn89
left a comment
There was a problem hiding this comment.
Super cool :)
I went through this a bit quickly. Some of it kinda hard to review where things are added to the history store in one commit and then removed or reshaped in the next commit, but 🤷♂️
Thinking out loud, I'm wondering if our monolith Ladybird.db makes sense long term, or if we want to split it out into Cookies.db, History.db, etc.? (This can be decided after merging)
|
A couple of things related SQLite and comparison with other browsers:
Not suggesting all of these should be fixed in this PR, but the current implementation will be too slow at some point when the history grows. |
Add a HistoryStore abstraction with transient and persisted backends, normalize recorded URLs, and skip non-browsable schemes. Cover lookup and persistence in TestHistoryStore so history-driven features can share one backend.
Teach LibWebView autocomplete to query HistoryStore before falling back to remote engines and move the wiring out of the AppKit frontend. Refine matching so scheme and www. boilerplate do not dominate results, short title and substring queries stay quiet, and history tracing can explain what the ranking code is doing.
Record visits as soon as a page produces useful metadata such as a title or favicon so pages that never finish loading still become autocomplete candidates. Store favicons in the history schema from the start instead of introducing an upgrade path inside this series, and cover persisted metadata behavior in TestHistoryStore.
Replace the frontend-facing Vector<String> flow with structured AutocompleteSuggestion objects carrying source, section, title, and favicon metadata. Build merged history and literal-URL rows in LibWebView, deduplicate equivalent URL suggestions, move the autocomplete URL helpers out of URL.h, and update the history and URL tests around the new model.
Replace the AppKit popover because it becomes key and steals focus from the location field while suggestions are visible. Use a borderless child window anchored to the toolbar item instead, and dismiss it on resize or focus changes so the browser chrome stays predictable.
Render AutocompleteSuggestion rows with section headers, favicons, titles, and secondary text in the child-window popup instead of just plain strings. Move the AppKit popup and inline completion onto the shared suggestion model, and share the base64 PNG decoding helper with the application menu icon loading path.
Route the existing Clear Browsing Data dialog through HistoryStore's time-range deletion path as well. That makes the Settings action remove visited pages from persisted history and from history-backed address bar suggestions instead of only touching cache and site data. Add a history checkbox to the dialog, thread its state through the Settings WebUI message, and cover remove_entries_accessed_since() for both transient and persisted stores in TestHistoryStore.
Some navigations report the same URL more than once through WebContentClient::did_change_url(). Forwarding those duplicate updates into the frontend turned an internal no-op into visible UI churn, including location bar resets and AppKit focus stealing. Treat repeated URL notifications as a no-op inside LibWebView so frontends only react to real URL changes.
Replace the old QCompleter-based popup with a custom list that renders AutocompleteSuggestion rows with titles/URLs/section headers/favicons. Parent the popup inside the window so it does not steal focus, route keyboard and mouse activation through WebView::Autocomplete, and add inline completion with backspace suppression and top-row selection.
Synthesize an extra AutocompleteSuggestion at the top of the Search Suggestions section whenever there is a configured search engine and the typed query is not URL-shaped. Use the query as the row's primary text, carry a "Search with <engine>" subtitle, and render that subtitle in the AppKit and Qt popups so the explicit search fallback stays visible and readable even when history fills the list.
Moved this to History.db right away. It just makes sense :) |
All good points that we can and should address! ... but let's do it separately 😅 |
This branch adds a SQLite-backed HistoryStore in LibWebView that persists visited pages along with their title, favicon, visit count, and last-visit time. WebContentClient now records navigations, title changes, and favicon updates into the store, and a "Clear browsing history" action is wired up in the Privacy settings page.
The address bar autocomplete pipeline has been reworked so that suggestions are structured rows, history hits, a "Search with" entry, and plain completions, each carrying a title, URL, and subtitle rather than a flat string.
Both the Qt and AppKit UIs render the new rich rows with favicons and subtitles.
This is all pretty simple and barebones! There's plenty more data we could track and plenty more UI we could build on top of it, but we gotta start somewhere. :)