From c4c118e425341707f2351621e94cf241f0706321 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Sat, 2 Sep 2023 21:22:58 +0300 Subject: [PATCH 1/2] centerlayout: Fix measuring in presence of baselines The measure logic (unlike the allocation logic) was enforcing strict baseline alignment of child widgets even if no child widget had valign set to baseline. This was causing GtkCenterLayout to request more size than it actually needed. Instead, bring the logic closer to that of GtkBoxLayout by introducing explicit have_baseline and align_baseline variables. We track and report baseline if have_baseline gets set, but it only affects our reported minimum and natural sizes if align_baseline ends up set, which happens if there's a child widget that has valign set to either one of the two baseline values, and itself reports a valid baseline. Signed-off-by: Sergey Bugaev --- gtk/gtkcenterlayout.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/gtk/gtkcenterlayout.c b/gtk/gtkcenterlayout.c index 2660a4d47c..a01522308d 100644 --- a/gtk/gtkcenterlayout.c +++ b/gtk/gtkcenterlayout.c @@ -282,6 +282,8 @@ gtk_center_layout_measure_opposite (GtkCenterLayout *self, int total_nat, above_nat, below_nat; GtkWidget *child[3]; GtkRequestedSize sizes[3]; + gboolean have_baseline = FALSE; + gboolean align_baseline = FALSE; int i; child[0] = self->start_widget; @@ -305,27 +307,33 @@ gtk_center_layout_measure_opposite (GtkCenterLayout *self, &child_min, &child_nat, &child_min_baseline, &child_nat_baseline); - if (child_min_baseline >= 0) + total_min = MAX (total_min, child_min); + total_nat = MAX (total_nat, child_nat); + + if (orientation == GTK_ORIENTATION_VERTICAL && child_min_baseline >= 0) { + have_baseline = TRUE; + if (gtk_widget_get_valign (child[i]) == GTK_ALIGN_BASELINE_FILL || + gtk_widget_get_valign (child[i]) == GTK_ALIGN_BASELINE_CENTER) + align_baseline = TRUE; + below_min = MAX (below_min, child_min - child_min_baseline); above_min = MAX (above_min, child_min_baseline); below_nat = MAX (below_nat, child_nat - child_nat_baseline); above_nat = MAX (above_nat, child_nat_baseline); } - else - { - total_min = MAX (total_min, child_min); - total_nat = MAX (total_nat, child_nat); - } } - if (above_min >= 0) + if (have_baseline) { int min_baseline = -1; int nat_baseline = -1; - total_min = MAX (total_min, above_min + below_min); - total_nat = MAX (total_nat, above_nat + below_nat); + if (align_baseline) + { + total_min = MAX (total_min, above_min + below_min); + total_nat = MAX (total_nat, above_nat + below_nat); + } switch (self->baseline_pos) { From 31da6f60d042d962981e1a10241b8f7d826eaf49 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Sat, 2 Sep 2023 21:31:18 +0300 Subject: [PATCH 2/2] entry, searchentry: Fix measuring baseline If the entry has icons, we may end up increasing our minimum and natural height compared to the values the text child returned. In that case, we should also adjust the baseline values to account for the text being shifted down. Signed-off-by: Sergey Bugaev --- gtk/gtkentry.c | 14 +++++++++++++- gtk/gtksearchentry.c | 11 ++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 67281c2f36..30521f640c 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -1646,14 +1646,18 @@ gtk_entry_measure (GtkWidget *widget, { GtkEntry *entry = GTK_ENTRY (widget); GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry); + int text_min, text_nat; int i; gtk_widget_measure (priv->text, orientation, for_size, - minimum, natural, + &text_min, &text_nat, minimum_baseline, natural_baseline); + *minimum = text_min; + *natural = text_nat; + for (i = 0; i < MAX_ICONS; i++) { EntryIconInfo *icon_info = priv->icons[i]; @@ -1691,6 +1695,14 @@ gtk_entry_measure (GtkWidget *widget, *minimum = MAX (*minimum, prog_min); *natural = MAX (*natural, prog_nat); } + + if (orientation == GTK_ORIENTATION_VERTICAL) + { + if (G_LIKELY (*minimum_baseline >= 0)) + *minimum_baseline += (*minimum - text_min) / 2; + if (G_LIKELY (*natural_baseline >= 0)) + *natural_baseline += (*natural - text_nat) / 2; + } } static void diff --git a/gtk/gtksearchentry.c b/gtk/gtksearchentry.c index 6191d1f01e..eb35fc1bd4 100644 --- a/gtk/gtksearchentry.c +++ b/gtk/gtksearchentry.c @@ -301,6 +301,7 @@ gtk_search_entry_measure (GtkWidget *widget, int *natural_baseline) { GtkSearchEntry *entry = GTK_SEARCH_ENTRY (widget); + int text_min, text_nat; int icon_min, icon_nat; int spacing; @@ -309,9 +310,12 @@ gtk_search_entry_measure (GtkWidget *widget, gtk_widget_measure (entry->entry, orientation, for_size, - minimum, natural, + &text_min, &text_nat, minimum_baseline, natural_baseline); + *minimum = text_min; + *natural = text_nat; + gtk_widget_measure (entry->search_icon, GTK_ORIENTATION_HORIZONTAL, -1, @@ -344,6 +348,11 @@ gtk_search_entry_measure (GtkWidget *widget, { *minimum = MAX (*minimum, icon_min); *natural = MAX (*natural, icon_nat); + + if (G_LIKELY (*minimum_baseline >= 0)) + *minimum_baseline += (*minimum - text_min) / 2; + if (G_LIKELY (*natural_baseline >= 0)) + *natural_baseline += (*natural - text_nat) / 2; } }