Tabs opened from links on AppKit can be created before their URL is
loaded. That left background open-url tabs with the location field as
their stored responder, so switching to them later restored address-bar
focus instead of web content focus.
Track each tab's preferred responder, restore it when AppKit makes
the tab key, and mark page-backed open-url tabs to prefer the web view.
Blank new-tab pages still keep the location field focused.
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.
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.
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.
We initially create the search field with no frame or size constraints.
The causes AppKit to log verbose warnings at start up. Here, we set an
intrinsic size initially, which becomes overridden once the window has
an actual size.
When an element is fullscreened, we now hide the application menu and
location bar. The user can hover over the top of the window to make
them show. When fullscreen is requested for the application directly
from the UI, we do not hide the location bar. This matches Safari's
behavior.
When the user focuses the address bar and presses Escape, the original
URL is now restored. Previously, the address bar would show whatever
text the user had typed, or be empty if they had cleared it.
Clicking outside the address bar keeps the typed text (matching
Chrome/Firefox behavior) — only Escape restores the original URL.
Fixes https://github.com/LadybirdBrowser/ladybird/issues/7264
When a new tab is created, the location bar should automatically
receive keyboard focus so users can immediately start typing a URL.
However, the onURLChange callback was stealing focus back to the
web view when loading the new tab page.
This fix:
1. Calls focusLocationToolbarItem when activating a new tab
2. Prevents onURLChange from stealing focus when loading the new
tab page URL
Fixes#1512
When trying to build Ladybird on macOS 14.3, it fails with the error:
```
No visible @interface for 'NSToolbar' declares the selector
'setAllowsDisplayModeCustomization:' (clang arc_may_not_respond)
```
This is caused by macOS < 15 not having the @interface definition for
in NSToolbar for setAllowsUserCustomization:(BOOL).
By dynamically calling the method, we can avoid the error altogether.
This lets us avoid each UI needing to handle link clicks directly, and
lets actions stored in LibWebView avoid awkwardly going through the link
click callbacks to open URLs.
On macOS Tahoe, it is now recommended to show menu item icons. We use
system symbols for this now. Symbols do not have constant variable names
and must be found via the SF Symbols app.
The symbols chosen here were to match Safari as close as possible.
By migrating the debug menu to LibWebView, the AppKit and Qt UIs are now
in sync - the AppKit UI was previously missing some actions.
Further, this inadvertently fixes bugs around applying debug settings to
new web views, especially across site-isolated processes. We were
previously not applying settings appropriately; this now "just works" in
the LibWebView infra.
This migrates all duplicated context menus from the UIs to LibWebView.
The context menu actions are now largely handled directly in LibWebView,
with some UI-specific callbacks added to display e.g. confirmation
dialogs.
Actions that only ever apply to a specific web view are stored on the
ViewImplementation itself. Actions that need to be dynamically applied
to the active web view are stored on the Application.
When we manually enter a new URL and hit enter, the web view gets
focused. But when the URL changes for other reasons, such as starting
Ladybird with a URL argument, the location field was still focused.
This is to prepare for custom search engines. If we use AK::format, it
would be trivial for a user (or bad actor) to come up with a template
search engine URL that ultimately crashes the browser due to internal
assertions in AK::format. For example:
https://example.com/crash={1}
Rather than coming up with a complicated pre-format validator, let's
just not use AK::format. Custom URLs will signify their template query
parameters with "%s". So we can do the same with our built-in engines.
When it comes time to format the URL, we will do a simple string
replacement.
This removes the old autoplay allowlist file in favor of the new site
setting. We still support the command-line flag to enable autoplay
globally, as this is needed for WPT.
This adds a WebView::Settings class to own persistent browser settings.
In this first pass, it now owns the new tab page URL and search engine
settings.
For simplicitly, we currently use a JSON format for these settings. They
are stored alongside the cookie database. As of this commit, the saved
JSON will have the form:
{
"newTabPageURL": "about:blank",
"searchEngine": {
"name": "Google"
}
}
(The search engine is an object to allow room for a future patch to
implement custom search engine URLs.)
For Qt, this replaces the management of these particular settings in the
Qt settings UI. We will have an internal browser page to control these
settings instead. In the future, we will want to port all settings to
this new class. We will also want to allow UI-specific settings (such as
whether the hamburger menu is displayed in Qt).