window: Create a backing MetaWindow for unmapped Wayland surfaces

We require a MetaWindow to properly implement some of the requests
for xdg_surface, so add a way to have an unmapped MetaWindow that
we can store properties on, that we later map when the client
attaches a buffer...
This commit is contained in:
Jasper St. Pierre 2013-11-19 17:33:57 -05:00
parent be744775c1
commit 153d8efcf5
3 changed files with 36 additions and 38 deletions

View File

@ -351,6 +351,10 @@ struct _MetaWindow
/* whether or not the window is from a program running on another machine */ /* whether or not the window is from a program running on another machine */
guint is_remote : 1; guint is_remote : 1;
/* Used for Wayland -- surfaces can behave as if they were unmapped if
* they have a NULL buffer attached... */
guint surface_mapped;
/* if non-NULL, the bounds of the window frame */ /* if non-NULL, the bounds of the window frame */
cairo_region_t *frame_bounds; cairo_region_t *frame_bounds;
@ -740,4 +744,7 @@ void meta_window_handle_enter (MetaWindow *window,
guint root_x, guint root_x,
guint root_y); guint root_y);
void meta_window_set_surface_mapped (MetaWindow *window,
gboolean surface_mapped);
#endif #endif

View File

@ -827,6 +827,7 @@ meta_window_new_shared (MetaDisplay *display,
MetaWindowClientType client_type, MetaWindowClientType client_type,
MetaWaylandSurface *surface, MetaWaylandSurface *surface,
Window xwindow, Window xwindow,
gboolean surface_mapped,
gulong existing_wm_state, gulong existing_wm_state,
MetaCompEffect effect, MetaCompEffect effect,
XWindowAttributes *attrs) XWindowAttributes *attrs)
@ -856,6 +857,7 @@ meta_window_new_shared (MetaDisplay *display,
window->client_type = client_type; window->client_type = client_type;
window->surface = surface; window->surface = surface;
window->xwindow = xwindow; window->xwindow = xwindow;
window->surface_mapped = surface_mapped;
/* this is in window->screen->display, but that's too annoying to /* this is in window->screen->display, but that's too annoying to
* type * type
@ -1417,6 +1419,7 @@ meta_window_new_for_wayland (MetaDisplay *display,
META_WINDOW_CLIENT_TYPE_WAYLAND, META_WINDOW_CLIENT_TYPE_WAYLAND,
surface, surface,
None, None,
FALSE,
WithdrawnState, WithdrawnState,
META_COMP_EFFECT_NONE, META_COMP_EFFECT_NONE,
&attrs); &attrs);
@ -1596,6 +1599,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
META_WINDOW_CLIENT_TYPE_X11, META_WINDOW_CLIENT_TYPE_X11,
NULL, NULL,
xwindow, xwindow,
TRUE,
existing_wm_state, existing_wm_state,
effect, effect,
attrs); attrs);
@ -2347,6 +2351,9 @@ meta_window_should_be_showing (MetaWindow *window)
{ {
gboolean on_workspace; gboolean on_workspace;
if (!window->surface_mapped)
return FALSE;
meta_verbose ("Should be showing for window %s\n", window->desc); meta_verbose ("Should be showing for window %s\n", window->desc);
/* See if we're on the workspace */ /* See if we're on the workspace */
@ -11942,3 +11949,14 @@ meta_window_handle_enter (MetaWindow *window,
break; break;
} }
} }
void
meta_window_set_surface_mapped (MetaWindow *window,
gboolean surface_mapped)
{
if (window->surface_mapped == (guint) surface_mapped)
return;
window->surface_mapped = surface_mapped;
meta_window_queue (window, META_QUEUE_CALC_SHOWING);
}

View File

@ -236,26 +236,6 @@ empty_region (cairo_region_t *region)
cairo_region_intersect_rectangle (region, &rectangle); cairo_region_intersect_rectangle (region, &rectangle);
} }
static gboolean
surface_wants_window (MetaWaylandSurface *surface)
{
return (surface->xdg_surface.resource != NULL);
}
static void
surface_ensure_window (MetaWaylandSurface *surface)
{
MetaDisplay *display = meta_get_display ();
if (surface->window)
return;
if (!surface_wants_window (surface))
return;
surface->window = meta_window_new_for_wayland (display, surface);
}
static void static void
ensure_buffer_texture (MetaWaylandBuffer *buffer) ensure_buffer_texture (MetaWaylandBuffer *buffer)
{ {
@ -307,14 +287,14 @@ meta_wayland_surface_commit (struct wl_client *client,
} }
} }
surface_ensure_window (surface);
if (surface == compositor->seat->sprite) if (surface == compositor->seat->sprite)
meta_wayland_seat_update_sprite (compositor->seat); meta_wayland_seat_update_sprite (compositor->seat);
else if (surface->window) else if (surface->window)
{ {
MetaWindow *window = surface->window; MetaWindow *window = surface->window;
meta_window_set_surface_mapped (window, surface->pending.buffer != NULL);
if (surface->pending.buffer) if (surface->pending.buffer)
{ {
MetaWaylandBuffer *buffer = surface->pending.buffer; MetaWaylandBuffer *buffer = surface->pending.buffer;
@ -579,8 +559,7 @@ xdg_surface_set_transient_for (struct wl_client *client,
MetaWaylandSurfaceExtension *parent_xdg_surface = wl_resource_get_user_data (parent); MetaWaylandSurfaceExtension *parent_xdg_surface = wl_resource_get_user_data (parent);
MetaWaylandSurface *parent_surface = wl_container_of (parent_xdg_surface, surface, xdg_surface); MetaWaylandSurface *parent_surface = wl_container_of (parent_xdg_surface, surface, xdg_surface);
if (surface->window && parent_surface->window) meta_window_set_transient_for (surface->window, parent_surface->window);
meta_window_set_transient_for (surface->window, parent_surface->window);
} }
static void static void
@ -621,9 +600,6 @@ begin_grab_op_on_surface (MetaWaylandSurface *surface,
{ {
MetaWindow *window = surface->window; MetaWindow *window = surface->window;
if (!window)
return FALSE;
if (grab_op == META_GRAB_OP_NONE) if (grab_op == META_GRAB_OP_NONE)
return FALSE; return FALSE;
@ -719,8 +695,7 @@ xdg_surface_set_fullscreen (struct wl_client *client,
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
if (surface->window) meta_window_make_fullscreen (surface->window);
meta_window_make_fullscreen (surface->window);
} }
static void static void
@ -730,8 +705,7 @@ xdg_surface_unset_fullscreen (struct wl_client *client,
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
if (surface->window) meta_window_unmake_fullscreen (surface->window);
meta_window_unmake_fullscreen (surface->window);
} }
static void static void
@ -741,8 +715,7 @@ xdg_surface_set_maximized (struct wl_client *client,
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
if (surface->window) meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
} }
static void static void
@ -752,8 +725,7 @@ xdg_surface_unset_maximized (struct wl_client *client,
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
if (surface->window) meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
} }
static void static void
@ -763,8 +735,7 @@ xdg_surface_set_minimized (struct wl_client *client,
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface); MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
if (surface->window) meta_window_minimize (surface->window);
meta_window_minimize (surface->window);
} }
static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = { static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = {
@ -807,6 +778,8 @@ get_xdg_surface (struct wl_client *client,
wl_resource_post_error (surface_resource, wl_resource_post_error (surface_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT, WL_DISPLAY_ERROR_INVALID_OBJECT,
"xdg_shell::get_xdg_surface already requested"); "xdg_shell::get_xdg_surface already requested");
surface->window = meta_window_new_for_wayland (meta_get_display (), surface);
} }
static void static void