gtk: GtkScrolledView (and GtkPanedView) for 3.22.11 (Ubuntu 17.04).
authorMatt Birkholz <matt@birchwood-abbey.net>
Sat, 8 Jul 2017 03:30:25 +0000 (20:30 -0700)
committerMatt Birkholz <matt@birchwood-abbey.net>
Sat, 8 Jul 2017 03:30:25 +0000 (20:30 -0700)
src/gtk/Makefile.am
src/gtk/configure.ac
src/gtk/gtkpanedview-3.22.11.c [new file with mode: 0644]
src/gtk/gtkscrolledview-3.22.11.c [new file with mode: 0644]

index e60ca84751e578f2a064ae0c850130dd918ff466..5bec07fd9c1f1aebfe34c111e9a4575df35e1639 100644 (file)
@@ -144,6 +144,7 @@ EXTRA_DIST += gtkpanedview-3.14.13.c gtkscrolledview-3.14.13.c
 EXTRA_DIST += gtkpanedview-3.16.7.c gtkscrolledview-3.16.7.c
 EXTRA_DIST += gtkpanedview-3.18.9.c gtkscrolledview-3.18.9.c
 EXTRA_DIST += gtkpanedview-3.20.9.c gtkscrolledview-3.20.9.c
+EXTRA_DIST += gtkpanedview-3.22.11.c gtkscrolledview-3.22.11.c
 EXTRA_DIST += conses.png hello.scm test-gport-performance.scm
 EXTRA_DIST += debian
 
index 0541b90d17988420fa710ed793ae4e2990697298..848a043febc54acd33b481ab8fdb035f7248d959 100644 (file)
@@ -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.22.11' 2>/dev/null; then
+    GTK_VERSION=3.22.11
 elif pkg-config --exists 'gtk+-3.0 >= 3.20.9' 2>/dev/null; then
     GTK_VERSION=3.20.9
 elif pkg-config --exists 'gtk+-3.0 >= 3.18.9' 2>/dev/null; then
diff --git a/src/gtk/gtkpanedview-3.22.11.c b/src/gtk/gtkpanedview-3.22.11.c
new file mode 100644 (file)
index 0000000..8714d5a
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*-C-*-
+
+Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
+    2016, 2017 Matthew Birkholz
+
+This file is part of a Gtk plugin for MIT/GNU Scheme Pucked.
+
+This plugin is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+This plugin is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this plugin; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+/* A specialized GtkPaned.  See documentation of <gtk-paned-view>. */
+
+/* The v3.20.9 of GtkPaned seems to do the right thing with
+   GtkScrolledViews, so this version of GtkPanedView is not actually
+   specialized. */
+
+#include "gtkpanedview.h"
+
+G_DEFINE_TYPE (GtkPanedView, gtk_paned_view,
+              GTK_TYPE_PANED)
+
+static void
+gtk_paned_view_class_init (GtkPanedViewClass *class)
+{
+}
+
+static void
+gtk_paned_view_init (GtkPanedView *paned_view)
+{
+}
+
+/**
+ * gtk_paned_view_new:
+ * @orientation: GTK_ORIENTATION_VERTICAL or GTK_ORIENTATION_HORIZONTAL.
+ *
+ * Creates a new paned view.
+ *
+ * Returns: a new paned view.
+ */
+GtkWidget*
+gtk_paned_view_new (GtkOrientation orientation)
+{
+  return (g_object_new (GTK_TYPE_PANED_VIEW,
+                       "orientation", orientation,
+                       NULL));
+}
diff --git a/src/gtk/gtkscrolledview-3.22.11.c b/src/gtk/gtkscrolledview-3.22.11.c
new file mode 100644 (file)
index 0000000..c0b8d79
--- /dev/null
@@ -0,0 +1,361 @@
+/* -*-C-*-
+
+Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
+    2016, 2017 Matthew Birkholz
+
+This file is part of a Gtk plugin for MIT/GNU Scheme Pucked.
+
+This plugin is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+This plugin is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this plugin; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+/* A specialized GtkScrolledWindow.  See documentation of
+   <gtk-scrolled-view>. */
+
+#include "gtkscrolledview.h"
+
+static void  gtk_scrolled_window_get_preferred_width   (GtkWidget           *widget,
+                                                       gint                *minimum_size,
+                                                       gint                *natural_size);
+static void  gtk_scrolled_window_get_preferred_height  (GtkWidget           *widget,
+                                                       gint                *minimum_size,
+                                                       gint                *natural_size);
+static void  gtk_scrolled_window_get_preferred_height_for_width  (GtkWidget           *layout,
+                                                       gint                 width,
+                                                       gint                *minimum_height,
+                                                       gint                *natural_height);
+static void  gtk_scrolled_window_get_preferred_width_for_height  (GtkWidget           *layout,
+                                                       gint                 width,
+                                                       gint                *minimum_height,
+                                                       gint                *natural_height);
+
+G_DEFINE_TYPE (GtkScrolledView, gtk_scrolled_view,
+              GTK_TYPE_SCROLLED_WINDOW)
+
+static void
+gtk_scrolled_view_class_init (GtkScrolledViewClass *class)
+{
+  GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
+
+  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
+gtk_scrolled_view_init (GtkScrolledView *scrolled_view)
+{
+  g_assert (GTK_SCROLLED_WINDOW (scrolled_view) ->priv != NULL);
+}
+
+/**
+ * gtk_scrolled_view_new:
+ * @hadjustment: (allow-none): horizontal adjustment
+ * @vadjustment: (allow-none): vertical adjustment
+ *
+ * Creates a new scrolling window.
+ *
+ * The two arguments are the scrolling window's adjustments; these will be
+ * shared with the scrollbars and the child widget to keep the bars in sync 
+ * with the child. Usually you want to pass %NULL for the adjustments, which 
+ * will cause the scrolling window to create them for you.
+ *
+ * Returns: a new scrolling window
+ */
+GtkWidget*
+gtk_scrolled_view_new (GtkAdjustment *hadjustment,
+                      GtkAdjustment *vadjustment)
+{
+  GtkWidget *scrolled_view;
+
+  if (hadjustment)
+    g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), NULL);
+
+  if (vadjustment)
+    g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), NULL);
+
+  scrolled_view = g_object_new (GTK_TYPE_SCROLLED_VIEW,
+                               "hadjustment", hadjustment,
+                               "vadjustment", vadjustment,
+                               NULL);
+
+  return scrolled_view;
+}
+\f
+/* The following definitions were copied unchanged from
+   gtkscrolledwindow.c v3.18.9 unless otherwise noted.  The geometry
+   protocol methods in v3.20.9 now use private gadget functions, but
+   the v3.18.9 code is still correct, so it is used instead.  This
+   presumably means limited CSS styling for GtkScrolledView (until the
+   gadget functions are no longer private).
+
+   struct _GtkProgressTracker                                          v3.22.11
+   struct Indicator                                                    v3.22.11
+   struct _GtkScrolledWindowPrivate                                    v3.22.11
+   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 _GtkProgressTracker GtkProgressTracker;
+
+struct _GtkProgressTracker
+{
+  gboolean is_running;
+  guint64 last_frame_time;
+  guint64 duration;
+  gdouble iteration;
+  gdouble iteration_count;
+};
+
+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;
+  GtkProgressTracker tracker;
+  guint      tick_id;
+  guint      over_timeout_id;
+} Indicator;
+
+typedef long GtkCssGadget;
+typedef long GtkCssNode;
+
+struct _GtkScrolledWindowPrivate
+{
+  GtkWidget     *hscrollbar;
+  GtkWidget     *vscrollbar;
+
+  GtkCssGadget  *gadget;
+  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;
+  guint    auto_added_viewport      : 1;
+  guint    propagate_natural_width  : 1;
+  guint    propagate_natural_height : 1;
+
+  gint     min_content_width;
+  gint     min_content_height;
+  gint     max_content_width;
+  gint     max_content_height;
+
+  guint scroll_events_overshoot_id;
+
+  /* Kinetic scrolling */
+  GtkGesture *long_press_gesture;
+  GtkGesture *swipe_gesture;
+
+  GArray *scroll_history;
+  GdkDevice *scroll_device;
+  GdkWindow *scroll_window;
+  GdkCursor *scroll_cursor;
+
+  /* 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)
+{
+  GtkScrolledWindowClass *class;
+
+  g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window), 0);
+
+  class = GTK_SCROLLED_WINDOW_GET_CLASS (scrolled_window);
+
+  if (class->scrollbar_spacing >= 0)
+    return class->scrollbar_spacing;
+  else
+    {
+      gint scrollbar_spacing;
+
+      gtk_widget_style_get (GTK_WIDGET (scrolled_window),
+                           "scrollbar-spacing", &scrollbar_spacing,
+                           NULL);
+
+      return scrollbar_spacing;
+    }
+}
+
+static void
+gtk_scrolled_window_get_preferred_size (GtkWidget      *widget,
+                                        GtkOrientation  orientation,
+                                        gint           *minimum_size,
+                                        gint           *natural_size)
+{
+  GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
+  GtkScrolledWindowPrivate *priv = scrolled_window->priv;
+  GtkBin *bin = GTK_BIN (scrolled_window);
+  GtkWidget *child;
+  gint min_size, nat_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, &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);
+       }
+    }
+
+  if (!priv->use_indicators)
+    {
+      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);
+           }
+       }
+    }
+
+  if (priv->shadow_type != GTK_SHADOW_NONE)
+    {
+      GtkStyleContext *context;
+      GtkStateFlags state;
+      GtkBorder padding, border;
+
+      context = gtk_widget_get_style_context (GTK_WIDGET (widget));
+      state = gtk_style_context_get_state (context);
+
+      gtk_style_context_get_padding (context, state, &padding);
+      gtk_style_context_get_border (context, state, &border);
+
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+       {
+         min_size += padding.left + padding.right + border.left + border.right;
+         nat_size += padding.left + padding.right + border.left + border.right;
+       }
+      else
+       {
+         min_size += padding.top + padding.bottom + border.top + border.bottom;
+         nat_size += padding.top + padding.bottom + border.top + border.bottom;
+       }
+    }
+
+  *minimum_size = min_size;
+  *natural_size = nat_size;
+}
+
+static void
+gtk_scrolled_window_get_preferred_width (GtkWidget *widget,
+                                         gint      *minimum_size,
+                                         gint      *natural_size)
+{
+  gtk_scrolled_window_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
+}
+
+static void
+gtk_scrolled_window_get_preferred_height (GtkWidget *widget,
+                                          gint      *minimum_size,
+                                          gint      *natural_size)
+{
+  gtk_scrolled_window_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
+}
+
+static void
+gtk_scrolled_window_get_preferred_height_for_width (GtkWidget *widget,
+                                                    gint       width,
+                                                    gint      *minimum_height,
+                                                    gint      *natural_height)
+{
+  GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
+}
+
+static void
+gtk_scrolled_window_get_preferred_width_for_height (GtkWidget *widget,
+                                                    gint       height,
+                                                    gint      *minimum_width,
+                                                    gint      *natural_width)
+{
+  GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
+}