[gtk+/xi2: 451/1239] Synthesize motion/multidevice events when a group changes.



commit 00019f7ad4766ad5fc0884eb5e46077bb31a4e10
Author: Carlos Garnacho <carlos lanedo com>
Date:   Sun Jul 5 15:28:09 2009 +0100

    Synthesize motion/multidevice events when a group changes.
    
    Ideally, devices are added to a group on button-press or enter-notify, so
    a motion event is synthesized from these to force the widget to have
    information about all devices in order to generate correct multidevice
    events.

 gtk/gtkwidget.c |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 0d154cd..49fba0a 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -10463,6 +10463,58 @@ gtk_widget_set_support_multidevice (GtkWidget *widget,
     }
 }
 
+static GdkEventMotion *
+convert_event_to_motion (GdkEvent *event)
+{
+  GdkEventMotion *new_event;
+
+  new_event = gdk_event_new (GDK_MOTION_NOTIFY);
+
+  switch (event->type)
+    {
+    case GDK_BUTTON_PRESS:
+    case GDK_2BUTTON_PRESS:
+    case GDK_3BUTTON_PRESS:
+    case GDK_BUTTON_RELEASE:
+      new_event->window = g_object_ref (event->button.window);
+      new_event->send_event = TRUE;
+      new_event->time = event->button.time;
+      new_event->x = event->button.x;
+      new_event->y = event->button.y;
+
+      if (event->button.axes)
+	new_event->axes = g_memdup (event->button.axes,
+                                    sizeof (gdouble) * event->button.device->num_axes);
+
+      new_event->state = 0; /* FIXME */
+      new_event->is_hint = FALSE;
+      new_event->device = g_object_ref (event->button.device);
+      new_event->x_root = event->button.x_root;
+      new_event->y_root = event->button.y_root;
+      break;
+    case GDK_ENTER_NOTIFY:
+    case GDK_LEAVE_NOTIFY:
+      new_event->window = g_object_ref (event->crossing.window);
+      new_event->send_event = TRUE;
+      new_event->time = event->crossing.time;
+      new_event->x = event->crossing.x;
+      new_event->y = event->crossing.y;
+      new_event->axes = NULL; /* FIXME: not ideal for non-mice */
+      new_event->state = 0; /* FIXME */
+      new_event->is_hint = FALSE;
+      new_event->device = g_object_ref (event->crossing.device);
+      new_event->x_root = event->crossing.x_root;
+      new_event->y_root = event->crossing.y_root;
+      break;
+    default:
+      g_warning ("Event with type %d can not be transformed to GdkEventMotion", event->type);
+      gdk_event_free ((GdkEvent *) new_event);
+      new_event = NULL;
+    }
+
+  return new_event;
+}
+
 static void
 device_group_device_added (GtkDeviceGroup *group,
                            GdkDevice      *device,
@@ -10470,6 +10522,9 @@ device_group_device_added (GtkDeviceGroup *group,
 {
   GtkMultiDeviceData *data;
   GtkDeviceGroup *old_group;
+  GdkEventMotion *new_event = NULL;
+  GtkWidget *event_widget;
+  GdkEvent *event;
 
   data = g_object_get_qdata (G_OBJECT (widget), quark_multidevice_data);
 
@@ -10485,6 +10540,29 @@ device_group_device_added (GtkDeviceGroup *group,
   g_hash_table_insert (data->by_dev,
                        g_object_ref (device),
                        g_object_ref (group));
+
+  event = gtk_get_current_event ();
+
+  if (!event)
+    return;
+
+  if (event->type == GDK_MOTION_NOTIFY)
+    new_event = (GdkEventMotion *) event;
+  else
+    {
+      event_widget = gtk_get_event_widget (event);
+
+      if (widget == event_widget)
+        new_event = convert_event_to_motion (event);
+
+      gdk_event_free (event);
+    }
+
+  if (new_event)
+    {
+      gtk_widget_event_internal (widget, (GdkEvent *) new_event);
+      gdk_event_free ((GdkEvent *) new_event);
+    }
 }
 
 static void
@@ -10498,6 +10576,7 @@ device_group_device_removed (GtkDeviceGroup *group,
 
   g_assert (data != NULL);
 
+  compose_multidevice_event (widget, device, NULL);
   g_hash_table_remove (data->by_dev, device);
 }
 



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