/* * _clutter_input_device_set_actor: * @device: a #ClutterInputDevice * @actor: a #ClutterActor * * Sets the actor under the pointer coordinates of @device * * This function is called by _clutter_input_device_update() * and it will: * * - queue a %CLUTTER_LEAVE event on the previous pointer actor * of @device, if any * - set to %FALSE the :has-pointer property of the previous * pointer actor of @device, if any * - queue a %CLUTTER_ENTER event on the new pointer actor * - set to %TRUE the :has-pointer property of the new pointer * actor */ void _clutter_input_device_set_actor (ClutterInputDevice *device, ClutterActor *actor) { ClutterActor *old_actor; ClutterEvent cev; g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device)); if (actor == device->cursor_actor) return; old_actor = device->cursor_actor; if (old_actor != NULL) { cev.crossing.type = CLUTTER_LEAVE; cev.crossing.time = device->current_time; cev.crossing.flags = 0; cev.crossing.stage = device->stage; cev.crossing.source = device->cursor_actor; cev.crossing.x = device->current_x; cev.crossing.y = device->current_y; cev.crossing.device = device; cev.crossing.related = actor; /* we need to make sure that this event is processed before * any other event we might have queued up until now, so we * go on and synthesize the event emission */ _clutter_process_event (&cev); _clutter_actor_set_has_pointer (device->cursor_actor, FALSE); g_object_weak_unref (G_OBJECT (device->cursor_actor), cursor_weak_unref, device); device->cursor_actor = NULL; } if (actor != NULL) { cev.crossing.type = CLUTTER_ENTER; cev.crossing.time = device->current_time; cev.crossing.flags = 0; cev.crossing.stage = device->stage; cev.crossing.x = device->current_x; cev.crossing.y = device->current_y; cev.crossing.device = device; CLUTTER_NOTE (EVENT, "Device '%s' entering '%s' at %d, %d", device->device_name, clutter_actor_get_name (actor) != NULL ? clutter_actor_get_name (actor) : G_OBJECT_TYPE_NAME (actor), device->current_x, device->current_y); /* if there is an actor overlapping the Stage boundary and we * don't do this check then we'll emit an ENTER event only on * the actor instead of emitting it on the Stage *and* the * actor */ if (old_actor == NULL && actor != CLUTTER_ACTOR (device->stage)) { cev.crossing.source = CLUTTER_ACTOR (device->stage); cev.crossing.related = NULL; CLUTTER_NOTE (EVENT, "Adding Crossing[Enter] event for Stage"); _clutter_process_event (&cev); cev.crossing.source = actor; cev.crossing.related = CLUTTER_ACTOR (device->stage); } else { cev.crossing.source = actor; cev.crossing.related = old_actor; } /* as above: we need to make sure that this event is processed * before any other event we might have queued up until now, so * we go on and synthesize the event emission */ _clutter_process_event (&cev); } device->cursor_actor = actor; if (device->cursor_actor != NULL) { g_object_weak_ref (G_OBJECT (device->cursor_actor), cursor_weak_unref, device); _clutter_actor_set_has_pointer (device->cursor_actor, TRUE); } }
/*< private > * clutter_input_device_set_actor: * @device: a #ClutterInputDevice * @actor: a #ClutterActor * @emit_crossing: %TRUE to emit crossing events * * Sets the actor under the pointer coordinates of @device * * This function is called by _clutter_input_device_update() * and it will: * * - queue a %CLUTTER_LEAVE event on the previous pointer actor * of @device, if any * - set to %FALSE the :has-pointer property of the previous * pointer actor of @device, if any * - queue a %CLUTTER_ENTER event on the new pointer actor * - set to %TRUE the :has-pointer property of the new pointer * actor */ void _clutter_input_device_set_actor (ClutterInputDevice *device, ClutterActor *actor, gboolean emit_crossing) { ClutterActor *old_actor; if (device->cursor_actor == actor) return; old_actor = device->cursor_actor; if (old_actor != NULL) { if (emit_crossing) { ClutterEvent *event; event = clutter_event_new (CLUTTER_LEAVE); event->crossing.time = device->current_time; event->crossing.flags = 0; event->crossing.stage = device->stage; event->crossing.source = device->cursor_actor; event->crossing.x = device->current_x; event->crossing.y = device->current_y; event->crossing.related = actor; clutter_event_set_device (event, device); /* we need to make sure that this event is processed * before any other event we might have queued up until * now, so we go on, and synthesize the event emission * ourselves */ _clutter_process_event (event); clutter_event_free (event); } /* processing the event might have destroyed the actor */ if (device->cursor_actor != NULL) { _clutter_actor_set_has_pointer (device->cursor_actor, FALSE); g_object_weak_unref (G_OBJECT (device->cursor_actor), cursor_weak_unref, device); device->cursor_actor = NULL; } } if (actor != NULL) { if (emit_crossing) { ClutterEvent *event; event = clutter_event_new (CLUTTER_ENTER); event->crossing.time = device->current_time; event->crossing.flags = 0; event->crossing.stage = device->stage; event->crossing.x = device->current_x; event->crossing.y = device->current_y; event->crossing.source = actor; event->crossing.related = old_actor; clutter_event_set_device (event, device); /* see above */ _clutter_process_event (event); clutter_event_free (event); } } device->cursor_actor = actor; if (device->cursor_actor != NULL) { g_object_weak_ref (G_OBJECT (device->cursor_actor), cursor_weak_unref, device); _clutter_actor_set_has_pointer (device->cursor_actor, TRUE); } }