Commit graph

456 commits

Author SHA1 Message Date
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
sideshowbarker
a82c7939d9 LibWeb+UI/AppKit: Implement macOS IME support
This makes macOS IME input in web content work as expected.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9712
2026-06-08 10:23:14 +09:00
Shannon Booth
2dc3e3da55 Meta: Remove obsolete Lagom host-tools build 2026-06-08 01:11:40 +02:00
Callum Law
e2277e2e8a UI/GTK: Avoid nested event loop when waiting for download path
We no longer support more than one event loop per process as of 02b2053
so this was causing a crash when taking a screenshot. We now spin the
main event loop until a "done" flag is set.
2026-06-07 00:26:30 +02:00
Callum Law
728e6b010a UI/GTK: Avoid nested event loop when waiting for clipboard text
We no longer support more than one event loop per thread as of 02b2053
so this was causing a crash when pasting. We now spin the main event
loop until a "done" flag is set.

Fixes #9928
2026-06-07 00:26:30 +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
85c7620805 UI/Qt: Collapse hover-expanded vertical tabs after leaving window
When collapsed vertical tabs are expanded on hover, the collapse check
used QCursor::pos() against the vertical tabs rect. On some platforms,
after the cursor leaves the browser window entirely, that position can
remain at the last in-window coordinate, so the tabs stay expanded.
2026-06-04 22:16:16 +01: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
Timothy Flynn
83105b8349 LibWebView+UI/Qt: Move the show menu bar setting to LibWebView settings 2026-06-03 18:14:12 -04:00
Timothy Flynn
0e8a4f9747 UI/Qt: Cache the Application as a local in the BrowserWindow constructor 2026-06-03 18:14:12 -04:00
Timothy Flynn
80554dc914 LibWebView+UI/Qt: Move the vertical tab width to LibWebView settings
Let's store this alongside all other vertical tab settings.
2026-06-03 18:14:12 -04:00
Timothy Flynn
1d36fc2997 UI/Qt: Let fullscreen content occupy the whole window
Hide fullscreen chrome at the TabWidget level instead of hiding the
current tab's toolbar child directly. This lets the toolbar container
and reserved verticaltabs space stop contributing to layout while
fullscreen content is shown.

Also keep the exit fullscreen button above native web content on macOS
and center it using the fullscreen screen geometry rather than a
potentially stale parent widget size.
2026-06-03 13:39:11 -04:00
Timothy Flynn
e18cd253f0 UI/Qt: Add an advanced setting to enable server-side decorations
This adds a setting to disable our custom window decorations and let the
system's window server paint the window instead.
2026-06-03 17:30:26 +01:00
Andreas Kling
d9d8c5ce89 LibWeb: Allow Option-generated text insertion
Track whether a keydown should perform text insertion separately from
the delivered code point. Native frontends and text-oriented test paths
can now mark events that came from text input, while shortcut-style key
events keep Alt-modified default insertion suppressed.

This lets macOS Option-generated text such as Option+A and Option+Space
insert into editable controls without making plain Alt shortcuts insert
their base character. Add coverage for Alt text, Ctrl+Alt text,
separator text, Ctrl-only shortcuts, and Alt shortcuts.
2026-06-03 13:51:32 +02:00
Christian Frey
c8556c166a UI/Qt: Prevent autocomplete highlight flicker while typing
While typing in the location bar, intermediate autocomplete updates
caused the highlighted suggestion to flicker.

These updates trigger on each keystroke and lead to unnecessary
selection changes.

Skip intermediate popup updates while it is visible and rely on final
results to update both suggestions and selection atomically.
2026-06-03 13:50:01 +02:00
Christian Frey
a8cb27ddd0 UI/AppKit: Prevent autocomplete highlight flicker while typing
While typing in the location bar, intermediate autocomplete updates
caused the highlighted suggestion to flicker.

These updates trigger on each keystroke and lead to unnecessary
selection changes.

Skip intermediate popup updates while it is visible and rely on final
results to update both suggestions and selection atomically.
2026-06-03 13:50:01 +02:00
Timothy Flynn
388189d979 UI/Qt: Tweak the color used for the collapsed tab close button
The previous color was a bit jarringly bright.
2026-06-03 13:48:44 +02:00
Andreas Kling
530c71a2c1 UI/Qt: Put vertical tabs below bookmarks bar
Anchor the vertical tab sidebar to the full toolbar container height so
it starts below the bookmarks bar when that bar is visible. This keeps
the navigation toolbar and bookmarks bar unified, with the separator at
the content edge.

Update the sidebar geometry whenever the toolbar container resizes so
toggling the bookmarks bar moves the vertical tab chrome immediately.
2026-06-03 12:10:39 +02:00
Tim Ledbetter
462cd59f58 UI/Qt: Keep location bar selection when right-click context menu opens
Previously, selecting all or part of the URL in the location bar, then
right clicking it would cause the URL to become deselected.
2026-06-03 10:26:03 +02:00
Andreas Kling
51c9ffc8d8 UI/Qt: Submit autocomplete selections directly
When Return is pressed while the autocomplete popup is visible, submit
the location edit directly instead of falling through to QLineEdit's
default key handling after closing the popup. This keeps the omnibox
responsive to Return after chrome layout changes rebuild nearby widgets.
2026-06-03 02:53:37 +02:00
Andreas Kling
9551af9a28 UI/Qt: Keep autocomplete popup above web content
Make the autocomplete popup a native child widget on macOS so it can
receive mouse events while overlapping the native QRhiWidget web content
view. Keep it parented to the top-level browser widget so showing the
popup does not steal keyboard focus from the address bar.
2026-06-03 02:53:37 +02:00
Andreas Kling
4f411dce7b UI/Qt: Remove omnibox hover styling
Make hovering the location editor use the same fill and border as its
normal state in both light and dark mode. Focus still uses the focused
border, with a subtle focused fill retained for dark mode.
2026-06-03 02:53:37 +02:00
Andreas Kling
7cd93753c4 UI/Qt: Keep light-mode omnibox bright on focus
Use the normal light chrome surface for the focused location editor
background instead of reusing the hover fill. Dark mode keeps its
slightly distinct focused fill so the input remains readable there.
2026-06-03 02:53:37 +02:00
Andreas Kling
78887566f1 UI/Qt: Align horizontal New Tab spacing with tabs
Bring horizontal tab cards one pixel closer together and make the
horizontal New Tab button a square with the same height as tabs.
Remove the layout gap between the tab bar and New Tab button so the
painted card gap matches the gap between adjacent tabs.
2026-06-03 02:53:37 +02:00
Andreas Kling
15eec69341 UI/Qt: Use tab card styling for horizontal New Tab
Use the same icon-only card-shaped New Tab button in horizontal tab mode
that collapsed vertical tabs use. This keeps the New Tab affordance in
the same visual language as the tab cards instead of using a standard
flat tool button.
2026-06-03 02:53:37 +02:00
Andreas Kling
e783e99861 UI/Qt: Tighten horizontal tab card spacing
Bring horizontal tab card visuals one pixel closer together by reducing
the painted card inset by half a pixel on each side. Keep vertical tab
geometry unchanged.
2026-06-03 02:53:37 +02:00
Andreas Kling
a1bb958419 UI/Qt: Remove obsolete vertical toolbar layout branch
Vertical tab mode always keeps the toolbar in the full-width chrome row.
Remove the older split path that could place the toolbar in the page
column, and simplify the window-control visibility checks around that
single layout model.
2026-06-03 02:53:37 +02:00
Andreas Kling
79b892ec7c UI/Qt: Add breathing room around the omnibox
Add fixed empty toolbar gaps on both sides of the location editor. This
slightly reduces the omnibox width and leaves reliable toolbar chrome
space next to it for window dragging.
2026-06-03 02:53:37 +02:00
Andreas Kling
456d94cb5b UI/Qt: Align vertical tab chrome across platforms
Use the full-width toolbar layout for vertical tabs on every platform.
Also use the same collapsed vertical tabs width everywhere so collapsed
tab shapes remain square.
2026-06-03 02:53:37 +02:00
Andreas Kling
f03b675c2a UI/Qt: Keep vertical tab overlays native only on macOS
Make the vertical tab overlay column and resize handle native only on
macOS. This preserves stacking over native web views there without
breaking input routing on non-macOS platforms.
2026-06-03 02:53:37 +02:00
Andreas Kling
a310091402 UI/Qt: Avoid native churn while resizing chrome
Do not clear the Qt window mask from the non-macOS corner update path.
The custom rounded-corner implementation is macOS-only, so the Linux
resize path should not touch native mask state on every resize event.

Also make dynamic property updates idempotent for tab chrome widgets.
Vertical tab resize and hover updates now only repolish when a property
actually changes, and avoid reapplying unchanged New Tab button text,
style, and size.
2026-06-03 02:53:37 +02:00
Andreas Kling
807efef7e6 UI/Qt: Guard macOS window helpers
Declare the AppKit window-drag and window-control helpers only on
macOS. The implementation is already compiled only for Apple targets,
and call sites are guarded, so keep the header aligned with that
platform boundary.
2026-06-03 02:53:37 +02:00
Andreas Kling
be2cbc0f07 UI/Qt: Simplify browser chrome layout
Remove dead vertical-tab separator and sidebar traffic-light paths from
the unified chrome layout. Keep the toolbar stack owned by TabWidget so
layout changes no longer move each tab toolbar in and out of its page.
Share the vertical New Tab button setup between initial layout and
hover expansion, and keep window-control sizing helpers private.
2026-06-03 02:53:37 +02: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
a6e67d58ea UI/Qt: Draw tab close and audio state icons on collapsed tabs
We previously just hid this icons as a future TODO. We now draw a tab
close icon on hover in the upper-left corner of the tab, and an audio
state icon when audio is playing on the lower-right corner. Just like
expanded tabs, the audio state icon is interactable and may be used to
mute the page.
2026-06-02 21:55:14 +02:00
Timothy Flynn
748ef48f26 UI/Qt: Draw the tab audio state icons with chrome icon infra
We currently rely on QStyle icons to draw the audio state icons. But
these icons are system dependent. The macOS icons look particularly
out-of-place here. So let's draw chrome icons.
2026-06-02 21:55:14 +02:00
Timothy Flynn
caf6e526b6 UI/Qt: Make the new tab button consistent for all vertical tab modes
The new tab button would jump around a bit when switching between
collapsed and expanded vertical tabs. This is easier to notice when
expand-on-hover is enabled.

We now:
* Consistently draw the separator above the new tab button.
* Draw the new tab icon with a consistent icon size and placement.
2026-06-02 07:57:05 -04:00
Timothy Flynn
3b46b0bf09 UI/Qt: Add a setting to expand collapsed vertical tabs on hover
This as a pesudo third mode to vertical tabs. Now when the vertical tabs
are collapsed, users can enable a setting that will expand the vertical
tab area on hover. Unlike full expansion, the hovered vertical tab area
will cover the web content area to avoid pushing the web content area
around.
2026-06-02 07:57:05 -04:00
Sam Atkins
a92b9a7e34 UI/Qt: Put DevTools banner in its own widget, not a status bar
Using the status bar for this meant that the "DevTools is enabled on
port X" message would get overwritten whenever the user hovered over a
menu item. We don't otherwise use or need a status bar, so replace it
with an explicit banner widget that's only used for this purpose. Keep
the existing styling so it looks the same as before.
2026-06-01 15:29:51 +01:00
Timothy Flynn
62e514e8ed UI/Qt: Restore horizontal tab widths after turning off vertical tabs
After commit a7e68ef, When switching from vertical tabs to horizontal
tabs, the QTabBar could keep its stale narrow vertical width. This made
horizontal tabs render too small and, with multiple tabs, caused scroll
buttons to appear even though there was enough room in the tab strip.

Make the horizontal tab bar width explicit from the same available-width
calculation used for tab size hints.
2026-06-01 14:35:44 +02:00
Timothy Flynn
fde052136b UI/Qt: Remove no longer needed new tab polish/unpolish invocations
These were needed before commit 24e767a in order to propagate dynamic
property changes to Qt's CSS engine (for the verticalTabsExpanded
property). We now handle this in C++, so these calls aren't needed.
2026-06-01 14:35:44 +02:00
Timothy Flynn
188eb09d2e UI/Qt: Remove redundant layout clearing invocations
These layouts were cleared just before entering these functions.
2026-06-01 14:35:44 +02:00
Timothy Flynn
374dedf398 UI/Qt: Remove redundant TabWidget visibility updates
This is handled by the call to update_tab_chrome_visibility just below.
2026-06-01 14:35:44 +02:00
Timothy Flynn
e463d92bc0 UI/Qt: Remove unnecessary update to toolbar buttons for vertical tabs
Commits a7e68ef and 24e767a shuffled things around in that they ended up
performing manual updates to the toolbar buttons in order to update the
collapse/expand vertical tabs button. However, this isn't needed - that
button's state is totally controlled by LibWebView already (through the
WebView::Action infrastructure).
2026-06-01 14:35:44 +02:00
Andreas Kling
587abbcc6f UI/Qt: Give expanded vertical tabs more width
Reduce the horizontal margins and shape inset used by expanded vertical
tabs so the sidebar content uses more of the available space. Keep the
collapsed sidebar margin unchanged so icon-only tabs remain centered.

Share the expanded-tab geometry through helpers so painting, button
placement, and the new-tab button stay in sync.
2026-06-01 12:13:47 +02:00
Andreas Kling
3ea52a8447 UI/Qt: Avoid repaint loop in vertical tab bar
Move tab button geometry updates out of TabBar::paintEvent(). That path
mutates child widgets, and Qt schedules more updates for those buttons.
During painting, that can keep the tab bar dirty and churn CPU.

Update buttons from layout, hover, and current-tab changes instead. Keep
hover bookkeeping in one helper, and skip widget mutators when they are
already in the desired state.
2026-06-01 12:13:47 +02:00
Andreas Kling
4cc0ee5f47 UI/Qt: Keep macOS chrome out of RHI flushes
Stop forcing RHI for every QWidget on macOS. The web content view is
the only widget that needs Metal, and QRhiWidget already requests that.

Make the web content view a native child before parenting it into the
tab UI so Qt does not propagate its RHI config to the browser window
backing store. This keeps chrome repaints on the normal Cocoa backing
store path instead of copying the full window backing store into a
texture.
2026-06-01 12:13:47 +02:00
Andreas Kling
7c34917677 UI/Qt: Apply rounded corners after surface creation
The macOS rounded-corner helper needs the native view to be attached to
an NSWindow. The constructor can run too early for that, leaving startup
windows square even though the setting is enabled.

Reapply the corner state after Qt creates the platform surface, deferred
until Cocoa has attached the view to the native window.
2026-06-01 12:13:47 +02:00
Andreas Kling
aec4f8ab96 UI/Qt: Add macOS shortcuts for switching tabs
Support Command+Shift+[ and Command+Shift+] for moving between
Qt tabs on macOS. Also support the physical Control+Tab and
Control+Shift+Tab shortcuts accepted by other browsers.

Treat these as browser-reserved shortcuts so WebContent does not
consume the shortcut override before the browser action can run.
2026-06-01 12:13:47 +02:00