From b281f9566dfeda758eef99478876f1977c31c463 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Thu, 14 Jul 2016 14:39:26 +0200 Subject: [PATCH] wayland-surface: Make get_relative_coordinates() accurate for X apps Using clutter API to transform coordinates is only accurate right after a clutter layout pass but this function is used e.g. to deliver pointer motion events which can happen at any time. This isn't a problem for wayland clients since they don't control their position, but X clients do and we'd be sending outdated coordinates if a client is moving a window in response to motion events. https://bugzilla.gnome.org/show_bug.cgi?id=768039 --- src/wayland/meta-wayland-surface.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 29588205d..dd8484dfb 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1773,12 +1773,32 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, float *sx, float *sy) { - ClutterActor *actor = - CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)); + /* Using clutter API to transform coordinates is only accurate right + * after a clutter layout pass but this function is used e.g. to + * deliver pointer motion events which can happen at any time. This + * isn't a problem for wayland clients since they don't control + * their position, but X clients do and we'd be sending outdated + * coordinates if a client is moving a window in response to motion + * events. + */ + if (surface->window && + surface->window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + MetaRectangle window_rect; - clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy); - *sx /= surface->scale; - *sy /= surface->scale; + meta_window_get_buffer_rect (surface->window, &window_rect); + *sx = abs_x - window_rect.x; + *sy = abs_y - window_rect.y; + } + else + { + ClutterActor *actor = + CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)); + + clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy); + *sx /= surface->scale; + *sy /= surface->scale; + } } void