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)