diff --git a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
index 13b39e96aa8..9767ccc3291 100644
--- a/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
+++ b/Userland/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp
@@ -327,7 +327,10 @@ void EventLoop::process()
if (navigable && navigable->needs_repaint()) {
auto* browsing_context = document.browsing_context();
auto& page = browsing_context->page();
- page.client().schedule_repaint();
+ if (navigable->is_traversable()) {
+ VERIFY(page.client().is_ready_to_paint());
+ page.client().paint_next_frame();
+ }
}
});
diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp
index 61a0bbffa06..be8097a5946 100644
--- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp
@@ -2133,8 +2133,9 @@ void Navigable::paint(Painting::RecordingPainter& recording_painter, PaintConfig
auto background_color = document->background_color();
recording_painter.fill_rect(bitmap_rect, background_color);
- if (!document->paintable())
- return;
+ if (!document->paintable()) {
+ VERIFY_NOT_REACHED();
+ }
Web::PaintContext context(recording_painter, page.palette(), page.client().device_pixels_per_css_pixel());
context.set_device_viewport_rect(viewport_rect);
diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h
index 5c730b668df..e2f347c909d 100644
--- a/Userland/Libraries/LibWeb/Page/Page.h
+++ b/Userland/Libraries/LibWeb/Page/Page.h
@@ -247,6 +247,7 @@ public:
virtual DevicePixelRect screen_rect() const = 0;
virtual double device_pixels_per_css_pixel() const = 0;
virtual CSS::PreferredColorScheme preferred_color_scheme() const = 0;
+ virtual void paint_next_frame() = 0;
virtual void paint(DevicePixelRect const&, Gfx::Bitmap&, PaintOptions = {}) = 0;
virtual void page_did_change_title(ByteString const&) { }
virtual void page_did_change_url(URL::URL const&) { }
diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h
index e7e9eb63b85..2cbcdaaf408 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h
+++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.h
@@ -73,6 +73,7 @@ public:
virtual double device_pixels_per_css_pixel() const override { return 1.0; }
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_next_frame() override { }
virtual void paint(DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override { }
virtual void schedule_repaint() override { }
virtual bool is_ready_to_paint() const override { return true; }
diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp
index 3e0288e591e..6d77686dd5c 100644
--- a/Userland/Services/WebContent/PageClient.cpp
+++ b/Userland/Services/WebContent/PageClient.cpp
@@ -57,23 +57,6 @@ PageClient::PageClient(PageHost& owner, u64 id)
{
setup_palette();
- m_repaint_timer = Web::Platform::Timer::create_single_shot(0, [this] {
- if (!m_backing_stores.back_bitmap) {
- return;
- }
-
- auto& back_bitmap = *m_backing_stores.back_bitmap;
- auto viewport_rect = page().css_to_device_rect(page().top_level_traversable()->viewport_rect());
- paint(viewport_rect, back_bitmap);
-
- auto& backing_stores = m_backing_stores;
- swap(backing_stores.front_bitmap, backing_stores.back_bitmap);
- swap(backing_stores.front_bitmap_id, backing_stores.back_bitmap_id);
-
- m_paint_state = PaintState::WaitingForClient;
- client().async_did_paint(m_id, viewport_rect.to_type(), backing_stores.front_bitmap_id);
- });
-
#ifdef HAS_ACCELERATED_GRAPHICS
if (s_use_gpu_painter) {
auto context = AccelGfx::Context::create();
@@ -92,9 +75,6 @@ void PageClient::schedule_repaint()
m_paint_state = PaintState::PaintWhenReady;
return;
}
-
- if (!m_repaint_timer->is_active())
- m_repaint_timer->start();
}
bool PageClient::is_ready_to_paint() const
@@ -197,6 +177,24 @@ Web::Layout::Viewport* PageClient::layout_root()
return document->layout_node();
}
+void PageClient::paint_next_frame()
+{
+ if (!m_backing_stores.back_bitmap) {
+ return;
+ }
+
+ auto& back_bitmap = *m_backing_stores.back_bitmap;
+ auto viewport_rect = page().css_to_device_rect(page().top_level_traversable()->viewport_rect());
+ paint(viewport_rect, back_bitmap);
+
+ auto& backing_stores = m_backing_stores;
+ swap(backing_stores.front_bitmap, backing_stores.back_bitmap);
+ swap(backing_stores.front_bitmap_id, backing_stores.back_bitmap_id);
+
+ m_paint_state = PaintState::WaitingForClient;
+ client().async_did_paint(m_id, viewport_rect.to_type(), backing_stores.front_bitmap_id);
+}
+
void PageClient::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& target, Web::PaintOptions paint_options)
{
Web::Painting::CommandList painting_commands;
diff --git a/Userland/Services/WebContent/PageClient.h b/Userland/Services/WebContent/PageClient.h
index d7c333f4fec..4774f68076e 100644
--- a/Userland/Services/WebContent/PageClient.h
+++ b/Userland/Services/WebContent/PageClient.h
@@ -39,6 +39,7 @@ public:
ErrorOr connect_to_webdriver(ByteString const& webdriver_ipc_path);
+ virtual void paint_next_frame() override;
virtual void paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap&, Web::PaintOptions = {}) override;
void set_palette_impl(Gfx::PaletteImpl&);
@@ -177,7 +178,6 @@ private:
};
PaintState m_paint_state { PaintState::Ready };
- RefPtr m_repaint_timer;
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
diff --git a/Userland/Services/WebWorker/PageHost.h b/Userland/Services/WebWorker/PageHost.h
index 6f85ddbaf91..9c995a82a70 100644
--- a/Userland/Services/WebWorker/PageHost.h
+++ b/Userland/Services/WebWorker/PageHost.h
@@ -29,6 +29,7 @@ public:
virtual Web::DevicePixelRect screen_rect() const override;
virtual double device_pixels_per_css_pixel() const override;
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override;
+ virtual void paint_next_frame() override {};
virtual void paint(Web::DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override;
virtual void request_file(Web::FileRequest) override;
virtual void schedule_repaint() override {};