From 92e36e7076c85b7da5d40c947c45fdd6fd4602fa Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 1 Feb 2014 17:05:14 -0500 Subject: [PATCH] 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 | 80 ++++++++++++++++-------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7817a3101..7a9001734 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)); + if (buffer_changed) + { + MetaSurfaceActor *surface_actor = surface->surface_actor; + MetaWaylandBuffer *buffer = pending->buffer; + float x, y; - 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 != 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,