[gtk+/wip/carlosg/event-delivery: 78/104] widget: Copy event in gtk_widget_event and _captured_event



commit a0016758a8442f747d95ff741a249e10dd7040e1
Author: Timm Bäder <mail baedert org>
Date:   Tue May 9 15:48:20 2017 +0200

    widget: Copy event in gtk_widget_event and _captured_event
    
    To ensure that we never translate the coordinates to widget coordinates
    twice.

 gtk/gtkmain.c          |    2 +-
 gtk/gtkwidget.c        |   73 +++++++++++++++++++++++++++++-------------------
 gtk/gtkwidget.h        |    2 +-
 gtk/gtkwidgetprivate.h |    4 +-
 4 files changed, 48 insertions(+), 33 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 33429ac..e32cbb7 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -2501,7 +2501,7 @@ propagate_event (GtkWidget *widget,
                  GtkWidget *topmost)
 {
   gboolean handled_event = FALSE;
-  gboolean (* propagate_func) (GtkWidget *widget, GdkEvent  *event);
+  gboolean (* propagate_func) (GtkWidget *widget, const GdkEvent *event);
 
   propagate_func = captured ? _gtk_widget_captured_event : gtk_widget_event;
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index ce3e54f..17158c2 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -688,7 +688,7 @@ static void         gtk_widget_propagate_state              (GtkWidget        *widget,
 static void             gtk_widget_update_alpha                 (GtkWidget        *widget);
 
 static gint            gtk_widget_event_internal               (GtkWidget        *widget,
-                                                                GdkEvent         *event);
+                                                                 const GdkEvent   *event);
 static gboolean                gtk_widget_real_mnemonic_activate       (GtkWidget        *widget,
                                                                 gboolean          group_cycling);
 static void             gtk_widget_real_measure                 (GtkWidget        *widget,
@@ -764,7 +764,7 @@ static void gtk_widget_set_device_enabled_internal (GtkWidget *widget,
 static void gtk_widget_on_frame_clock_update (GdkFrameClock *frame_clock,
                                               GtkWidget     *widget);
 
-static gboolean event_window_is_still_viewable (GdkEvent *event);
+static gboolean event_window_is_still_viewable (const GdkEvent *event);
 
 static void gtk_widget_update_input_shape (GtkWidget *widget);
 
@@ -6656,8 +6656,8 @@ gtk_widget_real_grab_broken_event (GtkWidget          *widget,
  *               the event was handled)
  **/
 gboolean
-gtk_widget_event (GtkWidget *widget,
-                 GdkEvent  *event)
+gtk_widget_event (GtkWidget       *widget,
+                 const GdkEvent  *event)
 {
   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
   g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
@@ -6748,12 +6748,16 @@ cancel_event_sequence_on_hierarchy (GtkWidget        *widget,
     }
 }
 
+static void
+translate_coordinates (GdkEvent  *event,
+                       GtkWidget *widget);
 gboolean
-_gtk_widget_captured_event (GtkWidget *widget,
-                            GdkEvent  *event)
+_gtk_widget_captured_event (GtkWidget      *widget,
+                            const GdkEvent *event)
 {
   gboolean return_val = FALSE;
   GtkCapturedEventHandler handler;
+  GdkEvent *event_copy;
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
   g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE);
@@ -6769,30 +6773,36 @@ _gtk_widget_captured_event (GtkWidget *widget,
   if (!event_window_is_still_viewable (event))
     return TRUE;
 
-  return_val = _gtk_widget_run_controllers (widget, event, GTK_PHASE_CAPTURE);
+  event_copy = gdk_event_copy (event);
+  translate_coordinates (event_copy, widget);
+
+  return_val = _gtk_widget_run_controllers (widget, event_copy, GTK_PHASE_CAPTURE);
 
   handler = g_object_get_data (G_OBJECT (widget), "captured-event-handler");
   if (!handler)
-    return return_val;
+    goto out;
 
   g_object_ref (widget);
 
-  return_val |= handler (widget, event);
-  return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event);
+  return_val |= handler (widget, event_copy);
+  return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event_copy);
 
   /* The widget that was originally to receive the event
    * handles motion hints, but the capturing widget might
    * not, so ensure we get further motion events.
    */
   if (return_val &&
-      event->type == GDK_MOTION_NOTIFY &&
-      event->motion.is_hint &&
-      (gdk_window_get_events (event->any.window) &
+      event_copy->type == GDK_MOTION_NOTIFY &&
+      event_copy->motion.is_hint &&
+      (gdk_window_get_events (event_copy->any.window) &
        GDK_POINTER_MOTION_HINT_MASK) != 0)
-    gdk_event_request_motions (&event->motion);
+    gdk_event_request_motions (&event_copy->motion);
 
   g_object_unref (widget);
 
+out:
+  gdk_event_free (event_copy);
+
   return return_val;
 }
 
@@ -6871,7 +6881,7 @@ gtk_cairo_transform_to_window (cairo_t   *cr,
 }
 
 static gboolean
-event_window_is_still_viewable (GdkEvent *event)
+event_window_is_still_viewable (const GdkEvent *event)
 {
   /* Check that we think the event's window is viewable before
    * delivering the event, to prevent surprises. We do this here
@@ -6927,14 +6937,17 @@ translate_coordinates (GdkEvent  *event,
   y = yd;
   gtk_widget_translate_coordinates (event_widget, widget,
                                     x, y, &x, &y);
+
+  /*g_message ("New coords for %p: %d/%d (widget %s)", event, x, y, G_OBJECT_TYPE_NAME (widget));*/
   gdk_event_set_coords (event, x, y);
 }
 
 static gint
-gtk_widget_event_internal (GtkWidget *widget,
-                          GdkEvent  *event)
+gtk_widget_event_internal (GtkWidget      *widget,
+                           const GdkEvent *event)
 {
   gboolean return_val = FALSE, handled;
+  GdkEvent *event_copy;
 
   /* We check only once for is-still-visible; if someone
    * hides the window in on of the signals on the widget,
@@ -6945,22 +6958,23 @@ gtk_widget_event_internal (GtkWidget *widget,
     return TRUE;
 
   g_object_ref (widget);
+  event_copy = gdk_event_copy (event);
   translate_coordinates (event_copy, widget);
 
-  if (widget == gtk_get_event_widget (event))
-    return_val |= _gtk_widget_run_controllers (widget, event, GTK_PHASE_TARGET);
+  if (widget == gtk_get_event_widget (event_copy))
+    return_val |= _gtk_widget_run_controllers (widget, event_copy, GTK_PHASE_TARGET);
 
-  g_signal_emit (widget, widget_signals[EVENT], 0, event, &handled);
-  return_val |= handled | !WIDGET_REALIZED_FOR_EVENT (widget, event);
+  g_signal_emit (widget, widget_signals[EVENT], 0, event_copy, &handled);
+  return_val |= handled | !WIDGET_REALIZED_FOR_EVENT (widget, event_copy);
   if (!return_val)
     {
       gint signal_num;
 
-      switch (event->type)
+      switch (event_copy->type)
        {
         case GDK_TOUCHPAD_SWIPE:
         case GDK_TOUCHPAD_PINCH:
-          return_val |= _gtk_widget_run_controllers (widget, event, GTK_PHASE_BUBBLE);
+          return_val |= _gtk_widget_run_controllers (widget, event_copy, GTK_PHASE_BUBBLE);
           /* Fall through */
         case GDK_PAD_BUTTON_PRESS:
         case GDK_PAD_BUTTON_RELEASE:
@@ -7012,8 +7026,8 @@ gtk_widget_event_internal (GtkWidget *widget,
          signal_num = LEAVE_NOTIFY_EVENT;
          break;
        case GDK_FOCUS_CHANGE:
-         signal_num = event->focus_change.in ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
-         if (event->focus_change.in)
+         signal_num = event_copy->focus_change.in ? FOCUS_IN_EVENT : FOCUS_OUT_EVENT;
+         if (event_copy->focus_change.in)
            _gtk_tooltip_focus_in (widget);
          else
            _gtk_tooltip_focus_out (widget);
@@ -7052,22 +7066,23 @@ gtk_widget_event_internal (GtkWidget *widget,
          signal_num = GRAB_BROKEN_EVENT;
          break;
        default:
-         g_warning ("gtk_widget_event(): unhandled event type: %d", event->type);
+         g_warning ("gtk_widget_event(): unhandled event type: %d", event_copy->type);
          signal_num = -1;
          break;
        }
       if (signal_num != -1)
         {
-         g_signal_emit (widget, widget_signals[signal_num], 0, event, &handled);
+         g_signal_emit (widget, widget_signals[signal_num], 0, event_copy, &handled);
           return_val |= handled;
         }
     }
-  if (WIDGET_REALIZED_FOR_EVENT (widget, event))
-    g_signal_emit (widget, widget_signals[EVENT_AFTER], 0, event);
+  if (WIDGET_REALIZED_FOR_EVENT (widget, event_copy))
+    g_signal_emit (widget, widget_signals[EVENT_AFTER], 0, event_copy);
   else
     return_val = TRUE;
 
   g_object_unref (widget);
+  gdk_event_free (event_copy);
 
   return return_val;
 }
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 34a1e47..da5583f 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -596,7 +596,7 @@ gboolean   gtk_widget_mnemonic_activate   (GtkWidget           *widget,
                                           gboolean             group_cycling);
 GDK_AVAILABLE_IN_ALL
 gboolean   gtk_widget_event              (GtkWidget           *widget,
-                                          GdkEvent            *event);
+                                           const GdkEvent      *event);
 GDK_AVAILABLE_IN_ALL
 gboolean   gtk_widget_send_focus_change   (GtkWidget           *widget,
                                            GdkEvent            *event);
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 8763278..5211b40 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -248,8 +248,8 @@ typedef gboolean (*GtkCapturedEventHandler) (GtkWidget *widget, GdkEvent *event)
 void              _gtk_widget_set_captured_event_handler (GtkWidget               *widget,
                                                           GtkCapturedEventHandler  handler);
 
-gboolean          _gtk_widget_captured_event               (GtkWidget *widget,
-                                                            GdkEvent  *event);
+gboolean          _gtk_widget_captured_event               (GtkWidget      *widget,
+                                                            const GdkEvent *event);
 
 GtkWidgetPath *   _gtk_widget_create_path                  (GtkWidget    *widget);
 void              gtk_widget_clear_path                    (GtkWidget    *widget);


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