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
This commit is contained in:
Jonas Ådahl 2019-10-09 09:47:23 +02:00 committed by Robert Mader
parent c0c74484bc
commit 54194e67e3
4 changed files with 48 additions and 26 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 =