Be more careful with private event data

When copying allocated events, also copy the source device.
When synthesizing double or triple clicks, copy the original
button press event including device information.

https://bugzilla.gnome.org/show_bug.cgi?id=639822
This commit is contained in:
Matthias Clasen 2011-01-19 22:52:55 -05:00
parent 6869ff26f3
commit 99812be7d7

View File

@ -503,9 +503,9 @@ gdk_event_copy (const GdkEvent *event)
{
GdkEventPrivate *new_private;
GdkEvent *new_event;
g_return_val_if_fail (event != NULL, NULL);
new_event = gdk_event_new (GDK_NOTHING);
new_private = (GdkEventPrivate *)new_event;
@ -519,21 +519,22 @@ gdk_event_copy (const GdkEvent *event)
new_private->screen = private->screen;
new_private->device = private->device;
new_private->source_device = private->source_device;
}
switch (event->any.type)
{
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
new_event->key.string = g_strdup (event->key.string);
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
if (event->crossing.subwindow != NULL)
g_object_ref (event->crossing.subwindow);
g_object_ref (event->crossing.subwindow);
break;
case GDK_DRAG_ENTER:
case GDK_DRAG_LEAVE:
case GDK_DRAG_MOTION:
@ -542,28 +543,28 @@ gdk_event_copy (const GdkEvent *event)
case GDK_DROP_FINISHED:
g_object_ref (event->dnd.context);
break;
case GDK_EXPOSE:
case GDK_DAMAGE:
if (event->expose.region)
new_event->expose.region = cairo_region_copy (event->expose.region);
new_event->expose.region = cairo_region_copy (event->expose.region);
break;
case GDK_SETTING:
new_event->setting.name = g_strdup (new_event->setting.name);
break;
case GDK_BUTTON_PRESS:
case GDK_BUTTON_RELEASE:
if (event->button.axes)
new_event->button.axes = g_memdup (event->button.axes,
if (event->button.axes)
new_event->button.axes = g_memdup (event->button.axes,
sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
break;
case GDK_MOTION_NOTIFY:
if (event->motion.axes)
new_event->motion.axes = g_memdup (event->motion.axes,
sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
if (event->motion.axes)
new_event->motion.axes = g_memdup (event->motion.axes,
sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
break;
default:
@ -1129,9 +1130,10 @@ gdk_event_get_device (const GdkEvent *event)
* @event: a #GdkEvent
* @device: a #GdkDevice
*
* Sets the slave device for @event to @device. The event
* must have been allocated by GTK+, for instance, by
* gdk_event_copy().
* Sets the slave device for @event to @device.
*
* The event must have been allocated by GTK+,
* for instance by gdk_event_copy().
*
* Since: 3.0
**/
@ -1153,15 +1155,17 @@ gdk_event_set_source_device (GdkEvent *event,
* gdk_event_get_source_device:
* @event: a #GdkEvent
*
* This function returns the hardware (slave) #GdkDevice that has triggered the event,
* falling back to the virtual (master) device (as in gdk_event_get_device()) if the
* event wasn't caused by interaction with a hardware device. This may happen for
* example in synthesized crossing events after a #GdkWindow updates its geometry or
* a grab is acquired/released.
* This function returns the hardware (slave) #GdkDevice that has
* triggered the event, falling back to the virtual (master) device
* (as in gdk_event_get_device()) if the event wasn't caused by
* interaction with a hardware device. This may happen for example
* in synthesized crossing events after a #GdkWindow updates its
* geometry or a grab is acquired/released.
*
* If the event does not contain device field, this function will return %NULL.
* If the event does not contain a device field, this function will
* return %NULL.
*
* Returns: a #GdkDevice, or %NULL.
* Returns: a #GdkDevice, or %NULL
*
* Since: 3.0
**/
@ -1189,6 +1193,7 @@ gdk_event_get_source_device (const GdkEvent *event)
* @event: a valid #GdkEvent
*
* Request more motion notifies if @event is a motion notify hint event.
*
* This function should be used instead of gdk_window_get_pointer() to
* request further motion notifies, because it also works for extension
* events where motion notifies are provided for devices other than the
@ -1196,7 +1201,7 @@ gdk_event_get_source_device (const GdkEvent *event)
* motion events from a %GDK_MOTION_NOTIFY event usually works like this:
*
* |[
* {
* {
* /* motion_event handler */
* x = motion_event->x;
* y = motion_event->y;
@ -1450,19 +1455,15 @@ gdk_get_show_events (void)
static void
gdk_synthesize_click (GdkDisplay *display,
GdkEvent *event,
gint nclicks)
GdkEvent *event,
gint nclicks)
{
GdkEvent temp_event;
GdkEvent *event_copy;
GList *link;
g_return_if_fail (event != NULL);
temp_event = *event;
temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
event_copy = gdk_event_copy (&temp_event);
event_copy = gdk_event_copy (event);
event_copy->type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
link = _gdk_event_queue_append (display, event_copy);
}
@ -1472,6 +1473,8 @@ _gdk_event_button_generate (GdkDisplay *display,
{
GdkMultipleClickInfo *info;
g_return_if_fail (event->type == GDK_BUTTON_PRESS);
info = g_hash_table_lookup (display->multiple_click_info, event->button.device);
if (G_UNLIKELY (!info))