From 153d8efcf5827c3d444088801cb5de7a5c241d4b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 19 Nov 2013 17:33:57 -0500 Subject: [PATCH] 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... --- src/core/window-private.h | 9 +++++- src/core/window.c | 18 ++++++++++++ src/wayland/meta-wayland-surface.c | 47 +++++++----------------------- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index 82d68fd18..49dbfc7c3 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -102,7 +102,7 @@ struct _MetaWindow MetaWindowType type; Atom type_atom; - + /* NOTE these five are not in UTF-8, we just treat them as random * binary data */ @@ -351,6 +351,10 @@ struct _MetaWindow /* whether or not the window is from a program running on another machine */ 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 */ cairo_region_t *frame_bounds; @@ -740,4 +744,7 @@ void meta_window_handle_enter (MetaWindow *window, guint root_x, guint root_y); +void meta_window_set_surface_mapped (MetaWindow *window, + gboolean surface_mapped); + #endif diff --git a/src/core/window.c b/src/core/window.c index 6d0c295a3..f8823b68b 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -827,6 +827,7 @@ meta_window_new_shared (MetaDisplay *display, MetaWindowClientType client_type, MetaWaylandSurface *surface, Window xwindow, + gboolean surface_mapped, gulong existing_wm_state, MetaCompEffect effect, XWindowAttributes *attrs) @@ -856,6 +857,7 @@ meta_window_new_shared (MetaDisplay *display, window->client_type = client_type; window->surface = surface; window->xwindow = xwindow; + window->surface_mapped = surface_mapped; /* this is in window->screen->display, but that's too annoying to * type @@ -1417,6 +1419,7 @@ meta_window_new_for_wayland (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_WAYLAND, surface, None, + FALSE, WithdrawnState, META_COMP_EFFECT_NONE, &attrs); @@ -1596,6 +1599,7 @@ meta_window_new_with_attrs (MetaDisplay *display, META_WINDOW_CLIENT_TYPE_X11, NULL, xwindow, + TRUE, existing_wm_state, effect, attrs); @@ -2347,6 +2351,9 @@ meta_window_should_be_showing (MetaWindow *window) { gboolean on_workspace; + if (!window->surface_mapped) + return FALSE; + meta_verbose ("Should be showing for window %s\n", window->desc); /* See if we're on the workspace */ @@ -11942,3 +11949,14 @@ meta_window_handle_enter (MetaWindow *window, 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); +} diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index c7c2eb797..af951795b 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -236,26 +236,6 @@ empty_region (cairo_region_t *region) 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 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) meta_wayland_seat_update_sprite (compositor->seat); else if (surface->window) { MetaWindow *window = surface->window; + meta_window_set_surface_mapped (window, surface->pending.buffer != NULL); + if (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); 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 @@ -621,9 +600,6 @@ begin_grab_op_on_surface (MetaWaylandSurface *surface, { MetaWindow *window = surface->window; - if (!window) - return FALSE; - if (grab_op == META_GRAB_OP_NONE) return FALSE; @@ -719,8 +695,7 @@ xdg_surface_set_fullscreen (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); 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 @@ -730,8 +705,7 @@ xdg_surface_unset_fullscreen (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); 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 @@ -741,8 +715,7 @@ xdg_surface_set_maximized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); 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 @@ -752,8 +725,7 @@ xdg_surface_unset_maximized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); 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 @@ -763,8 +735,7 @@ xdg_surface_set_minimized (struct wl_client *client, MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource); 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 = { @@ -807,6 +778,8 @@ get_xdg_surface (struct wl_client *client, wl_resource_post_error (surface_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "xdg_shell::get_xdg_surface already requested"); + + surface->window = meta_window_new_for_wayland (meta_get_display (), surface); } static void