From 14f3e4cc63f059eb95d7aedad7b861cfcb507144 Mon Sep 17 00:00:00 2001 From: Matt Birkholz Date: Thu, 11 Aug 2016 17:24:38 -0700 Subject: [PATCH] gtk: GtkPanedView and GtkScrolledView for 3.18.9 (Ubuntu 16.04). --- src/gtk/README | 1 + src/gtk/configure.ac | 2 + ...kpanedview-new.c => gtkpanedview-3.18.9.c} | 663 +++++++++--------- ...ledview-new.c => gtkscrolledview-3.18.9.c} | 298 ++++---- 4 files changed, 519 insertions(+), 445 deletions(-) rename src/gtk/{gtkpanedview-new.c => gtkpanedview-3.18.9.c} (70%) rename src/gtk/{gtkscrolledview-new.c => gtkscrolledview-3.18.9.c} (57%) diff --git a/src/gtk/README b/src/gtk/README index 55b570343..7c4ec3daf 100644 --- a/src/gtk/README +++ b/src/gtk/README @@ -19,6 +19,7 @@ matching or "close enough" version of the toolkit, you will get a treat. Ubuntu Gtk+ + 16.04lts 3.18.9 15.10 3.16.7 15.04 3.14.13 14.10lts 3.10.8 diff --git a/src/gtk/configure.ac b/src/gtk/configure.ac index 25eac34df..f5ce85f4a 100644 --- a/src/gtk/configure.ac +++ b/src/gtk/configure.ac @@ -74,6 +74,8 @@ AC_ARG_WITH([gtk-version], if test "${with_gtk_version}" != guess; then GTK_VERSION=$with_gtk_version +elif pkg-config --exists 'gtk+-3.0 >= 3.18.9' 2>/dev/null; then + GTK_VERSION=3.18.9 elif pkg-config --exists 'gtk+-3.0 >= 3.16.7' 2>/dev/null; then GTK_VERSION=3.16.7 elif pkg-config --exists 'gtk+-3.0 >= 3.14.13' 2>/dev/null; then diff --git a/src/gtk/gtkpanedview-new.c b/src/gtk/gtkpanedview-3.18.9.c similarity index 70% rename from src/gtk/gtkpanedview-new.c rename to src/gtk/gtkpanedview-3.18.9.c index c75c9c7a8..78eaf039a 100644 --- a/src/gtk/gtkpanedview-new.c +++ b/src/gtk/gtkpanedview-3.18.9.c @@ -25,25 +25,32 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. #include "gtkpanedview.h" -static void gtk_paned_view_get_preferred_width (GtkWidget *widget, - gint *minimum_size, - gint *natural_size); -static void gtk_paned_view_get_preferred_height (GtkWidget *widget, - gint *minimum_size, - gint *natural_size); -static void gtk_paned_view_get_preferred_height_for_width - (GtkWidget *layout, - gint width, - gint *minimum_height, - gint *natural_height); -static void gtk_paned_view_get_preferred_width_for_height - (GtkWidget *layout, - gint width, - gint *minimum_height, - gint *natural_height); - -static void gtk_paned_view_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); +static void gtk_paned_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural); +static void gtk_paned_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural); +static void gtk_paned_get_preferred_width_for_height + (GtkWidget *widget, + gint height, + gint *minimum, + gint *natural); +static void gtk_paned_get_preferred_height_for_width + (GtkWidget *widget, + gint width, + gint *minimum, + gint *natural); + +static void gtk_paned_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); + +static void gtk_paned_calc_position (GtkPaned *paned, + gint allocation, + gint child1_width, + gint child1_nat_width, + gint child2_width, + gint child2_nat_width); G_DEFINE_TYPE (GtkPanedView, gtk_paned_view, GTK_TYPE_PANED) @@ -53,11 +60,11 @@ gtk_paned_view_class_init (GtkPanedViewClass *class) { GtkWidgetClass *widget_class = (GtkWidgetClass*) class; - widget_class->get_preferred_width = gtk_paned_view_get_preferred_width; - widget_class->get_preferred_height = gtk_paned_view_get_preferred_height; - widget_class->get_preferred_height_for_width = gtk_paned_view_get_preferred_height_for_width; - widget_class->get_preferred_width_for_height = gtk_paned_view_get_preferred_width_for_height; - widget_class->size_allocate = gtk_paned_view_size_allocate; + widget_class->get_preferred_width = gtk_paned_get_preferred_width; + widget_class->get_preferred_height = gtk_paned_get_preferred_height; + widget_class->get_preferred_height_for_width = gtk_paned_get_preferred_height_for_width; + widget_class->get_preferred_width_for_height = gtk_paned_get_preferred_width_for_height; + widget_class->size_allocate = gtk_paned_size_allocate; } static void @@ -81,17 +88,71 @@ gtk_paned_view_new (GtkOrientation orientation) "orientation", orientation, NULL)); } + +/* Copied from gtkprivate.h. */ +#define OPPOSITE_ORIENTATION(_orientation) (1 - (_orientation)) + +/* Copied from gtksizerequest.c. */ +static void +_gtk_widget_get_preferred_size_for_size (GtkWidget *widget, + GtkOrientation orientation, + gint size, + gint *minimum, + gint *natural, + gint *minimum_baseline, + gint *natural_baseline) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (size >= -1); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + if (size < 0) + gtk_widget_get_preferred_width (widget, minimum, natural); + else + gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural); + + if (minimum_baseline) + *minimum_baseline = -1; + if (natural_baseline) + *natural_baseline = -1; + } + else + { + gtk_widget_get_preferred_height_and_baseline_for_width (widget, + size, + minimum, + natural, + minimum_baseline, + natural_baseline); + } +} -/* The rest of this file was copied from gtkpaned.c v3.6.0 with - minimal modification. */ +/* The following definitions were copied unchanged from gtkpaned.c + v3.18.9 unless otherwise noted. + + enum { CHILD1, CHILD2 } + struct _GtkPanedPrivate + static void gtk_paned_compute_position () PATCHED + static void gtk_paned_get_preferred_size_for_orientation () + static void gtk_paned_get_preferred_size_for_opposite_orientation () PATCHED + static void gtk_paned_get_preferred_size () + static void gtk_paned_get_preferred_width () + static void gtk_paned_get_preferred_height () + static void gtk_paned_get_preferred_width_for_height () + static void gtk_paned_get_preferred_height_for_width () + static void flip_child () + static void gtk_paned_set_child_visible () + static void gtk_paned_child_allocate () + static void gtk_paned_size_allocate () PATCHED + static void gtk_paned_calc_position () PATCHED +*/ enum { CHILD1, CHILD2 }; -typedef struct _GtkCssNode GtkCssNode; - struct _GtkPanedPrivate { GtkPaned *first_paned; @@ -106,7 +167,6 @@ struct _GtkPanedPrivate GdkRectangle handle_pos; GdkWindow *handle; - GtkCssNode *handle_node; GtkGesture *pan_gesture; @@ -127,70 +187,13 @@ struct _GtkPanedPrivate guint panning : 1; }; -static void -flip_child (GtkWidget *widget, - GtkAllocation *child_pos) -{ - GtkAllocation allocation; - gint x, width; - - gtk_widget_get_allocation (widget, &allocation); - x = allocation.x; - width = allocation.width; - - child_pos->x = 2 * x + width - child_pos->x - child_pos->width; -} - -static void -gtk_paned_set_child_visible (GtkPaned *paned, - guint id, - gboolean visible) -{ - GtkPanedPrivate *priv = paned->priv; - GtkWidget *child; - - child = id == CHILD1 ? priv->child1 : priv->child2; - - if (child == NULL) - return; - - gtk_widget_set_child_visible (child, visible); - - if (gtk_widget_get_mapped (GTK_WIDGET (paned))) - { - GdkWindow *window = id == CHILD1 ? priv->child1_window : priv->child2_window; - - if (visible != gdk_window_is_visible (window)) - { - if (visible) - gdk_window_show (window); - else - gdk_window_hide (window); - } - } -} - -static void -gtk_paned_child_allocate (GtkWidget *child, - GdkWindow *child_window, /* can be NULL */ - const GtkAllocation *window_allocation, - GtkAllocation *child_allocation) -{ - if (child_window) - gdk_window_move_resize (child_window, - window_allocation->x, window_allocation->y, - window_allocation->width, window_allocation->height); - - gtk_widget_size_allocate (child, child_allocation); -} - static void gtk_paned_compute_position (GtkPaned *paned, gint allocation, gint child1_min, - gint child1_nat, + gint child1_nat, gint child2_min, - gint child2_nat, + gint child2_nat, gint *min_pos, gint *max_pos, gint *out_pos) @@ -198,11 +201,12 @@ gtk_paned_compute_position (GtkPaned *paned, GtkPanedPrivate *priv = paned->priv; gint min, max, pos; - min = priv->child1_shrink ? 0 : child1_min; + min = (!priv->child1_resize ? child1_nat + : priv->child1_shrink ? 0 : child1_min); - max = allocation; - if (!priv->child2_shrink) - max = MAX (1, max - child2_min); + max = MAX (0, (allocation + - (!priv->child2_resize ? child2_nat + : priv->child2_shrink ? 0 : child2_min))); max = MAX (min, max); if (!priv->position_set) @@ -210,7 +214,7 @@ gtk_paned_compute_position (GtkPaned *paned, if (priv->child1_resize && !priv->child2_resize) pos = MAX (0, allocation - child2_nat); else if (!priv->child1_resize && priv->child2_resize) - pos = child1_nat; + pos = MIN (allocation, child1_nat); else if (child1_nat + child2_nat != 0) pos = allocation * ((gdouble)child1_nat / (child1_nat + child2_nat)) + 0.5; else @@ -245,44 +249,219 @@ gtk_paned_compute_position (GtkPaned *paned, } static void -gtk_paned_calc_position (GtkPaned *paned, - gint allocation, - gint child1_min, - gint child1_nat, - gint child2_min, - gint child2_nat) +gtk_paned_get_preferred_size_for_orientation (GtkWidget *widget, + gint size, + gint *minimum, + gint *natural) { + GtkPaned *paned = GTK_PANED (widget); GtkPanedPrivate *priv = paned->priv; - gint old_position; - gint old_min_position; - gint old_max_position; + gint child_min, child_nat; - old_position = priv->child1_size; - old_min_position = priv->min_position; - old_max_position = priv->max_position; + *minimum = *natural = 0; - gtk_paned_compute_position (paned, - allocation, child1_min, child1_nat, child2_min, child2_nat, - &priv->min_position, &priv->max_position, - &priv->child1_size); + if (priv->child1 && gtk_widget_get_visible (priv->child1)) + { + _gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, size, &child_min, &child_nat, NULL, NULL); + if (priv->child1_shrink) + *minimum = 0; + else + *minimum = child_min; + *natural = child_nat; + } - gtk_paned_set_child_visible (paned, CHILD1, priv->child1_size != 0); - gtk_paned_set_child_visible (paned, CHILD2, priv->child1_size != allocation); + if (priv->child2 && gtk_widget_get_visible (priv->child2)) + { + _gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, size, &child_min, &child_nat, NULL, NULL); - g_object_freeze_notify (G_OBJECT (paned)); - if (priv->child1_size != old_position) - g_object_notify (G_OBJECT (paned), "position"); - if (priv->min_position != old_min_position) - g_object_notify (G_OBJECT (paned), "min-position"); - if (priv->max_position != old_max_position) - g_object_notify (G_OBJECT (paned), "max-position"); - g_object_thaw_notify (G_OBJECT (paned)); + if (!priv->child2_shrink) + *minimum += child_min; + *natural += child_nat; + } - priv->last_allocation = allocation; + if (priv->child1 && gtk_widget_get_visible (priv->child1) && + priv->child2 && gtk_widget_get_visible (priv->child2)) + { + gint handle_size; + + gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); + + *minimum += handle_size; + *natural += handle_size; + } } static void -gtk_paned_view_size_allocate (GtkWidget *widget, +gtk_paned_get_preferred_size_for_opposite_orientation (GtkWidget *widget, + gint size, + gint *minimum, + gint *natural) +{ + GtkPaned *paned = GTK_PANED (widget); + GtkPanedPrivate *priv = paned->priv; + gint for_child1, for_child2; + gint child_min, child_nat; + + if (size > -1 && + priv->child1 && gtk_widget_get_visible (priv->child1) && + priv->child2 && gtk_widget_get_visible (priv->child2)) + { + gint child1_min, child1_nat, child2_min, child2_nat; + gint handle_size; + + gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); + + _gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, -1, &child1_min, &child1_nat, NULL, NULL); + _gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, -1, &child2_min, &child2_nat, NULL, NULL); + + gtk_paned_compute_position (paned, + size - handle_size, child1_min, child1_nat, child2_min, child2_nat, + NULL, NULL, &for_child1); + + for_child2 = size - for_child1 - handle_size; + } + else + { + for_child1 = size; + for_child2 = size; + } + + *minimum = *natural = 0; + + if (priv->child1 && gtk_widget_get_visible (priv->child1)) + { + _gtk_widget_get_preferred_size_for_size (priv->child1, + OPPOSITE_ORIENTATION (priv->orientation), + for_child1, + &child_min, &child_nat, + NULL, NULL); + + *minimum = child_min; + *natural = child_nat; + } + + if (priv->child2 && gtk_widget_get_visible (priv->child2)) + { + _gtk_widget_get_preferred_size_for_size (priv->child2, + OPPOSITE_ORIENTATION (priv->orientation), + for_child2, + &child_min, &child_nat, + NULL, NULL); + + *minimum = MAX (*minimum, child_min); + *natural = MAX (*natural, child_nat); + } +} + +static void +gtk_paned_get_preferred_size (GtkWidget *widget, + GtkOrientation orientation, + gint size, + gint *minimum, + gint *natural) +{ + GtkPaned *paned = GTK_PANED (widget); + GtkPanedPrivate *priv = paned->priv; + + if (orientation == priv->orientation) + gtk_paned_get_preferred_size_for_orientation (widget, size, minimum, natural); + else + gtk_paned_get_preferred_size_for_opposite_orientation (widget, size, minimum, natural); +} + +static void +gtk_paned_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + gtk_paned_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum, natural); +} + +static void +gtk_paned_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + gtk_paned_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum, natural); +} + +static void +gtk_paned_get_preferred_width_for_height (GtkWidget *widget, + gint height, + gint *minimum, + gint *natural) +{ + gtk_paned_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural); +} + +static void +gtk_paned_get_preferred_height_for_width (GtkWidget *widget, + gint width, + gint *minimum, + gint *natural) +{ + gtk_paned_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, width, minimum, natural); +} + +static void +flip_child (GtkWidget *widget, + GtkAllocation *child_pos) +{ + GtkAllocation allocation; + gint x, width; + + gtk_widget_get_allocation (widget, &allocation); + x = allocation.x; + width = allocation.width; + + child_pos->x = 2 * x + width - child_pos->x - child_pos->width; +} + +static void +gtk_paned_set_child_visible (GtkPaned *paned, + guint id, + gboolean visible) +{ + GtkPanedPrivate *priv = paned->priv; + GtkWidget *child; + + child = id == CHILD1 ? priv->child1 : priv->child2; + + if (child == NULL) + return; + + gtk_widget_set_child_visible (child, visible); + + if (gtk_widget_get_mapped (GTK_WIDGET (paned))) + { + GdkWindow *window = id == CHILD1 ? priv->child1_window : priv->child2_window; + + if (visible != gdk_window_is_visible (window)) + { + if (visible) + gdk_window_show (window); + else + gdk_window_hide (window); + } + } +} + +static void +gtk_paned_child_allocate (GtkWidget *child, + GdkWindow *child_window, /* can be NULL */ + const GtkAllocation *window_allocation, + GtkAllocation *child_allocation) +{ + if (child_window) + gdk_window_move_resize (child_window, + window_allocation->x, window_allocation->y, + window_allocation->width, window_allocation->height); + + gtk_widget_size_allocate (child, child_allocation); +} + +static void +gtk_paned_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GtkPaned *paned = GTK_PANED (widget); @@ -305,20 +484,19 @@ gtk_paned_view_size_allocate (GtkWidget *widget, if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { - gint child1_min_width, child1_nat_width; - gint child2_min_width, child2_nat_width; + gint child1_width, child1_nat_width, child2_width, child2_nat_width; gtk_widget_get_preferred_width_for_height (priv->child1, allocation->height, - &child1_min_width, &child1_nat_width); + &child1_width, &child1_nat_width); gtk_widget_get_preferred_width_for_height (priv->child2, allocation->height, - &child2_min_width, &child2_nat_width); + &child2_width, &child2_nat_width); gtk_paned_calc_position (paned, MAX (1, allocation->width - handle_size), - child1_min_width, child1_nat_width, - child2_min_width, child2_nat_width); + child1_width, child1_nat_width, + child2_width, child2_nat_width); priv->handle_pos.x = allocation->x + priv->child1_size; priv->handle_pos.y = allocation->y; @@ -343,41 +521,38 @@ gtk_paned_view_size_allocate (GtkWidget *widget, child1_allocation.x = child1_allocation.y = 0; child1_allocation.width = window1_allocation.width; child1_allocation.height = window1_allocation.height; - if (child1_min_width > child1_allocation.width) + if (child1_width > child1_allocation.width) { if (gtk_widget_get_direction (GTK_WIDGET (widget)) == GTK_TEXT_DIR_LTR) - child1_allocation.x -= child1_min_width - child1_allocation.width; - child1_allocation.width = child1_min_width; + child1_allocation.x -= child1_width - child1_allocation.width; + child1_allocation.width = child1_width; } child2_allocation.x = child2_allocation.y = 0; child2_allocation.width = window2_allocation.width; child2_allocation.height = window2_allocation.height; - if (child2_min_width > child2_allocation.width) + if (child2_width > child2_allocation.width) { if (gtk_widget_get_direction (GTK_WIDGET (widget)) == GTK_TEXT_DIR_RTL) - child2_allocation.x -= child2_min_width - child2_allocation.width; - child2_allocation.width = child2_min_width; + child2_allocation.x -= child2_width - child2_allocation.width; + child2_allocation.width = child2_width; } } else { - gint child1_min_height, child1_nat_height; - gint child2_min_height, child2_nat_height; + gint child1_height, child1_nat_height, child2_height, child2_nat_height; gtk_widget_get_preferred_height_for_width (priv->child1, allocation->width, - &child1_min_height, - &child1_nat_height); + &child1_height, &child1_nat_height); gtk_widget_get_preferred_height_for_width (priv->child2, allocation->width, - &child2_min_height, - &child2_nat_height); + &child2_height, &child2_nat_height); gtk_paned_calc_position (paned, MAX (1, allocation->height - handle_size), - child1_min_height, child1_nat_height, - child2_min_height, child2_nat_height); + child1_height, child1_nat_height, + child2_height, child2_nat_height); priv->handle_pos.x = allocation->x; priv->handle_pos.y = allocation->y + priv->child1_size; @@ -395,17 +570,17 @@ gtk_paned_view_size_allocate (GtkWidget *widget, child1_allocation.x = child1_allocation.y = 0; child1_allocation.width = window1_allocation.width; child1_allocation.height = window1_allocation.height; - if (child1_min_height > child1_allocation.height) + if (child1_height > child1_allocation.height) { - child1_allocation.y -= child1_min_height - child1_allocation.height; - child1_allocation.height = child1_min_height; + child1_allocation.y -= child1_height - child1_allocation.height; + child1_allocation.height = child1_height; } child2_allocation.x = child2_allocation.y = 0; child2_allocation.width = window2_allocation.width; child2_allocation.height = window2_allocation.height; - if (child2_min_height > child2_allocation.height) - child2_allocation.height = child2_min_height; + if (child2_height > child2_allocation.height) + child2_allocation.height = child2_height; } if (gtk_widget_get_mapped (widget) && @@ -424,10 +599,9 @@ gtk_paned_view_size_allocate (GtkWidget *widget, if (gtk_widget_get_realized (widget)) { GtkBorder margin; - GtkStyleContext *context = gtk_widget_get_style_context (widget); - gtk_style_context_get_margin (context, - gtk_style_context_get_state (context), + gtk_style_context_get_margin (gtk_widget_get_style_context (widget), + gtk_widget_get_state_flags (widget), &margin); if (gtk_widget_get_mapped (widget)) @@ -527,175 +701,38 @@ gtk_paned_view_size_allocate (GtkWidget *widget, } static void -get_preferred_size_for_size (GtkWidget *widget, - GtkOrientation orientation, - gint size, - gint *minimum, - gint *natural) -{ - if (orientation == GTK_ORIENTATION_HORIZONTAL) - if (size < 0) - gtk_widget_get_preferred_width (widget, minimum, natural); - else - gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural); - else - if (size < 0) - gtk_widget_get_preferred_height (widget, minimum, natural); - else - gtk_widget_get_preferred_height_for_width (widget, size, minimum, natural); -} - -static void -gtk_paned_get_preferred_size_for_orientation (GtkWidget *widget, - gint size, - gint *minimum, - gint *natural) -{ - GtkPaned *paned = GTK_PANED (widget); - GtkPanedPrivate *priv = paned->priv; - gint child_min, child_nat; - - *minimum = *natural = 0; - - if (priv->child1 && gtk_widget_get_visible (priv->child1)) - { - get_preferred_size_for_size (priv->child1, priv->orientation, size, &child_min, &child_nat); - if (priv->child1_shrink) - *minimum = 0; - else - *minimum = child_min; - *natural = child_nat; - } - - if (priv->child2 && gtk_widget_get_visible (priv->child2)) - { - get_preferred_size_for_size (priv->child2, priv->orientation, size, &child_min, &child_nat); - - if (!priv->child2_shrink) - *minimum += child_min; - *natural += child_nat; - } - - if (priv->child1 && gtk_widget_get_visible (priv->child1) && - priv->child2 && gtk_widget_get_visible (priv->child2)) - { - gint handle_size; - - gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); - - *minimum += handle_size; - *natural += handle_size; - } -} - -#define OPPOSITE_ORIENTATION(_orientation) (1 - (_orientation)) - -static void -gtk_paned_get_preferred_size_for_opposite_orientation (GtkWidget *widget, - gint size, - gint *minimum, - gint *natural) -{ - GtkPaned *paned = GTK_PANED (widget); - GtkPanedPrivate *priv = paned->priv; - gint for_child1, for_child2; - gint child_min, child_nat; - - if (size > -1 && - priv->child1 && gtk_widget_get_visible (priv->child1) && - priv->child2 && gtk_widget_get_visible (priv->child2)) - { - gint child1_min, child1_nat, child2_min, child2_nat; - gint handle_size; - - gtk_widget_style_get (widget, "handle-size", &handle_size, NULL); - - get_preferred_size_for_size (priv->child1, priv->orientation, -1, &child1_min, &child1_nat); - get_preferred_size_for_size (priv->child2, priv->orientation, -1, &child2_min, &child2_nat); - - gtk_paned_compute_position (paned, - size - handle_size, child1_min, child1_nat, child2_min, child2_nat, - NULL, NULL, &for_child1); - - for_child2 = size - for_child1 - handle_size; - } - else - { - for_child1 = size; - for_child2 = size; - } - - *minimum = *natural = 0; - - if (priv->child1 && gtk_widget_get_visible (priv->child1)) - { - get_preferred_size_for_size (priv->child1, - OPPOSITE_ORIENTATION (priv->orientation), - for_child1, - &child_min, &child_nat); - - *minimum = child_min; - *natural = child_nat; - } - - if (priv->child2 && gtk_widget_get_visible (priv->child2)) - { - get_preferred_size_for_size (priv->child2, - OPPOSITE_ORIENTATION (priv->orientation), - for_child2, - &child_min, &child_nat); - - *minimum = MAX (*minimum, child_min); - *natural = MAX (*natural, child_nat); - } -} - -static void -gtk_paned_view_get_preferred_size (GtkWidget *widget, - GtkOrientation orientation, - gint size, - gint *minimum, - gint *natural) +gtk_paned_calc_position (GtkPaned *paned, + gint allocation, + gint child1_width, + gint child1_nat_width, + gint child2_width, + gint child2_nat_width) { - GtkPaned *paned = GTK_PANED (widget); GtkPanedPrivate *priv = paned->priv; + gint old_position; + gint old_min_position; + gint old_max_position; - if (orientation == priv->orientation) - gtk_paned_get_preferred_size_for_orientation (widget, size, minimum, natural); - else - gtk_paned_get_preferred_size_for_opposite_orientation (widget, size, minimum, natural); -} + old_position = priv->child1_size; + old_min_position = priv->min_position; + old_max_position = priv->max_position; -static void -gtk_paned_view_get_preferred_width (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - gtk_paned_view_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum, natural); -} + gtk_paned_compute_position (paned, + allocation, child1_width, child1_nat_width, child2_width, child2_nat_width, + &priv->min_position, &priv->max_position, + &priv->child1_size); -static void -gtk_paned_view_get_preferred_height (GtkWidget *widget, - gint *minimum, - gint *natural) -{ - gtk_paned_view_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum, natural); -} + gtk_paned_set_child_visible (paned, CHILD1, priv->child1_size != 0); + gtk_paned_set_child_visible (paned, CHILD2, priv->child1_size != allocation); -static void -gtk_paned_view_get_preferred_width_for_height (GtkWidget *widget, - gint height, - gint *minimum, - gint *natural) -{ - gtk_paned_view_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural); -} + g_object_freeze_notify (G_OBJECT (paned)); + if (priv->child1_size != old_position) + g_object_notify (G_OBJECT (paned), "position"); + if (priv->min_position != old_min_position) + g_object_notify (G_OBJECT (paned), "min-position"); + if (priv->max_position != old_max_position) + g_object_notify (G_OBJECT (paned), "max-position"); + g_object_thaw_notify (G_OBJECT (paned)); -static void -gtk_paned_view_get_preferred_height_for_width (GtkWidget *widget, - gint width, - gint *minimum, - gint *natural) -{ - gtk_paned_view_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, width, minimum, natural); + priv->last_allocation = allocation; } diff --git a/src/gtk/gtkscrolledview-new.c b/src/gtk/gtkscrolledview-3.18.9.c similarity index 57% rename from src/gtk/gtkscrolledview-new.c rename to src/gtk/gtkscrolledview-3.18.9.c index 099e6c0da..3c6e04de3 100644 --- a/src/gtk/gtkscrolledview-new.c +++ b/src/gtk/gtkscrolledview-3.18.9.c @@ -21,88 +21,22 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -/* A specialized GtkScrolledWindow. - - A GtkScrolledWindow is used to squeeze an overly large widget into a - smaller space and allow the user to scroll it. The geometry - implementation ignores the natural size of the problem widget, - expecting @code{gtk_widget_set_size_request} to override its minimum - size. - - A GtkScrolledView is used to stick scrollbars on a viewport. Its - natural size is the natural size of the viewport, plus scrollbars, - frame, etc. Using @code{gtk_widget_set_size_request} is unnecessary - and interferes with resizing. - */ +/* A specialized GtkScrolledWindow. See documentation of + . */ #include "gtkscrolledview.h" -struct _GtkScrolledWindowPrivate -{ - GtkWidget *hscrollbar; - GtkWidget *vscrollbar; - - GtkCssNode *overshoot_node[4]; - GtkCssNode *undershoot_node[4]; - - Indicator hindicator; - Indicator vindicator; - - GtkCornerType window_placement; - guint16 shadow_type; - - guint hscrollbar_policy : 2; - guint vscrollbar_policy : 2; - guint hscrollbar_visible : 1; - guint vscrollbar_visible : 1; - guint focus_out : 1; /* used by ::move-focus-out implementation */ - guint overlay_scrolling : 1; - guint use_indicators : 1; - - gint min_content_width; - gint min_content_height; - - guint scroll_events_overshoot_id; - - /* Kinetic scrolling */ - GtkGesture *long_press_gesture; - GtkGesture *swipe_gesture; - - GArray *scroll_history; - GdkDevice *scroll_device; - - /* These two gestures are mutually exclusive */ - GtkGesture *drag_gesture; - GtkGesture *pan_gesture; - - gdouble drag_start_x; - gdouble drag_start_y; - - GdkDevice *drag_device; - guint kinetic_scrolling : 1; - guint capture_button_press : 1; - guint in_drag : 1; - - guint deceleration_id; - - gdouble x_velocity; - gdouble y_velocity; - - gdouble unclamped_hadj_value; - gdouble unclamped_vadj_value; -}; - -static void gtk_scrolled_view_get_preferred_width (GtkWidget *widget, +static void gtk_scrolled_window_get_preferred_width (GtkWidget *widget, gint *minimum_size, gint *natural_size); -static void gtk_scrolled_view_get_preferred_height (GtkWidget *widget, +static void gtk_scrolled_window_get_preferred_height (GtkWidget *widget, gint *minimum_size, gint *natural_size); -static void gtk_scrolled_view_get_preferred_height_for_width (GtkWidget *layout, +static void gtk_scrolled_window_get_preferred_height_for_width (GtkWidget *layout, gint width, gint *minimum_height, gint *natural_height); -static void gtk_scrolled_view_get_preferred_width_for_height (GtkWidget *layout, +static void gtk_scrolled_window_get_preferred_width_for_height (GtkWidget *layout, gint width, gint *minimum_height, gint *natural_height); @@ -115,10 +49,10 @@ gtk_scrolled_view_class_init (GtkScrolledViewClass *class) { GtkWidgetClass *widget_class = (GtkWidgetClass*) class; - widget_class->get_preferred_width = gtk_scrolled_view_get_preferred_width; - widget_class->get_preferred_height = gtk_scrolled_view_get_preferred_height; - widget_class->get_preferred_height_for_width = gtk_scrolled_view_get_preferred_height_for_width; - widget_class->get_preferred_width_for_height = gtk_scrolled_view_get_preferred_width_for_height; + widget_class->get_preferred_width = gtk_scrolled_window_get_preferred_width; + widget_class->get_preferred_height = gtk_scrolled_window_get_preferred_height; + widget_class->get_preferred_height_for_width = gtk_scrolled_window_get_preferred_height_for_width; + widget_class->get_preferred_width_for_height = gtk_scrolled_window_get_preferred_width_for_height; } static void @@ -160,12 +94,102 @@ gtk_scrolled_view_new (GtkAdjustment *hadjustment, return scrolled_view; } + +/* The following definitions were copied unchanged from + gtkscrolledwindow.c v3.18.9 unless otherwise noted. + + struct Indicator + struct ScrollHistoryElem + struct _GtkScrolledWindowPrivate + static gint _gtk_scrolled_window_get_scrollbar_spacing () + static void gtk_scrolled_window_get_preferred_size () PATCHED + static void gtk_scrolled_window_get_preferred_width () + static void gtk_scrolled_window_get_preferred_height () + static void gtk_scrolled_window_get_preferred_height_for_width () + static void gtk_scrolled_window_get_preferred_width_for_height () +*/ + +typedef struct +{ + GtkWidget *scrollbar; + GdkWindow *window; + gboolean over; /* either mouse over, or while dragging */ + gint64 last_scroll_time; + guint conceil_timer; + + gdouble current_pos; + gdouble source_pos; + gdouble target_pos; + gint64 start_time; + gint64 end_time; + guint tick_id; + guint over_timeout_id; +} Indicator; + +typedef struct +{ + gdouble dx; + gdouble dy; + guint32 evtime; +} ScrollHistoryElem; + +struct _GtkScrolledWindowPrivate +{ + GtkWidget *hscrollbar; + GtkWidget *vscrollbar; + + Indicator hindicator; + Indicator vindicator; + + GtkCornerType window_placement; + guint16 shadow_type; + + guint hscrollbar_policy : 2; + guint vscrollbar_policy : 2; + guint hscrollbar_visible : 1; + guint vscrollbar_visible : 1; + guint focus_out : 1; /* used by ::move-focus-out implementation */ + guint overlay_scrolling : 1; + guint use_indicators : 1; + + gint min_content_width; + gint min_content_height; + + guint scroll_events_overshoot_id; + + /* Kinetic scrolling */ + GtkGesture *long_press_gesture; + GtkGesture *swipe_gesture; + + GArray *scroll_history; + GdkDevice *scroll_device; + + /* These two gestures are mutually exclusive */ + GtkGesture *drag_gesture; + GtkGesture *pan_gesture; + + gdouble drag_start_x; + gdouble drag_start_y; + + GdkDevice *drag_device; + guint kinetic_scrolling : 1; + guint capture_button_press : 1; + guint in_drag : 1; + + guint deceleration_id; + + gdouble x_velocity; + gdouble y_velocity; + + gdouble unclamped_hadj_value; + gdouble unclamped_vadj_value; +}; static gint -gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window) +_gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window) { GtkScrolledWindowClass *class; - + g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window), 0); class = GTK_SCROLLED_WINDOW_GET_CLASS (scrolled_window); @@ -175,7 +199,7 @@ gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window) else { gint scrollbar_spacing; - + gtk_widget_style_get (GTK_WIDGET (scrolled_window), "scrollbar-spacing", &scrollbar_spacing, NULL); @@ -193,51 +217,66 @@ gtk_scrolled_window_get_preferred_size (GtkWidget *widget, GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget); GtkScrolledWindowPrivate *priv = scrolled_window->priv; GtkBin *bin = GTK_BIN (scrolled_window); - gint extra_width; - gint extra_height; - gint minimum; - gint natural; GtkWidget *child; + gint min_size, nat_size; - /* Init to child size. */ child = gtk_bin_get_child (bin); if (child && gtk_widget_get_visible (child)) { if (orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_widget_get_preferred_width (child, &minimum, &natural); - else - gtk_widget_get_preferred_height (child, &minimum, &natural); + { + gtk_widget_get_preferred_width (child, &min_size, &nat_size); + if (priv->min_content_width >= 0) + min_size = MAX (min_size, priv->min_content_width); + } + else /* GTK_ORIENTATION_VERTICAL */ + { + gtk_widget_get_preferred_height (child, &min_size, &nat_size); + if (priv->min_content_height >= 0) + min_size = MAX (min_size, priv->min_content_height); + } } - /* Add min_content_width/height. */ - { - gint min_content_size = (orientation == GTK_ORIENTATION_HORIZONTAL - ? priv->min_content_width - : priv->min_content_height); - if (min_content_size >= 0) - { - minimum = MAX (minimum, min_content_size); - natural = MAX (natural, min_content_size); - } - } - - /* Add scrollbar size. */ - if ((orientation == GTK_ORIENTATION_VERTICAL - && priv->hscrollbar_policy != GTK_POLICY_NEVER) || - (orientation == GTK_ORIENTATION_HORIZONTAL - && priv->vscrollbar_policy != GTK_POLICY_NEVER)) + if (!priv->use_indicators) { - gint min, nat; - gint space = gtk_scrolled_window_get_scrollbar_spacing (scrolled_window); - if (orientation == GTK_ORIENTATION_VERTICAL) - gtk_widget_get_preferred_height (priv->hscrollbar, &min, &nat); - else - gtk_widget_get_preferred_width (priv->vscrollbar, &min, &nat); - minimum += space + min; - natural += space + nat; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + if (priv->vscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_width, nat_width; + gint scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window); + gtk_widget_get_preferred_width (priv->vscrollbar, &min_width, &nat_width); + min_size += MAX (0, scrollbar_spacing + min_width); + nat_size += MAX (0, scrollbar_spacing + nat_width); + } + if (priv->hscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_width, nat_width; + gtk_widget_get_preferred_width (priv->hscrollbar, &min_width, &nat_width); + min_size = MAX (min_size, min_width); + nat_size = MAX (nat_size, nat_width); + } + } + else /* orientation == GTK_ORIENTATION_VERTICAL */ + { + if (priv->hscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_height, nat_height; + gint scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window); + gtk_widget_get_preferred_height (priv->hscrollbar, &min_height, &nat_height); + min_size += MAX (0, scrollbar_spacing + min_height); + nat_size += MAX (0, scrollbar_spacing + nat_height); + } + if (priv->vscrollbar_policy != GTK_POLICY_NEVER) + { + gint min_height, nat_height; + gtk_widget_get_preferred_height (priv->vscrollbar, &min_height, &nat_height); + min_size = MAX (min_size, min_height); + nat_size = MAX (nat_size, nat_height); + } + } } - /* Add shadow size. */ if (priv->shadow_type != GTK_SHADOW_NONE) { GtkStyleContext *context; @@ -245,50 +284,45 @@ gtk_scrolled_window_get_preferred_size (GtkWidget *widget, GtkBorder padding, border; context = gtk_widget_get_style_context (GTK_WIDGET (widget)); - state = gtk_widget_get_state_flags (GTK_WIDGET (widget)); + state = gtk_style_context_get_state (context); - gtk_style_context_save (context); - gtk_style_context_add_class (context, GTK_STYLE_CLASS_FRAME); gtk_style_context_get_padding (context, state, &padding); gtk_style_context_get_border (context, state, &border); - gtk_style_context_restore (context); - if (orientation == GTK_ORIENTATION_VERTICAL) + if (orientation == GTK_ORIENTATION_HORIZONTAL) { - minimum += padding.top + padding.bottom + border.top + border.bottom; - natural += padding.top + padding.bottom + border.top + border.bottom; + min_size += padding.left + padding.right + border.left + border.right; + nat_size += padding.left + padding.right + border.left + border.right; } else { - minimum += padding.left + padding.right + border.left + border.right; - natural += padding.left + padding.right + border.left + border.right; + min_size += padding.top + padding.bottom + border.top + border.bottom; + nat_size += padding.top + padding.bottom + border.top + border.bottom; } } - if (minimum_size) - *minimum_size = minimum; - if (natural_size) - *natural_size = natural; + *minimum_size = min_size; + *natural_size = nat_size; } static void -gtk_scrolled_view_get_preferred_width (GtkWidget *widget, +gtk_scrolled_window_get_preferred_width (GtkWidget *widget, gint *minimum_size, gint *natural_size) { - gtk_scrolled_view_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); + gtk_scrolled_window_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); } static void -gtk_scrolled_view_get_preferred_height (GtkWidget *widget, +gtk_scrolled_window_get_preferred_height (GtkWidget *widget, gint *minimum_size, gint *natural_size) { - gtk_scrolled_view_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); + gtk_scrolled_window_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } static void -gtk_scrolled_view_get_preferred_height_for_width (GtkWidget *widget, +gtk_scrolled_window_get_preferred_height_for_width (GtkWidget *widget, gint width, gint *minimum_height, gint *natural_height) @@ -297,7 +331,7 @@ gtk_scrolled_view_get_preferred_height_for_width (GtkWidget *widget, } static void -gtk_scrolled_view_get_preferred_width_for_height (GtkWidget *widget, +gtk_scrolled_window_get_preferred_width_for_height (GtkWidget *widget, gint height, gint *minimum_width, gint *natural_width) -- 2.25.1