Commit graph

483 commits

Author SHA1 Message Date
Tim Ledbetter
91cd6e85c9 UI/Qt: Use parent maximization state when detaching to a new window 2026-05-26 09:07:57 +02:00
Tim Ledbetter
ee3960e425 UI/Qt: Detach dragged tabs dropped outside any tab bar to a new window
Previously, a tab would only detach into a new window when dropped
outside the source window entirely. Dropping a tab onto the content
area of any browser window would instead silently move it to the end of
that window's tab bar.

TabWidget now rejects tab drag events outside its tab bar row, and the
detach condition checks the tab bar row bounds rather than the full
window geometry. This means dropping a tab anywhere that is not a tab
bar row opens a new window at the cursor position.
2026-05-26 09:07:57 +02:00
Andreas Kling
5e42dd0e26 UI/Qt: Keep chrome style refreshes coalesced
Keep the pending chrome style refresh marker set while the deferred
refresh runs. Applying the refreshed stylesheet can synchronously
deliver palette/style change events, and clearing the marker first lets
those self-induced events enqueue another immediate refresh.

This prevents the Qt chrome from spinning through repeated stylesheet
updates and repainting the location field shadow at idle.
2026-05-26 02:03:43 +02:00
Andreas Kling
7a4a633d04 UI/Qt+WebContent: Refresh theme colors live
Refresh Qt chrome palettes from the current color scheme when the
application palette changes. Recompute autocomplete and location field
colors and repaint WebContent immediately so theme changes do not
require another interaction or restart.
2026-05-26 01:18:51 +02:00
Andreas Kling
3adeed9581 UI/Qt: Polish browser chrome appearance
Refine the material colors, tab integration, toolbar spacing, and
custom glyphs used by the Qt browser chrome. Keep the visual density
compact while making the controls feel clearer and less toolkit-like.
Mark the window opaque and show resize cursors for frameless chrome.
2026-05-26 01:18:51 +02:00
Andreas Kling
6aeec196f0 UI/Qt: Support dragging tabs between windows
Allow custom Qt tabs to be reordered, detached, and reparented to
other browser windows while preserving the existing tab state. Draw a
full-tab drag preview and keep tab drags from being interpreted as
frameless window moves.
2026-05-26 01:18:51 +02:00
Andreas Kling
328d89f3c1 UI/Qt: Draw custom browser window chrome
Add shared chrome styling helpers and use them to paint the Linux
browser tab strip and surrounding toolbar widgets. Make the browser
window frameless on Qt so the tabs, toolbar, and window controls can
share one integrated chrome surface.
2026-05-26 01:18:51 +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
Andreas Kling
5b324718ec LibWebView: Add JSON-backed config variables
Add a small registry for config variables backed by JsonValue defaults.
Persist values under configVariables and expose the registry through the
Advanced tab in about:settings so every key remains visible and
filterable.

Use the default JsonValue type for validation instead of maintaining a
parallel type enum.
2026-05-24 13:11:17 +02:00
Andreas Kling
96bad93bb2 LibWeb: Use adblock-rust in ContentBlocker
Replace the local substring matcher with the adblock-rust engine exposed
through the dedicated content blocker Rust FFI. Keep the previous engine
when a replacement list cannot be parsed.

Pass shared list buffers directly into Rust instead of building a
duplicate C++ vector of lines first. Generate cosmetic CSS through the
Rust matcher, including generic class and id selectors collected from
shadow-including descendants.

Keep a supplemental index for generic cosmetic selector-list rules.
adblock-rust indexes these rules under the first class or id token only,
so also key them by later simple class and id selectors in the list.

Update ContentBlocker coverage for rule options, exceptions, third-party
checks, blob and file URLs, invalid list replacement, filtering toggles,
cosmetic CSS, and generic selector-list cosmetics.
2026-05-24 08:16:46 +02:00
Aliaksandr Kalenik
bfc9bf80d9 Compositor+LibWebView+WebContent: Scaffold opt-in Compositor process
The compositor is moving into a dedicated helper process. That requires
a process to launch, channels for Browser and WebContent to talk to it
over, and client proxies on each side. Land all of that as an inert
scaffold first, gated behind --enable-compositor-process, so the default
rendering path is unchanged and later commits can fill in the protocol,
the service-side state, and the runtime switch against a stable target.
2026-05-22 19:50:42 +01:00
Andreas Kling
46e1a08742 LibWeb: Rename ContentFilter to ContentBlocker
Rename the local content blocking implementation and its tests from
ContentFilter to ContentBlocker while keeping the existing substring
matcher backend and behavior.

Update the WebContent IPC method, WebView option names, debug toggle,
and default config file name to use content blocker terminology.
2026-05-21 21:16:56 +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
b6b13e3bbd UI/Qt: Left-align browser tab titles
Use a small proxy style for the tab label control so QTabBar still
owns tab layout, scrolling, buttons, dragging, and native tab shapes.
Only the text draw flags change to use left alignment.
2026-05-20 09:37:44 +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
Andreas Kling
8a1f855ce8 UI/Qt: Remove collect garbage shortcut
Leave the debug menu action available without binding Ctrl+Shift+G,
which conflicts with the standard find previous shortcut.
2026-05-19 11:22:58 +02:00
Sam Atkins
f489a8e1d0 UI/Qt: Copy window size and maximized state for new windows
Create new windows with the size of the previously active window, and
maximized if it was maximized. This matches the behaviour of other
browsers, and solves an annoying issue where new windows would always
be tiny.

Application::new_window() now takes a WindowConfiguration struct that
lets you specify the position, size, and maximized-ness of the window.
All previous callers of new_window() now use this instead of modifying
the window state afterwards.

WindowConfiguration is slightly awkwardly broken up into individual x/y
and width/height fields instead of a position and a size, for the sake
of compatibility with HTML::WebViewHints.
2026-05-13 11:04:20 +01:00
Sam Atkins
f0cb7d9a6f UI/Qt: Add functionality for reopening recently-closed tabs
Record when we close a tab, and map Ctrl+Shift+T to an action that opens
the most recently closed one.
2026-05-13 11:03:41 +01: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
Shehab Ahmed
f6a009e757 UI/Qt: Add a tooltip for the close tab button 2026-05-10 10:45:11 -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
Aliaksandr Kalenik
f8640d813a LibGfx+LibWeb: Make DecodedImageFrame a value type
DecodedImageFrame only wraps a ref-counted Bitmap and color-space
metadata. The frame object itself does not provide shared mutable
state or lifetime ownership beyond those members, so ref-counting it
adds an unnecessary layer of indirection.
2026-05-07 16:08:13 +02:00
Timothy Flynn
b221d7fe8b LibWeb+LibWebView+WebContent+UI: Add an action to cut text 2026-05-07 09:13:06 -04:00
Vanand Gasparyan
4668e7ed11 UI/Qt: Make the zoom buttton width flexible to fit the text 2026-05-06 08:25:23 +02:00
Undefine
b9fec5edbf Meta: Rename and merge some lagom_* and ladybird_*
We had both {lagom,ladybird}_test and {lagom,ladybird}_lib, now both
are just one helper. Also rename all other lagom_* helpers to be
ladybird_*.
2026-05-05 22:08:24 +02:00
Undefine
1d83e8c896 Meta: Move all remaining dependency checks to check_for_dependencies
This also allows us to get rid of a couple of files that were meant
for dependency specific checks.
2026-05-05 22:08:24 +02:00
Aliaksandr Kalenik
40f2abb7fe LibGfx+LibWeb: Add DecodedImageFrame
Decoded image data should not continue to traffic in ImmutableBitmap now
that the bitmap wrapper is being retired. Introduce DecodedImageFrame as
the paintable decoded-image unit and store a Bitmap plus ColorSpace in
it directly.

Thread the new frame type through decoded image data, display-list
image commands, filters, canvas drawImage, patterns, WebGL texture
upload, and CSS/SVG image consumers. ImmutableBitmap remains only at
the legacy boundaries that still need it, such as HTML video snapshots
and callers that explicitly ask for a bitmap snapshot.

This keeps color-space ownership with the decoded frame while making
the expensive or legacy ImmutableBitmap path explicit at the few call
sites that still need it.
2026-05-05 14:39:17 -05:00
rgret-dev
19e74815ed UI/Gtk: Support keypad buttons for zoom actions
The Qt UI supports this so GTK should have it, too :^)
2026-05-03 17:08:34 +02:00
Johan Dahlin
1454e90c93 Meta: Add vcpkg overlay port for pdf.js 5.6.205 2026-04-30 07:46:12 +02:00
Johan Dahlin
70b74d3f17 UI/Gtk: Fix wheel scroll position on Wayland
GDK4 scroll events do not carry reliable pointer coordinates on Wayland
(gdk_event_get_position returns INT_MIN). Track the last known pointer
position from the motion controller and use it when building the wheel
event, matching the approach used by WebKit GTK.

This fixes mouse-wheel scrolling and scrollbar interaction in pages
with overflow containers such as the pdf.js viewer.
2026-04-27 17:54:24 -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
Timothy Flynn
06796f5f7f LibURL+LibWeb+LibWebView: Convert about:version to a proper WebUI
Passing the browser command line and executable path to every WebContent
process just in case we load about:version always felt a bit weird. We
now use the WebUI framework to load this information on demand.
2026-04-21 06:59:11 -04:00
Undefine
61c9e819bb Meta: Replace the Android BuildLagomTools.sh script with Python code
There weren't many changes required to integrate it with ladybird.py
and that seems much cleaner.
2026-04-20 16:41:29 -06:00
Timothy Flynn
66cc1ef20b Meta: Use find_compiler.sh in fuzzer builder script
In commit b9c6263408, I had forgotten we
had this wrapper script to handle the eval magic for us. We just need
to forward the --clang-only argument to the underlying python script.
2026-04-20 13:17:06 -04:00
Timothy Flynn
dfeb1e6b98 UI/Qt: Adjust color of autocomplete title and header rows
The previous color was a bit difficult to read.
2026-04-17 18:50:59 +02:00
Johan Dahlin
0a00a5d61a UI/Gtk: Add browser window, tabs, menus, and dialogs
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.
2026-04-17 11:17:56 -04:00
Johan Dahlin
2573aff090 UI/Gtk: Add input events and WebContentView
Add the web content rendering surface and input handling:
- Events: GDK keyboard, mouse, and scroll event
  translation to Web::KeyEvent/MouseEvent
- WebContentView: ViewImplementation backed by
  GdkMemoryTextureBuilder with incremental update hints,
  enqueue_native_event helpers for mouse/key events
- LadybirdWebView: Custom GtkWidget with focus, key,
  click, motion, and scroll controllers
- Builder.h: Typed GtkBuilder object lookup helper
2026-04-17 11:17:56 -04:00
Johan Dahlin
e8be4a88d9 UI/Gtk: Add GLib event loop integration and application entry point
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.
2026-04-17 11:17:56 -04: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
1572429541 UI/Qt: Restore focus when activating a tab
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.
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
bb9f789eae UI/Qt: Show rich, history-backed address bar autocomplete
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.
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
CalebC48
c35c29993a UI/Qt: Pass new tab page URL when creating a new window 2026-04-15 15:12:01 -04:00
Timothy Flynn
79893b9cef LibWeb+LibWebView+WebContent: Add a setting to control autoscrolling 2026-04-13 13:01:45 -04:00
Andreas Kling
2ca7dfa649 LibJS: Move bytecode interpreter state to VM
The bytecode interpreter only needed the running execution context,
but still threaded a separate Interpreter object through both the C++
and asm entry points. Move that state and the bytecode execution
helpers onto VM instead, and teach the asm generator and slow paths to
use VM directly.
2026-04-13 18:29:43 +02:00
ayeteadoe
e3c2393d96 UI/Qt: Implement register_process for Qt Windows event loop
Qt does not use IOCP's in their underlying Windows event loop
implementation; however, QWinEventNotifier allows us to register a wait
on a process handle that has SYNCHRONIZE access rights. This means an
event will be signalled when that process terminates which emits the
QWinEventNotifier::activated signal.

Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
2026-04-12 16:08:07 +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
Timothy Flynn
cd76622452 UI/Qt: Close all open bookmark menus when the bookmarks change
Qt will leave any existing menu open, which may be stale. We already do
the same in AppKit.
2026-04-09 10:08:06 -04:00
Timothy Flynn
6bf2279dfe Base: Extract some about:settings CSS classes to a common file
We will re-use the card classes in about:bookmarks.
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
0b36c867f9 UI/Qt: Handle middle and ctrl+left mouse clicks on bookmarks 2026-04-04 10:23:06 -04:00
Timothy Flynn
6e75c40233 UI/Qt: Reorganize bookmark bar mouse event handling a bit
No functional change. This is just to make it simpler to add handling of
middle and ctrl+left mouse clicks.
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
Jonathan
bbb6653c4f UI/Qt: Add Ctrl+Tab and Ctrl+Shift+Tab for tab navigation
In addition to Ctrl+PageDown and Ctrl+PageUp, also support Ctrl+Tab and
Ctrl+Shift+Tab to switch between browser tabs. This is the common
behavior in other browsers.
2026-04-01 11:53:15 +01: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
Timothy Flynn
d8fb0ed59a UI/Qt: Integrate bookmark context menus into the bookmarks bar 2026-04-01 04:57:28 +02:00
Undefine
829d112327 Meta: Move Lagom CMakeLists stuff to the top level CMakeLists
This allows us to get rid of the annoying Build/.../Lagom directory
and helps to deduplicate a bunch of logic while also drastically
simplifying everything.
2026-03-29 13:59:11 -06:00
Undefine
fbbcc73fea Meta: Refactor the way the GUI framework is picked
This is largely based of off the work done by Andrew Kaster in #5918.
Having this toggle makes much more sense, especially if there will be
more UIs in the future.

Co-authored-by: Andrew Kaster <andrew@ladybird.org>
2026-03-29 13:59:11 -06:00
Undefine
4eda70a4f1 Meta: Move the Qt6 dependency stuff to the Qt UI CMake
Instead of this awkward place let's move it to the Qt UI CMakeLists,
which makes much more sense for stuff like this.
2026-03-29 13:59:11 -06:00
Timothy Flynn
2b9cce8f62 UI/Qt: Create a bookmarks application menu and toolbar 2026-03-24 12:04:50 -04:00
Timothy Flynn
a0d9c6f0a9 UI/AppKit: Create a bookmarks application menu and toolbar 2026-03-24 12:04:50 -04:00
Timothy Flynn
a4ed90a482 UI/AppKit: Ensure application action observers are removed
In AppKit, we were never calling Action::remove_observer.
2026-03-24 12:04:50 -04:00
Timothy Flynn
afcc0fdbb0 LibWebView+UI: Add option to render an icon for application submenus 2026-03-24 12:04:50 -04:00
Timothy Flynn
0a3e2196c9 UI/Qt: Store the TabWidget parent directly on TabBar
The parent owner of the TabBar changes as it is added to layout objects
within other widgets. So the parent we set at the beginning is no longer
the parent when we right-click on a tab. We now just store the TabWidget
directly.
2026-03-22 18:36:36 -04:00
Timothy Flynn
7e3bb9d984 UI/Qt: Replace QTabWidget with a custom TabWidget composition
QTabWidget's built-in tab bar management made it difficult to properly
position the new tab button, and caused visual artifacts with the
separator line across themes.

Replace QTabWidget with a custom TabWidget that places a QTabBar
alongside an explicit new tab button. This us gives full control over
the tab bar row layout.
2026-03-18 18:39:53 -04:00
Timothy Flynn
7b78d3786e UI/AppKit: Set an initial intrinsic size for the location search field
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.
2026-03-18 18:04:01 -04:00
Zaggy1024
ac69815740 Everywhere: Add an is_fullscreen parameter to set_viewport
This will be used by the UIs to notify WebContent when fullscreen for
content is entered or exited.
2026-03-17 18:58:37 -05:00
Zaggy1024
1ceb012100 UI/AppKit: Don't call fully_exit_fullscreen() if WebContent initiated
This is a no-op on the WebContent side if it asked the UI to exit
fullscreen.
2026-03-17 18:58:37 -05:00
Zaggy1024
d22bd7334a UI/Qt: Don't trigger fully_exit_fullscreen() when WebContent initiated
If WebContent requested a fullscreen exit, then this is a no-op anyway.
2026-03-17 18:58:37 -05:00
Timothy Flynn
ebaad09b1b UI/Qt: Correctly adjust hamburger menu positioning on first open
The HamburgerMenu subclass overrode showEvent() to reposition the menu
using move() after QMenu::popup() had already shown it. On the first
open, rect().width() could return a stale value, causing the menu to
appear detached from the button and truncated to a single item. The
move() call also bypassed Qt's screen boundary adjustments.

Instead, we can replace the HamburgerMenu with a normal QMenu, and use a
custom HamburgerButton class for the menu's tool button. In this class,
we override mousePressEvent() to call popup() with the correct right-
aligned position before the menu is shown. This lets Qt manage sizing
and screen boundaries correctly.
2026-03-17 07:12:05 -04:00
Zaggy1024
07cf09a0f2 UI/AppKit+LibWeb: Handle the Ctrl+click context menu in EventHandler
Changing Ctrl+click to a secondary click is incorrect. It prevents
sites from using Ctrl+click themselves. Instead, just maybe open the
context menu in mousedown for primary clicks with Ctrl pressed.

Fixes the autofire shortcut not working in the Humble Mozilla Bundle's
asm.js FTL.
2026-03-17 04:01:29 -05:00
Zaggy1024
6c73323732 UI/Qt: Store the click count as int to match UIEvent.detail's type
Also, ensure that it never goes below 0.
2026-03-17 04:01:29 -05:00
Zaggy1024
a51967311e Everywhere: Consolidate double/triple click handling to use click count
This moves normal/double/triple click checking into WebContent, the
client only has to send a click count in order to activate a double
or triple click in the content. This means that the AppKit UI will no
longer fire multiple double clicks when clicking in place more than 3
times. This matches the behavior of other browsers on macOS.

We will now also fire the click event regardless of whether a dblclick
event will follow, as the spec requires.
2026-03-17 04:01:29 -05:00
Timothy Flynn
b9c71df147 UI/AppKit: Hide the location bar when elements are fullscreened
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.
2026-03-05 10:00:12 -05:00
Timothy Flynn
ae8181b467 LibWeb+LibWebView+UI: Add a context menu item to toggle fullscreen state 2026-03-01 15:41:43 -06:00
Zaggy1024
e77167f2f4 UI/AppKit: Make CPU painting work again
We were incorrectly calling presentMetalFrame while force-cpu-painting
was enabled, so updateLayer never had any chance to be called.

However, in addition to that, it turned out that there's a subclass of
CALayer that is used by NSView by default which cannot be created in a
makeBackingLayer override, so updateLayer was never going to be called
anyway. In order to update the layer at the requisite time, a new
LadybirdWebViewContentLayer had to be added to simply call the delegate
on our view.

Setting the contentsRect on the layer was also incorrect, and caused
the contents to shift and stretch until WebContent's backing stores
shrank to fit the new view size.
2026-03-01 08:32:36 +01:00
Andreas Kling
b20d14970f LibWeb: Flatten Platform::FontPlugin by merging WebView::FontPlugin
WebView::FontPlugin was the only implementation of the abstract
FontPlugin base class. Its dependencies (LibGfx, LibCore) are
already visible to LibWeb.

Remove the virtual dispatch by making FontPlugin concrete and
absorbing the WebView::FontPlugin implementation directly.
2026-02-28 15:32:14 +01:00
Andreas Kling
3cfc7aa629 LibWeb: Flatten Platform::EventLoopPlugin by merging Serenity impl
EventLoopPluginSerenity was the only implementation of the abstract
EventLoopPlugin base class. Its methods simply wrapped Core::EventLoop
calls with GC function unwrapping.

Remove the virtual dispatch by making EventLoopPlugin concrete and
absorbing the EventLoopPluginSerenity implementation directly.
2026-02-28 15:32:14 +01:00
Luke Wilde
1d34abd96f UI/AppKit: Implement exiting fullscreen 2026-02-23 18:44:26 +00:00
Simon Farre
25eef2e6e6 UI/Qt: Add interface for exiting fullscreen
This adds the following features to the Qt UI:
- An "exit fullscreen" button that displays when entering fullscreen
  This will disappear after a certain amount of time. Moving the
  cursor to the top of the screen will make it reappear.
- Switching tabs exits fullscreen

The look and feel of this is preliminary and should be expanded upon
in the future.
2026-02-23 18:44:26 +00:00
Simon Farre
44e0735d9b LibWebView+UI/Qt: Allow WebContent to enter/exit the fullscreen UI
These IPC methods should be expanded in the future to allow WebContent
to specify what UI elements should be kept/removed, for example, the
navigation UI.
2026-02-23 18:44:26 +00:00
Jelle Raaijmakers
1cc29c669a WebContent: Combine viewport size and DPR into a single IPC message
The set_viewport_size and set_device_pixel_ratio IPC messages were sent
separately, potentially causing a race condition when the DPR changes
(e.g. moving a window between screens): the DPR message would arrive
and use a stale viewport size, computing a temporarily wrong CSS
viewport. Combine both into a single set_viewport IPC that updates the
device viewport size and DPR together.
2026-02-23 15:22:12 +01:00
Shannon Booth
1be69479a6 LibURL+Elsewhere: Consider file:// origins opaque by default
This aligns our behaviour closer to other browsers, which
_mostly_ consider file scheme URLs as opaque. For test
purposes, allow overriding this behaviour with a commandline
flag.
2026-02-21 23:00:57 +01:00
Timothy Flynn
ea32502947 Everywhere: Run clang-format
The following command was used to clang-format these files:

    clang-format-21 -i $(find . \
        -not \( -path "./\.*" -prune \) \
        -not \( -path "./Build/*" -prune \) \
        -not \( -path "./Toolchain/*" -prune \) \
        -type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")
2026-02-18 08:02:45 -05:00
Luke Wilde
0e958ca8d5 LibWebView+UI/AppKit: Present IOSurfaces directly
Instead of copying the Bitmap that wraps the IOSurface, we can just
present the IOSurface directly. This significantly reduces CPU usage in
the UI process, particularly at high refresh rates such as 120Hz where
it would saturate a full CPU core.

This is done by using CAMetalLayer and blitting the IOSurface to the
next drawable buffer, which handles triple buffering, locking the
IOSurface and vsync automatically. This also allows the Metal HUD to
work, but the only accurate stat is the frame intervals/FPS because
it's in the UI layer, not WebContent. However, that's still useful
to detect frame drops.
2026-02-16 14:57:17 +00:00
Luke Wilde
891af6a6a5 UI/Qt: Request closure instead of always force closing tabs 2026-02-14 23:26:10 +00:00
Luke Wilde
05e6019447 UI/AppKit: Request closure instead of always force closing tabs 2026-02-14 23:26:10 +00:00
Jelle Raaijmakers
2a2f8ef90b LibWeb+UI: Support triple clicking and dragging paragraphs
When triple clicking on text, we should select the entire paragraph, or
entire line in <input>s and <textarea>s. If the mouse button is held
down and the user starts dragging, the selection expands with additional
paragraphs or lines.

This expands on the work of Kai Wildberger (PR #7681) but was adjusted
for the work that happened previously to support double click + drag
moves and includes triple click support for our Qt UI.

Co-authored-by: Kai Wildberger <kiawildberger@gmail.com>
2026-02-06 14:18:10 +00:00
Timothy Flynn
f322e8a29c LibWebView+UI: Add a context menu item to download images
This introduces a simple FileDownloader to download files in the UI
process from RequestServer. We use this to download the context menu
image - this download is likely to hit the disk cache.
2026-02-05 07:27:34 -05:00
Timothy Flynn
70482687a2 LibWebView+UI: Always ask the user where to save screenshots
We currently always save screenshots to the Downloads folder. We will
now always ask for a save location.

This will just let an upcoming feature to save images from web pages
behave the same way. We will want the user to be able to choose a file
name, since the file name from the URL might be nonsense or already
exist.
2026-02-05 07:27:34 -05:00
Timothy Flynn
4a3a96b913 UI/AppKit: Do not handle cmd+w events for non-Tab windows
We used to have several of our own window types to close. We now only
have Tab windows. Our delegate handler is invoked even for windows such
file picker modals. The result was that we would close the modal window,
but the application would be left in a modal-active state.

We now behave like Safari. If cmd+w is pressed while a file picker modal
is open, no window is closed, and an error beep is played by AppKit.
2026-02-05 07:27:34 -05:00
Andreas Kling
9ad9c65368 Revert "LibCore: Add thread-safe weak deferred_invoke()"
This reverts commit 96ce468b60.

Appears to have regressed WPT.
2026-01-25 12:20:39 +01:00
Andreas Kling
96ce468b60 LibCore: Add thread-safe weak deferred_invoke()
Add a thread-safe deferred_invoke() API on WeakEventLoopReference that
queues work onto the owning thread's event queue and wakes that thread
via EventLoopManager hooks. This avoids calling wake() from foreign
threads during teardown.

Implement current_thread_handle()/wake_thread() in each backend and
track per-thread data so handles are validated before waking:

- Unix: wake via per-thread wake pipe
- Windows: wake via thread wake event
- macOS: wake via stored CFRunLoopRef
- Qt: wake via event target or QEventLoop::wakeUp()
- Android: wake via stored ALooper
2026-01-25 09:32:51 +01:00
Andreas Kling
367296fce6 UI/AppKit: Override deferred_invoke() to signal CFRunLoopSource
The base class deferred_invoke() adds work to the thread event queue
and calls wake(), but that's not sufficient for CFRunLoop. We also
need to signal the deferred_source via CFRunLoopSourceSignal() so the
run loop knows to call its perform callback which processes the queue.

Without this signal, deferred invocations posted from other threads
(such as IPC I/O threads) would not be processed, causing deadlocks
when waiting for sync IPC responses.
2026-01-25 09:32:51 +01:00
Andreas Kling
da77c803c1 UI/AppKit: Fix wake() to use the correct run loop
wake() was using CFRunLoopGetCurrent() which returns the calling
thread's run loop. When called from an I/O thread to wake the main
thread's event loop, this would wake the wrong run loop.

Fixed by using the stored m_impl->run_loop which is captured at
construction time and refers to the event loop's owning thread.
2026-01-25 09:32:51 +01:00
Sam Atkins
cdf55ea371 WebContent+LibWebView: Rename --layout-test-mode flag to --test-mode
This name has been outdated for a while, as it's enabled when running
any kind of test, not just layout tests.
2026-01-20 06:58:16 -05:00
Jonathan Gamble
fc22c9ea38 LibWeb+WebContent: Allow WebContent to disentangle zoom from css pixels
So Ladybird can paint scrollbar & resizer chrome at the same size
regardless of zoom level while still respecting device pixel ratio
2026-01-12 11:00:14 +00:00
Jonathan Gamble
559f6bf784 UI: Add sw/se resize cursors for macos 15+ 2026-01-12 11:00:14 +00:00
sideshowbarker
16fd2ccee0 UI/Qt: Restore address bar URL when pressing Escape
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.

This matches the AppKit implementation and Chrome/Firefox behavior.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/7264
2026-01-06 06:37:19 -05:00
sideshowbarker
34d7fe2074 UI/AppKit: Restore address bar URL when pressing Escape
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
2026-01-06 06:37:19 -05:00
Zaggy1024
d5e980aa61 LibMedia: Drop the Oboe audio stream implementation for Android
The Android build is likely bitrotted, and breaking changes need to be
made to the PlaybackStream interface. This should be reverted and the
implementation updated if the Android build is maintained again.
2025-12-13 08:58:26 +01:00
Timothy Flynn
7d6616669c LibWebView+UI: Move the UI event loops to the UI folder
Once upon a time, we needed the UI-specific event loops outside of the
UI process. This is no longer the case. Let's move the event loops back
to the UI folder to remove the awkward interface library we were left
with.
2025-12-05 14:24:05 -05:00
Andreas Kling
cebc4d00dd LibCore: Remove ability to post heap-allocated Core::Event objects
We no longer need this API since all clients have been converted to
simply posting the Core::Event::Type (or a callback function).
2025-12-03 13:26:27 +01:00
Andreas Kling
69515f8c85 LibCore: Allow posting stateless events without heap-allocated Event
This patch adds an API for posting a Core::Event::Type to the thread
event queue without requiring a full Core::Event object.

We use this API to avoid heap allocations for every timer and notifier
activation event.
2025-12-03 13:26:27 +01:00
Tim Ledbetter
e9519b132f Base: Use the correct memory unit suffixes in about::processes
Previously the GB suffix was displayed as BB.
2025-12-01 07:30:23 -05:00
InvalidUsernameException
7c315ef67f Everywhere: Unify naming of RGBA-like colors
The `Bitmap` type was referring to to its internal pixel format by a
name that represents the order of the color components as they are layed
out in memory. Contrary, the `Color` type was using a naming that where
the name represents the order of the components from most to least
significant byte when viewed as a unsigned 32bit integer. This is
confusing as you have to keep remembering which mental model to use
depending on which code you work with.

To unify the two, the naming of RGBA-like colors in the `Color` type has
been adjusted to match the one from the Bitmap type. This seems to be
generally in line with how web APIs think about these types:
* `ImageData.pixelFormat` can be `rgba-8unorm` backed by a
  `Uint8ClamedArray`, but there is no pixel format backed by a 32bit
  unsigned type.
* WebGL can use format `RGBA` with type `UNSIGNED_BYTE`, but there is no
  such format with type `UNSIGNED_INT`.

Additionally, it appears that other browsers and browser-adjacent
libraries also think similarly about these types:
* Firefox:
  https://github.com/mozilla-firefox/firefox/blob/main/gfx/2d/Types.h
* WebKit:
  https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/graphics/PixelFormat.h
* Skia:
  https://chromium.googlesource.com/skia/+/refs/heads/main/include/core/SkColorType.h

This has the not so nice side effect that APIs that interact with these
types through 32bit unsigned integers now have the component order
inverted due to little-endian byte order. E.g. specifying a color as hex
constant needs to be done as `0xAABBGGRR` if it is to be treated as
RGBA8888.

We could alleviate this by providing endian-independent APIs to callers.
But I suspect long-term we might want to think differently about bitmap
data anyway, e.g. to better support HDR in the future. However, such
changes would be more involved than just unifying the naming as done
here. So I considered that out of scope for now.
2025-11-28 18:32:48 +01:00
Timothy Flynn
bf75f52ce0 UI/AppKit: Store the original key-down event for WebContent processing
When a shortcut is an alternative key, macOS first fires a key event for
the primary key. Then if it is not handled, it fires an event for the
alternative key. For example, we see these two events in a row when we
press cmd and =/+:

    NSEvent: type=KeyDown flags=0x100108 chars="=" keyCode=25
    NSEvent: type=KeyDown flags=0x100108 chars="+" keyCode=24

For dead key processing, we don't handle these events right away. By the
time we get to doCommandBySelector, when we call [NSApp currentEvent],
we see the following events:

    NSEvent: type=KeyDown flags=0x100108 chars="=" keyCode=24
    NSEvent: type=AppDefined flags=0

The AppDefined event is internally posted by our event loop. So it seems
we cannot rely on currentEvent being the key-down event we are looking
for.

Instead, we can store the key-down event that we last saw.
2025-11-27 13:51:45 +00:00
SvDp
5b7c9af340 UI/AppKit: Auto-focus location bar when opening new tabs on macOS
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
2025-11-26 10:47:37 +01:00
SvDp
150828af98 UI/AppKit: Prevent autocomplete popover from stealing focus
The autocomplete popover on macOS was stealing focus from the location
bar when suggestions were displayed. This change saves the current
first responder before showing the popover and restores it immediately
after, ensuring the user can continue typing without interruption.
2025-11-24 11:49:24 +01:00
ayeteadoe
4fb1ba0193 LibCore: Remove unused NotifierActivationEvent fd() and type() methods
In 11b8bbe one thing that was claimed was that we now properly set the
Notifier's actual fd on the NotifierActivationEvent. It turns out that
claim was false because a crucial step was forgotten: actually set the
m_notifier_fd when registering. Despite that mistake, it ultimately was
irrelevant as the methods on NotifierActivationEvent are currently
unused code. We were posting the event to the correct Notifier receiver
so the on_activation was still getting invoked.

Given they are unused, NotifierActivationEvent can be defined the same
way as TimerEvent is, where we just pass the event type enum to the
Event base class. Additionally, NotificationType can be moved to
the Notifier header as this enum is now always used in the context of
creating or using a Notifier instance.
2025-11-22 09:47:25 +01:00
Timothy Flynn
a853bb43ef LibWebView+UI: Pass RequestServerOptions to Application implementations
This will be needed by test-web.
2025-11-20 09:33:49 +01:00
Pavel Shliak
0311d40425 UI/AppKit: Fix tab overview toolbar identifier typo 2025-11-15 08:13:11 -05:00
Timothy Flynn
c80b698589 LibWebView+UI: Remove some now-superfluous debug menu items
No need to keep these actions around, users can use the about:settings
page instead.
2025-11-12 09:06:21 -05:00
ayeteadoe
2880d40dfb CMake: Specify no translations for Qt deploy script on Windows
When building Ladybird with the Qt UI framework on Windows, we were
getting the following warning in the CMake target post build step:
"Could not find any translations in <binary_dir>\vcpkg_installed\
x64-windows\translations\Qt6 (developer build?)". We now tell the
deploy script that we have no translations, which removes the warning.
2025-11-03 13:23:47 -05:00
ayeteadoe
782cf581e4 CMake: Make Ladybird and all Services executables console applications
We set bInheritHandles to TRUE for all child processes we spawn. Some
of the types of objects that support handle inheritence is all of the
STD handles (STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE) and
the console screen buffer. This means if Ladybird and all the child
service processes it launches/communicates with our console apps, only
a single console needs to be allocated and all child process output
their logs to that single console.
2025-11-03 13:23:47 -05:00
ayeteadoe
95f239a357 CMake: Add Windows executable helper function
The function currently has 2 purposes: (1) To copy dependent dlls for
executables to output binary directory. This ensures that these helper
processes can be ran after a build given not all DLLs from vcpkg libs
get implicitly copied to the bin folder. (2) Allow fully background
and/or GUI processes to use the Windows Subsystem. This prevents
unnecessarily launching a console for the process, as we either require
no user interaction or the user interaction is all handled in the GUI.
2025-10-29 21:07:52 -06:00
ayeteadoe
20f9510687 CMake: Output helper process binaries to bin instead of libexec
libexec is not a standard convention on Windows. Everything should go
into bin
2025-10-29 21:07:52 -06:00
Tim Ledbetter
e4e18ca84b UI/AppKit: Support dead keys on MacOS 2025-10-29 12:38:59 -04:00
Zaggy1024
9f44fcbded Everywhere: Remove AudioCodecPlugin and Qt Multimedia
These are no longer needed now that audio is played through
PlaybackManager.
2025-10-27 17:28:49 -07:00
Junior Rantila
8c8961171c UI/AppKit: Make project buildable on macOS < 15
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.
2025-10-24 12:41:42 -04:00
Timothy Flynn
e57176b484 LibWebView: Move headless clipboard management to LibWebView
We only supported headless clipboard management in test-web. So when WPT
tests the clipboard APIs, we would blindly try to access the Qt app,
which does not exist.

Note that the AppKit UI has no such restriction, as the NSPasteboard is
accessible even without a GUI.
2025-10-10 15:10:03 -04:00
Timothy Flynn
a4a15b9a1e LibWeb+UI/AppKit: Ignore unknown clipboard MIME types
This prevents the AppKit UI from sending unknown MIME types to LibWeb,
where we would previously blindly dereference the result of parsing the
MIME string. We now ignore unknown MIME types as well.
2025-10-10 15:10:03 -04:00
Aliaksandr Kalenik
c630de17ab LibWeb+UI+WebContent: Pipe pinch events from AppKit UI to WebContent 2025-10-10 15:37:45 +02:00
ayeteadoe
f4c8fd4bef LibCore+LibWebView+UI/Qt: Support TimeZoneWatcher on Windows
To detect system time zone changes on Windows, the event we need to look
for is WM_TIMECHANGE. The problem is how the callback with said message
actually gets invoked is very particular. (1) We must have an active
message pump (event loop) for the message to ever be processed. (2) We
must be a GUI application as WM_TIMECHANGE messages are seemingly sent
to top level windows only. It doesn't say that in the docs for the
event, but attempts of creating a LibTest-based application with a
message pump and a message only window and never receiving the event
point to that probably being true.

This workaround is built off the fact that Qt's message pump defined
internally in QEventDispatcherWin32::processEvents does in fact receive
WM_TIMECHANGE events, even though it is not exposed as a QEvent::Type.
Given the requirements stated above it makes sense that it works here as
the message pump is executing in a QGuiApplication context. So we use a
native event filter to hook into the unexposed WM_TIMECHANGE event and
forward it along to the on_time_zone_changed() callback.

Note that if a Windows GUI framework is done in the future, we'll have
to re-add support to ensure the TimeZoneWatcher still gets invoked.
2025-10-05 15:46:15 +02:00
Timothy Flynn
efa9311527 LibWeb+WebContent+UI: Port text pasting to UTF-16 2025-09-19 06:38:52 -04:00
Timothy Flynn
ca082d6d73 LibWebView+UI: Move clipboard handling from the WebView to the App
Clipboard handling largely has nothing to do with the individual web
views. Rather, we interact with the system clipboard at the application
level. So let's move these implementations to the Application.
2025-09-19 06:38:52 -04:00
Timothy Flynn
8b2187bf92 LibWebView+UI: Generate the entire Inspect menu
Now that all the actions in the Inspect menu are generated, we can
generate the menu itself.
2025-09-18 07:27:24 -04:00
Timothy Flynn
14d49d5a3a LibWebView+UI: Generate action to enable/disable DevTools 2025-09-18 07:27:24 -04:00
Timothy Flynn
6d30b0f4d4 LibWebView+UI: Generate actions to open about: pages 2025-09-18 07:27:24 -04:00
Timothy Flynn
ce331cbcd5 LibWebView+UI: Add an Application method to open a URL in a new tab
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.
2025-09-18 07:27:24 -04:00
Timothy Flynn
60b71805bc UI/AppKit: Add menu icons for the zoom menu
Neglected to add these in ede6314cb6.
2025-09-18 07:27:24 -04:00
Timothy Flynn
255c4c2d9b UI/Qt: Simplify setting some action shortcuts
These were copied from their previous instantiations, but we don't need
to go through QKeySequence::keyBindings for standard shortcuts.
2025-09-18 07:27:24 -04:00
Timothy Flynn
dbce62bc0d UI/Qt: Move the View Source action back to the Inspect menu
Accidental copy/paste from e6b32bbbbf6c3b80649e355c2ad7f6ad87430fc3.
2025-09-18 07:27:24 -04:00
Timothy Flynn
ede6314cb6 LibWebView+UI/AppKit: Display icons in the macOS UI on Tahoe
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.
2025-09-17 11:29:01 +01:00
Timothy Flynn
8ebc20a4f0 UI/AppKit: Make the location field bordered on Tahoe
Otherwise, it sticks out on macOS Tahoe when it is unbordered. This
matches Safari's look.
2025-09-17 11:29:01 +01:00
Timothy Flynn
e0a7217c4b UI/AppKit: Hide button borders when the button should be invisible
On macOS Tahoe, the zoom button's border is visible when the button
itself is hidden. This feels like a macOS bug, but for now let's hide
the borders as well.
2025-09-17 11:29:01 +01:00
Timothy Flynn
d9ebd44924 UI/Qt: Remove unused/undefined declaration from Qt settings 2025-09-16 10:38:20 +02:00
Louis Dalibard
660bcfa2cd LibGfx+LibWeb+UI: Add OpenHand cursor for CSS grab property 2025-09-13 14:27:18 +02:00
Timothy Flynn
4a5c374084 UI/Qt: Place the "reset zoom" button to the left of the hamburger menu
It feels a bit awkward having this button displace the menu.
2025-09-11 14:23:45 -04:00
Timothy Flynn
9684e6dbc5 LibWebView+UI: Generate the zoom menu 2025-09-11 14:23:45 -04:00
Timothy Flynn
7d6ea99d0d LibWebView+UI: Generate the preferred color, contrast, and motion menus 2025-09-11 14:23:45 -04:00
Timothy Flynn
9c99c48f47 LibWebView+UI: Generate the application debug menu
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.
2025-09-11 14:23:45 -04:00
Timothy Flynn
5d8d9b337a LibWebView+UI: Generate application context menus
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.
2025-09-11 14:23:45 -04:00
Timothy Flynn
a5be0f0a18 LibWebView+UI: Add structures to hold context menu and action data
We currently duplicate a lot of code to handle application/context menus
and actions. The goal here is to hold the data for the menus and actions
in LibWebView. Each UI will then be able to generate menus from the data
on-the-fly.

The structures added here are meant to support generic and checkable
actions, action groups, submenus, etc.
2025-09-11 14:23:45 -04:00
Timothy Flynn
2632b1375b LibWebView+UI: Extract some UI-specific displays to Application helpers
This is preparation for moving application menus to LibWebView. We will
need a way to display these dialogs from outside of the UI layer.
2025-09-11 14:23:45 -04:00
Timothy Flynn
95dca6c787 UI/Qt: Clean up some manual forward declarations
Several are unused, and there's certainly no need for the `using`
declaration.
2025-09-11 14:23:45 -04:00
Luke Wilde
b17783bb10 Everywhere: Change west consts caught by clang-format-21 to east consts 2025-08-29 18:18:55 +01:00
Viktor Szépe
1c01e183b7 Everywhere: Fix even more typos 2025-08-27 08:48:01 +02:00
rmg-x
9b0157523d Base+UI: Implement user interface for defaultZoomLevelFactor setting 2025-08-26 06:31:22 -04:00
ayeteadoe
9ec1643d88 CMake: Add helper to ensure vcpkg DLLs are copied to the output dir
The BUILD_RPATH/INSTALL_RPATH CMake infrastructure is not supported
on Windows, but we want to ensure Ladybird executables are runnable
after the build phase so there can be an efficient dev loop.
lagom_copy_runtime_dlls() can be used by executable targets so all
their dependent dlls are copied to their output directory in their
post build step.
2025-08-23 16:04:36 -06:00
ayeteadoe
9c67c4a270 LibWebView: Enable EXPLICIT_SYMBOL_EXPORT 2025-08-23 16:04:36 -06:00
ayeteadoe
ed93551d59 Qt/ladybird: Enable in Windows CI 2025-08-23 16:04:36 -06:00
ayeteadoe
0b19c04b53 test-web: Enable building in Windows CI
The tests are not registered with CTest yet
2025-08-23 16:04:36 -06:00
Andreas Kling
c47e253c60 LibCore: Remove unused "visible for timer purposes" concept
This was a long-unused leftover from SerenityOS.
2025-08-11 16:55:25 +02:00
zac
6602fa5d15 UI/Qt: Add Alt+D as a shortcut to focus the location editor 2025-08-07 07:01:22 -04:00
Sam Atkins
b06d2370c1 UI/Qt: Initialize BrowserWindow fields
Initializing m_current_screen may not be necessary, but the initial
value of m_preferred_color_scheme is sent to WebContent, so failing to
give it an initializer would cause bugs.
2025-08-04 14:01:00 +02:00
Sam Atkins
31536c53a2 UI/AppKit: Add "Dump CSS Errors" menu item 2025-08-04 10:50:09 +01:00
Sam Atkins
d65d46f4f0 UI/Qt: Add "Dump CSS Errors" menu item
Dumps out any CSS errors that have appeared since launch.
2025-08-04 10:50:09 +01:00
Timothy Flynn
50fed1d65c LibWeb+LibWebView+WebContent+UI: Port the document title to UTF-16 2025-08-02 10:10:14 -07:00
Jelle Raaijmakers
8537f0fa82 UI/AppKit: Focus webview if URL was changed
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.
2025-08-01 10:09:26 +02:00
Luke Wilde
3f5bc023e2 LibWeb+WebContent+UI: Remove unused same-origin policy toggle
Page::is_same_origin_policy_enabled is unused, and the original FIXME
has been implemented.
2025-07-31 18:38:03 -04:00
Andrew Kaster
cf355d48b1 CMake: Install AppStream metainfo file with absolute path
Fixes CMake install with a separate build directory breakage introduced
by 1b1eae4409
2025-07-29 11:31:12 +02:00
Jan Koudijs
1b1eae4409 Meta: Add a freedesktop appstream/metainfo manifest 2025-07-28 19:37:48 -06:00
Timothy Flynn
67cc02ab59 LibWeb+UI: Add an explicit IPC to handle mouse leave events
The faux position we created here is adjusted by the device pixel ratio
later on, which would invoke integer overflow on screens with a DPR
greater than 1.

Instead of creating special data for a mouse move event, let's just add
an explicit leave event handler.
2025-07-28 21:26:33 +02:00
Timothy Flynn
bc4112bf18 UI: Inform WebContent when the mouse leaves the WebView widget
Previously, when the mouse left the WebView, the currently hovered node
would remain hovered (including the scroll bar). This felt a bit awkward
and is not how other browsers behave.
2025-07-27 23:38:00 -04:00
Luke Wilde
124bdce99c UI/Qt: Set WC's max FPS to the refresh rate of the current screen 2025-07-26 10:09:12 -04:00
Luke Wilde
b0d97c991f UI/AppKit: Set WC's max FPS to the max FPS of the current screen 2025-07-26 10:09:12 -04:00
Aliaksandr Kalenik
f65db4507a UI+WebContent: Add menu option to dump display list 2025-07-13 19:15:05 +02:00
Jelle Raaijmakers
0fccc75fd7 Meta: Remove bookmarks.json
This seems to be unused.
2025-07-11 14:04:23 +02:00
Olekoop
f26a898ffc Android: Workaround the system certificate issue
Due to removal of local ca-certificates we need to use system's
certificate. However, on Android it is stored in multiple files.
Ladybird doesn't support multiple certificates yet, so we just
concatenate all of them into one big file.
2025-07-10 15:44:53 -06:00
Olekoop
6f350c51fd Android: Keep up with the times
While some of the changes are due to syntax and have no effect on
the functionality, others are more important.

The major changes are
- Use Painter instead of now removed DeprecatedPainter
- Remove the need of LibArchive by using Java's native zip support
- Have a proper C++23 compiler by updating NDK to r29 beta 2
- Store user data and config in an user accessible way
- Update AGP to 8.11 and update compile target to SDK level 35
2025-07-10 15:44:53 -06:00
Andrew Kaster
204e787131 CMake: Add service, desktop, and icon files for Linux-like systems
These files are lifted from the ladybird-gtk4 repository and adapted
to work with the Qt UI port. They are installed by default on Linux, but
can be installed via a CMake option on other platforms.

Co-Authored-By: Sergey Bugaev <bugaevc@serenityos.org>
Co-Authored-By: Nicolas Ramz <nicolas.ramz@adevinta.com>
Co-Authored-By: Beckett Normington <beckett@b0ba.dev>
Co-Authored-By: Xexxa <93391300+Xexxa@users.noreply.github.com>
2025-07-08 11:45:32 -06:00
Jelle Raaijmakers
ead0a2c78a Everywhere: Rename serenity_main to ladybird_main
No functional changes.
2025-07-08 09:17:16 -04:00
Andrew Kaster
62c5f4b822 CMake: Remove unconditional Qt linkage from WebContent and WebWorker
WebContent only needs it when using QtMultimedia for audio playback, and
WebWorker never needs it.
2025-07-07 15:53:15 -06:00
Andrew Kaster
5523158b95 CMake: Install files for fonts, internal, about-settings on non-macOS
The corresponding install commands were missed when these file groups
were added.
2025-07-07 06:47:06 -04:00
Andrew Kaster
ffd600a7f5 Meta+RequestServer: Remove local download of ca-certificates
We haven't required a local copy of the ca-certificates since switching
to OpenSSL as the backend for TLS. Remove the script to download the
PEM file, and update the tests to use the system's CA certificates.
2025-07-07 09:10:05 +02:00
ayeteadoe
f737ec2570 CMake: Rename SERENITY_* helper variables to LADYBIRD_* 2025-07-03 23:19:41 +02:00
ayeteadoe
d897bfae91 CMake: Rename all_generated target to better convey intent 2025-07-03 23:19:41 +02:00
Timothy Flynn
b55d2909f6 LibWebView+UI: Launch the DevTools server if --devtools is specified
This replaces the --devtools-port flag with a --devtools flag, which
optionally accepts a port. If the --devtools flag is set, we will now
automatically launch the DevTools server.
2025-07-02 15:27:54 -04:00
Timothy Flynn
df0dc32006 LibWebView: Defer creating services until after application init
In particular, we need to defer creating the process manager until after
we have decided whether or not to create a UI-specific event loop. If we
create the process manager sooner, its event loop signal registration
does not work, and we don't handle child processes exiting.
2025-06-11 08:26:29 -04:00
Timothy Flynn
39da2d9a2f LibWebView+UI: Migrate some UI process init to LibWebView
No need to do this setup in every UI's main().
2025-06-11 07:26:32 -04:00
Timothy Flynn
b425ce93b1 LibWebView+UI: Don't declare a magic ctor for Application subclasses
You would have to just know that you need to define the constructor with
this declaration. Let's allow subclasses to define constructors as they
see fit.
2025-06-11 07:26:32 -04:00
Timothy Flynn
fa164083fd LibWebView+UI: Do not create a QApplication in headless mode
This is causing errors on the WPT runner, which does not have a display
output. To do this requires shuffling around the Main::Arguments struct,
as we now need access to it from overridden WebView::Application methods
after construction.
2025-06-10 23:10:48 +01:00
Timothy Flynn
f66cac3417 LibWebView+UI: Define concrete Application::the accessor automatically
This avoids assuming that the Qt Application is a QApplication, which
will not be the case in an upcoming commit.
2025-06-10 23:10:48 +01:00
Timothy Flynn
9a5b31ccd1 LibWebView+Tests+UI: Migrate headless-browser to test-web
Now that headless mode is built into the main Ladybird executable, the
headless-browser's only purpose is to run tests. So let's move it to the
testing directory and rename it to test-web (a la test-js / test-wasm).
2025-06-10 12:04:59 -04:00
Timothy Flynn
c011dc766f LibWebView+WebDriver+UI: Migrate headless browsing to main Ladybird exe
We currently create a separate headless-browser application to serve two
purposes:

1. Allow headless browsing to take a screenshot of a page or print its
   layout tree / internal text.
2. Run the LibWeb test framework.

This patch migrates (1) to the main Ladybird executable. The --headless
flag enables this mode. This matches the behavior of other browsers, and
means we have one less executable to ship at distribution time.

We want to avoid creating too many AppKit / Qt facilities in headless
mode. So this involves some shuffling of application init to ensure we
don't create them until after we've parsed the command line arguments.
Namely, we avoid creating the NSApp in AppKit and QCoreApplication in
Qt. Doing so also requires that we don't create the application event
loop until we've parsed the command line as well, because the loop we
create depends on whether we're creating those UI facilities.
2025-06-10 12:04:59 -04:00