Commit Graph

77 Commits

Author SHA1 Message Date
Luke Wilde
1d34abd96f UI/AppKit: Implement exiting fullscreen 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
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
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
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
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
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
Pavel Shliak
0311d40425 UI/AppKit: Fix tab overview toolbar identifier typo 2025-11-15 08:13:11 -05:00
Tim Ledbetter
e4e18ca84b UI/AppKit: Support dead keys on MacOS 2025-10-29 12:38:59 -04: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
Aliaksandr Kalenik
c630de17ab LibWeb+UI+WebContent: Pipe pinch events from AppKit UI to WebContent 2025-10-10 15:37:45 +02: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
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
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
Louis Dalibard
660bcfa2cd LibGfx+LibWeb+UI: Add OpenHand cursor for CSS grab property 2025-09-13 14:27:18 +02: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
Viktor Szépe
1c01e183b7 Everywhere: Fix even more typos 2025-08-27 08:48:01 +02:00
Sam Atkins
31536c53a2 UI/AppKit: Add "Dump CSS Errors" menu item 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
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
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
Dan Berglund
d9e90d4556 AppKit: Check availability before using macOS 15 API in TabController
This keeps the code building on older macOS versions.
2025-05-27 13:39:24 -06:00
Bastiaan van der Plaat
0b6f693636 UI/AppKit: Use webview layout event instead of window resize events
Currently the window resize events are used to resize the webview.
But when extra window items appear, for example: search or DevTools
Bar then the webview is clipped out of the window. This also happens
when the tab bar is opened and closed. Listening to layout events
resolves these clipping issues completely.
2025-05-08 11:23:21 +01:00
Bastiaan van der Plaat
5a3b98e0a9 UI/AppKit: Disable toolbar mode customization
Currently you can right click on the toolbar for a system
contextmenu. When you change the display mode
the toolbar goes into a weird smaller state.
2025-05-08 11:23:21 +01:00
Timothy Flynn
61c0f67c8c LibWeb+LibWebVew+WebContent+UI: Add IPC to retrieve the system clipboard
We currently have a single IPC to set clipboard data. We will also need
an IPC to retrieve that data from the UI. This defines system clipboard
data in LibWeb to handle this transfer, and adds the IPC to provide it.
2025-05-02 17:46:16 -04:00
Shannon Booth
00bbb2105b LibURL: Port create_with_file_scheme to Optional
Removing one of the main remaining users of URL valid state.
2025-04-19 07:18:43 -04:00
Andrew Kaster
6ff0373556 UI: Pass parent WebView by non-const ref when creating children
We need to call non-const methods on this guy and access its members in
a non-const way.
2025-04-16 10:41:44 -06:00
Andrew Kaster
91b549f797 LibGfx+LibWebView+UI: Store Gfx::Bitmap in RefPtr to const 2025-04-16 10:41:44 -06:00
Timothy Flynn
dbf4b189a4 LibWebView: Do not use AK::format to format search engine URLs
This is to prepare for custom search engines. If we use AK::format, it
would be trivial for a user (or bad actor) to come up with a template
search engine URL that ultimately crashes the browser due to internal
assertions in AK::format. For example:

    https://example.com/crash={1}

Rather than coming up with a complicated pre-format validator, let's
just not use AK::format. Custom URLs will signify their template query
parameters with "%s". So we can do the same with our built-in engines.
When it comes time to format the URL, we will do a simple string
replacement.
2025-04-06 13:45:10 +02:00
Timothy Flynn
c1fe912bf9 UI/AppKit: Implement an autocomplete view for the location bar 2025-04-02 08:52:45 -04:00
Timothy Flynn
b23b21fa4a UI/AppKit: Restore custom cursor shown on link hover
This seems to have broken in some recent-ish AppKit update. When we add
the status label to the view hierarchy / change its visibility state,
the NSApp is resetting the cursor to the standard cursor. By overriding
the cursorUpdate method to do nothing, we prevent this from happening.
2025-04-01 23:10:14 +02:00