* clutter/clutter-main.c: (clutter_do_event): avoid computing source

of events if it is already set (for synthetic events.)
* clutter/clutter-event.c: Add more information to the documentation
of clutter_event_put.
This commit is contained in:
Øyvind Kolås 2007-11-20 17:03:53 +00:00
parent 3c653b00a4
commit 4320c354a3
3 changed files with 119 additions and 95 deletions

View File

@ -1,3 +1,10 @@
2007-11-20 Øyvind Kolås <pippin@o-hand.com>
* clutter/clutter-main.c: (clutter_do_event): avoid computing source
of events if it is already set (for synthetic events.)
* clutter/clutter-event.c: Add more information to the documentation
of clutter_event_put.
2007-11-20 Emmanuele Bassi <ebassi@openedhand.com> 2007-11-20 Emmanuele Bassi <ebassi@openedhand.com>
* README: Add diff example command lines for submitting patches. * README: Add diff example command lines for submitting patches.

View File

@ -413,8 +413,11 @@ clutter_event_peek (void)
* clutter_event_put: * clutter_event_put:
* @event: a #ClutterEvent * @event: a #ClutterEvent
* *
* Puts a copy of the event on the back of the event queue. * Puts a copy of the event on the back of the event queue. The event will have
* The event will have the #CLUTTER_EVENT_FLAG_SYNTHETIC flag set. * the #CLUTTER_EVENT_FLAG_SYNTHETIC flag set. If the source is set event
* signals will be emitted for this source and capture/bubbling for it's
* ancestors. If the source is not set it will be generated by picking or use
* the actor that currently has keyboard focus.
* *
* Since: 0.6 * Since: 0.6
*/ */

View File

@ -1120,64 +1120,56 @@ static void
event_click_count_generate (ClutterEvent *event) event_click_count_generate (ClutterEvent *event)
{ {
/* multiple button click detection */ /* multiple button click detection */
static guint32 button_click_time[2] = { 0, 0 }; static gint click_count[2] = {0, 0};
static guint32 button_number[2] = { -1, -1 }; static gint previous_x[2] = {-1, -1};
static gint button_x[2] = { 0, 0 }; static gint previous_y[2] = {-1, -1};
static gint button_y[2] = { 0, 0 }; static guint32 previous_time[2] = {0, 0};
static gint previous_button_number[2] = {-1, -1};
gint s; /* index into the state variable's arrays, 0 for normal
* events and 1 for synthetic events
*/
guint double_click_time, double_click_distance; ClutterBackend *backend;
ClutterBackend *backend; guint double_click_time;
ClutterMainContext *context; guint double_click_distance;
context = clutter_context_get_default ();
backend = context->backend;
backend = clutter_context_get_default ()->backend;
double_click_distance = clutter_backend_get_double_click_distance (backend); double_click_distance = clutter_backend_get_double_click_distance (backend);
double_click_time = clutter_backend_get_double_click_time (backend); double_click_time = clutter_backend_get_double_click_time (backend);
/* FIXME: below could be reduced in lines and handle >3 clicks */ s = (event->button.flags & CLUTTER_EVENT_FLAG_SYNTHETIC)?1:0;
if ((event->button.time < (button_click_time[1] + 2 * double_click_time))
&& (event->button.button == button_number[1])
&& (ABS (event->button.x - button_x[1]) <= double_click_distance)
&& (ABS (event->button.y - button_y[1]) <= double_click_distance))
{
event->button.click_count = 2;
button_click_time[1] = 0; switch (event->type)
button_click_time[0] = 0;
button_number[1] = -1;
button_number[0] = -1;
button_x[0] = button_x[1] = 0;
button_y[0] = button_y[1] = 0;
}
else if ((event->button.time < (button_click_time[0] + double_click_time)) &&
(event->button.button == button_number[0]) &&
(ABS (event->button.x - button_x[0]) <= double_click_distance) &&
(ABS (event->button.y - button_y[0]) <= double_click_distance))
{ {
event->button.click_count = 3; case CLUTTER_BUTTON_PRESS:
case CLUTTER_SCROLL:
/* check if we are in time and within distance to increment an
* existing click count
*/
if (event->button.time < previous_time[s] + double_click_time &&
(ABS (event->button.x - previous_x[s]) <= double_click_distance) &&
(ABS (event->button.y - previous_y[s]) <= double_click_distance)
&& event->button.button == previous_button_number[s])
{
click_count[s] ++;
}
else /* start a new click count*/
{
click_count[s]=1;
previous_button_number[s] = event->button.button;
}
button_click_time[1] = button_click_time[0]; /* store time and position for this click for comparison with next event */
button_click_time[0] = event->button.time; previous_time[s] = event->button.time;
button_number[1] = button_number[0]; previous_x[s] = event->button.x;
button_number[0] = event->button.button; previous_y[s] = event->button.y;
button_x[1] = button_x[0];
button_x[0] = event->button.x;
button_y[1] = button_y[0];
button_y[0] = event->button.y;
}
else
{
event->button.click_count = 1;
button_click_time[1] = 0; /* fallthrough */
button_click_time[0] = event->button.time; case CLUTTER_BUTTON_RELEASE:
button_number[1] = -1; event->button.click_count=click_count[s];
button_number[0] = event->button.button; break;
button_x[1] = 0; default:
button_x[0] = event->button.x; g_assert (NULL);
button_y[1] = 0;
button_y[0] = event->button.y;
} }
} }
@ -1360,39 +1352,50 @@ clutter_do_event (ClutterEvent *event)
{ {
ClutterActor *actor = NULL; ClutterActor *actor = NULL;
actor = clutter_stage_get_key_focus (CLUTTER_STAGE (stage)); /* check that we're not a synthetic event with source set */
event->any.source = actor; if (event->any.source == NULL)
{
actor = clutter_stage_get_key_focus (CLUTTER_STAGE (stage));
event->any.source = actor;
g_return_if_fail (actor != NULL);
}
g_return_if_fail (actor != NULL);
emit_keyboard_event (event); emit_keyboard_event (event);
} }
break; break;
case CLUTTER_MOTION: case CLUTTER_MOTION:
{
gint32 frame_rate, delta;
/* avoid issuing too many motion events, which leads to many redraws /* avoid rate throttling for synthetic motion events */
* in pick mode (performance penalty) if (! (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
*/ {
frame_rate = clutter_get_motion_events_frequency (); gint32 frame_rate, delta;
delta = 1000 / frame_rate;
CLUTTER_NOTE (EVENT, /* avoid issuing too many motion events, which leads to many
"skip motion event: %s (last:%d, delta:%d, time:%d)", * redraws in pick mode (performance penalty)
(event->any.time < (motion_last_time + delta) ? "yes" : "no"), */
motion_last_time, frame_rate = clutter_get_motion_events_frequency ();
delta, delta = 1000 / frame_rate;
event->any.time);
if (event->any.time < (motion_last_time + delta)) CLUTTER_NOTE (EVENT,
break; "skip motion event: %s (last:%d, delta:%d, time:%d)",
else (event->any.time < (motion_last_time + delta) ? "yes" : "no"),
motion_last_time = event->any.time; motion_last_time,
} delta,
event->any.time);
if (!context->motion_events_per_actor) if (event->any.time < (motion_last_time + delta))
break;
else
motion_last_time = event->any.time;
}
/* Only stage gets motion events if clutter_set_motion_events is TRUE,
* and the event is not a synthetic event with source set.
*/
if (!context->motion_events_per_actor &&
event->any.source == NULL)
{ {
/* Only stage gets motion events */ /* Only stage gets motion events */
event->any.source = stage; event->any.source = stage;
@ -1423,31 +1426,42 @@ clutter_do_event (ClutterEvent *event)
clutter_event_get_coords (event, &x, &y); clutter_event_get_coords (event, &x, &y);
/* Handle release off stage */ /* Only do a pick to find the source if source is not already set
if ((x >= CLUTTER_STAGE_WIDTH () || * (as it could be in a synthetic event)
y >= CLUTTER_STAGE_HEIGHT() || */
x < 0 || y < 0)) if (event->any.source == NULL)
{ {
if (event->type == CLUTTER_BUTTON_RELEASE) /* Handle release off stage */
if ((x >= CLUTTER_STAGE_WIDTH () ||
y >= CLUTTER_STAGE_HEIGHT() ||
x < 0 || y < 0))
{ {
CLUTTER_NOTE (EVENT, "Release off stage received at %i, %i", if (event->type == CLUTTER_BUTTON_RELEASE)
x, y); {
CLUTTER_NOTE (EVENT,"Release off stage received at %i, %i",
x, y);
event->button.source = stage; event->button.source = stage;
emit_pointer_event (event); emit_pointer_event (event);
}
break;
} }
break;
/* Map the event to a reactive actor */
actor = _clutter_do_pick (CLUTTER_STAGE (stage),
x, y,
CLUTTER_PICK_REACTIVE);
event->any.source = actor;
if (!actor)
break;
}
else
{
/* use the source already set in the synthetic event */
actor = event->any.source;
} }
/* Map the event to a reactive actor */
actor = _clutter_do_pick (CLUTTER_STAGE (stage),
x, y,
CLUTTER_PICK_REACTIVE);
event->any.source = actor;
if (!actor)
break;
/* FIXME: for an optimisation should check if there are /* FIXME: for an optimisation should check if there are
* actually any reactive actors and avoid the pick all togeather * actually any reactive actors and avoid the pick all togeather