[mutter/wayland] wayland-surface: Attach the buffer to a surface, even if it doesn't have a role



commit 92e36e7076c85b7da5d40c947c45fdd6fd4602fa
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sat Feb 1 17:05:14 2014 -0500

    wayland-surface: Attach the buffer to a surface, even if it doesn't have a role
    
    Currently, set_cursor isn't properly working. Often, the requests look
    like this:
    
      cursor_surface = wl_compositor.create_surface()
      cursor_buffer = create_cursor_buffer()
      cursor_surface.attach(cursor_buffer, 0, 0)
      cursor_surface.commit()
      wl_pointer.set_cursor(cursor_surface, 7, 14)
    
    But since the surface doesn't "have a role" when the commit comes in,
    we ignore it, and don't do anything with the pending buffer. When
    set_cursor is called, however, we don't immediately update anything
    since it doesn't have a buffer.
    
    This effectively means that set_cursor has unpredictable side effects.
    Weston's toy toolkit reuses the same surface for every buffer, so it
    only fails the first time. In clients that use a new surface for every
    cursor sprite, the cursor is effectively invisible.
    
    To solve this, change the code to always set the buffer for a surface,
    even if it doesn't have any real role.

 src/wayland/meta-wayland-surface.c |   82 +++++++++++++++++++----------------
 1 files changed, 44 insertions(+), 38 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 7817a31..7a90017 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -250,34 +250,25 @@ ensure_buffer_texture (MetaWaylandBuffer *buffer)
 
 static void
 cursor_surface_commit (MetaWaylandSurface             *surface,
-                       MetaWaylandDoubleBufferedState *pending)
+                       MetaWaylandDoubleBufferedState *pending,
+                       gboolean                        buffer_changed)
 {
-  MetaWaylandBuffer *buffer = pending->buffer;
-
-  if (pending->newly_attached && buffer != surface->buffer_ref.buffer)
-    {
-      ensure_buffer_texture (buffer);
-      meta_wayland_buffer_reference (&surface->buffer_ref, buffer);
-    }
-
-  meta_wayland_seat_update_sprite (surface->compositor->seat);
+  if (buffer_changed)
+    meta_wayland_seat_update_sprite (surface->compositor->seat);
 }
 
-static gboolean
+static void
 actor_surface_commit (MetaWaylandSurface             *surface,
-                      MetaWaylandDoubleBufferedState *pending)
+                      MetaWaylandDoubleBufferedState *pending,
+                      gboolean                        buffer_changed)
 {
   MetaSurfaceActor *surface_actor = surface->surface_actor;
   MetaWaylandBuffer *buffer = pending->buffer;
-  gboolean changed = FALSE;
 
-  /* wl_surface.attach */
-  if (pending->newly_attached && buffer != surface->buffer_ref.buffer)
+  if (buffer_changed)
     {
       ensure_buffer_texture (buffer);
-      meta_wayland_buffer_reference (&surface->buffer_ref, buffer);
       meta_surface_actor_attach_wayland_buffer (surface_actor, buffer);
-      changed = TRUE;
     }
 
   surface_process_damage (surface, pending->damage);
@@ -286,15 +277,16 @@ actor_surface_commit (MetaWaylandSurface             *surface,
     meta_surface_actor_set_opaque_region (surface_actor, pending->opaque_region);
   if (pending->input_region)
     meta_surface_actor_set_input_region (surface_actor, pending->input_region);
-
-  return changed;
 }
 
 static void
 toplevel_surface_commit (MetaWaylandSurface             *surface,
-                         MetaWaylandDoubleBufferedState *pending)
+                         MetaWaylandDoubleBufferedState *pending,
+                         gboolean                        buffer_changed)
 {
-  if (actor_surface_commit (surface, pending))
+  actor_surface_commit (surface, pending, buffer_changed);
+
+  if (buffer_changed)
     {
       MetaWindow *window = surface->window;
       MetaWaylandBuffer *buffer = pending->buffer;
@@ -398,7 +390,8 @@ move_double_buffered_state (MetaWaylandDoubleBufferedState *from,
 
 static void
 subsurface_surface_commit (MetaWaylandSurface             *surface,
-                           MetaWaylandDoubleBufferedState *pending)
+                           MetaWaylandDoubleBufferedState *pending,
+                           gboolean                        buffer_changed)
 {
   /*
    * If the sub-surface is in synchronous mode, post-pone the commit of its
@@ -416,21 +409,26 @@ subsurface_surface_commit (MetaWaylandSurface             *surface,
     {
       move_double_buffered_state (pending, &surface->sub.pending_surface_state);
     }
-  else if (actor_surface_commit (surface, pending))
+  else
     {
-      MetaSurfaceActor *surface_actor = surface->surface_actor;
-      MetaWaylandBuffer *buffer = pending->buffer;
-      float x, y;
+      actor_surface_commit (surface, pending, buffer_changed);
 
-      if (buffer != NULL)
-        clutter_actor_show (CLUTTER_ACTOR (surface_actor));
-      else
-        clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
-
-      clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
-      x += pending->dx;
-      y += pending->dy;
-      clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
+      if (buffer_changed)
+        {
+          MetaSurfaceActor *surface_actor = surface->surface_actor;
+          MetaWaylandBuffer *buffer = pending->buffer;
+          float x, y;
+
+          if (buffer != NULL)
+            clutter_actor_show (CLUTTER_ACTOR (surface_actor));
+          else
+            clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
+
+          clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
+          x += pending->dx;
+          y += pending->dy;
+          clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
+        }
     }
 }
 
@@ -448,13 +446,21 @@ commit_double_buffered_state (MetaWaylandSurface             *surface,
                               MetaWaylandDoubleBufferedState *pending)
 {
   MetaWaylandCompositor *compositor = surface->compositor;
+  gboolean buffer_changed = FALSE;
+
+  /* wl_surface.attach */
+  if (pending->newly_attached && pending->buffer != surface->buffer_ref.buffer)
+    {
+      meta_wayland_buffer_reference (&surface->buffer_ref, pending->buffer);
+      buffer_changed = TRUE;
+    }
 
   if (surface == compositor->seat->sprite)
-    cursor_surface_commit (surface, pending);
+    cursor_surface_commit (surface, pending, buffer_changed);
   else if (surface->window)
-    toplevel_surface_commit (surface, pending);
+    toplevel_surface_commit (surface, pending, buffer_changed);
   else if (surface->subsurface.resource)
-    subsurface_surface_commit (surface, pending);
+    subsurface_surface_commit (surface, pending, buffer_changed);
 
   g_list_foreach (surface->subsurfaces,
                   parent_surface_committed,


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