Commit graph

163 commits

Author SHA1 Message Date
Andreas Kling
202159be18 UI: Share macOS web selection color
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.
2026-06-22 01:13:53 +02:00
Jelle Raaijmakers
d819152b4e LibGfx+LibWeb: Preserve text color for selections
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.
2026-06-18 22:43:26 +02:00
Timothy Flynn
1a99bdad29 LibWebView+UI: Add a small history application menu
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.
2026-06-10 20:27:36 +02:00
Timothy Flynn
f72a18095d LibWebView+UI: Remove the clear-everything history store API
This was only used by the AppKit UI's history menu. We have more fine-
grained control over deleting history in about:settings#privacy.
2026-06-10 20:27:36 +02:00
sideshowbarker
a82c7939d9 LibWeb+UI/AppKit: Implement macOS IME support
This makes macOS IME input in web content work as expected.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9712
2026-06-08 10:23:14 +09:00
Andreas Kling
83b293e4f2 LibCore: Keep main event loops alive
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.
2026-06-05 09:18:39 +02:00
Timothy Flynn
7fc71e563b LibWebView+UI: Reduce boilerplate to update the bookmarks bar display
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.
2026-06-03 18:14:12 -04:00
Andreas Kling
d9d8c5ce89 LibWeb: Allow Option-generated text insertion
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.
2026-06-03 13:51:32 +02:00
Christian Frey
a8cb27ddd0 UI/AppKit: Prevent autocomplete highlight flicker while typing
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.
2026-06-03 13:50:01 +02:00
Aliaksandr Kalenik
758688a7a1 LibWebView+UI: Replay display metadata after Compositor restart
Compositor recovery recreated contexts and replayed viewport sizes,
but it left the restarted helper with the default display metadata. A
recovered context could fall back to a 60 Hz timer instead of the
window's current display id and refresh rate until the frontend later
observed a screen change.

Store the display id in the shared view state, alongside the existing
maximum frame rate, and replay both values while restoring view state
after reconnect.
2026-05-31 20:07:58 +01:00
Andreas Kling
3f45f8cce0 UI: Shorten web URLs in location fields
Show web URLs without their scheme, a leading host www., or the
root slash while the location field is not being edited. Restore the
fully serialized URL while editing so the original scheme is preserved,
but keep mouse focus stable until release so clicks target the visible
text.

Keep the domain emphasis for shortened Qt location text by deriving the
highlight ranges from the serialized URL and remapping them to the
visible display form. Special URLs like about, data, and file remain
unchanged. Add LibWebView coverage for the shared display helper used by
both UI frontends.
2026-05-31 19:20:59 +02:00
Andreas Kling
8e8bced900 UI/AppKit: Reserve browser key equivalents
Let AppKit menu dispatch handle browser-owned key equivalents before the
web view forwards them to WebContent. This keeps commands like opening a
new tab, closing the current tab, quitting, and focusing the location
field in the browser chrome even when WebContent is the first responder.
2026-05-31 15:41:27 +02:00
Sam Atkins
e5e3099ce7 UI: Route node picker input through WebView
Picker input starts in each platform UI, while protocol state lives in
LibWebView. Route movement, primary clicks, Escape, and leave events
through the WebView picker API so each frontend drives the same hit-test
and picker-event path.

The selected click is consumed because picker mode uses it to choose an
element for DevTools rather than activate page content.

AppKit routes normal mouse input through WebViewBridge, which converts
view points to device pixels before forwarding to LibWeb. Picker input
bypasses that enqueue path, so apply the same scaling before requesting
a picker hit test.
2026-05-29 17:01:34 +01:00
Timothy Flynn
11d80c122e LibWebView+UI: Add an option to toggle a menu's visibility
This requires setting up an observer interface akin to menu actions.
2026-05-29 10:46:27 -04:00
Timothy Flynn
a1b545e179 UI/AppKit: Add a function to create NSMenuItem menus
This abstraction is needed for an upcoming commit to make the UI layer
react to changes in menu visibility. It turned out to be a nice cleanup
in any case.
2026-05-29 10:46:27 -04:00
Andreas Kling
3746fbf7f4 LibWeb: Use themed text selection colors
Use the page palette for default selection backgrounds instead of a
hardcoded blue color. Tint opaque selection backgrounds before painting.
Selected images stay visible through the overlay.

Use SelectionText for default selected text and HighlightText. Authored
::selection colors still take precedence. On macOS, use a light
translucent color matching other engines.

Update selection and system-color baselines for the themed colors. Add
macOS-specific screenshot baselines for tests whose expectations depend
on system colors.
2026-05-29 13:49:51 +02:00
Aliaksandr Kalenik
6598fb838d LibWebView+Compositor+UI: Send display metadata to Compositor
The browser process forwards the maximum frame rate to WebContent, but
the compositor process had no copy of that display timing metadata or
the display identity needed by compositor-local vsync.

Add one compositor control IPC message carrying the optional display ID
and refresh rate together, and store both values on each compositor
context.
2026-05-28 23:12:35 +01:00
Andreas Kling
43b9cfe5a9 LibWebView: Avoid white initial web view fills in dark mode
Seed the page background fallback from the platform color scheme before
WebContent has painted. Update the same fallback when the platform theme
changes, and when the preferred color scheme is forced through the debug
menu, so unpainted web view areas use the matching Canvas color.
2026-05-27 20:57:38 +02:00
Timothy Flynn
adf5e0a226 LibWeb+LibWebView+UI: Use the system selection text for primary pasting
Commit 218d82cb65 added support for
pasting text with the middle mouse button. But primary pasting is
actually meant to interact with the "selection" clipboard, not the
text clipboard.
2026-05-27 13:33:44 -04:00
Andreas Kling
e0e8460c47 UI: Update page visibility when switching tabs
Send hidden and visible system visibility updates from explicit tab
switch paths instead of relying only on widget show and hide events. Tab
containers can keep inactive web views mapped, which leaves documents
visible from WebContent's perspective and lets animated images keep
running in background tabs.

Use AppKit window occlusion state rather than the app-wide active tab.
That keeps still-visible background windows in the visible document
state. Avoid resending duplicate visibility updates from
ViewImplementation so existing widget visibility notifications remain
harmless.
2026-05-27 18:44:42 +02:00
Aliaksandr Kalenik
9ab311507e LibWeb+UI: Synthesize ctrl-wheel events for pinches
Trackpad pinches applied directly as visual viewport zoom, so pages
could not observe the gesture or cancel the browser default. Canvas
apps such as maps expect the ctrl-wheel path instead.
2026-05-27 12:53:08 +02:00
Aliaksandr Kalenik
baecb14472 UI/AppKit: Normalize pinch magnification updates
NSMagnificationGestureRecognizer exposes magnification as an accumulated
value for the current gesture. Ladybird kept its own previous value in
WebViewBridge and emitted the residual delta when the gesture ended, so
the Web input pipeline did not receive the same per-update shape as the
native changed events.

Reset the recognizer's magnification accumulator after changed updates
and skip begin/end states. This keeps the AppKit side responsible for
delivering concrete scale changes and removes the bridge pinch state.
2026-05-27 12:53:08 +02:00
Andreas Kling
42f89bb679 LibWebView: Fast-close pages without beforeunload prompts
Track whether WebContent still needs a beforeunload check and let the
frontends immediately remove a tab or window when no prompt can be
shown. WebContent still receives the close request so pagehide, unload,
and cleanup steps can run.

When the visible view is removed immediately, keep detached ownership of
the WebContent page until it reports that the top-level traversable
closed. If no acknowledgement arrives, release detached ownership and
ask ProcessManager to shut down the unused WebContent process.
2026-05-26 20:40:25 +02:00
Andreas Kling
8be96396d9 LibWebView: Use page background color while resizing
Notify the UI process with the solid canvas background color recorded
for the top-level document. This is the Canvas system color with the
effective document background composited over it, matching the color
used before normal painting.

Store that color on the view and use it when AppKit, Qt, and Gtk need
to fill areas exposed while an older bitmap is still on screen during a
window resize.
2026-05-24 23:41:41 +02:00
Andreas Kling
82b270a154 UI: Add WebContent PID debug preference
Register debug.process.show_web_content_process_id and use it to append
the active WebContent process ID to tab titles and tab tooltips in the
Qt, Gtk, and AppKit frontends.

Keep the stored page title unchanged so toggling the preference can
refresh each tab without waiting for a new title update.
2026-05-24 13:11:17 +02:00
Timothy Flynn
f0d7e28f55 LibWeb+LibWebView+UI: Move SelectedFile factory to LibWebView
This factory is only used by the UI. An upcoming commit will make it
depend on LibFileSystem. LibWeb currently does not link LibFileSystem,
and doing so would push LibWeb in the wrong direction (we should be
doing less file IO in LibWeb, not more).
2026-05-20 21:09:22 +02:00
Andreas Kling
31a9878223 UI/AppKit: Add New Window menu action
Open the configured new tab page in a separate AppKit window from
the File menu, matching the existing Qt action.
2026-05-20 19:31:07 +02:00
Andreas Kling
ad1b4ad76e UI: Focus web views after location bar navigation
Move keyboard focus to the web view when the user commits the
location field. Relying on URL-change callbacks is unreliable because
ViewImplementation::load() stores the requested URL before WebContent
reports it, so same-URL reports are suppressed before frontends can
perform their focus handoff.

Keep the new-tab page behavior unchanged: creating a blank tab still
focuses the location field until the user starts a navigation.
2026-05-20 15:04:58 +02:00
Andreas Kling
9f8d4fdb3b UI: Mirror loading state in tab icons
Show visible tab icons as loading while the focused location field
keeps its existing page-level loading state. Cache the favicon under the
spinner so each tab restores its page icon when loading finishes.

Reuse the Qt spinner drawing for the location field and tab strip, and
draw the AppKit spinner into the attributed tab title.
2026-05-20 09:37:33 +02:00
Andreas Kling
0a70dadfb1 UI: Show page loading state in the location field
Use the leading icon in the location field as a contextual page
indicator. While a page is loading, the field shows an indeterminate
activity indicator. Once loading finishes, it shows the page favicon
when available and falls back to the generic page icon where the toolkit
has one.

Keep the GTK implementation aligned with the other frontends by using
that slot only for loading and favicon state, without a separate
security icon.

This keeps single-tab windows from losing all visual feedback when the
tab bar is hidden, without adding a fake progress bar.
2026-05-20 09:37:33 +02:00
jeetsh4h
44476de9c5 UI+LibWebView: Implement "Open Link in New Window" 2026-05-13 05:00:50 -05:00
Andreas Kling
9f35827aa0 LibWeb: Use double precision for wheel scroll deltas
Wheel deltas were truncated to int at the platform input boundary,
which dropped the sub-pixel tail of trackpad momentum scrolls. Each
NSEvent's scrollingDeltaY arrived as a CGFloat, got cast to int, and
flowed through IPC, EventHandler, and PaintableBox::scroll_by as int,
losing fractional information that never came back.

Widen Web::MouseEvent::wheel_delta_{x,y} to double and propagate
through Page, EventHandler, Paintable, PaintableBox, and the AppKit,
Qt, and GTK input paths.
2026-05-13 11:00:59 +02:00
Andreas Kling
49f694ea01 UI: Increase mouse wheel scroll step from 24 to 40 pixels
Other engines converge on roughly 40 pixels per line as the per-line
step for discrete mouse wheel input (Chrome's kWheelDelta of 120 over
3 lines, WebKit's Scrollbar::pixelsPerLineStep of 40, Chrome's macOS
kScrollbarPixelsPerCocoaTick of 40). At a step of 24 we were scrolling
about 60% as far per tick as Chrome on the same input, which made the
browser feel sluggish under a regular wheel.

Bumping the constant to 40 in the Qt, Gtk, and AppKit frontends puts
us at 120 pixels per discrete tick on Linux (3 lines * 40 pixels) and
aligns the macOS imprecise-scroll multiplier with WebKit and Chrome.
High-precision (trackpad) input is unaffected on all platforms, since
those paths use pixel deltas directly without applying a multiplier.
2026-05-12 23:30:19 +02:00
Christian Frey
b50b7a41d7 UI/AppKit: Fix autocomplete row clipping using visible scroll view width
Autocomplete rows were sized using the table view bounds instead of the
visible scroll view width, which caused the rounded selection highlight
to be clipped on the right edge.
2026-05-11 10:23:20 -04:00
R-Goc
02bb892d7a LibThreading/LibSync: Split out sync primitives
This commit splits out synchronization primitives from LibThreading into
LibSync. This is because LibThreading depends on LibCore, while LibCore
needs the synchronization primitives from LibThreading. This worked
while they were header only, but when I tried to add an implementation
file it ran into the circular dependency. To abstract away the pthread
implementation using cpp files is necessary so the synchronization
primitives were moved to a separate library.
2026-05-08 18:58:35 -05:00
Timothy Flynn
b221d7fe8b LibWeb+LibWebView+WebContent+UI: Add an action to cut text 2026-05-07 09:13:06 -04:00
Luke Wilde
5d38e37a53 UI/AppKit: Add missing AutocompleteRowModel text field initializer 2026-04-25 08:47:15 +02:00
Timothy Flynn
fdbdb0ecd2 LibWebView+UI: Show an error page when we cannot sanitize a URL
Previously, if search was disabled, entering non-URL text would just
silently drop the search query (and on Qt, we would reload the current
URL). We now detect that the query did not result in a navigation and
load an error page instead, which directs the user to enable search.
2026-04-24 20:17:23 +02:00
Andreas Kling
71d92c7298 UI/AppKit: Restore focus when activating a tab
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.
2026-04-17 08:06:24 +02:00
Andreas Kling
586da4e610 LibWebView: Add a "Search with <engine>" autocomplete row
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.
2026-04-16 21:01:28 +02:00
Andreas Kling
1802a05bc2 UI/AppKit: Show rich autocomplete suggestion rows
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.
2026-04-16 21:01:28 +02:00
Andreas Kling
4121b7c0d0 UI/AppKit: Show autocomplete in a child window
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.
2026-04-16 21:01:28 +02:00
Andreas Kling
fe2cab9270 LibWebView: Add history-backed location autocomplete
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.
2026-04-16 21:01:28 +02:00
Timothy Flynn
b544e42809 LibWebView+UI: Add an about:bookmarks page to manage bookmarks
This page renders the bookmarks as a tree and hook context menu events
up to the UI's bookmarks bar context menus to allow editing bookmarks.
Users can also drag-and-drop bookmark items around.
2026-04-09 10:08:06 -04:00
Aliaksandr Kalenik
75af441bff Everywhere: Replace SharedBackingStore with Gfx::SharedImage
Generalize the backing store sharing abstraction into SharedImage, which
represents shared GPU memory independently of Skia and can be used to
share memory between different processes or different GPU contexts.
2026-04-09 01:18:59 +02:00
Timothy Flynn
22dc7808ae UI/AppKit: Handle cmd+left mouse clicks on bookmarks 2026-04-04 10:23:06 -04:00
Timothy Flynn
f69ed86da6 UI/AppKit: Rename a couple bookmarks bar fields to match Qt
AppKit doesn't need the bookmarks bar reorganization that Qt needed to
handle more mouse events. But let's rename these member fields to match
what they are now called in Qt.
2026-04-04 10:23:06 -04:00
Timothy Flynn
ef4ff5d490 LibWebView+UI: Centralize option to treat file:// URLs as non-opaque 2026-04-02 10:21:15 +02:00
Timothy Flynn
e23a894c2a UI/AppKit: Integrate bookmark context menus into the bookmarks bar 2026-04-01 04:57:28 +02:00
Timothy Flynn
81c2426b03 UI/AppKit: Create custom popup views for bookmarks bar folders
Unfortunately, the NSMenu-based bookmarks implementation cannot support
context menus within arbitrary folders. The NSMenu consumes the right-
click events during its own menu tracking, and we are not able to see
those events from our interface.

This patch replaces the NSMenu for folders with a custom NSPopup. This
implementation makes it much easier to handle context menus.
2026-04-01 04:57:28 +02:00