LibWeb: Create clip and scroll frame trees separately for each navigable

While introducing clip and scroll frame trees, I made a mistake by
assuming that the paintable tree includes boxes from nested navigables.
Therefore, this comment in the code was incorrect, and clip/scroll
frames were simply not assigned for iframes:
// NOTE: We only need to refresh the scroll state for traversables
//       because they are responsible for tracking the state of all
//       nested navigables.

As a result, anything with "overflow: scroll" is currently not
scrollable inside an iframe

This change fixes that by ensuring clip and scroll frames are assigned
and refreshed for each navigable. To achieve this, I had to modify the
display list building process to record a separate display list for each
navigable. This is necessary because scroll frame ids are local to a
navigable, making it impossible to call
`DisplayList::apply_scroll_offsets()` on a display list that contains
ids from multiple navigables.
This commit is contained in:
Aliaksandr Kalenik 2024-08-08 14:17:54 +03:00 committed by Andreas Kling
parent 1b2f35c3af
commit ea8d0304e9
Notes: github-actions[bot] 2024-08-10 08:40:33 +00:00
15 changed files with 156 additions and 46 deletions

View file

@ -92,17 +92,16 @@ RefPtr<Gfx::Bitmap> SVGDecodedImageData::render(Gfx::IntSize size) const
m_document->navigable()->set_viewport_size(size.to_type<CSSPixels>());
m_document->update_layout();
auto display_list = Painting::DisplayList::create();
Painting::DisplayListRecorder display_list_recorder(display_list);
m_document->navigable()->record_display_list(display_list_recorder, {});
auto display_list = m_document->navigable()->record_display_list({});
if (!display_list)
return {};
auto painting_command_executor_type = m_page_client->display_list_player_type();
switch (painting_command_executor_type) {
case DisplayListPlayerType::SkiaGPUIfAvailable:
case DisplayListPlayerType::SkiaCPU: {
Painting::DisplayListPlayerSkia display_list_player { *bitmap };
display_list_player.execute(display_list);
display_list_player.execute(*display_list);
break;
}
default: