浏览代码

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.
Andreas Kling 4 年之前
父节点
当前提交
15e35b0d71

+ 2 - 2
Libraries/LibWeb/InProcessWebView.cpp

@@ -248,7 +248,7 @@ void InProcessWebView::layout_and_sync_size()
         set_content_size(layout_root()->size().to_type<int>());
     }
 
-    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({});
 }
 

+ 5 - 5
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()) {

+ 3 - 3
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<InProcessWebView>);
 
@@ -109,7 +109,7 @@ private:
     WeakPtr<DOM::Element> m_host_element;
     RefPtr<DOM::Document> m_document;
     Gfx::IntSize m_size;
-    Gfx::IntRect m_viewport_rect;
+    Gfx::IntPoint m_viewport_scroll_offset;
 
     DOM::Position m_cursor_position;
     RefPtr<Core::Timer> m_cursor_blink_timer;

+ 1 - 1
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)