Drain the clutter event queue

When multiple events are generated from a single event (for example,
when a motion event generates an enter/leave pair), events accumulate
in the clutter event queue if the clutter event source is not running.
Add a simple event source that checks clutter_events_pending() and
dispatches events as necessary.
This commit is contained in:
Owen W. Taylor 2008-11-05 17:49:55 -05:00
parent 04619df818
commit b26fc771b1

View File

@ -346,6 +346,50 @@ meta_parse_options (int *argc, char ***argv,
#ifdef WITH_CLUTTER #ifdef WITH_CLUTTER
/* Metacity is responsible for pulling events off the X queue, so Clutter
* doesn't need (and shouldn't) run its normal event source which polls
* the X fd, but we do have to deal with dispatching events that accumulate
* in the clutter queue. This happens, for example, when clutter generate
* enter/leave events on mouse motion - several events are queued in the
* clutter queue but only one dispatched. It could also happen because of
* explicit calls to clutter_event_put(). We add a very simple custom
* event loop source which is simply responsible for pulling events off
* of the queue and dispatching them before we block for new events.
*/
static gboolean
event_prepare (GSource *source,
gint *timeout_)
{
*timeout_ = -1;
return clutter_events_pending ();
}
static gboolean
event_check (GSource *source)
{
return clutter_events_pending ();
}
static gboolean
event_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
ClutterEvent *event = clutter_event_get ();
if (event)
clutter_do_event (event);
return TRUE;
}
static GSourceFuncs event_funcs = {
event_prepare,
event_check,
event_dispatch
};
static void static void
meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv) meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
{ {
@ -355,6 +399,10 @@ meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv)) if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv))
{ {
meta_compositor_can_use_clutter__ = 1; meta_compositor_can_use_clutter__ = 1;
GSource *source = g_source_new (&event_funcs, sizeof (GSource));
g_source_attach (source, NULL);
g_source_unref (source);
} }
else else
{ {