gdk: Add internal API to deal with touch implicit grabs
The necessary information about a touch implicit grab is stored in GdkTouchGrabInfo structs, these are meant to be transient to the touch sequence.
This commit is contained in:
		
				
					committed by
					
						
						Matthias Clasen
					
				
			
			
				
	
			
			
			
						parent
						
							b5de12debd
						
					
				
				
					commit
					b5cfdf2db4
				
			
							
								
								
									
										103
									
								
								gdk/gdkdisplay.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								gdk/gdkdisplay.c
									
									
									
									
									
								
							@ -186,6 +186,7 @@ gdk_display_init (GdkDisplay *display)
 | 
			
		||||
  display->double_click_time = 250;
 | 
			
		||||
  display->double_click_distance = 5;
 | 
			
		||||
 | 
			
		||||
  display->touch_implicit_grabs = g_array_new (FALSE, FALSE, sizeof (GdkTouchGrabInfo));
 | 
			
		||||
  display->device_grabs = g_hash_table_new (NULL, NULL);
 | 
			
		||||
  display->motion_hint_info = g_hash_table_new_full (NULL, NULL, NULL,
 | 
			
		||||
                                                     (GDestroyNotify) g_free);
 | 
			
		||||
@ -234,6 +235,8 @@ gdk_display_finalize (GObject *object)
 | 
			
		||||
                               NULL);
 | 
			
		||||
  g_hash_table_destroy (display->device_grabs);
 | 
			
		||||
 | 
			
		||||
  g_array_free (display->touch_implicit_grabs, TRUE);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (display->motion_hint_info);
 | 
			
		||||
  g_hash_table_destroy (display->pointers_info);
 | 
			
		||||
  g_hash_table_destroy (display->multiple_click_info);
 | 
			
		||||
@ -692,6 +695,79 @@ _gdk_display_add_device_grab (GdkDisplay       *display,
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
_gdk_display_break_touch_grabs (GdkDisplay *display,
 | 
			
		||||
                                GdkDevice  *device,
 | 
			
		||||
                                GdkWindow  *new_grab_window)
 | 
			
		||||
{
 | 
			
		||||
  guint i = 0;
 | 
			
		||||
 | 
			
		||||
  while (i < display->touch_implicit_grabs->len)
 | 
			
		||||
    {
 | 
			
		||||
      GdkTouchGrabInfo *info;
 | 
			
		||||
 | 
			
		||||
      info = &g_array_index (display->touch_implicit_grabs,
 | 
			
		||||
                             GdkTouchGrabInfo, i);
 | 
			
		||||
 | 
			
		||||
      if (info->device == device &&
 | 
			
		||||
          info->window != new_grab_window)
 | 
			
		||||
        {
 | 
			
		||||
          generate_grab_broken_event (GDK_WINDOW (info->window),
 | 
			
		||||
                                      device, TRUE, new_grab_window);
 | 
			
		||||
          g_array_remove_index_fast (display->touch_implicit_grabs, i);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_gdk_display_add_touch_grab (GdkDisplay       *display,
 | 
			
		||||
                             GdkDevice        *device,
 | 
			
		||||
                             GdkEventSequence *sequence,
 | 
			
		||||
                             GdkWindow        *window,
 | 
			
		||||
                             GdkWindow        *native_window,
 | 
			
		||||
                             GdkEventMask      event_mask,
 | 
			
		||||
                             unsigned long     serial,
 | 
			
		||||
                             guint32           time)
 | 
			
		||||
{
 | 
			
		||||
  GdkTouchGrabInfo info;
 | 
			
		||||
 | 
			
		||||
  info.device = device;
 | 
			
		||||
  info.sequence = sequence;
 | 
			
		||||
  info.window = g_object_ref (window);
 | 
			
		||||
  info.native_window = g_object_ref (native_window);
 | 
			
		||||
  info.serial = serial;
 | 
			
		||||
  info.event_mask = event_mask;
 | 
			
		||||
  info.time = time;
 | 
			
		||||
 | 
			
		||||
  g_array_append_val (display->touch_implicit_grabs, info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
_gdk_display_end_touch_grab (GdkDisplay       *display,
 | 
			
		||||
                             GdkDevice        *device,
 | 
			
		||||
                             GdkEventSequence *sequence)
 | 
			
		||||
{
 | 
			
		||||
  guint i;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < display->touch_implicit_grabs->len; i++)
 | 
			
		||||
    {
 | 
			
		||||
      GdkTouchGrabInfo *info;
 | 
			
		||||
 | 
			
		||||
      info = &g_array_index (display->touch_implicit_grabs,
 | 
			
		||||
                             GdkTouchGrabInfo, i);
 | 
			
		||||
 | 
			
		||||
      if (info->device == device && info->sequence == sequence)
 | 
			
		||||
        {
 | 
			
		||||
          g_array_remove_index_fast (display->touch_implicit_grabs, i);
 | 
			
		||||
          return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* _gdk_synthesize_crossing_events only works inside one toplevel.
 | 
			
		||||
   This function splits things into two calls if needed, converting the
 | 
			
		||||
   coordinates to the right toplevel */
 | 
			
		||||
@ -1037,6 +1113,33 @@ _gdk_display_has_device_grab (GdkDisplay *display,
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GdkTouchGrabInfo *
 | 
			
		||||
_gdk_display_has_touch_grab (GdkDisplay       *display,
 | 
			
		||||
                             GdkDevice        *device,
 | 
			
		||||
                             GdkEventSequence *sequence,
 | 
			
		||||
                             gulong            serial)
 | 
			
		||||
{
 | 
			
		||||
  guint i;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < display->touch_implicit_grabs->len; i++)
 | 
			
		||||
    {
 | 
			
		||||
      GdkTouchGrabInfo *info;
 | 
			
		||||
 | 
			
		||||
      info = &g_array_index (display->touch_implicit_grabs,
 | 
			
		||||
                             GdkTouchGrabInfo, i);
 | 
			
		||||
 | 
			
		||||
      if (info->device == device && info->sequence == sequence)
 | 
			
		||||
        {
 | 
			
		||||
          if (serial >= info->serial)
 | 
			
		||||
            return info;
 | 
			
		||||
          else
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns true if last grab was ended
 | 
			
		||||
 * If if_child is non-NULL, end the grab only if the grabbed
 | 
			
		||||
 * window is the same as if_child or a descendant of it */
 | 
			
		||||
 | 
			
		||||
@ -58,6 +58,19 @@ typedef struct
 | 
			
		||||
  guint implicit : 1;
 | 
			
		||||
} GdkDeviceGrabInfo;
 | 
			
		||||
 | 
			
		||||
/* Tracks information about a touch implicit grab on this display */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GdkDevice *device;
 | 
			
		||||
  GdkEventSequence *sequence;
 | 
			
		||||
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
  GdkWindow *native_window;
 | 
			
		||||
  gulong serial;
 | 
			
		||||
  guint event_mask;
 | 
			
		||||
  guint32 time;
 | 
			
		||||
} GdkTouchGrabInfo;
 | 
			
		||||
 | 
			
		||||
/* Tracks information about which window and position the pointer last was in.
 | 
			
		||||
 * This is useful when we need to synthesize events later.
 | 
			
		||||
 * Note that we track toplevel_under_pointer using enter/leave events,
 | 
			
		||||
@ -103,6 +116,7 @@ struct _GdkDisplay
 | 
			
		||||
  guint closed             : 1;  /* Whether this display has been closed */
 | 
			
		||||
  guint ignore_core_events : 1;  /* Don't send core motion and button event */
 | 
			
		||||
 | 
			
		||||
  GArray *touch_implicit_grabs;
 | 
			
		||||
  GHashTable *device_grabs;
 | 
			
		||||
  GHashTable *motion_hint_info;
 | 
			
		||||
  GdkDeviceManager *device_manager;
 | 
			
		||||
@ -260,6 +274,21 @@ gboolean            _gdk_display_end_device_grab      (GdkDisplay       *display
 | 
			
		||||
gboolean            _gdk_display_check_grab_ownership (GdkDisplay       *display,
 | 
			
		||||
                                                       GdkDevice        *device,
 | 
			
		||||
                                                       gulong            serial);
 | 
			
		||||
void                _gdk_display_add_touch_grab       (GdkDisplay       *display,
 | 
			
		||||
                                                       GdkDevice        *device,
 | 
			
		||||
                                                       GdkEventSequence *sequence,
 | 
			
		||||
                                                       GdkWindow        *window,
 | 
			
		||||
                                                       GdkWindow        *native_window,
 | 
			
		||||
                                                       GdkEventMask      event_mask,
 | 
			
		||||
                                                       unsigned long     serial_start,
 | 
			
		||||
                                                       guint32           time);
 | 
			
		||||
GdkTouchGrabInfo *  _gdk_display_has_touch_grab       (GdkDisplay       *display,
 | 
			
		||||
                                                       GdkDevice        *device,
 | 
			
		||||
                                                       GdkEventSequence *sequence,
 | 
			
		||||
                                                       gulong            serial);
 | 
			
		||||
gboolean            _gdk_display_end_touch_grab       (GdkDisplay       *display,
 | 
			
		||||
                                                       GdkDevice        *device,
 | 
			
		||||
                                                       GdkEventSequence *sequence);
 | 
			
		||||
void                _gdk_display_enable_motion_hints  (GdkDisplay       *display,
 | 
			
		||||
                                                       GdkDevice        *device);
 | 
			
		||||
GdkPointerWindowInfo * _gdk_display_get_pointer_info  (GdkDisplay       *display,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user