Commit graph

40 commits

Author SHA1 Message Date
Andreas Kling
b91ff9ebfd UI/Qt: Keep macOS app alive without windows
Disable Qt quit-on-last-window behavior on macOS and install an
application-level menu so useful commands remain available after the
last browser window closes.

Reuse shared application actions and menus for Settings, Bookmarks,
History, Help, and global appearance controls. Centralize window-aware
commands such as New Tab, New Window, Open File, Open Location, and
Reopen Recently Closed so the browser window and windowless app menu
use the same behavior. Keep the location editor focused for new blank
windows after the native window has been activated.
2026-06-22 01:13:53 +02:00
Tim Ledbetter
0db82b3133 LibWebView+UI/Qt: Reuse an existing history tab when viewing history
Previously, the "View History" action always opened a new tab. We now
switch to an existing `about:history` tab when one exists in the active
window and fall back to opening a new tab otherwise.
2026-06-17 12:31:07 +02:00
Timothy Flynn
409e5edbf1 LibURL+LibWeb+LibWebView: Move internal URLs to their own header
This nearly eliminates the compilation impact of adding a new WebUI URL.
2026-06-10 20:27:36 +02: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
d0bb0deff4 UI/Qt: Focus the location bar when the browser first opens with no URLs
When no URLs are provided on the command line, LibWebView actually adds
about:newtab to the initial URL list. The only time this list is empty
is when we open a popup window.
2026-06-04 08:30:49 -04: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
4f314b0aa0 UI/Qt: Unify browser chrome layout
Treat the toolbar, tab strip, and vertical sidebar as one browser
chrome surface. Add an explicit layout policy for platform window
controls and sidebar widths. This lets macOS use left-side traffic
lights while other platforms keep right-side custom controls.

Keep the macOS toolbar stable in vertical-tabs mode. Traffic lights and
navigation controls stay in the top row, and the sidebar sits below it.
Draw chrome/content separators explicitly so the content edge remains
clear without adding seams inside the chrome surface.

Retune tab, toolbar, and omnibox styling for the unified chrome. Tabs
use card-like selected states, quiet inactive states, and matching
horizontal and vertical geometry.

Make hover-expanded vertical tabs draw as a chrome overlay so the web
content does not relayout. Keep the overlay above native web views and
route macOS window drags through AppKit events for reliable dragging
from custom chrome.
2026-06-03 02:53:37 +02:00
Timothy Flynn
a7f1ed7a10 UI/Qt: Begin implementing vertical tab support
This implements an initial version of vertical tabs for the Qt UI. Users
may enable vertical tabs in about:settings. When enabled, a button is
added to the toolbar to expand/collapse the vertical tabs.

There is plenty more to do here. We will want to support expanding on
hover, drawing the close tab / audio button indicators on collapsed
vertical tabs, positioning the vetical tab bar, etc.
2026-05-31 21:24:57 +02:00
Andreas Kling
0baeddd972 UI/Qt: Style popup menus
Add application-level QMenu styling using the existing chrome palette so
menu bar dropdowns, hamburger menus, context menus, and other popups use
the same colors and item states. Refresh the application stylesheet when
the Qt palette or theme changes.
2026-05-27 22:05:54 +02:00
Timothy Flynn
793e7dd01b LibWeb+LibWebView+UI: Update the selection keyboard on selection changes
When the selected text on a page changes, update the system selection
clipboard on supported systems (if primary pasting is enabled).
2026-05-27 13:33:44 -04:00
Timothy Flynn
082281da62 LibWebView+UI: Disable primary paste on unsupported systems
A selection clipboard is not available on all systems. The UI now
controls whether this feature is available.
2026-05-27 13:33:44 -04: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
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
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
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
Timothy Flynn
d8fb0ed59a UI/Qt: Integrate bookmark context menus into the bookmarks bar 2026-04-01 04:57:28 +02:00
Timothy Flynn
2b9cce8f62 UI/Qt: Create a bookmarks application menu and toolbar 2026-03-24 12:04:50 -04: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
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
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
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
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
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
14d49d5a3a LibWebView+UI: Generate action to enable/disable DevTools 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
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
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
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
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
Timothy Flynn
45d8cd5c9f UI/Qt: Replace the Task Manager window with about:processes 2025-03-19 10:03:17 -04:00
Timothy Flynn
e00c0c176e LibWebView+UI: Rename ChromeOptions to BrowserOptions 2025-03-15 19:57:27 -04:00
Timothy Flynn
bb7dff7dfe LibWebView+UI: Move ownership of application services to LibWebView
LibWebView now knows how to launch RequestServer and ImageDecoderServer
without help from the UI, so let's move ownership of these services over
to LibWebView for de-duplication.
2024-11-14 11:47:32 +01:00
Timothy Flynn
0ff91a5273 LibWebView+Services+UI: Move process helpers to LibWebView 2024-11-11 07:35:43 -05:00
Timothy Flynn
db47cc41f8 Everywhere: Move the Ladybird folder to UI 2024-11-10 12:50:45 +01:00
Renamed from Ladybird/Qt/Application.cpp (Browse further)