[gtk/wip/chergert/controller-motion-coordinates] eventcontrollermotion: translate event to widget coordinates



commit 526ec24079d1fdcb7d4fa37ecf6473b7ea576f80
Author: Christian Hergert <chergert redhat com>
Date:   Thu Oct 4 18:51:25 2018 -0700

    eventcontrollermotion: translate event to widget coordinates
    
    When creating the motion controller, we know the widget that is of interest
    based on gtk_event_controller_motion_new(). However, not all incoming
    events are guaranteed to be of the GdkWindow associated to that widget.
    They may also be for a descendant. Therefore, it is useful to translate
    those coordinates into the target widget coordinate space as that is
    likely what they care about.

 gtk/gtkeventcontrollermotion.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkeventcontrollermotion.c b/gtk/gtkeventcontrollermotion.c
index c20c3710da..65adc5cd9c 100644
--- a/gtk/gtkeventcontrollermotion.c
+++ b/gtk/gtkeventcontrollermotion.c
@@ -58,18 +58,46 @@ 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);
+    }
+
+  *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;
-      gdk_event_get_coords (event, &x, &y);
+      get_coords (widget, event, &x, &y);
       g_signal_emit (controller, signals[ENTER], 0, x, y);
     }
   else if (type == GDK_LEAVE_NOTIFY)
@@ -79,7 +107,7 @@ gtk_event_controller_motion_handle_event (GtkEventController *controller,
   else if (type == GDK_MOTION_NOTIFY)
     {
       double x, y;
-      gdk_event_get_coords (event, &x, &y);
+      get_coords (widget, event, &x, &y);
       g_signal_emit (controller, signals[MOTION], 0, x, y);
     }
 


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