If we do not unset the Stage we will have stale data, and the Crossing
event when re-entering a Stage will not be emitted, as the actor under
the pointer might be the same as before.
If an actor is on the boundary of a Stage and the pointer for a device
enters the Stage over that actor, the sequence of events currently is:
➔ ENTER (source: actor, related: NULL)
➔ MOTION
Thus the Stage never gets an ENTER event. This is a regression from
Clutter 1.0.
The correct sequence is:
➔ ENTER (source: stage, related: NULL)
➔ ENTER (source: actor, related: stage)
➔ MOTION
This also maps to the sequence of events sythesized by Clutter when
leaving the Stage through an actor overlapping the Stage boundary.
http://bugzilla.moblin.org/show_bug.cgi?id=9781
Embedding toolkits should benefit from a proper documentation of
clutter_input_device_update_from_event(): its meaning, its use and
the caveats for the "update_stage" argument.
Embedding toolkits most likely will disable the event handling, so all
the input device code will not be executed. Unfortunately, the newly
added synthetic event generation of ENTER and LEAVE event pairs depends
on having input devices.
In order to unbreak things without reintroducing the madness of the
previous code we should allow embedding toolkits to just update the
state of an InputDevice by using the data contained inside the
ClutterEvent. This strategy has two obvious reasons:
• the embedding toolkit is creating a ClutterEvent by translating
a toolkit-native event anyway
• this is exactly what ClutterStage does when processing events
We are, essentially, deferring input device handling to the embedding
toolkits, just like we're deferring event handling to them.
If an actor is lying on the border of the Stage it might miss the LEAVE
event when the pointer of a device leaves the Stage window. Since the
backend is unsetting the Stage back pointer on the InputDevice we can
queue the emission of a LEAVE event on the pointer actor as well.
http://bugzilla.moblin.org/show_bug.cgi?id=9677
If the stage associated to the InputDevice is not set we should
short-circuit out and return NULL. This will result in a pick()
done on the event's stage - if applicable.
http://bugzilla.moblin.org/show_bug.cgi?id=9602
When an InputDevice leaves a stage we set the stage member of
InputDevice to NULL. We should also unset the cursor_actor (as the
device is obviously not on an actor any more).
When the device re-enters the Stage the ENTER/LEAVE event generation
machinery will then be able to emit the ENTER event on the Stage.
The previous state for the device is used by the click count machinery
and we should not be overwriting it at every event; instead, we should
use a parallel storage for the current state coming from the windowing
system.
The LEAVE/ENTER event pairs should be queued during the InputDevice
update process, when we change the actor under the device pointer.
This commit cleans up the event emission code inside clutter-main.c
and the logic of the event processing.
The InputDevice objects stores pointer coordinates, state, stage and
the actor under the cursor, so if the current backend provides us with
one attached to the Event structure then we want the InputDevice itself
to update its state and give us the ClutterActor underneath the
pointer's cursor.