[gtk/wip/otte/hfw-min-size] window: Add a new fancy way to compute min size
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/hfw-min-size] window: Add a new fancy way to compute min size
- Date: Sun, 21 Nov 2021 06:47:11 +0000 (UTC)
commit 4517d91ecfaf985d96d4d1279b062765ed5f550e
Author: Benjamin Otte <otte redhat com>
Date: Sun Nov 21 07:06:11 2021 +0100
window: Add a new fancy way to compute min size
Try to compute a min size that matches the current aspect ratio.
This means that when interactively resizing, we adapt the min size to
the current window area dynamically.
And that means that we always have a min size that is large enough, but
users can interactively cause it to be small-width x large-height,
large-width x small-width or anything inbetween.
gtk/gtkwindow.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 25efe4e6b9..ce4436e1b2 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -4179,6 +4179,61 @@ update_realized_window_properties (GtkWindow *window)
}
}
+/* NB: When orientation is VERTICAL, width/height are flipped.
+ * The code uses the terms nonetheless to make it more intuitive
+ * to understand.
+ */
+static void
+gtk_window_compute_min_size (GtkWidget *window,
+ GtkOrientation orientation,
+ double ideal_ratio,
+ int *min_width,
+ int *min_height)
+{
+ int start, end, mid, other;
+ double ratio;
+
+ /* start = min width, end = min width for min height (ie max width) */
+ gtk_widget_measure (window, orientation, -1, &start, NULL, NULL, NULL);
+ gtk_widget_measure (window, OPPOSITE_ORIENTATION (orientation), start, &other, NULL, NULL, NULL);
+ if ((double) start / other >= ideal_ratio)
+ {
+ *min_width = start;
+ *min_height = other;
+ return;
+ }
+ gtk_widget_measure (window, OPPOSITE_ORIENTATION (orientation), -1, &other, NULL, NULL, NULL);
+ gtk_widget_measure (window, orientation, other, &end, NULL, NULL, NULL);
+ if ((double) end / other <= ideal_ratio)
+ {
+ *min_width = end;
+ *min_height = other;
+ return;
+ }
+
+ while (start < end)
+ {
+ mid = (start + end) / 2;
+
+ gtk_widget_measure (window, OPPOSITE_ORIENTATION (orientation), mid, &other, NULL, NULL, NULL);
+ ratio = (double) mid / other;
+ if(ratio == ideal_ratio)
+ {
+ *min_width = mid;
+ *min_height = other;
+ return;
+ }
+ else if (ratio < ideal_ratio)
+ start = mid + 1;
+ else
+ end = mid - 1;
+ }
+
+ gtk_widget_measure (window, orientation, other, &start, NULL, NULL, NULL);
+ *min_width = start;
+ *min_height = other;
+}
+
static void
gtk_window_compute_default_size (GtkWindow *window,
int cur_width,
@@ -4191,8 +4246,9 @@ gtk_window_compute_default_size (GtkWindow *window,
int *height)
{
GtkWidget *widget = GTK_WIDGET (window);
+ GtkSizeRequestMode request_mode = gtk_widget_get_request_mode (widget);
- if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
+ if (request_mode == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
{
int minimum, natural;
@@ -4212,6 +4268,8 @@ gtk_window_compute_default_size (GtkWindow *window,
if (cur_width <= 0)
cur_width = natural;
*width = MAX (minimum, MIN (max_width, cur_width));
+
+ gtk_window_compute_min_size (widget, GTK_ORIENTATION_VERTICAL, (double) *height / *width, min_height,
min_width);
}
else /* GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or CONSTANT_SIZE */
{
@@ -4234,6 +4292,9 @@ gtk_window_compute_default_size (GtkWindow *window,
cur_height = natural;
*height = MAX (minimum, MIN (max_height, cur_height));
+
+ if (request_mode != GTK_SIZE_REQUEST_CONSTANT_SIZE)
+ gtk_window_compute_min_size (widget, GTK_ORIENTATION_HORIZONTAL, (double) *width / *height,
min_width, min_height);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]