diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index 7c354d64a..76c11944e 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -102,6 +102,45 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor) return (double)output_scale / (double)priv->surface->scale; } +static void +logical_to_actor_position (MetaSurfaceActorWayland *self, + int *x, + int *y) +{ + MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self); + MetaWindow *toplevel_window; + int monitor_scale = 1; + + toplevel_window = meta_wayland_surface_get_toplevel_window (surface); + if (toplevel_window) + monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window); + + *x = *x * monitor_scale; + *y = *y * monitor_scale; +} + +void +meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self) +{ + MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self); + MetaWindow *window; + int x = surface->offset_x + surface->sub.x; + int y = surface->offset_y + surface->sub.y; + + window = meta_wayland_surface_get_toplevel_window (surface); + if (window && window->client_type == META_WINDOW_CLIENT_TYPE_X11) + { + /* Bail directly if this is part of a Xwayland window and warn + * if there happen to be offsets anyway since that is not supposed + * to happen. */ + g_warn_if_fail (x == 0 && y == 0); + return; + } + + logical_to_actor_position (self, &x, &y); + clutter_actor_set_position (CLUTTER_ACTOR (self), x, y); +} + void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self) { @@ -148,22 +187,28 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self) scaled_opaque_region); cairo_region_destroy (scaled_opaque_region); } + + meta_surface_actor_wayland_sync_subsurface_state (self); } void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self) { MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self); + MetaWindow *window = meta_wayland_surface_get_toplevel_window (surface); GList *iter; meta_surface_actor_wayland_sync_state (self); - for (iter = surface->subsurfaces; iter != NULL; iter = iter->next) + if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11) { - MetaWaylandSurface *subsurf = iter->data; + for (iter = surface->subsurfaces; iter != NULL; iter = iter->next) + { + MetaWaylandSurface *subsurf = iter->data; - meta_surface_actor_wayland_sync_state_recursive ( - META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor)); + meta_surface_actor_wayland_sync_state_recursive ( + META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor)); + } } } diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h index 443bacc3c..4051abde2 100644 --- a/src/compositor/meta-surface-actor-wayland.h +++ b/src/compositor/meta-surface-actor-wayland.h @@ -70,6 +70,8 @@ void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self); void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self); +void meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self); + gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self, MetaMonitorInfo *monitor); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 8f0ae9504..b116bada8 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -382,18 +382,13 @@ static void subsurface_surface_commit (MetaWaylandSurface *surface, MetaWaylandPendingState *pending) { - MetaSurfaceActor *surface_actor = surface->surface_actor; - float x, y; + MetaSurfaceActorWayland *surface_actor = + META_SURFACE_ACTOR_WAYLAND (surface->surface_actor); if (surface->buffer != NULL) clutter_actor_show (CLUTTER_ACTOR (surface_actor)); else clutter_actor_hide (CLUTTER_ACTOR (surface_actor)); - - clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y); - x += pending->dx; - y += pending->dy; - clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y); } /* A non-subsurface is always desynchronized. @@ -427,9 +422,8 @@ parent_surface_state_applied (gpointer data, gpointer user_data) if (surface->sub.pending_pos) { - clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), - surface->sub.pending_x, - surface->sub.pending_y); + surface->sub.x = surface->sub.pending_x; + surface->sub.y = surface->sub.pending_y; surface->sub.pending_pos = FALSE; } @@ -477,6 +471,9 @@ parent_surface_state_applied (gpointer data, gpointer user_data) if (is_surface_effectively_synchronized (surface)) apply_pending_state (surface, &surface->sub.pending); + + meta_surface_actor_wayland_sync_subsurface_state ( + META_SURFACE_ACTOR_WAYLAND (surface->surface_actor)); } static void @@ -522,9 +519,6 @@ apply_pending_state (MetaWaylandSurface *surface, surface->input_region = cairo_region_reference (pending->input_region); } - meta_surface_actor_wayland_sync_state ( - META_SURFACE_ACTOR_WAYLAND (surface->surface_actor)); - /* wl_surface.frame */ wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list); wl_list_init (&pending->frame_callback_list); @@ -549,6 +543,9 @@ apply_pending_state (MetaWaylandSurface *surface, break; } + meta_surface_actor_wayland_sync_state ( + META_SURFACE_ACTOR_WAYLAND (surface->surface_actor)); + pending_state_reset (pending); g_list_foreach (surface->subsurfaces, parent_surface_state_applied, NULL); diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index a1d4c7eab..e599af6ad 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -136,6 +136,9 @@ struct _MetaWaylandSurface MetaWaylandSurface *parent; struct wl_listener parent_destroy_listener; + int x; + int y; + /* When the surface is synchronous, its state will be applied * when the parent is committed. This is done by moving the * "real" pending state below to here when this surface is