[gtk+/xi2: 451/1239] Synthesize motion/multidevice events when a group changes.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 451/1239] Synthesize motion/multidevice events when a group changes.
- Date: Tue, 29 Sep 2009 10:47:54 +0000 (UTC)
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]