mirror of
https://github.com/brl/mutter.git
synced 2024-12-26 04:42:14 +00:00
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.
This commit is contained in:
parent
d74796ee80
commit
92e36e7076
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user