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:
Carlos Garnacho 2011-12-28 02:14:18 +01:00 committed by Matthias Clasen
parent b5de12debd
commit b5cfdf2db4
2 changed files with 132 additions and 0 deletions

View File

@ -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 */

View File

@ -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,