Handle recursion from motion event handlers

If a motion event handler (or other handler running from the flush-events
phase of the frame clock) recursed the main loop then flushing wouldn't
complete until after the recursed main loop returned, and various aspects
of the state would get out of sync.

To fix this, change flushing of the event queue to simply mark events as
ready to flush, and let normal event delivery handle the rest.

https://bugzilla.gnome.org/show_bug.cgi?id=705176
This commit is contained in:
Owen W. Taylor
2013-11-11 18:04:34 -05:00
committed by Matthias Clasen
parent 0db8aeaad9
commit f50a3af1b7
10 changed files with 38 additions and 45 deletions

View File

@ -88,20 +88,20 @@ _gdk_event_queue_find_first (GdkDisplay *display)
GList *tmp_list;
GList *pending_motion = NULL;
if (display->event_pause_count > 0)
return NULL;
gboolean paused = display->event_pause_count > 0;
tmp_list = display->queued_events;
while (tmp_list)
{
GdkEventPrivate *event = tmp_list->data;
if (!(event->flags & GDK_EVENT_PENDING))
if ((event->flags & GDK_EVENT_PENDING) == 0 &&
(!paused || (event->flags & GDK_EVENT_FLUSHED) != 0))
{
if (pending_motion)
return pending_motion;
if (event->event.type == GDK_MOTION_NOTIFY && !display->flushing_events)
if (event->event.type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
pending_motion = tmp_list;
else
return tmp_list;
@ -321,6 +321,18 @@ _gdk_event_queue_handle_motion_compression (GdkDisplay *display)
}
}
void
_gdk_event_queue_flush (GdkDisplay *display)
{
GList *tmp_list;
for (tmp_list = display->queued_events; tmp_list; tmp_list = tmp_list->next)
{
GdkEventPrivate *event = tmp_list->data;
event->flags |= GDK_EVENT_FLUSHED;
}
}
/**
* gdk_event_handler_set:
* @func: the function to call to handle events from GDK.