Move the remaining call sites that constructed StringBuilder in UTF-16
mode over to Utf16StringBuilder or explicit UTF-8 to UTF-16 conversion.
Teach FormatBuilder to target Utf16StringBuilder directly so formatted
Utf16String construction no longer needs StringBuilder's UTF-16 mode.
Update the Utf16String tests to cover Utf16StringBuilder adoption and
clear behavior directly.
Use Qt's platform shortcut bindings for back and forward navigation
instead of only installing the primary binding. On macOS this keeps
Command-[ and Command-] while also accepting Command-Left and
Command-Right.
Disable Qt quit-on-last-window behavior on macOS and install an
application-level menu so useful commands remain available after the
last browser window closes.
Reuse shared application actions and menus for Settings, Bookmarks,
History, Help, and global appearance controls. Centralize window-aware
commands such as New Tab, New Window, Open File, Open Location, and
Reopen Recently Closed so the browser window and windowless app menu
use the same behavior. Keep the location editor focused for new blank
windows after the native window has been activated.
Disable AppKit's native resize handling for client-side decorated macOS
windows so AppKit does not show a resize cursor for points it will not
deliver to Ladybird. Reapply this after Qt creates the native surface,
since Qt may restore the resizable style mask during Cocoa window setup.
Handle the resize gesture in BrowserWindow instead, with thin side edges
and a slightly larger corner target that avoids the rounded corner
cutouts.
Move the active macOS web selection color into LibWebView so AppKit
and Qt use the same value when building the WebContent system palette.
Qt now also asks AppKit for inactive selection colors on macOS, matching
the AppKit frontend while leaving other Qt platforms on QPalette.
macOS can be configured to drag windows with Cmd+Ctrl+click via
NSWindowShouldDragOnGesture. AppKit does not see its usual titlebar
drag path for our frameless Qt windows, so handle the native mouse
down in the AppKit event filter when that default is enabled.
Forward the event to performWindowDragWithEvent before Qt turns it into
normal widget input. This restores the system gesture without changing
behavior for users who have not enabled the default.
After web content has focus on macOS, its native QRhiWidget can
remain the AppKit first responder even after Qt focuses the location
edit.
Make the top-level Qt content view first responder before focusing the
location edit so keyboard input returns to chrome.
Allow highlighted rows that are not valid inline completions to preview
their full suggestion text in the location editor. This covers history
entries matched by title or URL substring, while ordinary typing stays
on the inline-only path.
Keep automatic inline autocomplete text when Escape closes the popup.
Escape still cancels hovered or keyboard-selected preview text.
Remember which query produced the visible autocomplete popup rows, and
only activate selected rows when the visible popup still belongs to the
current query.
When Enter is pressed while fresh results are pending, rerun
autocomplete for the current query and activate once matching results
arrive. Ignore late completions after focus leaves. Avoid canceling
autocomplete while its completion callback activates the pending result.
Open the autocomplete popup when the location editor is focused
through the browser action, such as Cmd+L. Keep the selected URL text
intact by skipping inline completion for that explicit popup request.
Position the native popup again after its first show so Qt has realized
the tooltip window before the final placement, avoiding the brief macOS
Y-coordinate jump.
The autoplay setting was binary and its default blocked all media,
including muted video, leaving sites that rely on muted autoplay
visibly broken. Replace it with a tri-state user-agent autoplay
policy (allow audio and video, block audio, or block audio and video)
defaulting to allowing only inaudible media to autoplay.
This is enforced through the media element's "allowed to play" check,
so unmuting a muted autoplay or calling `play()` cannot slip audio
past the policy; audible playback is permitted once the document has
been activated by the user. The policy lives in a dedicated
AutoplaySettings consulted from HTMLMediaElement instead of the
Permissions Policy "allowed to use feature" check it was previously
conflated with.
Selecting text without custom ::selection styling changed the
foreground color of the selected content. This was especially visible
for links, where the text changed color but the underline did not.
The default selection style supplied both a selection background and a
foreground color from the palette or HighlightText system color. That
made ordinary selections behave as if the page had explicitly styled
::selection color.
Only provide a default selection background, so selected content keeps
its own foreground color unless CSS overrides it. Remove the now-unused
SelectionText palette role.
Previously, the "View History" action always opened a new tab. We now
switch to an existing `about:history` tab when one exists in the active
window and fall back to opening a new tab otherwise.
Show native history menus when users right-click or long-press
the back and forward toolbar buttons. Populate entries from the
UI-process session history mirror, using saved history titles and
favicons when available and falling back to the URL and globe icon
otherwise.
Share the Qt base64 PNG icon helper so bookmark menus and navigation
history menus render stored favicons consistently.
Use the LibWebView history mirror to preserve traversable session
history across WebContent process swaps. WebContent reports snapshots to
the UI process, and new renderers can be seeded from the mirror.
Browser back and forward now resolve through the UI-owned used history
steps. WebContent still runs the spec traversal path when the current
renderer has enough matching state to do so.
Handle canceled and no-op UI navigations without leaving speculative
history entries or pending WebDriver waits behind. Preserve traversal
precheck state across synchronous IPC shutdown, and avoid overwriting a
restored target entry's persisted scroll state before the document has
adopted that entry.
Hide the native Vulkan child window whenever the current paintable
cannot be imported and rendered through the dmabuf path. This lets the
existing QWidget paint path remain visible for shareable bitmap frames
instead of covering it with a clear-only Vulkan frame.
Make the address autocomplete popup a non-activating top-level window.
The Linux Vulkan web view is a native child window, so ordinary widgets
that overlap it can be obscured by native stacking. Keeping the popup as
a top-level tooltip-style window lets it appear above web content while
preserving keyboard focus in the location edit.
Use a native QVulkanWindow child for Linux DMABUF presentation instead
of making WebContentView itself a QRhiWidget. This keeps BrowserWindow
on Qt's normal QWidget backing store path while sampling compositor
DMABUF backing stores directly in Vulkan.
Keep WebContentView's paintEvent as fallback for builds without Vulkan
DMABUF support and for cases where the Vulkan instance or window cannot
be created. Set an explicit Vulkan API version before creating the
shared QVulkanInstance so validation layers do not reject Qt defaults.
Show a delayed preview popup when hovering background tabs. Build the
thumbnail from the cached front or backup WebContent bitmap so chrome
does not need a fresh screenshot request or WebContent repaint on hover.
Tie the popup to the tab hover lifecycle and hide it on current-tab
hovers, tab presses, drags, layout changes, and tab strip exits.
When using client-side decorations, the window was a flat rectangle
with no outline, so its edge disappeared against similarly colored
backgrounds. Paint a 1px border in a new chrome window outline color
and reserve a matching 1px contents margin so child widgets do not
cover it.
The outline color matches chrome_border() in dark mode, but is darker
in light mode, since the window edge has to hold up against arbitrary
backdrops behind the window rather than our own chrome surfaces.
The border is skipped when the window is maximized or fullscreen, and
on macOS, where frameless windows already get rounded corners and a
native shadow.
Mark the search field with a dynamic property when a find-in-page query
has zero matches, and let the chrome stylesheet show a red-tinted
background. Clear the state immediately for empty searches.
This currently just contains a menu item to open about:history. But in
the future, we can add a list of recently closed / recently visited
pages as well.
This adds a WebUI to view the local browsing history, with controls to
search and delete entries. The APIs used to search history are paginated
to prevent excessive query sizes.
We no longer support more than one event loop per process as of 02b2053
so this was causing a crash when taking a screenshot. We now spin the
main event loop until a "done" flag is set.
We no longer support more than one event loop per thread as of 02b2053
so this was causing a crash when pasting. We now spin the main event
loop until a "done" flag is set.
Fixes#9928
Add an explicit initializer for process-lifetime event loops and use it
for browser, helper service, and utility main loops. This preserves weak
event loop references for cross-thread users while making main thread
loop lifetime independent of normal program teardown.
When collapsed vertical tabs are expanded on hover, the collapse check
used QCursor::pos() against the vertical tabs rect. On some platforms,
after the cursor leaves the browser window entirely, that position can
remain at the last in-window coordinate, so the tabs stay expanded.
When no URLs are provided on the command line, LibWebView actually adds
about:newtab to the initial URL list. The only time this list is empty
is when we open a popup window.
We currently use LibWebView's Application as the entry point to learn
about the bookmarks bar being shown/hidden, and propagate that through
virtual methods. At the time this was added, AppKit's Tab window and
Qt's BrowserWindow did not have a settings observer. They do now, so
let's skip a couple of middle-men.
For AppKit, we change the settings observer to just (weakly) store the
Tab instance so that we don't have to add callback functions for each
setting.
Hide fullscreen chrome at the TabWidget level instead of hiding the
current tab's toolbar child directly. This lets the toolbar container
and reserved verticaltabs space stop contributing to layout while
fullscreen content is shown.
Also keep the exit fullscreen button above native web content on macOS
and center it using the fullscreen screen geometry rather than a
potentially stale parent widget size.
Track whether a keydown should perform text insertion separately from
the delivered code point. Native frontends and text-oriented test paths
can now mark events that came from text input, while shortcut-style key
events keep Alt-modified default insertion suppressed.
This lets macOS Option-generated text such as Option+A and Option+Space
insert into editable controls without making plain Alt shortcuts insert
their base character. Add coverage for Alt text, Ctrl+Alt text,
separator text, Ctrl-only shortcuts, and Alt shortcuts.
While typing in the location bar, intermediate autocomplete updates
caused the highlighted suggestion to flicker.
These updates trigger on each keystroke and lead to unnecessary
selection changes.
Skip intermediate popup updates while it is visible and rely on final
results to update both suggestions and selection atomically.
While typing in the location bar, intermediate autocomplete updates
caused the highlighted suggestion to flicker.
These updates trigger on each keystroke and lead to unnecessary
selection changes.
Skip intermediate popup updates while it is visible and rely on final
results to update both suggestions and selection atomically.
Anchor the vertical tab sidebar to the full toolbar container height so
it starts below the bookmarks bar when that bar is visible. This keeps
the navigation toolbar and bookmarks bar unified, with the separator at
the content edge.
Update the sidebar geometry whenever the toolbar container resizes so
toggling the bookmarks bar moves the vertical tab chrome immediately.
When Return is pressed while the autocomplete popup is visible, submit
the location edit directly instead of falling through to QLineEdit's
default key handling after closing the popup. This keeps the omnibox
responsive to Return after chrome layout changes rebuild nearby widgets.
Make the autocomplete popup a native child widget on macOS so it can
receive mouse events while overlapping the native QRhiWidget web content
view. Keep it parented to the top-level browser widget so showing the
popup does not steal keyboard focus from the address bar.
Make hovering the location editor use the same fill and border as its
normal state in both light and dark mode. Focus still uses the focused
border, with a subtle focused fill retained for dark mode.