diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
index cb583a7db95..9461fb47bd9 100644
--- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
+++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
@@ -196,6 +196,22 @@ void EventLoop::process()
}
};
+ // AD-HOC: Since event loop processing steps do not constantly running in parallel, and
+ // something must trigger them, we need to manually schedule a repaint for all
+ // navigables that do not have a rendering opportunity at this event loop iteration.
+ // Otherwise their repaint will be delayed until something else will trigger event
+ // loop processing.
+ for_each_fully_active_document_in_docs([&](DOM::Document& document) {
+ auto navigable = document.navigable();
+ if (navigable && navigable->has_a_rendering_opportunity())
+ return;
+ auto* browsing_context = document.browsing_context();
+ if (!browsing_context)
+ return;
+ auto& page = browsing_context->page();
+ page.client().schedule_repaint();
+ });
+
// 2. Rendering opportunities: Remove from docs all Document objects whose node navigables do not have a rendering opportunity.
docs.remove_all_matching([&](auto& document) {
auto navigable = document->navigable();
diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp
index 51a4039d71b..0ea02a26d05 100644
--- a/Userland/Services/WebContent/PageClient.cpp
+++ b/Userland/Services/WebContent/PageClient.cpp
@@ -105,8 +105,11 @@ void PageClient::ready_to_paint()
{
auto old_paint_state = exchange(m_paint_state, PaintState::Ready);
- if (old_paint_state == PaintState::PaintWhenReady)
- schedule_repaint();
+ if (old_paint_state == PaintState::PaintWhenReady) {
+ // NOTE: Repainting always has to be scheduled from HTML event loop processing steps
+ // to make sure style and layout are up-to-date.
+ page().top_level_traversable()->set_needs_display();
+ }
}
void PageClient::add_backing_store(i32 front_bitmap_id, Gfx::ShareableBitmap const& front_bitmap, i32 back_bitmap_id, Gfx::ShareableBitmap const& back_bitmap)