diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-26 12:27:01 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-26 12:28:54 +0200 |
commit | 98a6149b4fe584cda9c2ba0736b513044a3e893e (patch) | |
tree | 1fcc3b3196af6f86e2f4def04eed89802f5c49ff /Libraries | |
parent | d0799f3648323cf3a6c19c21dda7ab87cb6f3ec0 (diff) | |
download | serenity-98a6149b4fe584cda9c2ba0736b513044a3e893e.zip |
LibGUI: Make GWindow drive relayout and do it recursively
Instead of only doing a relayout in the widget you're invalidating,
we now do a recursive top-down relayout so everything gets updated.
This fixes invalid results after updating a preferred size in some
situations with nested layouts.
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibGUI/GWidget.cpp | 19 | ||||
-rw-r--r-- | Libraries/LibGUI/GWidget.h | 3 | ||||
-rw-r--r-- | Libraries/LibGUI/GWindow.cpp | 13 | ||||
-rw-r--r-- | Libraries/LibGUI/GWindow.h | 3 |
4 files changed, 24 insertions, 14 deletions
diff --git a/Libraries/LibGUI/GWidget.cpp b/Libraries/LibGUI/GWidget.cpp index 07b2fe98e0..a5004de332 100644 --- a/Libraries/LibGUI/GWidget.cpp +++ b/Libraries/LibGUI/GWidget.cpp @@ -146,6 +146,10 @@ void GWidget::set_layout(OwnPtr<GLayout>&& layout) void GWidget::do_layout() { + for_each_child_widget([&](auto& child) { + child.do_layout(); + return IterationDecision::Continue; + }); custom_layout(); if (!m_layout) return; @@ -434,19 +438,8 @@ void GWidget::set_size_policy(SizePolicy horizontal_policy, SizePolicy vertical_ void GWidget::invalidate_layout() { - if (m_layout_dirty) - return; - m_layout_dirty = true; - deferred_invoke([this](auto&) { - m_layout_dirty = false; - auto* w = window(); - if (!w) - return; - if (!w->main_widget()) - return; - do_layout(); - w->main_widget()->do_layout(); - }); + if (window()) + window()->schedule_relayout(); } void GWidget::set_visible(bool visible) diff --git a/Libraries/LibGUI/GWidget.h b/Libraries/LibGUI/GWidget.h index c5f459e690..b7acaa773b 100644 --- a/Libraries/LibGUI/GWidget.h +++ b/Libraries/LibGUI/GWidget.h @@ -201,6 +201,8 @@ public: virtual void save_to(AK::JsonObject&) override; + void do_layout(); + protected: explicit GWidget(GWidget* parent = nullptr); @@ -234,7 +236,6 @@ private: void handle_mouseup_event(GMouseEvent&); void handle_enter_event(CEvent&); void handle_leave_event(CEvent&); - void do_layout(); void focus_previous_widget(); void focus_next_widget(); diff --git a/Libraries/LibGUI/GWindow.cpp b/Libraries/LibGUI/GWindow.cpp index 7620f30acc..bd03ef61d3 100644 --- a/Libraries/LibGUI/GWindow.cpp +++ b/Libraries/LibGUI/GWindow.cpp @@ -736,3 +736,16 @@ void GWindow::set_fullscreen(bool fullscreen) request.value = fullscreen; GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetFullscreen); } + +void GWindow::schedule_relayout() +{ + if (m_layout_pending) + return; + m_layout_pending = true; + deferred_invoke([this](auto&) { + if (main_widget()) + main_widget()->do_layout(); + update(); + m_layout_pending = false; + }); +} diff --git a/Libraries/LibGUI/GWindow.h b/Libraries/LibGUI/GWindow.h index b33b62dfb1..ff11e7e10a 100644 --- a/Libraries/LibGUI/GWindow.h +++ b/Libraries/LibGUI/GWindow.h @@ -131,6 +131,8 @@ public: virtual void save_to(AK::JsonObject&) override; + void schedule_relayout(); + protected: GWindow(CObject* parent = nullptr); virtual void wm_event(GWMEvent&); @@ -175,4 +177,5 @@ private: String m_entered_keybind; int m_max_keybind_length { 0 }; HashMap<String, WeakPtr<GWidget>> m_keyboard_activation_targets; + bool m_layout_pending { false }; }; |