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:
		@ -519,6 +519,7 @@ gdk_event_copy (const GdkEvent *event)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      new_private->screen = private->screen;
 | 
					      new_private->screen = private->screen;
 | 
				
			||||||
      new_private->device = private->device;
 | 
					      new_private->device = private->device;
 | 
				
			||||||
 | 
					      new_private->source_device = private->source_device;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch (event->any.type)
 | 
					  switch (event->any.type)
 | 
				
			||||||
@ -531,7 +532,7 @@ gdk_event_copy (const GdkEvent *event)
 | 
				
			|||||||
    case GDK_ENTER_NOTIFY:
 | 
					    case GDK_ENTER_NOTIFY:
 | 
				
			||||||
    case GDK_LEAVE_NOTIFY:
 | 
					    case GDK_LEAVE_NOTIFY:
 | 
				
			||||||
      if (event->crossing.subwindow != NULL)
 | 
					      if (event->crossing.subwindow != NULL)
 | 
				
			||||||
	g_object_ref (event->crossing.subwindow);
 | 
					        g_object_ref (event->crossing.subwindow);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case GDK_DRAG_ENTER:
 | 
					    case GDK_DRAG_ENTER:
 | 
				
			||||||
@ -546,7 +547,7 @@ gdk_event_copy (const GdkEvent *event)
 | 
				
			|||||||
    case GDK_EXPOSE:
 | 
					    case GDK_EXPOSE:
 | 
				
			||||||
    case GDK_DAMAGE:
 | 
					    case GDK_DAMAGE:
 | 
				
			||||||
      if (event->expose.region)
 | 
					      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;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case GDK_SETTING:
 | 
					    case GDK_SETTING:
 | 
				
			||||||
@ -556,14 +557,14 @@ gdk_event_copy (const GdkEvent *event)
 | 
				
			|||||||
    case GDK_BUTTON_PRESS:
 | 
					    case GDK_BUTTON_PRESS:
 | 
				
			||||||
    case GDK_BUTTON_RELEASE:
 | 
					    case GDK_BUTTON_RELEASE:
 | 
				
			||||||
      if (event->button.axes)
 | 
					      if (event->button.axes)
 | 
				
			||||||
	new_event->button.axes = g_memdup (event->button.axes,
 | 
					        new_event->button.axes = g_memdup (event->button.axes,
 | 
				
			||||||
                                           sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
 | 
					                                           sizeof (gdouble) * gdk_device_get_n_axes (event->button.device));
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case GDK_MOTION_NOTIFY:
 | 
					    case GDK_MOTION_NOTIFY:
 | 
				
			||||||
      if (event->motion.axes)
 | 
					      if (event->motion.axes)
 | 
				
			||||||
	new_event->motion.axes = g_memdup (event->motion.axes,
 | 
					        new_event->motion.axes = g_memdup (event->motion.axes,
 | 
				
			||||||
					   sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
 | 
					                                           sizeof (gdouble) * gdk_device_get_n_axes (event->motion.device));
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
@ -1129,9 +1130,10 @@ gdk_event_get_device (const GdkEvent *event)
 | 
				
			|||||||
 * @event: a #GdkEvent
 | 
					 * @event: a #GdkEvent
 | 
				
			||||||
 * @device: a #GdkDevice
 | 
					 * @device: a #GdkDevice
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Sets the slave device for @event to @device. The event
 | 
					 * Sets the slave device for @event to @device.
 | 
				
			||||||
 * must have been allocated by GTK+, for instance, by
 | 
					 *
 | 
				
			||||||
 * gdk_event_copy().
 | 
					 * The event must have been allocated by GTK+,
 | 
				
			||||||
 | 
					 * for instance by gdk_event_copy().
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Since: 3.0
 | 
					 * Since: 3.0
 | 
				
			||||||
 **/
 | 
					 **/
 | 
				
			||||||
@ -1153,15 +1155,17 @@ gdk_event_set_source_device (GdkEvent  *event,
 | 
				
			|||||||
 * gdk_event_get_source_device:
 | 
					 * gdk_event_get_source_device:
 | 
				
			||||||
 * @event: a #GdkEvent
 | 
					 * @event: a #GdkEvent
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function returns the hardware (slave) #GdkDevice that has triggered the event,
 | 
					 * This function returns the hardware (slave) #GdkDevice that has
 | 
				
			||||||
 * falling back to the virtual (master) device (as in gdk_event_get_device()) if the
 | 
					 * triggered the event, falling back to the virtual (master) device
 | 
				
			||||||
 * event wasn't caused by interaction with a hardware device. This may happen for
 | 
					 * (as in gdk_event_get_device()) if the event wasn't caused by
 | 
				
			||||||
 * example in synthesized crossing events after a #GdkWindow updates its geometry or
 | 
					 * interaction with a hardware device. This may happen for example
 | 
				
			||||||
 * a grab is acquired/released.
 | 
					 * 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
 | 
					 * Since: 3.0
 | 
				
			||||||
 **/
 | 
					 **/
 | 
				
			||||||
@ -1189,6 +1193,7 @@ gdk_event_get_source_device (const GdkEvent *event)
 | 
				
			|||||||
 * @event: a valid #GdkEvent
 | 
					 * @event: a valid #GdkEvent
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Request more motion notifies if @event is a motion notify hint event.
 | 
					 * Request more motion notifies if @event is a motion notify hint event.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * This function should be used instead of gdk_window_get_pointer() to
 | 
					 * This function should be used instead of gdk_window_get_pointer() to
 | 
				
			||||||
 * request further motion notifies, because it also works for extension
 | 
					 * request further motion notifies, because it also works for extension
 | 
				
			||||||
 * events where motion notifies are provided for devices other than the
 | 
					 * events where motion notifies are provided for devices other than the
 | 
				
			||||||
@ -1450,19 +1455,15 @@ gdk_get_show_events (void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
gdk_synthesize_click (GdkDisplay *display,
 | 
					gdk_synthesize_click (GdkDisplay *display,
 | 
				
			||||||
		      GdkEvent   *event,
 | 
					                      GdkEvent   *event,
 | 
				
			||||||
		      gint	  nclicks)
 | 
					                      gint        nclicks)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GdkEvent temp_event;
 | 
					 | 
				
			||||||
  GdkEvent *event_copy;
 | 
					  GdkEvent *event_copy;
 | 
				
			||||||
  GList *link;
 | 
					  GList *link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_return_if_fail (event != NULL);
 | 
					  event_copy = gdk_event_copy (event);
 | 
				
			||||||
 | 
					  event_copy->type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  temp_event = *event;
 | 
					 | 
				
			||||||
  temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  event_copy = gdk_event_copy (&temp_event);
 | 
					 | 
				
			||||||
  link = _gdk_event_queue_append (display, event_copy);
 | 
					  link = _gdk_event_queue_append (display, event_copy);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1472,6 +1473,8 @@ _gdk_event_button_generate (GdkDisplay *display,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  GdkMultipleClickInfo *info;
 | 
					  GdkMultipleClickInfo *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_return_if_fail (event->type == GDK_BUTTON_PRESS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  info = g_hash_table_lookup (display->multiple_click_info, event->button.device);
 | 
					  info = g_hash_table_lookup (display->multiple_click_info, event->button.device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (G_UNLIKELY (!info))
 | 
					  if (G_UNLIKELY (!info))
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user