From 54194e67e3fe29b60df97817a4843d6a2ee138ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 9 Oct 2019 09:47:23 +0200 Subject: [PATCH] wayland/surface: Move relative coordinate calculating to roles The role determines how a relative coordinate is calculated. More specifically, using clutters 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. This was already done already, but now move the Xwayland specific logic to the Xwayland surface role, keeping the generic transformation logic in the generic actor surface role. https://gitlab.gnome.org/GNOME/mutter/merge_requests/835 --- src/wayland/meta-wayland-actor-surface.c | 19 +++++++++++++++ src/wayland/meta-wayland-surface.c | 31 ++++-------------------- src/wayland/meta-wayland-surface.h | 5 ++++ src/wayland/meta-xwayland-surface.c | 19 +++++++++++++++ 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c index efccede83..d61603905 100644 --- a/src/wayland/meta-wayland-actor-surface.c +++ b/src/wayland/meta-wayland-actor-surface.c @@ -325,6 +325,23 @@ meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surfac return is_on_monitor; } +static void +meta_wayland_actor_surface_get_relative_coordinates (MetaWaylandSurfaceRole *surface_role, + float abs_x, + float abs_y, + float *out_sx, + float *out_sy) +{ + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (surface_role); + MetaWaylandActorSurfacePrivate *priv = + meta_wayland_actor_surface_get_instance_private (actor_surface); + + clutter_actor_transform_stage_point (CLUTTER_ACTOR (priv->actor), + abs_x, abs_y, + out_sx, out_sy); +} + static void meta_wayland_actor_surface_init (MetaWaylandActorSurface *actor_surface) { @@ -348,6 +365,8 @@ meta_wayland_actor_surface_class_init (MetaWaylandActorSurfaceClass *klass) surface_role_class->apply_state = meta_wayland_actor_surface_apply_state; surface_role_class->is_on_logical_monitor = meta_wayland_actor_surface_is_on_logical_monitor; + surface_role_class->get_relative_coordinates = + meta_wayland_actor_surface_get_relative_coordinates; klass->sync_actor_state = meta_wayland_actor_surface_real_sync_actor_state; } diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index a17431853..d94e5b63a 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1592,33 +1592,12 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface, float *sx, float *sy) { - MetaWindow *window; + MetaWaylandSurfaceRoleClass *surface_role_class = + META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); - /* 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. - */ - window = meta_wayland_surface_get_window (surface); - if (window && - window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - MetaRectangle window_rect; - - meta_window_get_buffer_rect (window, &window_rect); - *sx = abs_x - window_rect.x; - *sy = abs_y - window_rect.y; - } - else - { - ClutterActor *actor = - CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface)); - - clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy); - } + surface_role_class->get_relative_coordinates (surface->role, + abs_x, abs_y, + sx, sy); } void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 5477eb99e..7420274d4 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -63,6 +63,11 @@ struct _MetaWaylandSurfaceRoleClass MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role); gboolean (*should_cache_state) (MetaWaylandSurfaceRole *surface_role); void (*notify_subsurface_state_changed) (MetaWaylandSurfaceRole *surface_role); + void (*get_relative_coordinates) (MetaWaylandSurfaceRole *surface_role, + float abs_x, + float abs_y, + float *out_sx, + float *out_sy); }; struct _MetaWaylandSurfaceState diff --git a/src/wayland/meta-xwayland-surface.c b/src/wayland/meta-xwayland-surface.c index b1894ef8c..905b49afd 100644 --- a/src/wayland/meta-xwayland-surface.c +++ b/src/wayland/meta-xwayland-surface.c @@ -80,6 +80,23 @@ meta_xwayland_surface_associate_with_window (MetaXwaylandSurface *xwayland_surfa } } +static void +meta_xwayland_surface_get_relative_coordinates (MetaWaylandSurfaceRole *surface_role, + float abs_x, + float abs_y, + float *out_sx, + float *out_sy) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaRectangle window_rect; + + meta_window_get_buffer_rect (meta_wayland_surface_get_window (surface), + &window_rect); + *out_sx = abs_x - window_rect.x; + *out_sy = abs_y - window_rect.y; +} + static MetaWaylandSurface * meta_xwayland_surface_get_toplevel (MetaWaylandSurfaceRole *surface_role) { @@ -143,6 +160,8 @@ meta_xwayland_surface_class_init (MetaXwaylandSurfaceClass *klass) object_class->finalize = meta_xwayland_surface_finalize; + surface_role_class->get_relative_coordinates = + meta_xwayland_surface_get_relative_coordinates; surface_role_class->get_toplevel = meta_xwayland_surface_get_toplevel; actor_surface_class->get_geometry_scale =