+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>
* configure.ac: Post branch bump to 0.9.0
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
generate_enter_leave_events (ClutterEvent *event)
{
ClutterMainContext *context = ClutterCntx;
ClutterActor *motion_current_actor = event->motion.source;
ClutterActor *last_actor = context->motion_last_actor;
+ ClutterInputDevice *device = clutter_event_get_device (event);
- if (event->motion.device != NULL)
- last_actor = event->motion.device->motion_last_actor;
+ if (device != NULL)
+ last_actor = device->motion_last_actor;
if (last_actor != motion_current_actor)
{
if (motion_current_actor)
{
+ gint x, y;
ClutterEvent cev;
- cev.crossing.device = event->motion.device;
+ cev.crossing.device = device;
+ clutter_event_get_coords (event, &x, &y);
if (context->motion_last_actor)
{
cev.crossing.type = CLUTTER_LEAVE;
cev.crossing.time = event->any.time;
cev.crossing.flags = 0;
- cev.crossing.x = event->motion.x;
- cev.crossing.y = event->motion.y;
+ cev.crossing.x = x;
+ cev.crossing.y = y;
cev.crossing.source = last_actor;
cev.crossing.stage = event->any.stage;
-
- /* unref in free */
cev.crossing.related = motion_current_actor;
- g_queue_push_head (context->events_queue,
- clutter_event_copy (&cev));
+ emit_pointer_event (&cev, device);
}
cev.crossing.type = CLUTTER_ENTER;
cev.crossing.time = event->any.time;
cev.crossing.flags = 0;
- cev.crossing.x = event->motion.x;
- cev.crossing.y = event->motion.y;
+ cev.crossing.x = x;
+ cev.crossing.y = y;
cev.crossing.source = motion_current_actor;
cev.crossing.stage = event->any.stage;
if (context->motion_last_actor)
cev.crossing.related = last_actor;
else
- {
- /* the previous actor we were getting events from seems to have
- * vanished
- */
- cev.crossing.related = NULL;
- }
+ cev.crossing.related = NULL;
- g_queue_push_head (context->events_queue,
- clutter_event_copy (&cev));
+ emit_pointer_event (&cev, device);
}
}
g_signal_handlers_disconnect_by_func
(last_actor,
G_CALLBACK (unset_motion_last_actor),
- event->motion.device);
+ device);
}
if (motion_current_actor && last_actor != motion_current_actor)
{
g_signal_connect (motion_current_actor, "destroy",
G_CALLBACK (unset_motion_last_actor),
- event->motion.device);
+ device);
}
- if (event->motion.device != NULL)
- event->motion.device->motion_last_actor = motion_current_actor;
+ if (device != NULL)
+ device->motion_last_actor = motion_current_actor;
else
context->motion_last_actor = motion_current_actor;
}
CLUTTER_NOTE (EVENT, "Reactive event received at %i, %i - actor: %p",
x, y, actor);
- if (event->type == CLUTTER_MOTION)
- {
- /* Generate enter leave events (if any) */
- generate_enter_leave_events (event);
- }
- else /* (button event) */
+ /* Create, enter/leave events if needed */
+ generate_enter_leave_events (event);
+
+ if (event->type != CLUTTER_MOTION)
{
/* Generate click count */
event_click_count_generate (event);