From 15e35b0d716ea8fe2fab7a9607902dedc978688a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 2 Dec 2020 23:40:57 +0100 Subject: [PATCH] LibWeb: Layout viewport rect was lagging behind when resizing Layout was using an outdated viewport rect that we set *after* doing a layout due to resize. That meant that layout-in-response-to-resize was always lagging behind the current size of the view. The root of this problem was how Frame kept both a viewport rect (with both scroll offset and size) and a frame size. To fix this, only store the viewport scroll offset, and always use the frame size. This way they can't get out of sync and the problem goes away. :^) Fixes #4250. --- Libraries/LibWeb/InProcessWebView.cpp | 4 ++-- Libraries/LibWeb/Page/Frame.cpp | 10 +++++----- Libraries/LibWeb/Page/Frame.h | 6 +++--- Services/WebContent/PageHost.cpp | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Libraries/LibWeb/InProcessWebView.cpp b/Libraries/LibWeb/InProcessWebView.cpp index 88fe7670090..c878f20750f 100644 --- a/Libraries/LibWeb/InProcessWebView.cpp +++ b/Libraries/LibWeb/InProcessWebView.cpp @@ -248,7 +248,7 @@ void InProcessWebView::layout_and_sync_size() set_content_size(layout_root()->size().to_type()); } - page().main_frame().set_viewport_rect(viewport_rect_in_content_coordinates()); + page().main_frame().set_viewport_scroll_offset({ horizontal_scrollbar().value(), vertical_scrollbar().value() }); } void InProcessWebView::resize_event(GUI::ResizeEvent& event) @@ -409,7 +409,7 @@ void InProcessWebView::set_document(DOM::Document* document) void InProcessWebView::did_scroll() { - page().main_frame().set_viewport_rect(viewport_rect_in_content_coordinates()); + page().main_frame().set_viewport_scroll_offset({ horizontal_scrollbar().value(), vertical_scrollbar().value() }); page().main_frame().did_scroll({}); } diff --git a/Libraries/LibWeb/Page/Frame.cpp b/Libraries/LibWeb/Page/Frame.cpp index c9e0a3e6cdc..333425f8acf 100644 --- a/Libraries/LibWeb/Page/Frame.cpp +++ b/Libraries/LibWeb/Page/Frame.cpp @@ -106,19 +106,19 @@ void Frame::set_size(const Gfx::IntSize& size) m_document->layout(); } -void Frame::set_viewport_rect(const Gfx::IntRect& rect) +void Frame::set_viewport_scroll_offset(const Gfx::IntPoint& offset) { - if (m_viewport_rect == rect) + if (m_viewport_scroll_offset == offset) return; - m_viewport_rect = rect; + m_viewport_scroll_offset = offset; if (m_document && m_document->layout_node()) - m_document->layout_node()->did_set_viewport_rect({}, rect); + m_document->layout_node()->did_set_viewport_rect({}, viewport_rect()); } void Frame::set_needs_display(const Gfx::IntRect& rect) { - if (!m_viewport_rect.intersects(rect)) + if (!viewport_rect().intersects(rect)) return; if (is_main_frame()) { diff --git a/Libraries/LibWeb/Page/Frame.h b/Libraries/LibWeb/Page/Frame.h index 2696454182b..6e0a336bf17 100644 --- a/Libraries/LibWeb/Page/Frame.h +++ b/Libraries/LibWeb/Page/Frame.h @@ -63,8 +63,8 @@ public: void set_needs_display(const Gfx::IntRect&); - void set_viewport_rect(const Gfx::IntRect&); - Gfx::IntRect viewport_rect() const { return m_viewport_rect; } + void set_viewport_scroll_offset(const Gfx::IntPoint&); + Gfx::IntRect viewport_rect() const { return { m_viewport_scroll_offset, m_size }; } void did_scroll(Badge); @@ -109,7 +109,7 @@ private: WeakPtr m_host_element; RefPtr m_document; Gfx::IntSize m_size; - Gfx::IntRect m_viewport_rect; + Gfx::IntPoint m_viewport_scroll_offset; DOM::Position m_cursor_position; RefPtr m_cursor_blink_timer; diff --git a/Services/WebContent/PageHost.cpp b/Services/WebContent/PageHost.cpp index a23cf0c764d..5e8952143c9 100644 --- a/Services/WebContent/PageHost.cpp +++ b/Services/WebContent/PageHost.cpp @@ -103,7 +103,7 @@ void PageHost::set_viewport_rect(const Gfx::IntRect& rect) page().main_frame().set_size(rect.size()); if (page().main_frame().document()) page().main_frame().document()->layout(); - page().main_frame().set_viewport_rect(rect); + page().main_frame().set_viewport_scroll_offset(rect.location()); } void PageHost::page_did_invalidate(const Gfx::IntRect& content_rect)