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.
This commit is contained in:
parent
d0799f3648
commit
98a6149b4f
Notes:
sideshowbarker
2024-07-19 11:32:20 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/98a6149b4fe
4 changed files with 24 additions and 14 deletions
|
@ -146,6 +146,10 @@ void GWidget::set_layout(OwnPtr<GLayout>&& layout)
|
||||||
|
|
||||||
void GWidget::do_layout()
|
void GWidget::do_layout()
|
||||||
{
|
{
|
||||||
|
for_each_child_widget([&](auto& child) {
|
||||||
|
child.do_layout();
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
custom_layout();
|
custom_layout();
|
||||||
if (!m_layout)
|
if (!m_layout)
|
||||||
return;
|
return;
|
||||||
|
@ -434,19 +438,8 @@ void GWidget::set_size_policy(SizePolicy horizontal_policy, SizePolicy vertical_
|
||||||
|
|
||||||
void GWidget::invalidate_layout()
|
void GWidget::invalidate_layout()
|
||||||
{
|
{
|
||||||
if (m_layout_dirty)
|
if (window())
|
||||||
return;
|
window()->schedule_relayout();
|
||||||
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)
|
void GWidget::set_visible(bool visible)
|
||||||
|
|
|
@ -201,6 +201,8 @@ public:
|
||||||
|
|
||||||
virtual void save_to(AK::JsonObject&) override;
|
virtual void save_to(AK::JsonObject&) override;
|
||||||
|
|
||||||
|
void do_layout();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit GWidget(GWidget* parent = nullptr);
|
explicit GWidget(GWidget* parent = nullptr);
|
||||||
|
|
||||||
|
@ -234,7 +236,6 @@ private:
|
||||||
void handle_mouseup_event(GMouseEvent&);
|
void handle_mouseup_event(GMouseEvent&);
|
||||||
void handle_enter_event(CEvent&);
|
void handle_enter_event(CEvent&);
|
||||||
void handle_leave_event(CEvent&);
|
void handle_leave_event(CEvent&);
|
||||||
void do_layout();
|
|
||||||
void focus_previous_widget();
|
void focus_previous_widget();
|
||||||
void focus_next_widget();
|
void focus_next_widget();
|
||||||
|
|
||||||
|
|
|
@ -736,3 +736,16 @@ void GWindow::set_fullscreen(bool fullscreen)
|
||||||
request.value = fullscreen;
|
request.value = fullscreen;
|
||||||
GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetFullscreen);
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -131,6 +131,8 @@ public:
|
||||||
|
|
||||||
virtual void save_to(AK::JsonObject&) override;
|
virtual void save_to(AK::JsonObject&) override;
|
||||||
|
|
||||||
|
void schedule_relayout();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GWindow(CObject* parent = nullptr);
|
GWindow(CObject* parent = nullptr);
|
||||||
virtual void wm_event(GWMEvent&);
|
virtual void wm_event(GWMEvent&);
|
||||||
|
@ -175,4 +177,5 @@ private:
|
||||||
String m_entered_keybind;
|
String m_entered_keybind;
|
||||||
int m_max_keybind_length { 0 };
|
int m_max_keybind_length { 0 };
|
||||||
HashMap<String, WeakPtr<GWidget>> m_keyboard_activation_targets;
|
HashMap<String, WeakPtr<GWidget>> m_keyboard_activation_targets;
|
||||||
|
bool m_layout_pending { false };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue