Bug 1108 - Enter/Leave events logics wrt. skipped motion events
Handle dropped motion events when computing crossing events, based on a patch from Gwenole Beauchesne. * clutter/clutter-main.c: (clutter_event_get_device): internal static utility function. (clutter_do_event): generate enter/leave events for all pointer events. (generate_enter_leave_events): modified enter/leave events generator to work for all pointer event types. Enter/leave events are now delivered before the motion/button event that caused the crossing to happen. * clutter/clutter-event.c: (clutter_event_copy), (clutter_event_free): removed reference counting logic that is not needed when the crossing events are directly delivered.
This commit is contained in:
parent
c05af0ed87
commit
c606547dcb
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
|||||||
|
2008-10-01 Øyvind Kolås <pippin@linux.intel.com>
|
||||||
|
|
||||||
|
Bug 1108 - Enter/Leave events logics wrt. skipped motion events
|
||||||
|
|
||||||
|
Handle dropped motion events when computing crossing events,
|
||||||
|
based on a patch from Gwenole Beauchesne.
|
||||||
|
|
||||||
|
* clutter/clutter-main.c: (clutter_event_get_device): internal static
|
||||||
|
utility function.
|
||||||
|
(clutter_do_event): generate enter/leave events for all pointer
|
||||||
|
events.
|
||||||
|
(generate_enter_leave_events): modified enter/leave events generator
|
||||||
|
to work for all pointer event types. Enter/leave events are now
|
||||||
|
delivered before the motion/button event that caused the crossing to
|
||||||
|
happen.
|
||||||
|
* clutter/clutter-event.c: (clutter_event_copy), (clutter_event_free):
|
||||||
|
removed reference counting logic that is not needed when the crossing
|
||||||
|
events are directly delivered.
|
||||||
|
|
||||||
2008-09-29 Emmanuele Bassi <ebassi@linux.intel.com>
|
2008-09-29 Emmanuele Bassi <ebassi@linux.intel.com>
|
||||||
|
|
||||||
* configure.ac: Post branch bump to 0.9.0
|
* configure.ac: Post branch bump to 0.9.0
|
||||||
|
@ -412,19 +412,6 @@ clutter_event_copy (ClutterEvent *event)
|
|||||||
new_event = clutter_event_new (CLUTTER_NOTHING);
|
new_event = clutter_event_new (CLUTTER_NOTHING);
|
||||||
*new_event = *event;
|
*new_event = *event;
|
||||||
|
|
||||||
/* deep copies or references must be added here */
|
|
||||||
switch (new_event->type)
|
|
||||||
{
|
|
||||||
case CLUTTER_ENTER:
|
|
||||||
case CLUTTER_LEAVE:
|
|
||||||
if (new_event->crossing.related)
|
|
||||||
g_object_ref (new_event->crossing.related);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new_event;
|
return new_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,10 +426,6 @@ clutter_event_free (ClutterEvent *event)
|
|||||||
{
|
{
|
||||||
if (G_LIKELY (event))
|
if (G_LIKELY (event))
|
||||||
{
|
{
|
||||||
if ((event->type == CLUTTER_LEAVE || event->type == CLUTTER_ENTER) &&
|
|
||||||
event->crossing.related)
|
|
||||||
g_object_unref (event->crossing.related);
|
|
||||||
|
|
||||||
g_slice_free (ClutterEvent, event);
|
g_slice_free (ClutterEvent, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1718,61 +1718,90 @@ unset_motion_last_actor (ClutterActor *actor, ClutterInputDevice *dev)
|
|||||||
dev->motion_last_actor = NULL;
|
dev->motion_last_actor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterInputDevice * clutter_event_get_device (ClutterEvent *event);
|
||||||
|
|
||||||
|
/* This function should perhaps be public and in clutter-event.c ?
|
||||||
|
*/
|
||||||
|
static ClutterInputDevice *
|
||||||
|
clutter_event_get_device (ClutterEvent *event)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (event != NULL, NULL);
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_NOTHING:
|
||||||
|
case CLUTTER_STAGE_STATE:
|
||||||
|
case CLUTTER_DESTROY_NOTIFY:
|
||||||
|
case CLUTTER_CLIENT_MESSAGE:
|
||||||
|
case CLUTTER_DELETE:
|
||||||
|
case CLUTTER_ENTER:
|
||||||
|
case CLUTTER_LEAVE:
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
case CLUTTER_BUTTON_PRESS:
|
||||||
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
|
return event->button.device;
|
||||||
|
case CLUTTER_MOTION:
|
||||||
|
return event->motion.device;
|
||||||
|
case CLUTTER_SCROLL:
|
||||||
|
return event->scroll.device;
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_PRESS:
|
||||||
|
case CLUTTER_KEY_RELEASE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
generate_enter_leave_events (ClutterEvent *event)
|
generate_enter_leave_events (ClutterEvent *event)
|
||||||
{
|
{
|
||||||
ClutterMainContext *context = ClutterCntx;
|
ClutterMainContext *context = ClutterCntx;
|
||||||
ClutterActor *motion_current_actor = event->motion.source;
|
ClutterActor *motion_current_actor = event->motion.source;
|
||||||
ClutterActor *last_actor = context->motion_last_actor;
|
ClutterActor *last_actor = context->motion_last_actor;
|
||||||
|
ClutterInputDevice *device = clutter_event_get_device (event);
|
||||||
|
|
||||||
if (event->motion.device != NULL)
|
if (device != NULL)
|
||||||
last_actor = event->motion.device->motion_last_actor;
|
last_actor = device->motion_last_actor;
|
||||||
|
|
||||||
if (last_actor != motion_current_actor)
|
if (last_actor != motion_current_actor)
|
||||||
{
|
{
|
||||||
if (motion_current_actor)
|
if (motion_current_actor)
|
||||||
{
|
{
|
||||||
|
gint x, y;
|
||||||
ClutterEvent cev;
|
ClutterEvent cev;
|
||||||
|
|
||||||
cev.crossing.device = event->motion.device;
|
cev.crossing.device = device;
|
||||||
|
clutter_event_get_coords (event, &x, &y);
|
||||||
|
|
||||||
if (context->motion_last_actor)
|
if (context->motion_last_actor)
|
||||||
{
|
{
|
||||||
cev.crossing.type = CLUTTER_LEAVE;
|
cev.crossing.type = CLUTTER_LEAVE;
|
||||||
cev.crossing.time = event->any.time;
|
cev.crossing.time = event->any.time;
|
||||||
cev.crossing.flags = 0;
|
cev.crossing.flags = 0;
|
||||||
cev.crossing.x = event->motion.x;
|
cev.crossing.x = x;
|
||||||
cev.crossing.y = event->motion.y;
|
cev.crossing.y = y;
|
||||||
cev.crossing.source = last_actor;
|
cev.crossing.source = last_actor;
|
||||||
cev.crossing.stage = event->any.stage;
|
cev.crossing.stage = event->any.stage;
|
||||||
|
|
||||||
/* unref in free */
|
|
||||||
cev.crossing.related = motion_current_actor;
|
cev.crossing.related = motion_current_actor;
|
||||||
|
|
||||||
g_queue_push_head (context->events_queue,
|
emit_pointer_event (&cev, device);
|
||||||
clutter_event_copy (&cev));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cev.crossing.type = CLUTTER_ENTER;
|
cev.crossing.type = CLUTTER_ENTER;
|
||||||
cev.crossing.time = event->any.time;
|
cev.crossing.time = event->any.time;
|
||||||
cev.crossing.flags = 0;
|
cev.crossing.flags = 0;
|
||||||
cev.crossing.x = event->motion.x;
|
cev.crossing.x = x;
|
||||||
cev.crossing.y = event->motion.y;
|
cev.crossing.y = y;
|
||||||
cev.crossing.source = motion_current_actor;
|
cev.crossing.source = motion_current_actor;
|
||||||
cev.crossing.stage = event->any.stage;
|
cev.crossing.stage = event->any.stage;
|
||||||
|
|
||||||
if (context->motion_last_actor)
|
if (context->motion_last_actor)
|
||||||
cev.crossing.related = last_actor;
|
cev.crossing.related = last_actor;
|
||||||
else
|
else
|
||||||
{
|
cev.crossing.related = NULL;
|
||||||
/* the previous actor we were getting events from seems to have
|
|
||||||
* vanished
|
|
||||||
*/
|
|
||||||
cev.crossing.related = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_queue_push_head (context->events_queue,
|
emit_pointer_event (&cev, device);
|
||||||
clutter_event_copy (&cev));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1781,18 +1810,18 @@ generate_enter_leave_events (ClutterEvent *event)
|
|||||||
g_signal_handlers_disconnect_by_func
|
g_signal_handlers_disconnect_by_func
|
||||||
(last_actor,
|
(last_actor,
|
||||||
G_CALLBACK (unset_motion_last_actor),
|
G_CALLBACK (unset_motion_last_actor),
|
||||||
event->motion.device);
|
device);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (motion_current_actor && last_actor != motion_current_actor)
|
if (motion_current_actor && last_actor != motion_current_actor)
|
||||||
{
|
{
|
||||||
g_signal_connect (motion_current_actor, "destroy",
|
g_signal_connect (motion_current_actor, "destroy",
|
||||||
G_CALLBACK (unset_motion_last_actor),
|
G_CALLBACK (unset_motion_last_actor),
|
||||||
event->motion.device);
|
device);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->motion.device != NULL)
|
if (device != NULL)
|
||||||
event->motion.device->motion_last_actor = motion_current_actor;
|
device->motion_last_actor = motion_current_actor;
|
||||||
else
|
else
|
||||||
context->motion_last_actor = motion_current_actor;
|
context->motion_last_actor = motion_current_actor;
|
||||||
}
|
}
|
||||||
@ -2012,12 +2041,10 @@ clutter_do_event (ClutterEvent *event)
|
|||||||
CLUTTER_NOTE (EVENT, "Reactive event received at %i, %i - actor: %p",
|
CLUTTER_NOTE (EVENT, "Reactive event received at %i, %i - actor: %p",
|
||||||
x, y, actor);
|
x, y, actor);
|
||||||
|
|
||||||
if (event->type == CLUTTER_MOTION)
|
/* Create, enter/leave events if needed */
|
||||||
{
|
generate_enter_leave_events (event);
|
||||||
/* Generate enter leave events (if any) */
|
|
||||||
generate_enter_leave_events (event);
|
if (event->type != CLUTTER_MOTION)
|
||||||
}
|
|
||||||
else /* (button event) */
|
|
||||||
{
|
{
|
||||||
/* Generate click count */
|
/* Generate click count */
|
||||||
event_click_count_generate (event);
|
event_click_count_generate (event);
|
||||||
|
Loading…
Reference in New Issue
Block a user