From 8ba18dfd404543290774f21ee3ed6c802e3371cd Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sun, 18 Feb 2024 19:40:11 +0100 Subject: [PATCH] LibWeb: Schedule repainting from EventLoop::process() In this change, updating layout and painting are moved to the EventLoop processing steps. This modification allows the addition of resize observation dispatching that needs to happen in event loop processing steps and must occur in the following order relative to layout and painting: 1. Update layout. 2. Gather and broadcast resize observations. 3. Paint. --- Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp | 8 +++++++- Userland/Libraries/LibWeb/Page/Page.h | 2 ++ Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp | 1 + Userland/Services/WebContent/PageClient.cpp | 4 ++-- Userland/Services/WebContent/PageClient.h | 2 +- Userland/Services/WebWorker/PageHost.h | 1 + 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp index dcb5ff2736..923be22bca 100644 --- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp +++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -213,7 +214,12 @@ void EventLoop::process() // FIXME: 15. Invoke the mark paint timing algorithm for each Document object in docs. - // FIXME: 16. For each fully active Document in docs, update the rendering or user interface of that Document and its browsing context to reflect the current state. + // 16. For each fully active Document in docs, update the rendering or user interface of that Document and its browsing context to reflect the current state. + for_each_fully_active_document_in_docs([&](DOM::Document& document) { + auto* browsing_context = document.browsing_context(); + auto& page = browsing_context->page(); + page.client().schedule_repaint(); + }); // 13. If all of the following are true // - this is a window event loop diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h index c2f402df5e..9e05a7d7ef 100644 --- a/Userland/Libraries/LibWeb/Page/Page.h +++ b/Userland/Libraries/LibWeb/Page/Page.h @@ -302,6 +302,8 @@ public: virtual void inspector_did_request_dom_tree_context_menu([[maybe_unused]] i32 node_id, [[maybe_unused]] CSSPixelPoint position, [[maybe_unused]] String const& type, [[maybe_unused]] Optional const& tag, [[maybe_unused]] Optional const& attribute_name, [[maybe_unused]] Optional const& attribute_value) { } virtual void inspector_did_execute_console_script([[maybe_unused]] String const& script) { } + virtual void schedule_repaint() = 0; + protected: virtual ~PageClient() = default; }; diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp index 9c32a874a5..ada4cb1183 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp @@ -48,6 +48,7 @@ public: virtual CSS::PreferredColorScheme preferred_color_scheme() const override { return m_host_page.client().preferred_color_scheme(); } virtual void request_file(FileRequest) override { } virtual void paint(DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override { } + virtual void schedule_repaint() override { } private: explicit SVGPageClient(Page& host_page) diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp index 56d2ed76de..52f0f882b6 100644 --- a/Userland/Services/WebContent/PageClient.cpp +++ b/Userland/Services/WebContent/PageClient.cpp @@ -222,12 +222,12 @@ void PageClient::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& ta void PageClient::set_viewport_rect(Web::DevicePixelRect const& rect) { page().top_level_traversable()->set_viewport_rect(page().device_to_css_rect(rect)); - schedule_repaint(); + Web::HTML::main_thread_event_loop().schedule(); } void PageClient::page_did_invalidate(Web::CSSPixelRect const&) { - schedule_repaint(); + Web::HTML::main_thread_event_loop().schedule(); } void PageClient::page_did_request_cursor_change(Gfx::StandardCursor cursor) diff --git a/Userland/Services/WebContent/PageClient.h b/Userland/Services/WebContent/PageClient.h index 318647f4cd..11af94568f 100644 --- a/Userland/Services/WebContent/PageClient.h +++ b/Userland/Services/WebContent/PageClient.h @@ -28,7 +28,7 @@ public: static void set_use_gpu_painter(); - void schedule_repaint(); + virtual void schedule_repaint() override; virtual Web::Page& page() override { return *m_page; } virtual Web::Page const& page() const override { return *m_page; } diff --git a/Userland/Services/WebWorker/PageHost.h b/Userland/Services/WebWorker/PageHost.h index 55e41a8e1d..61a2b8ef83 100644 --- a/Userland/Services/WebWorker/PageHost.h +++ b/Userland/Services/WebWorker/PageHost.h @@ -30,6 +30,7 @@ public: virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override; virtual void paint(Web::DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override; virtual void request_file(Web::FileRequest) override; + virtual void schedule_repaint() override {}; private: explicit PageHost(ConnectionFromClient&);