[libdazzle] backports: add GtkEventControllerMotion backport for pre-3.24



commit 9f6547346e12eab0e1e5752d08dd18cf4e83c550
Author: Christian Hergert <chergert redhat com>
Date:   Fri May 17 12:12:02 2019 -0700

    backports: add GtkEventControllerMotion backport for pre-3.24
    
    This is useful from a standpoint of being able to run on 3.22 such as
    availiable on RHEL 8 and Debian stable.
    
    The motion controller is pretty simple in nature. We just need to be able
    to copy over the size of some private structs so that callback positions
    line up properly.

 src/app/dzl-application-window.c         |   6 +
 src/backports/gtkeventcontrollermotion.c | 221 +++++++++++++++++++++++++++++++
 src/backports/gtkeventcontrollermotion.h |  39 ++++++
 3 files changed, 266 insertions(+)
---
diff --git a/src/app/dzl-application-window.c b/src/app/dzl-application-window.c
index 7f76c77..b23ec4d 100644
--- a/src/app/dzl-application-window.c
+++ b/src/app/dzl-application-window.c
@@ -20,6 +20,12 @@
 
 #include "config.h"
 
+#include <gtk/gtk.h>
+
+#if !GTK_CHECK_VERSION(3, 24, 0)
+# include "backports/gtkeventcontrollermotion.c"
+#endif
+
 #include "app/dzl-application-window.h"
 #include "shortcuts/dzl-shortcut-manager.h"
 #include "util/dzl-gtk.h"
diff --git a/src/backports/gtkeventcontrollermotion.c b/src/backports/gtkeventcontrollermotion.c
new file mode 100644
index 0000000..ae3fb7f
--- /dev/null
+++ b/src/backports/gtkeventcontrollermotion.c
@@ -0,0 +1,221 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2017, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Matthias Clasen <mclasen redhat com>
+ */
+
+/**
+ * SECTION:gtkeventcontrollermotion
+ * @Short_description: Event controller for motion events
+ * @Title: GtkEventControllerMotion
+ * @See_also: #GtkEventController
+ *
+ * #GtkEventControllerMotion is an event controller meant for situations
+ * where you need to track the position of the pointer.
+ *
+ * This object was added in 3.24.
+ **/
+#include "config.h"
+
+#include "gtkeventcontrollermotion.h"
+
+#if GTK_CHECK_VERSION(3, 24, 0)
+# error "Cannot use this in conjunction with 3.24"
+#endif
+
+#define I_(s) (g_intern_static_string(s))
+
+struct _GtkEventControllerMotion
+{
+  /* EventController adds no new instance fields up to 3.24 */
+  /* GtkEventController parent_instance; */
+  GObject parent_instance;
+};
+
+struct _GtkEventControllerClass
+{
+  GObjectClass parent_class;
+
+  gboolean (* handle_event) (GtkEventController *controller,
+                             const GdkEvent     *event);
+  void     (* reset)        (GtkEventController *controller);
+
+  /*<private>*/
+
+  /* Tells whether the event is filtered out, %TRUE makes
+   * the event unseen by the handle_event vfunc.
+   */
+  gboolean (* filter_event) (GtkEventController *controller,
+                             const GdkEvent     *event);
+  gpointer padding[10];
+};
+
+struct _GtkEventControllerMotionClass
+{
+  GtkEventControllerClass parent_class;
+};
+
+enum {
+  ENTER,
+  LEAVE,
+  MOTION,
+  N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0 };
+
+G_DEFINE_TYPE (GtkEventControllerMotion, gtk_event_controller_motion, GTK_TYPE_EVENT_CONTROLLER)
+
+static void
+get_coords (GtkWidget      *widget,
+            const GdkEvent *event,
+            double         *x,
+            double         *y)
+{
+  GdkWindow *window, *ancestor;
+  GtkAllocation alloc;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  gdk_event_get_coords (event, x, y);
+
+  ancestor = gtk_widget_get_window (widget);
+  window = gdk_event_get_window (event);
+
+  while (window && ancestor && (window != ancestor))
+    {
+      gdk_window_coords_to_parent (window, *x, *y, x, y);
+      window = gdk_window_get_parent (window);
+    }
+
+  if (!gtk_widget_get_has_window (widget))
+    {
+      *x -= alloc.x;
+      *y -= alloc.y;
+    }
+}
+
+static gboolean
+gtk_event_controller_motion_handle_event (GtkEventController *controller,
+                                          const GdkEvent     *event)
+{
+  GtkEventControllerClass *parent_class;
+  GtkWidget *widget;
+  GdkEventType type;
+
+  widget = gtk_event_controller_get_widget (controller);
+
+  type = gdk_event_get_event_type (event);
+  if (type == GDK_ENTER_NOTIFY)
+    {
+      double x, y;
+      get_coords (widget, event, &x, &y);
+      g_signal_emit (controller, signals[ENTER], 0, x, y);
+    }
+  else if (type == GDK_LEAVE_NOTIFY)
+    {
+      g_signal_emit (controller, signals[LEAVE], 0);
+    }
+  else if (type == GDK_MOTION_NOTIFY)
+    {
+      double x, y;
+      get_coords (widget, event, &x, &y);
+      g_signal_emit (controller, signals[MOTION], 0, x, y);
+    }
+
+  parent_class = GTK_EVENT_CONTROLLER_CLASS (gtk_event_controller_motion_parent_class);
+
+  return parent_class->handle_event (controller, event);
+}
+
+static void
+gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
+{
+  GtkEventControllerClass *controller_class = GTK_EVENT_CONTROLLER_CLASS (klass);
+
+  controller_class->handle_event = gtk_event_controller_motion_handle_event;
+
+  /**
+   * GtkEventControllerMotion::enter:
+   * @controller: The object that received the signal
+   * @x: the x coordinate
+   * @y: the y coordinate
+   *
+   * Signals that the pointer has entered the widget.
+   */
+  signals[ENTER] =
+    g_signal_new (I_("enter"),
+                  GTK_TYPE_EVENT_CONTROLLER_MOTION,
+                  G_SIGNAL_RUN_FIRST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
+
+  /**
+   * GtkEventControllerMotion::leave:
+   * @controller: The object that received the signal
+   *
+   * Signals that pointer has left the widget.
+   */
+  signals[LEAVE] =
+    g_signal_new (I_("leave"),
+                  GTK_TYPE_EVENT_CONTROLLER_MOTION,
+                  G_SIGNAL_RUN_FIRST,
+                  0, NULL, NULL,
+                 NULL,
+                  G_TYPE_NONE, 0);
+
+  /**
+   * GtkEventControllerMotion::motion:
+   * @controller: The object that received the signal
+   * @x: the x coordinate
+   * @y: the y coordinate
+   *
+   * Emitted when the pointer moves inside the widget.
+   */
+  signals[MOTION] =
+    g_signal_new (I_("motion"),
+                  GTK_TYPE_EVENT_CONTROLLER_MOTION,
+                  G_SIGNAL_RUN_FIRST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
+}
+
+static void
+gtk_event_controller_motion_init (GtkEventControllerMotion *motion)
+{
+}
+
+/**
+ * gtk_event_controller_motion_new:
+ * @widget: a #GtkWidget
+ *
+ * Creates a new event controller that will handle motion events
+ * for the given @widget.
+ *
+ * Returns: a new #GtkEventControllerMotion
+ *
+ * Since: 3.24
+ **/
+GtkEventController *
+gtk_event_controller_motion_new (GtkWidget *widget)
+{
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+  return g_object_new (GTK_TYPE_EVENT_CONTROLLER_MOTION,
+                       "widget", widget,
+                       NULL);
+}
diff --git a/src/backports/gtkeventcontrollermotion.h b/src/backports/gtkeventcontrollermotion.h
new file mode 100644
index 0000000..3368e89
--- /dev/null
+++ b/src/backports/gtkeventcontrollermotion.h
@@ -0,0 +1,39 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2017, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Matthias Clasen <mclasen redhat com>
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EVENT_CONTROLLER_MOTION         (gtk_event_controller_motion_get_type ())
+#define GTK_EVENT_CONTROLLER_MOTION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), 
GTK_TYPE_EVENT_CONTROLLER_MOTION, GtkEventControllerMotion))
+#define GTK_EVENT_CONTROLLER_MOTION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), 
GTK_TYPE_EVENT_CONTROLLER_MOTION, GtkEventControllerMotionClass))
+#define GTK_IS_EVENT_CONTROLLER_MOTION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), 
GTK_TYPE_EVENT_CONTROLLER_MOTION))
+#define GTK_IS_EVENT_CONTROLLER_MOTION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), 
GTK_TYPE_EVENT_CONTROLLER_MOTION))
+#define GTK_EVENT_CONTROLLER_MOTION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), 
GTK_TYPE_EVENT_CONTROLLER_MOTION, GtkEventControllerMotionClass))
+
+typedef struct _GtkEventControllerMotion GtkEventControllerMotion;
+typedef struct _GtkEventControllerMotionClass GtkEventControllerMotionClass;
+
+GType               gtk_event_controller_motion_get_type (void) G_GNUC_CONST;
+GtkEventController *gtk_event_controller_motion_new      (GtkWidget *widget);
+
+G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]