wayland: Move out window state application into the roles

A large part of meta_wayland_surface_apply_window_state() was only
relevant for xdg_surface. Make this more obvious by splitting it up,
moving the relevant parts to the relevant roles.

https://bugzilla.gnome.org/show_bug.cgi?id=763431
This commit is contained in:
Jonas Ådahl 2016-01-14 17:49:57 +08:00
parent e66f176c29
commit 9028e30b39
4 changed files with 94 additions and 63 deletions

View File

@ -262,11 +262,11 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending); meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
} }
static void void
calculate_surface_window_geometry (MetaWaylandSurface *surface, meta_wayland_surface_calculate_window_geometry (MetaWaylandSurface *surface,
MetaRectangle *total_geometry, MetaRectangle *total_geometry,
float parent_x, float parent_x,
float parent_y) float parent_y)
{ {
MetaSurfaceActorWayland *surface_actor = MetaSurfaceActorWayland *surface_actor =
META_SURFACE_ACTOR_WAYLAND (surface->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) for (l = surface->subsurfaces; l != NULL; l = l->next)
{ {
MetaWaylandSurface *subsurface = l->data; MetaWaylandSurface *subsurface = l->data;
calculate_surface_window_geometry (subsurface, total_geometry, meta_wayland_surface_calculate_window_geometry (subsurface,
subsurface_rect.x, total_geometry,
subsurface_rect.y); subsurface_rect.x,
subsurface_rect.y);
} }
} }
@ -362,54 +363,10 @@ meta_wayland_surface_apply_window_state (MetaWaylandSurface *surface,
{ {
MetaWindow *window = surface->window; MetaWindow *window = surface->window;
MetaWaylandBuffer *buffer = surface->buffer_ref.buffer; 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 window->buffer_rect.width = cogl_texture_get_width (texture);
* the window was unmanaged (for example popup destroyed, NULL buffer attached to window->buffer_rect.height = cogl_texture_get_height (texture);
* 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;
}
} }
static void static void

View File

@ -346,6 +346,11 @@ cairo_region_t * meta_wayland_surface_calculate_input_region (MetaWaylandSurf
void meta_wayland_surface_apply_window_state (MetaWaylandSurface *surface, void meta_wayland_surface_apply_window_state (MetaWaylandSurface *surface,
MetaWaylandPendingState *pending); 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); void meta_wayland_surface_destroy_window (MetaWaylandSurface *surface);
gboolean meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface, gboolean meta_wayland_surface_begin_grab_op (MetaWaylandSurface *surface,

View File

@ -487,6 +487,7 @@ wl_shell_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window = surface->window; MetaWindow *window = surface->window;
MetaRectangle geom = { 0 };
surface_role_class = surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_wl_shell_surface_parent_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; return;
} }
if (pending->newly_attached) if (!window)
meta_wayland_surface_apply_window_state (surface, pending); 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 * static MetaWaylandSurface *

View File

@ -38,6 +38,9 @@
struct _MetaWaylandXdgSurface struct _MetaWaylandXdgSurface
{ {
MetaWaylandSurfaceRoleShellSurface parent; MetaWaylandSurfaceRoleShellSurface parent;
MetaWaylandSerial acked_configure_serial;
gboolean has_set_geometry;
}; };
G_DEFINE_TYPE (MetaWaylandXdgSurface, G_DEFINE_TYPE (MetaWaylandXdgSurface,
@ -219,9 +222,10 @@ xdg_surface_ack_configure (struct wl_client *client,
uint32_t serial) uint32_t serial)
{ {
MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface->role);
surface->acked_configure_serial.set = TRUE; xdg_surface->acked_configure_serial.set = TRUE;
surface->acked_configure_serial.value = serial; xdg_surface->acked_configure_serial.value = serial;
} }
static void static void
@ -567,9 +571,12 @@ static void
xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role, xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending) MetaWaylandPendingState *pending)
{ {
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
MetaWaylandSurfaceRoleClass *surface_role_class; MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window = surface->window;
MetaRectangle geom = { 0 };
surface_role_class = surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_surface_parent_class); META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_surface_parent_class);
@ -584,8 +591,48 @@ xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
return; return;
} }
if (pending->newly_attached) if (!pending->newly_attached)
meta_wayland_surface_apply_window_state (surface, pending); 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 * static MetaWaylandSurface *
@ -688,6 +735,8 @@ xdg_popup_role_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceRoleClass *surface_role_class; MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window = surface->window;
MetaRectangle geom = { 0 };
surface_role_class = surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class); META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class);
@ -702,8 +751,18 @@ xdg_popup_role_commit (MetaWaylandSurfaceRole *surface_role,
return; return;
} }
if (pending->newly_attached) if (!pending->newly_attached)
meta_wayland_surface_apply_window_state (surface, pending); 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 * static MetaWaylandSurface *