diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 3d4f0a9e7..1da9f3c2b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -262,11 +262,11 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role, meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending); } -static void -calculate_surface_window_geometry (MetaWaylandSurface *surface, - MetaRectangle *total_geometry, - float parent_x, - float parent_y) +void +meta_wayland_surface_calculate_window_geometry (MetaWaylandSurface *surface, + MetaRectangle *total_geometry, + float parent_x, + float parent_y) { MetaSurfaceActorWayland *surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor); @@ -294,9 +294,10 @@ calculate_surface_window_geometry (MetaWaylandSurface *surface, for (l = surface->subsurfaces; l != NULL; l = l->next) { MetaWaylandSurface *subsurface = l->data; - calculate_surface_window_geometry (subsurface, total_geometry, - subsurface_rect.x, - subsurface_rect.y); + meta_wayland_surface_calculate_window_geometry (subsurface, + total_geometry, + subsurface_rect.x, + subsurface_rect.y); } } @@ -362,54 +363,10 @@ meta_wayland_surface_apply_window_state (MetaWaylandSurface *surface, { MetaWindow *window = surface->window; MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; + CoglTexture *texture = buffer->texture; - /* Update the state of the MetaWindow if we still have one. We might not if - * the window was unmanaged (for example popup destroyed, NULL buffer attached to - * wl_shell_surface wl_surface, xdg_surface object was destroyed, etc). - */ - if (window && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND) - { - MetaRectangle geom = { 0 }; - - CoglTexture *texture = buffer->texture; - /* Update the buffer rect immediately. */ - window->buffer_rect.width = cogl_texture_get_width (texture); - window->buffer_rect.height = cogl_texture_get_height (texture); - - if (pending->has_new_geometry) - { - /* If we have new geometry, use it. */ - geom = pending->new_geometry; - surface->has_set_geometry = TRUE; - } - else if (!surface->has_set_geometry) - { - /* If the surface has never set any geometry, calculate - * a default one unioning the surface and all subsurfaces together. */ - calculate_surface_window_geometry (surface, &geom, 0, 0); - } - else - { - /* Otherwise, keep the geometry the same. */ - - /* XXX: We don't store the geometry in any consistent place - * right now, so we can't re-fetch it. We should change - * meta_window_wayland_move_resize. */ - - /* XXX: This is the common case. Recognize it to prevent - * a warning. */ - if (pending->dx == 0 && pending->dy == 0) - return; - - g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now."); - return; - } - - meta_window_wayland_move_resize (window, - &surface->acked_configure_serial, - geom, pending->dx, pending->dy); - surface->acked_configure_serial.set = FALSE; - } + window->buffer_rect.width = cogl_texture_get_width (texture); + window->buffer_rect.height = cogl_texture_get_height (texture); } static void diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 85d33715f..9ac4659d8 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -346,6 +346,11 @@ cairo_region_t * meta_wayland_surface_calculate_input_region (MetaWaylandSurf void meta_wayland_surface_apply_window_state (MetaWaylandSurface *surface, MetaWaylandPendingState *pending); +void meta_wayland_surface_calculate_window_geometry (MetaWaylandSurface *surface, + MetaRectangle *total_geometry, + float parent_x, + float parent_y); + void meta_wayland_surface_destroy_window (MetaWaylandSurface *surface); gboolean meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface, diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c index 135e6ccc8..2a28f4887 100644 --- a/src/wayland/meta-wayland-wl-shell.c +++ b/src/wayland/meta-wayland-wl-shell.c @@ -487,6 +487,7 @@ wl_shell_surface_role_commit (MetaWaylandSurfaceRole *surface_role, MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); MetaWindow *window = surface->window; + MetaRectangle geom = { 0 }; surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_wl_shell_surface_parent_class); @@ -505,8 +506,17 @@ wl_shell_surface_role_commit (MetaWaylandSurfaceRole *surface_role, return; } - if (pending->newly_attached) - meta_wayland_surface_apply_window_state (surface, pending); + if (!window) + return; + + if (!pending->newly_attached) + return; + + meta_wayland_surface_apply_window_state (surface, pending); + meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0); + meta_window_wayland_move_resize (window, + NULL, + geom, pending->dx, pending->dy); } static MetaWaylandSurface * diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index 833d93455..30520ea92 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -38,6 +38,9 @@ struct _MetaWaylandXdgSurface { MetaWaylandSurfaceRoleShellSurface parent; + + MetaWaylandSerial acked_configure_serial; + gboolean has_set_geometry; }; G_DEFINE_TYPE (MetaWaylandXdgSurface, @@ -219,9 +222,10 @@ xdg_surface_ack_configure (struct wl_client *client, uint32_t serial) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface->role); - surface->acked_configure_serial.set = TRUE; - surface->acked_configure_serial.value = serial; + xdg_surface->acked_configure_serial.set = TRUE; + xdg_surface->acked_configure_serial.value = serial; } static void @@ -567,9 +571,12 @@ static void xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role, MetaWaylandPendingState *pending) { + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); MetaWaylandSurfaceRoleClass *surface_role_class; MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window = surface->window; + MetaRectangle geom = { 0 }; surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_surface_parent_class); @@ -584,8 +591,48 @@ xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role, return; } - if (pending->newly_attached) - meta_wayland_surface_apply_window_state (surface, pending); + if (!pending->newly_attached) + return; + + /* If the window disappeared the surface is not coming back. */ + if (!window) + return; + + meta_wayland_surface_apply_window_state (surface, pending); + + if (pending->has_new_geometry) + { + /* If we have new geometry, use it. */ + geom = pending->new_geometry; + xdg_surface->has_set_geometry = TRUE; + } + else if (!xdg_surface->has_set_geometry) + { + /* If the surface has never set any geometry, calculate + * a default one unioning the surface and all subsurfaces together. */ + meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0); + } + else + { + /* Otherwise, keep the geometry the same. */ + + /* XXX: We don't store the geometry in any consistent place + * right now, so we can't re-fetch it. We should change + * meta_window_wayland_move_resize. */ + + /* XXX: This is the common case. Recognize it to prevent + * a warning. */ + if (pending->dx == 0 && pending->dy == 0) + return; + + g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now."); + return; + } + + meta_window_wayland_move_resize (window, + &xdg_surface->acked_configure_serial, + geom, pending->dx, pending->dy); + xdg_surface->acked_configure_serial.set = FALSE; } static MetaWaylandSurface * @@ -688,6 +735,8 @@ xdg_popup_role_commit (MetaWaylandSurfaceRole *surface_role, MetaWaylandSurfaceRoleClass *surface_role_class; MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window = surface->window; + MetaRectangle geom = { 0 }; surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class); @@ -702,8 +751,18 @@ xdg_popup_role_commit (MetaWaylandSurfaceRole *surface_role, return; } - if (pending->newly_attached) - meta_wayland_surface_apply_window_state (surface, pending); + if (!pending->newly_attached) + return; + + /* If the window disappeared the surface is not coming back. */ + if (!window) + return; + + meta_wayland_surface_apply_window_state (surface, pending); + meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0); + meta_window_wayland_move_resize (window, + NULL, + geom, pending->dx, pending->dy); } static MetaWaylandSurface *