diff options
-rw-r--r-- | src/wayland/meta-wayland-surface.c | 44 | ||||
-rw-r--r-- | src/wayland/meta-wayland-surface.h | 5 |
2 files changed, 48 insertions, 1 deletions
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 14956860e..ac4de2dcf 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -76,10 +76,37 @@ gboolean meta_wayland_surface_assign_role (MetaWaylandSurface *surface, MetaWaylandSurfaceRole role) { + MetaSurfaceActorWayland *surface_actor; + if (surface->role == META_WAYLAND_SURFACE_ROLE_NONE || surface->role == role) { surface->role = role; + + switch (surface->role) + { + case META_WAYLAND_SURFACE_ROLE_NONE: + g_assert_not_reached(); + break; + case META_WAYLAND_SURFACE_ROLE_XWAYLAND: + /* See apply_pending_state for explanation why Xwayland is special here. */ + case META_WAYLAND_SURFACE_ROLE_CURSOR: + case META_WAYLAND_SURFACE_ROLE_DND: + wl_list_insert_list (&surface->compositor->frame_callbacks, + &surface->pending_frame_callback_list); + wl_list_init (&surface->pending_frame_callback_list); + break; + case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE: + case META_WAYLAND_SURFACE_ROLE_SUBSURFACE: + case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE: + case META_WAYLAND_SURFACE_ROLE_XDG_POPUP: + surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor); + meta_surface_actor_wayland_add_frame_callbacks (surface_actor, + &surface->pending_frame_callback_list); + wl_list_init (&surface->pending_frame_callback_list); + break; + } + return TRUE; } else @@ -495,6 +522,7 @@ apply_pending_state (MetaWaylandSurface *surface, MetaWaylandPendingState *pending) { MetaWaylandCompositor *compositor = surface->compositor; + MetaSurfaceActorWayland *surface_actor; if (pending->newly_attached) { @@ -543,6 +571,13 @@ apply_pending_state (MetaWaylandSurface *surface, switch (surface->role) { case META_WAYLAND_SURFACE_ROLE_NONE: + /* Since there is no role assigned to the surface yet, keep frame + * callbacks queued until a role is assigned and we know how + * the surface will be drawn. + */ + wl_list_insert_list (&surface->pending_frame_callback_list, + &pending->frame_callback_list); + break; case META_WAYLAND_SURFACE_ROLE_XWAYLAND: /* For Xwayland windows, throttling frames when the window isn't actually * drawn is less useful, because Xwayland still has to do the drawing @@ -563,7 +598,8 @@ apply_pending_state (MetaWaylandSurface *surface, case META_WAYLAND_SURFACE_ROLE_XDG_POPUP: case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE: case META_WAYLAND_SURFACE_ROLE_SUBSURFACE: - meta_surface_actor_wayland_add_frame_callbacks (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), + surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor); + meta_surface_actor_wayland_add_frame_callbacks (surface_actor, &pending->frame_callback_list); break; } @@ -942,6 +978,7 @@ wl_surface_destructor (struct wl_resource *resource) { MetaWaylandSurface *surface = wl_resource_get_user_data (resource); MetaWaylandCompositor *compositor = surface->compositor; + MetaWaylandFrameCallback *cb, *next; /* If we still have a window at the time of destruction, that means that * the client is disconnecting, as the resources are destroyed in a random @@ -966,6 +1003,9 @@ wl_surface_destructor (struct wl_resource *resource) g_hash_table_unref (surface->outputs); + wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link) + wl_resource_destroy (cb->resource); + if (surface->resource) wl_resource_set_user_data (surface->resource, NULL); @@ -1002,6 +1042,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor, surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface)); + wl_list_init (&surface->pending_frame_callback_list); + sync_drag_dest_funcs (surface); surface->outputs = g_hash_table_new (NULL, NULL); diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 3ac2834fd..74f37592e 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -113,6 +113,11 @@ struct _MetaWaylandSurface GList *subsurfaces; GHashTable *outputs; + /* List of pending frame callbacks that needs to stay queued longer than one + * commit sequence, such as when it has not yet been assigned a role. + */ + struct wl_list pending_frame_callback_list; + struct { const MetaWaylandDragDestFuncs *funcs; } dnd; |