Add GTK4/libadwaita build instructions alongside Qt.
Add Documentation/GtkFrontend.md with GTK-specific coding style
rules and a manual test checklist.
Add the complete browser UI:
- BrowserWindow: AdwHeaderBar with navigation, tab management via
AdwTabView/AdwTabBar, find-in-page, fullscreen, zoom, D-Bus
single-instance with open/activate handlers
- Tab: WebContentView lifecycle, ViewImplementation callbacks for
title, URL, favicon, cursor, tooltips, dialogs, window management
- LadybirdBrowserWindow: GtkBuilder template widget with toolbar,
tab bar, find bar, devtools banner, and hamburger menu
- LadybirdLocationEntry: URL entry with autocomplete, domain
highlighting, and security icon
- Menu: GAction-based context menus and application menu with
keyboard accelerators
- Dialogs: JS alert/confirm/prompt (AdwAlertDialog), color picker,
file picker, select dropdown, download save dialog, toast
- GtkBuilder .ui resources for browser window, location entry
completions, and list popovers
Updates Application and main.cpp to create browser windows and
handle D-Bus activation from remote instances.
Add the core infrastructure for the GTK frontend:
- EventLoopImplementationGtk: GLib main loop integration with
Core::EventLoop, timers, notifiers, and signal handling
- GObjectPtr RAII wrapper for GObject lifecycle management
- Application subclass with AdwApplication and D-Bus registration
- Minimal main.cpp entry point
The application starts and runs the event loop but does not yet
open any windows.
Add GTK as a possible GUI framework alongside Qt on Linux. When the gtk
or qt vcpkg manifest feature is selected, the corresponding framework
dependencies are pulled in automatically.
Enable the Wayland and Vulkan backends, add shaderc for GLSL
compilation, and drop the X11 backend to avoid requiring X11
development libraries on Wayland-only systems.
These overlay ports allow vcpkg to build Wayland libraries from source
when the force-build feature is enabled along with the
X_VCPKG_FORCE_VCPKG_WAYLAND_LIBRARIES triplet variable.
pre-commit sets GIT_DIR to an absolute path pointing at the main
repository. When check-flatpak.py shells out to run git inside
Build/vcpkg, this causes git to look at the wrong repo, failing to find
packages in the vcpkg baseline. Clear GIT_DIR from the subprocess
environment so git operates on Build/vcpkg's own repo.
While this does add some extra cases into the function, this is
effectively a rename to better match how we were effectively already
doing this. Rename the function and link it to the right location in
the specification. Doing this also allows us to drop the FIXME as it
makes it clear what this hardcoded list is meant to achieve.
sort_matching_rules() was calling Selector::specificity() inside the
sort comparator. MatchingRule already caches the specificity value
at rule insertion time, so use that directly instead.
Make the _string, _fly_string, _utf16, and _utf16_fly_string UDL
operators constexpr, with a fast path for short (<= 7 byte) ASCII
literals that folds directly into an inline ShortString. Previously,
every "foo"_fly_string (and friends) involved an out-of-line call
into the string factory, even though the result is entirely known
at compile time.
The clean-up in 71c457c36e turns out to
not be enough for all cases. So be more thorough and clear up anything
that could affect the next test.
In particular this fixes flakiness in `Text/input/select-text.html` but
hopefully it solves the issue for good!
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.
Restore the active tab's remembered focus widget when switching tabs.
If the tab has no remembered focused child, fall back to the web
view so keyboard scrolling works immediately in tabs opened from
links.
This keeps the existing new-tab location bar behavior while making
background-opened pages respond to keyboard inputs as soon as they
are activated.
Previously, when applying `text-overflow: ellipsis`, line box fragments
after the ellipsis point were removed from the line box. This
invalidated fragment indices stored in `containing_line_box_fragment`,
causing an out-of-bounds access in `LayoutState::commit()` when
resolving atomic inline positions.
Instead of removing fragments, mark them as hidden. This preserves
index stability while preventing hidden fragments from being displayed.
IntersectionObserver updates already iterate over each observer and its
observation targets. We then looked the same target and observer pair up
again through Element's registered observer list just to read and write
previousThresholdIndex and previousIsIntersecting.
Store that mutable state with the observer-side observation target
instead. The element-side list now only keeps strong observer
references for lifetime management and unobserve/disconnect.
This deviates from the spec's storage model, so document the difference
next to the preserved spec comments.
In other engines, the [CEReactions] extended attribute on an attribute
only applies to the setter steps. Attribute getters never fire custom
element reactions, yet our bindings generator was still pushing a new
element queue onto the custom element reactions stack on entry and
popping + invoking it on return for every single getter call on a
[CEReactions] attribute.
The UI process only reads these pixels to composite them - all writes
happen in WebContent via Vulkan. Some dmabuf exporters refuse writable
mappings on re-imported fds even when the Vulkan memory is
`HOST_VISIBLE`.
With numerators or denominators approaching NumericLimits<u32>::max(),
we could overflow in the sum of the remainder and the rounding
contribution. Instead, divide them separately and sum them afterward.
Overflow could happen in the multiplication of the remainder seconds
back into time units. Instead, take a remainder of the time units from
the division and use that for the nanoseconds.
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.
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.
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.
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.
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.
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.
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.
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.