[mutter/wayland] window: Create a backing MetaWindow for unmapped Wayland surfaces



commit 153d8efcf5827c3d444088801cb5de7a5c241d4b
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Nov 19 17:33:57 2013 -0500

    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 82d68fd..49dbfc7 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 6d0c295..f8823b6 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 c7c2eb7..af95179 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]