From b7f078f7399995dd1301b87dd6030685bfc0c0da Mon Sep 17 00:00:00 2001 From: Sergey Bugaev <bugaevc@gmail.com> Date: Tue, 22 Oct 2024 13:27:21 +0300 Subject: [PATCH 1/3] layoutmanager: Skip invisible children when determining request mode We don't generally care about hidden (or native) children when performing layout, as is indeed suggested by the should_layout () method name. Specifically for determining request mode, we'd like to return constant size whenever we can, since this can result in very valueable performance gains when measuring ancestor widgets. In case we have some visible constant-size children and some hidden height-for-width ones, we can still return constant-size. Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- gtk/gtklayoutmanager.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gtk/gtklayoutmanager.c b/gtk/gtklayoutmanager.c index 6467b8ee5a..20e974b5ae 100644 --- a/gtk/gtklayoutmanager.c +++ b/gtk/gtklayoutmanager.c @@ -122,7 +122,12 @@ gtk_layout_manager_real_get_request_mode (GtkLayoutManager *manager, child != NULL; child = _gtk_widget_get_next_sibling (child)) { - GtkSizeRequestMode res = gtk_widget_get_request_mode (child); + GtkSizeRequestMode res; + + if (!gtk_widget_should_layout (child)) + continue; + + res = gtk_widget_get_request_mode (child); switch (res) { From ed8c457c3a1db89b450380cfd860f1aede46c0f7 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev <bugaevc@gmail.com> Date: Thu, 19 Dec 2024 18:59:21 +0300 Subject: [PATCH 2/3] layoutmanager: With wfh == hfw, prefer hfw We generally much prefer height-for-width over width-for-height, since the former is typically better supported and faster, and the latter is known to cause issues, most notably with wrappable labels. So when we have two children with differing preferences and so have to make an arbitrary choice between the two, prefer height-for-width. Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- gtk/gtklayoutmanager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtk/gtklayoutmanager.c b/gtk/gtklayoutmanager.c index 20e974b5ae..47ced92b07 100644 --- a/gtk/gtklayoutmanager.c +++ b/gtk/gtklayoutmanager.c @@ -148,8 +148,8 @@ gtk_layout_manager_real_get_request_mode (GtkLayoutManager *manager, if (hfw == 0 && wfh == 0) return GTK_SIZE_REQUEST_CONSTANT_SIZE; - return hfw > wfh ? GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH - : GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT; + return hfw >= wfh ? GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH + : GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT; } static void From a71bb2165e2057ea51afd615b58f74bc067b62cf Mon Sep 17 00:00:00 2001 From: Sergey Bugaev <bugaevc@gmail.com> Date: Tue, 26 Nov 2024 10:34:22 +0300 Subject: [PATCH 3/3] stack: Report constant-size in more cases Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- gtk/gtkstack.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c index 001bb26d65..a19f9cea7b 100644 --- a/gtk/gtkstack.c +++ b/gtk/gtkstack.c @@ -2328,9 +2328,30 @@ gtk_stack_compute_expand (GtkWidget *widget, static GtkSizeRequestMode gtk_stack_get_request_mode (GtkWidget *widget) { + GtkStack *stack = GTK_STACK (widget); + GtkStackPrivate *priv = gtk_stack_get_instance_private (stack); GtkWidget *w; int wfh = 0, hfw = 0; + if (!priv->homogeneous[GTK_ORIENTATION_VERTICAL] && + !priv->homogeneous[GTK_ORIENTATION_HORIZONTAL]) + { + GtkSizeRequestMode lv_mode; + + /* Only the visible child, and perhaps the last visible child + * during a transition, matter. Attempt to return constant-size + * when we can. */ + if (priv->last_visible_child) + lv_mode = gtk_widget_get_request_mode (priv->last_visible_child->widget); + else + lv_mode = GTK_SIZE_REQUEST_CONSTANT_SIZE; + + if (lv_mode == GTK_SIZE_REQUEST_CONSTANT_SIZE && priv->visible_child) + return gtk_widget_get_request_mode (priv->visible_child->widget); + else + return lv_mode; + } + for (w = gtk_widget_get_first_child (widget); w != NULL; w = gtk_widget_get_next_sibling (w))