gtk: GtkPanedView and GtkScrolledView for 3.20.9 (Ubuntu 16.10).
authorMatt Birkholz <puck@birchwood-abbey.net>
Sun, 27 Nov 2016 18:41:34 +0000 (11:41 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Sun, 27 Nov 2016 18:41:34 +0000 (11:41 -0700)
src/gtk/Makefile.am
src/gtk/README
src/gtk/configure.ac
src/gtk/gtkpanedview-3.20.9.c [new file with mode: 0644]
src/gtk/gtkscrolledview-3.18.9.c
src/gtk/gtkscrolledview-3.20.9.c [new file with mode: 0644]

index dddb147d85578491cbdca0de417503b48739d83f..1632ca935fbb436e194b6457c387f39ccd43f1a6 100644 (file)
@@ -146,6 +146,7 @@ EXTRA_DIST += gtkpanedview-3.10.8.c gtkscrolledview-3.10.8.c
 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 += conses.png hello.scm test-gport-performance.scm
 EXTRA_DIST += debian
 
index 5643268804b0904a9715f60cb7a9b6186f091c6b..b7f199b53b2879138c280ebd4a16063e6006c77a 100644 (file)
@@ -13,12 +13,13 @@ require access to private members of their supertypes, so they need
 a struct declaration matching the private declaration in the toolkit.
 
 The trick: Select an implementation of the special widgets that is
-compatible with your system's toolkit.  Four are provided and
+compatible with your system's toolkit.  Five are provided and
 correspond to recent Ubuntu releases.  If your system is using a
 matching or "close enough" version of the toolkit, you will get a
 treat.
 
        Ubuntu    Gtk+
+       16.10     3.20.9
        16.04lts  3.18.9
        15.10     3.16.7
        15.04     3.14.13
index f5ce85f4a72c22b6fde96e9aa96007aa3177d5b1..05e7585e1fc243b4233d32cf85d2835bea4ad97d 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.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
     GTK_VERSION=3.18.9
 elif pkg-config --exists 'gtk+-3.0 >= 3.16.7' 2>/dev/null; then
diff --git a/src/gtk/gtkpanedview-3.20.9.c b/src/gtk/gtkpanedview-3.20.9.c
new file mode 100644 (file)
index 0000000..0f9d495
--- /dev/null
@@ -0,0 +1,61 @@
+/* -*-C-*-
+
+Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
+    2016 Matthew Birkholz
+
+This file is part of a gtk plugin for MIT/GNU Scheme.
+
+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)
+{
+  GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
+}
+
+static void
+gtk_paned_view_init (GtkPanedView *paned_view)
+{
+  g_assert (GTK_PANED (paned_view) ->priv != NULL);
+}
+
+/**
+ * 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));
+}
index 3c6e04de35300de4b3d218915dbda7b9f95cdeef..012e133cf649344aaf9578d0c34178e0752a9be0 100644 (file)
@@ -99,7 +99,6 @@ gtk_scrolled_view_new (GtkAdjustment *hadjustment,
    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
@@ -126,13 +125,6 @@ typedef struct
   guint      over_timeout_id;
 } Indicator;
 
-typedef struct
-{
-  gdouble dx;
-  gdouble dy;
-  guint32 evtime;
-} ScrollHistoryElem;
-
 struct _GtkScrolledWindowPrivate
 {
   GtkWidget     *hscrollbar;
diff --git a/src/gtk/gtkscrolledview-3.20.9.c b/src/gtk/gtkscrolledview-3.20.9.c
new file mode 100644 (file)
index 0000000..b6aafb4
--- /dev/null
@@ -0,0 +1,343 @@
+/* -*-C-*-
+
+Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
+    2016 Matthew Birkholz
+
+This file is part of a gtk plugin for MIT/GNU Scheme.
+
+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 Indicator                                                    v3.20.9
+   struct _GtkScrolledWindowPrivate                                    v3.20.9
+   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 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;
+
+  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)
+{
+  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);
+}