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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
Qt swaps Command into ControlModifier and Control into MetaModifier on
macOS so shortcut definitions can stay portable. Convert those modifiers
back to Web-facing semantics before sending input events to LibWeb.
This lets Command-click behave as platform-control click instead of
being mistaken for Control-click, while physical Control-click still
opens the context menu on macOS.
Platform wheel deltas describe movement in the view, not in page CSS
pixels. Convert them by page zoom before dispatch so physical scrolling
covers a smaller page area when zoomed in.
Do this before the UI-side async scrolling shortcut so compositor
scrolling and main-thread fallback scrolling use the same delta. Also
avoid applying the Qt device pixel ratio while converting angle-only
wheel input, since LibWeb later handles device-pixel scaling itself.
Translate Qt native zoom gestures into Web::PinchEvent for the web
content view. This gives the Qt UI the same pinch-to-zoom input path as
the AppKit UI while leaving ordinary wheel scrolling unchanged.
Map the Qt native gesture screen position back into WebContentView
before creating the event, since macOS delivers the gesture through the
top-level widget window after forwarding. Keeping the pinch focal point
in content coordinates lets visual viewport zoom preserve the user's
focus point.
Use QRhiWidget for the Qt web content view on macOS and render the
current IOSurface-backed shared image into the widget's Metal render
target. This keeps normal presentation on the GPU instead of painting a
QImage wrapper over the shared bitmap.
Force Qt Widgets' RHI backing store to Metal before QApplication is
created so QRhiWidget can obtain the top-level QRhi even when the native
window is created before the web content widget enters the hierarchy.
Other platforms keep the existing QWidget and QPainter path.
TabBar::paintEvent() drew a fresh globe icon for every tab without a
favicon. Creating a chrome icon renders several pixmaps for multiple
states and device pixel ratios, which is far too expensive for a paint
hot path.
Cache the fallback tab icon on TabBar and refresh it alongside the other
chrome icons when the palette changes.