mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
clutter: Switch to storing device->actor associations in ClutterStage
As planned and prepared with the last commits, let ClutterStage take care of tracking input devices and their respective actors. This means we now can remove the old infrastructure for this from ClutterInputDevice. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1633>
This commit is contained in:
parent
a9a9d27ead
commit
ae6d83fb47
@ -53,10 +53,6 @@ struct _ClutterInputDevice
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
/* the actor underneath the pointer */
|
||||
ClutterActor *cursor_actor;
|
||||
GHashTable *inv_touch_sequence_actors;
|
||||
|
||||
/* the actor that has a grab in place for the device */
|
||||
ClutterActor *pointer_grab_actor;
|
||||
ClutterActor *keyboard_grab_actor;
|
||||
@ -67,9 +63,6 @@ struct _ClutterInputDevice
|
||||
int click_count;
|
||||
int current_button_number;
|
||||
|
||||
/* the current touch points targets */
|
||||
GHashTable *touch_sequence_actors;
|
||||
|
||||
/* the previous state, used for click count generation */
|
||||
int previous_x;
|
||||
int previous_y;
|
||||
@ -81,14 +74,4 @@ struct _ClutterInputDevice
|
||||
ClutterPtrA11yData *ptr_a11y_data;
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_input_device_update (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
ClutterStage *stage,
|
||||
gboolean emit_crossing,
|
||||
ClutterEvent *for_event);
|
||||
CLUTTER_EXPORT
|
||||
void _clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
||||
ClutterEvent *event);
|
||||
|
||||
#endif /* CLUTTER_INPUT_DEVICE_PRIVATE_H */
|
||||
|
@ -73,12 +73,6 @@ enum
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static void on_cursor_actor_destroy (ClutterActor *actor,
|
||||
ClutterInputDevice *device);
|
||||
static void on_cursor_actor_reactive_changed (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
static GParamSpec *obj_props[PROP_LAST] = { NULL, };
|
||||
|
||||
typedef struct _ClutterInputDevicePrivate ClutterInputDevicePrivate;
|
||||
@ -123,42 +117,6 @@ clutter_input_device_dispose (GObject *gobject)
|
||||
if (device->accessibility_virtual_device)
|
||||
g_clear_object (&device->accessibility_virtual_device);
|
||||
|
||||
g_clear_pointer (&device->touch_sequence_actors, g_hash_table_unref);
|
||||
|
||||
if (device->cursor_actor)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (device->cursor_actor,
|
||||
G_CALLBACK (on_cursor_actor_destroy),
|
||||
device);
|
||||
g_signal_handlers_disconnect_by_func (device->cursor_actor,
|
||||
G_CALLBACK (on_cursor_actor_reactive_changed),
|
||||
device);
|
||||
_clutter_actor_set_has_pointer (device->cursor_actor, FALSE);
|
||||
device->cursor_actor = NULL;
|
||||
}
|
||||
|
||||
if (device->inv_touch_sequence_actors)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, device->inv_touch_sequence_actors);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (key,
|
||||
G_CALLBACK (on_cursor_actor_destroy),
|
||||
device);
|
||||
g_signal_handlers_disconnect_by_func (device->cursor_actor,
|
||||
G_CALLBACK (on_cursor_actor_reactive_changed),
|
||||
device);
|
||||
_clutter_actor_set_has_pointer (key, FALSE);
|
||||
g_list_free (value);
|
||||
}
|
||||
|
||||
g_hash_table_unref (device->inv_touch_sequence_actors);
|
||||
device->inv_touch_sequence_actors = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (clutter_input_device_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@ -476,180 +434,6 @@ clutter_input_device_init (ClutterInputDevice *self)
|
||||
self->previous_x = -1;
|
||||
self->previous_y = -1;
|
||||
self->current_button_number = self->previous_button_number = -1;
|
||||
|
||||
self->touch_sequence_actors = g_hash_table_new (NULL, NULL);
|
||||
self->inv_touch_sequence_actors = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_input_device_associate_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
if (sequence == NULL)
|
||||
device->cursor_actor = actor;
|
||||
else
|
||||
{
|
||||
GList *sequences =
|
||||
g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
|
||||
|
||||
g_hash_table_insert (device->touch_sequence_actors, sequence, actor);
|
||||
g_hash_table_insert (device->inv_touch_sequence_actors,
|
||||
actor, g_list_prepend (sequences, sequence));
|
||||
}
|
||||
|
||||
g_signal_connect (actor,
|
||||
"destroy", G_CALLBACK (on_cursor_actor_destroy),
|
||||
device);
|
||||
g_signal_connect (actor,
|
||||
"notify::reactive", G_CALLBACK (on_cursor_actor_reactive_changed),
|
||||
device);
|
||||
_clutter_actor_set_has_pointer (actor, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
_clutter_input_device_unassociate_actor (ClutterInputDevice *device,
|
||||
ClutterActor *actor,
|
||||
gboolean destroyed)
|
||||
{
|
||||
if (device->cursor_actor == actor)
|
||||
device->cursor_actor = NULL;
|
||||
else
|
||||
{
|
||||
GList *l, *sequences =
|
||||
g_hash_table_lookup (device->inv_touch_sequence_actors,
|
||||
actor);
|
||||
|
||||
for (l = sequences; l != NULL; l = l->next)
|
||||
g_hash_table_remove (device->touch_sequence_actors, l->data);
|
||||
|
||||
g_list_free (sequences);
|
||||
g_hash_table_remove (device->inv_touch_sequence_actors, actor);
|
||||
}
|
||||
|
||||
if (destroyed == FALSE)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (actor,
|
||||
G_CALLBACK (on_cursor_actor_destroy),
|
||||
device);
|
||||
g_signal_handlers_disconnect_by_func (actor,
|
||||
G_CALLBACK (on_cursor_actor_reactive_changed),
|
||||
device);
|
||||
_clutter_actor_set_has_pointer (actor, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_cursor_actor_destroy (ClutterActor *actor,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
_clutter_input_device_unassociate_actor (device, actor, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_cursor_actor_reactive_changed (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
if (!clutter_actor_get_reactive (actor))
|
||||
_clutter_input_device_unassociate_actor (device, actor, FALSE);
|
||||
}
|
||||
|
||||
/*< 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
|
||||
*/
|
||||
static void
|
||||
_clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
ClutterStage *stage,
|
||||
ClutterActor *actor,
|
||||
gboolean emit_crossing,
|
||||
graphene_point_t coords,
|
||||
uint32_t time_ms)
|
||||
{
|
||||
ClutterActor *old_actor = clutter_input_device_get_actor (device, sequence);
|
||||
|
||||
if (old_actor == actor)
|
||||
return;
|
||||
|
||||
if (old_actor != NULL)
|
||||
{
|
||||
ClutterActor *tmp_old_actor;
|
||||
|
||||
if (emit_crossing)
|
||||
{
|
||||
ClutterEvent *event;
|
||||
|
||||
event = clutter_event_new (CLUTTER_LEAVE);
|
||||
event->crossing.time = time_ms;
|
||||
event->crossing.flags = 0;
|
||||
event->crossing.stage = stage;
|
||||
event->crossing.source = old_actor;
|
||||
event->crossing.x = coords.x;
|
||||
event->crossing.y = coords.y;
|
||||
event->crossing.related = actor;
|
||||
event->crossing.sequence = sequence;
|
||||
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 */
|
||||
tmp_old_actor = clutter_input_device_get_actor (device, sequence);
|
||||
_clutter_input_device_unassociate_actor (device,
|
||||
old_actor,
|
||||
tmp_old_actor == NULL);
|
||||
old_actor = tmp_old_actor;
|
||||
}
|
||||
|
||||
if (actor != NULL)
|
||||
{
|
||||
_clutter_input_device_associate_actor (device, sequence, actor);
|
||||
|
||||
if (emit_crossing)
|
||||
{
|
||||
ClutterEvent *event;
|
||||
|
||||
event = clutter_event_new (CLUTTER_ENTER);
|
||||
event->crossing.time = time_ms;
|
||||
event->crossing.flags = 0;
|
||||
event->crossing.stage = stage;
|
||||
event->crossing.x = coords.x;
|
||||
event->crossing.y = coords.y;
|
||||
event->crossing.source = actor;
|
||||
event->crossing.related = old_actor;
|
||||
event->crossing.sequence = sequence;
|
||||
clutter_event_set_device (event, device);
|
||||
|
||||
/* see above */
|
||||
_clutter_process_event (event);
|
||||
|
||||
clutter_event_free (event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -674,106 +458,6 @@ clutter_input_device_get_device_type (ClutterInputDevice *device)
|
||||
return priv->device_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* clutter_input_device_update:
|
||||
* @device: a #ClutterInputDevice
|
||||
*
|
||||
* Updates the input @device by determining the #ClutterActor underneath the
|
||||
* pointer's cursor
|
||||
*
|
||||
* This function calls _clutter_input_device_set_actor() if needed.
|
||||
*
|
||||
* This function only works for #ClutterInputDevice of type
|
||||
* %CLUTTER_POINTER_DEVICE.
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_input_device_update (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence,
|
||||
ClutterStage *stage,
|
||||
gboolean emit_crossing,
|
||||
ClutterEvent *for_event)
|
||||
{
|
||||
ClutterActor *new_cursor_actor;
|
||||
ClutterActor *old_cursor_actor;
|
||||
graphene_point_t point = GRAPHENE_POINT_INIT (-1.0f, -1.0f);
|
||||
ClutterInputDevicePrivate *priv =
|
||||
clutter_input_device_get_instance_private (device);
|
||||
ClutterInputDeviceType device_type = priv->device_type;
|
||||
uint32_t time_ms;
|
||||
|
||||
g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
|
||||
device_type != CLUTTER_PAD_DEVICE);
|
||||
|
||||
if (for_event)
|
||||
{
|
||||
clutter_event_get_coords (for_event, &point.x, &point.y);
|
||||
time_ms = clutter_event_get_time (for_event);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_seat_query_state (clutter_input_device_get_seat (device),
|
||||
device, NULL, &point, NULL);
|
||||
time_ms = CLUTTER_CURRENT_TIME;
|
||||
}
|
||||
|
||||
old_cursor_actor = clutter_input_device_get_actor (device, sequence);
|
||||
new_cursor_actor =
|
||||
_clutter_stage_do_pick (stage, point.x, point.y, CLUTTER_PICK_REACTIVE);
|
||||
|
||||
/* if the pick could not find an actor then we do not update the
|
||||
* input device, to avoid ghost enter/leave events; the pick should
|
||||
* never fail, except for bugs in the glReadPixels() implementation
|
||||
* in which case this is the safest course of action anyway
|
||||
*/
|
||||
if (new_cursor_actor == NULL)
|
||||
return NULL;
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"Actor under cursor (device '%s', at %.2f, %.2f): %s",
|
||||
clutter_input_device_get_device_name (device),
|
||||
point.x,
|
||||
point.y,
|
||||
_clutter_actor_get_debug_name (new_cursor_actor));
|
||||
|
||||
/* short-circuit here */
|
||||
if (new_cursor_actor == old_cursor_actor)
|
||||
return old_cursor_actor;
|
||||
|
||||
_clutter_input_device_set_actor (device, sequence,
|
||||
stage,
|
||||
new_cursor_actor,
|
||||
emit_crossing,
|
||||
point, time_ms);
|
||||
|
||||
return new_cursor_actor;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_get_actor:
|
||||
* @device: a #ClutterInputDevice
|
||||
* @sequence: (allow-none): an optional #ClutterEventSequence
|
||||
*
|
||||
* Retrieves the #ClutterActor underneath the pointer or touchpoint
|
||||
* of @device and @sequence.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the #ClutterActor or %NULL
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
|
||||
|
||||
if (sequence == NULL)
|
||||
return device->cursor_actor;
|
||||
|
||||
return g_hash_table_lookup (device->touch_sequence_actors, sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_device_get_device_name:
|
||||
* @device: a #ClutterInputDevice
|
||||
@ -841,42 +525,6 @@ clutter_input_device_get_device_mode (ClutterInputDevice *device)
|
||||
return priv->device_mode;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* clutter_input_device_remove_sequence:
|
||||
* @device: a #ClutterInputDevice
|
||||
* @sequence: a #ClutterEventSequence
|
||||
*
|
||||
* Stop tracking information related to a touch point.
|
||||
*/
|
||||
void
|
||||
_clutter_input_device_remove_event_sequence (ClutterInputDevice *device,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = g_hash_table_lookup (device->touch_sequence_actors, sequence);
|
||||
|
||||
if (actor != NULL)
|
||||
{
|
||||
GList *sequences =
|
||||
g_hash_table_lookup (device->inv_touch_sequence_actors, actor);
|
||||
ClutterStage *stage =
|
||||
CLUTTER_STAGE (clutter_actor_get_stage (actor));
|
||||
graphene_point_t point;
|
||||
|
||||
sequences = g_list_remove (sequences, sequence);
|
||||
|
||||
g_hash_table_replace (device->inv_touch_sequence_actors,
|
||||
actor, sequences);
|
||||
clutter_event_get_coords (event, &point.x, &point.y);
|
||||
_clutter_input_device_set_actor (device, sequence, stage,
|
||||
NULL, TRUE, point,
|
||||
clutter_event_get_time (event));
|
||||
g_hash_table_remove (device->touch_sequence_actors, sequence);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_grab_actor_destroy (ClutterActor *actor,
|
||||
ClutterInputDevice *device)
|
||||
|
@ -73,9 +73,6 @@ GType clutter_input_device_get_type (void) G_GNUC_CONST;
|
||||
CLUTTER_EXPORT
|
||||
ClutterInputDeviceType clutter_input_device_get_device_type (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterActor * clutter_input_device_get_actor (ClutterInputDevice *device,
|
||||
ClutterEventSequence *sequence);
|
||||
CLUTTER_EXPORT
|
||||
const gchar * clutter_input_device_get_device_name (ClutterInputDevice *device);
|
||||
CLUTTER_EXPORT
|
||||
|
@ -1757,9 +1757,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
|
||||
emit_crossing_event (event, device);
|
||||
|
||||
actor = clutter_input_device_update (device, NULL,
|
||||
CLUTTER_STAGE (stage), FALSE,
|
||||
event);
|
||||
actor = update_device_for_event (CLUTTER_STAGE (stage), event, FALSE);
|
||||
if (actor != stage)
|
||||
{
|
||||
ClutterEvent *crossing;
|
||||
@ -1785,13 +1783,14 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
*/
|
||||
if (event->any.source == stage &&
|
||||
event->crossing.related == NULL &&
|
||||
device->cursor_actor != stage)
|
||||
clutter_stage_get_device_actor (CLUTTER_STAGE (stage), device, NULL) != stage)
|
||||
{
|
||||
ClutterEvent *crossing;
|
||||
|
||||
crossing = clutter_event_copy (event);
|
||||
crossing->crossing.related = stage;
|
||||
crossing->crossing.source = device->cursor_actor;
|
||||
crossing->crossing.source =
|
||||
clutter_stage_get_device_actor (CLUTTER_STAGE (stage), device, NULL);
|
||||
|
||||
emit_crossing_event (crossing, device);
|
||||
clutter_event_free (crossing);
|
||||
@ -1898,9 +1897,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
break;
|
||||
}
|
||||
|
||||
actor = clutter_input_device_update (device, NULL,
|
||||
CLUTTER_STAGE (stage),
|
||||
TRUE, event);
|
||||
actor = update_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
|
||||
if (actor == NULL)
|
||||
break;
|
||||
|
||||
@ -1970,12 +1967,8 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
case CLUTTER_TOUCH_END:
|
||||
{
|
||||
ClutterActor *actor;
|
||||
ClutterEventSequence *sequence;
|
||||
gfloat x, y;
|
||||
|
||||
sequence =
|
||||
clutter_event_get_event_sequence (event);
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
|
||||
/* Only do a pick to find the source if source is not already set
|
||||
@ -2000,14 +1993,12 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_END ||
|
||||
event->type == CLUTTER_TOUCH_CANCEL)
|
||||
_clutter_input_device_remove_event_sequence (device, event);
|
||||
remove_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
actor = clutter_input_device_update (device, sequence,
|
||||
CLUTTER_STAGE (stage),
|
||||
TRUE, event);
|
||||
actor = update_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
|
||||
if (actor == NULL)
|
||||
break;
|
||||
|
||||
@ -2028,7 +2019,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
|
||||
if (event->type == CLUTTER_TOUCH_END ||
|
||||
event->type == CLUTTER_TOUCH_CANCEL)
|
||||
_clutter_input_device_remove_event_sequence (device, event);
|
||||
remove_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2047,10 +2038,26 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
break;
|
||||
|
||||
case CLUTTER_DEVICE_ADDED:
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
_clutter_event_process_filters (event);
|
||||
break;
|
||||
|
||||
case CLUTTER_DEVICE_REMOVED:
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
_clutter_event_process_filters (event);
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
if (device_type == CLUTTER_POINTER_DEVICE ||
|
||||
device_type == CLUTTER_TABLET_DEVICE ||
|
||||
device_type == CLUTTER_PEN_DEVICE ||
|
||||
device_type == CLUTTER_ERASER_DEVICE ||
|
||||
device_type == CLUTTER_CURSOR_DEVICE)
|
||||
remove_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CLUTTER_EVENT_LAST:
|
||||
break;
|
||||
}
|
||||
|
@ -1005,6 +1005,7 @@ void
|
||||
clutter_stage_update_devices (ClutterStage *stage,
|
||||
GSList *devices)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
GSList *l;
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStageUpdateDevices, "UpdateDevices");
|
||||
@ -1012,7 +1013,23 @@ clutter_stage_update_devices (ClutterStage *stage,
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
ClutterInputDevice *device = l->data;
|
||||
clutter_input_device_update (device, NULL, stage, TRUE, NULL);
|
||||
PointerDeviceEntry *entry = NULL;
|
||||
ClutterActor *new_actor;
|
||||
|
||||
entry = g_hash_table_lookup (priv->pointer_devices, device);
|
||||
g_assert (entry != NULL);
|
||||
|
||||
new_actor = _clutter_stage_do_pick (stage,
|
||||
entry->coords.x,
|
||||
entry->coords.y,
|
||||
CLUTTER_PICK_REACTIVE);
|
||||
|
||||
clutter_stage_update_device (stage,
|
||||
device, NULL,
|
||||
entry->coords,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
new_actor,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3421,6 +3438,23 @@ on_device_actor_reactive_changed (ClutterActor *actor,
|
||||
GParamSpec *pspec,
|
||||
PointerDeviceEntry *entry)
|
||||
{
|
||||
ClutterStage *self = entry->stage;
|
||||
ClutterActor *new_device_actor;
|
||||
|
||||
g_assert (!clutter_actor_get_reactive (actor));
|
||||
|
||||
new_device_actor =
|
||||
_clutter_stage_do_pick (self,
|
||||
entry->coords.x,
|
||||
entry->coords.y,
|
||||
CLUTTER_PICK_REACTIVE);
|
||||
|
||||
clutter_stage_update_device (self,
|
||||
entry->device, entry->sequence,
|
||||
entry->coords,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
new_device_actor,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -8188,11 +8188,13 @@ window_has_pointer_wayland (MetaWindow *window)
|
||||
{
|
||||
ClutterSeat *seat;
|
||||
ClutterInputDevice *dev;
|
||||
ClutterStage *stage;
|
||||
ClutterActor *pointer_actor, *window_actor;
|
||||
|
||||
seat = clutter_backend_get_default_seat (clutter_get_default_backend ());
|
||||
dev = clutter_seat_get_pointer (seat);
|
||||
pointer_actor = clutter_input_device_get_actor (dev, NULL);
|
||||
stage = CLUTTER_STAGE (meta_backend_get_stage (meta_get_backend ()));
|
||||
pointer_actor = clutter_stage_get_device_actor (stage, dev, NULL);
|
||||
window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
|
||||
|
||||
return pointer_actor && clutter_actor_contains (window_actor, pointer_actor);
|
||||
|
@ -581,13 +581,15 @@ static void
|
||||
repick_for_event (MetaWaylandPointer *pointer,
|
||||
const ClutterEvent *for_event)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
ClutterActor *actor;
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
if (for_event)
|
||||
actor = clutter_event_get_source (for_event);
|
||||
else
|
||||
actor = clutter_input_device_get_actor (pointer->device, NULL);
|
||||
actor = clutter_stage_get_device_actor (stage, pointer->device, NULL);
|
||||
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (actor))
|
||||
{
|
||||
@ -1014,8 +1016,21 @@ meta_wayland_pointer_repick (MetaWaylandPointer *pointer)
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
|
||||
clutter_input_device_update (pointer->device, NULL, stage, FALSE,
|
||||
CLUTTER_CURRENT_TIME);
|
||||
graphene_point_t point;
|
||||
ClutterActor *new_actor;
|
||||
|
||||
clutter_stage_get_device_coords (stage, pointer->device, NULL, &point);
|
||||
new_actor =
|
||||
clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_REACTIVE,
|
||||
point.x, point.y);
|
||||
|
||||
clutter_stage_update_device (stage,
|
||||
pointer->device, NULL,
|
||||
point,
|
||||
CLUTTER_CURRENT_TIME,
|
||||
new_actor,
|
||||
FALSE);
|
||||
|
||||
repick_for_event (pointer, NULL);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user