diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h index d61746d5f..489e93f93 100644 --- a/clutter/clutter/clutter-mutter.h +++ b/clutter/clutter/clutter-mutter.h @@ -78,6 +78,11 @@ void clutter_stage_update_resource_scales (ClutterStage *stage); CLUTTER_EXPORT gboolean clutter_actor_has_damage (ClutterActor *actor); +CLUTTER_EXPORT +void clutter_stage_get_device_coords (ClutterStage *stage, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords); #undef __CLUTTER_H_INSIDE__ #endif /* __CLUTTER_MUTTER_H__ */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index fa20b8e28..11e63bb66 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -99,6 +99,15 @@ typedef struct _PickClipRecord graphene_point_t vertex[4]; } PickClipRecord; +typedef struct _PointerDeviceEntry +{ + ClutterStage *stage; + ClutterInputDevice *device; + ClutterEventSequence *sequence; + graphene_point_t coords; + ClutterActor *current_actor; +} PointerDeviceEntry; + struct _ClutterStagePrivate { /* the stage implementation */ @@ -147,6 +156,9 @@ struct _ClutterStagePrivate gboolean needs_update; + GHashTable *pointer_devices; + GHashTable *touch_sequences; + guint redraw_pending : 1; guint is_cursor_visible : 1; guint throttle_motion_events : 1; @@ -4796,3 +4808,27 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage, *view_scale = scale; return TRUE; } + +/** + * clutter_stage_get_device_coords: (skip): + */ +void +clutter_stage_get_device_coords (ClutterStage *stage, + ClutterInputDevice *device, + ClutterEventSequence *sequence, + graphene_point_t *coords) +{ + ClutterStagePrivate *priv = stage->priv; + PointerDeviceEntry *entry = NULL; + + g_return_if_fail (CLUTTER_IS_STAGE (stage)); + g_return_if_fail (device != NULL); + + if (sequence != NULL) + entry = g_hash_table_lookup (priv->touch_sequences, sequence); + else + entry = g_hash_table_lookup (priv->pointer_devices, device); + + if (entry && coords) + *coords = entry->coords; +} diff --git a/meson.build b/meson.build index d3cb8b4c8..81495d741 100644 --- a/meson.build +++ b/meson.build @@ -383,7 +383,7 @@ have_xwayland_initfd = false if have_wayland xwayland_path = get_option('xwayland_path') if xwayland_path == '' - xwayland_path = find_program('Xwayland').path() + xwayland_path = find_program('Xwayland').full_path() endif cdata.set_quoted('XWAYLAND_PATH', xwayland_path) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index d30085202..6187515bd 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -618,10 +618,10 @@ repick_for_event (MetaWaylandPointer *pointer, ClutterActor *actor; MetaWaylandSurface *surface; - if (for_event) - actor = clutter_event_get_source (for_event); + if (clutter_event_type (for_event) == CLUTTER_LEAVE) + actor = clutter_event_get_related (for_event); else - actor = clutter_input_device_get_pointer_actor (pointer->device); + actor = clutter_event_get_source (for_event); if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) { @@ -938,6 +938,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, if (surface != NULL) { + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); struct wl_client *client = wl_resource_get_client (surface->resource); graphene_point_t pos; MetaWindow *focus_window; @@ -949,7 +950,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, G_CALLBACK (focus_surface_destroyed), pointer); - clutter_input_device_get_coords (pointer->device, NULL, &pos); + clutter_stage_get_device_coords (stage, pointer->device, NULL, &pos); focus_window = meta_wayland_surface_get_window (pointer->focus_surface); if (focus_window) @@ -960,7 +961,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, pointer->focus_client = meta_wayland_pointer_get_pointer_client (pointer, client); - if (pointer->focus_client) + if (pointer->focus_client && pointer->focus_surface) { pointer->focus_serial = meta_wayland_input_device_next_serial (input_device); @@ -1054,10 +1055,12 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, wl_fixed_t *sx, wl_fixed_t *sy) { + MetaBackend *backend = meta_get_backend (); + ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); float xf = 0.0f, yf = 0.0f; graphene_point_t pos; - clutter_input_device_get_coords (pointer->device, NULL, &pos); + clutter_stage_get_device_coords (stage, pointer->device, NULL, &pos); meta_wayland_surface_get_relative_coordinates (surface, pos.x, pos.y, &xf, &yf); *sx = wl_fixed_from_double (xf); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index aecaac4ce..befac4f84 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1566,12 +1566,15 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, float *sx, float *sy) { - MetaWaylandSurfaceRoleClass *surface_role_class = - META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); + if (surface != NULL && surface->role) + { + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); - surface_role_class->get_relative_coordinates (surface->role, - abs_x, abs_y, - sx, sy); + surface_role_class->get_relative_coordinates (surface->role, + abs_x, abs_y, + sx, sy); + } } void