diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-18 22:57:24 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-18 22:57:24 +0200 |
commit | 9e6b0ccc0e1d5f830b82ae719a689d0605e0f607 (patch) | |
tree | 2e829b65ee43485e5fdbb1e27c2b2c861bdf75d4 | |
parent | 0e6b27362045c8f6511cec27c2e2108dd95c105a (diff) | |
download | serenity-9e6b0ccc0e1d5f830b82ae719a689d0605e0f607.zip |
LibCore+LibGUI: Make CObject child events synchronous.
...and then make GWidget layout invalidation lazy. This way we coalesce
multiple invalidations into a single relayout and we don't have to worry
about child widgets not being fully constructed.
-rw-r--r-- | LibCore/CObject.cpp | 7 | ||||
-rw-r--r-- | LibCore/CObject.h | 5 | ||||
-rw-r--r-- | LibGUI/GWidget.cpp | 22 | ||||
-rw-r--r-- | LibGUI/GWidget.h | 1 |
4 files changed, 22 insertions, 13 deletions
diff --git a/LibCore/CObject.cpp b/LibCore/CObject.cpp index 42b471eba0..e4f7392d87 100644 --- a/LibCore/CObject.cpp +++ b/LibCore/CObject.cpp @@ -4,8 +4,9 @@ #include <AK/Assertions.h> #include <stdio.h> -CObject::CObject(CObject* parent) +CObject::CObject(CObject* parent, bool is_widget) : m_parent(parent) + , m_widget(is_widget) { if (m_parent) m_parent->add_child(*this); @@ -43,7 +44,7 @@ void CObject::event(CEvent& event) void CObject::add_child(CObject& object) { m_children.append(&object); - CEventLoop::current().post_event(*this, make<CChildEvent>(CEvent::ChildAdded, object)); + event(*make<CChildEvent>(CEvent::ChildAdded, object)); } void CObject::remove_child(CObject& object) @@ -51,7 +52,7 @@ void CObject::remove_child(CObject& object) for (ssize_t i = 0; i < m_children.size(); ++i) { if (m_children[i] == &object) { m_children.remove(i); - CEventLoop::current().post_event(*this, make<CChildEvent>(CEvent::ChildRemoved, object)); + event(*make<CChildEvent>(CEvent::ChildRemoved, object)); return; } } diff --git a/LibCore/CObject.h b/LibCore/CObject.h index f8ae55a7b2..e0656b2019 100644 --- a/LibCore/CObject.h +++ b/LibCore/CObject.h @@ -10,7 +10,7 @@ class CTimerEvent; class CObject : public Weakable<CObject> { public: - CObject(CObject* parent = nullptr); + CObject(CObject* parent = nullptr, bool is_widget = false); virtual ~CObject(); virtual const char* class_name() const { return "CObject"; } @@ -36,7 +36,7 @@ public: void deferred_invoke(Function<void(CObject&)>); - virtual bool is_widget() const { return false; } + bool is_widget() const { return m_widget; } virtual bool is_window() const { return false; } protected: @@ -46,5 +46,6 @@ protected: private: CObject* m_parent { nullptr }; int m_timer_id { 0 }; + bool m_widget { false }; Vector<CObject*> m_children; }; diff --git a/LibGUI/GWidget.cpp b/LibGUI/GWidget.cpp index 59c0cb045a..139d3d8ea2 100644 --- a/LibGUI/GWidget.cpp +++ b/LibGUI/GWidget.cpp @@ -11,7 +11,7 @@ #include <unistd.h> GWidget::GWidget(GWidget* parent) - : CObject(parent) + : CObject(parent, true) { set_font(nullptr); m_background_color = Color::LightGray; @@ -143,7 +143,7 @@ void GWidget::do_layout() void GWidget::notify_layout_changed(Badge<GLayout>) { - do_layout(); + invalidate_layout(); } void GWidget::handle_resize_event(GResizeEvent& event) @@ -395,13 +395,19 @@ void GWidget::set_size_policy(SizePolicy horizontal_policy, SizePolicy vertical_ void GWidget::invalidate_layout() { - auto* w = window(); - if (!w) + if (m_layout_dirty) return; - if (!w->main_widget()) - return; - do_layout(); - w->main_widget()->do_layout(); + 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(); + }); } void GWidget::set_visible(bool visible) diff --git a/LibGUI/GWidget.h b/LibGUI/GWidget.h index 1b53543cd5..6198365dfe 100644 --- a/LibGUI/GWidget.h +++ b/LibGUI/GWidget.h @@ -200,6 +200,7 @@ private: bool m_visible { true }; bool m_greedy_for_hits { false }; bool m_enabled { true }; + bool m_layout_dirty { false }; CElapsedTimer m_click_clock; }; |