Commit graph

12 commits

Author SHA1 Message Date
InvalidUsernameException
fbf47e57d0 LibWeb: Paint inspector overlays as a separate pass
The overlay shown for the node hovered in the inspector is painted as
part of the normal tree traversal of all paintables. This works well in
most cases, but falls short in specific scenarios:
* If the hovered node or one of its ancestors establishes a stacking
  context and there is another element that establishes a stacking
  context close by or overlapping it, the overlay and especially the
  tooltip can become partially hidden behind the second element. Ditto
  for elements that act as if they established a stacking context.
* If the hovered node or one of its ancestors involves clipping, the
  clip is applied to the overlay and espicially the tooltip. This can
  cause them to be partially invisible.
* Similarly, if the hovered node or one of its ancestors has a defined
  mask, the mask is applied to the overlay, often making it mostly
  invisible.
* No overlays are shown for SVG nodes because they are painted
  differently from HTML documents.

Some of these problems may be fixable with the current system. But some
seem like they fundamentally cannot work fully when the overlays are
painted as part of the regular tree traversal.

Instead we pull out painting the overlay as a separate pass executed
after the tree traversal. This way we ensure that the overlays are
always painted last and therefore on top of everything else. This also
makes sure that the overlays are unaffected by clips and masks. And
since overlay painting is independent from painting the actual elements,
it just works as well.

However we need to be careful, because we still need to apply some of
the steps of the tree traversal to get the correct result. Namely we
need to apply scroll offsets and transforms. To do so, we collect all
ancestors of the hovered node and apply those as if we were in the
normal tree traversal.
2025-09-19 10:17:56 +02:00
Jelle Raaijmakers
c31eff6a47 Everywhere: Use Optional<T>::ensure() where useful
No functional changes.
2025-09-17 12:01:18 -04:00
Jelle Raaijmakers
64093f7d26 LibWeb: Detach paint tree from layout tree in one go
We used to only walk the paintable root tree from the layout root and
detach paintables from there. In some cases, this could leave paintables
behind, so we added another loop that iterates over all layout nodes and
detaches their paintables, if any remained.

Instead of traversing two trees like this, just traverse the layout tree
once and detach the inclusive descendant's paintables, similar to how we
deal with the DOM tree immediately after that.
2025-09-01 11:20:43 +01:00
Dan Vittegleo
c9fbc2db0b LibWeb: Implement CSS border radius overlapping algorithm
Fixes rendering of elements with large border-radius values by scaling
radii proportionally when they exceed element dimensions per CSS spec.

Co-authored-by: Samyat Gautam <thesamyatgautam@gmail.com>
2025-08-21 11:52:38 +02:00
Andreas Kling
f4ee341a14 Revert "LibWeb: Store visibility for Paintables"
This reverts commit 7dc8062283.

This did not propagate correctly to paintables whose style was inherited
from an ancestor, causing rendering artifacts on https://linear.app/
2025-08-20 09:14:58 +02:00
Andreas Kling
3b63582068 LibWeb: More thoroughly detach layout/paint trees from each other
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Before committing a new layout (and thus building a new paint tree)
we now go through both the old paint tree and the layout tree and detach
them from each other.

This is a little extra work, but it ensures that there are no lingering
references across the trees, which we were apparently accumulating in
some cases on Discord, causing GC leaks.
2025-07-30 16:58:29 -04:00
Jelle Raaijmakers
7dc8062283 LibWeb: Store visibility for Paintables
For every invocation of `::before_paint()` and `::after_paint()`, we
would reach into the node's computed values to determine its visibility.
Let's just do this once during construction of the paintable instead,
since this was showing up in profiles.
2025-06-17 11:55:28 +02:00
Sam Atkins
bfd7ac1204 LibWeb+WebContent+UI: Support image cursors
The `cursor` property accepts a list of possible cursors, which behave
as a fallback: We use whichever cursor is the first available one. This
is a little complicated because initially, any remote images have not
loaded, so we need to use the fallback standard cursor, and then switch
to another when it loads.

So, ComputedValues stores a Vector of cursors, and then in EventHandler
we scan down that list until we find a cursor that's ready for use.

The spec defines cursors as being `<url>`, but allows for `<image>`
instead. That includes functions like `linear-gradient()`.

This commit implements image cursors in the Qt UI, but not AppKit.
2025-02-28 13:50:13 +01:00
Tim Ledbetter
cb405c773b LibWeb: Ensure inert elements are not visible for hit testing 2025-02-21 12:41:57 +00:00
Aliaksandr Kalenik
9f541c363d LibWeb: Allow stacking context to only be created by PaintableBox
For a while we used the wider Paintable type for stacking context,
because it was allowed to be created by InlinePaintable and
PaintableBox. Now, when InlinePaintable type is gone, we can use more
specific PaintableBox type for a stacking context.
2024-11-18 20:07:30 +01:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Renamed from Userland/Libraries/LibWeb/Painting/Paintable.cpp (Browse further)