summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-26 12:27:01 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-26 12:28:54 +0200
commit98a6149b4fe584cda9c2ba0736b513044a3e893e (patch)
tree1fcc3b3196af6f86e2f4def04eed89802f5c49ff /Libraries
parentd0799f3648323cf3a6c19c21dda7ab87cb6f3ec0 (diff)
downloadserenity-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.cpp19
-rw-r--r--Libraries/LibGUI/GWidget.h3
-rw-r--r--Libraries/LibGUI/GWindow.cpp13
-rw-r--r--Libraries/LibGUI/GWindow.h3
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 };
};