wayland: Make wl_subsurface.place_(above|below) properly synchronized
The placement set by either wl_subsurface.place_above or wl_subsurface.place_below should be applied when the parent surface invokes wl_surface.commit. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> https://bugzilla.gnome.org/show_bug.cgi?id=705502
This commit is contained in:
parent
16de7f66fb
commit
9348c9bd4b
@ -58,6 +58,19 @@
|
|||||||
#include "meta-idle-monitor-private.h"
|
#include "meta-idle-monitor-private.h"
|
||||||
#include "monitor-private.h"
|
#include "monitor-private.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE,
|
||||||
|
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW
|
||||||
|
} MetaWaylandSubsurfacePlacement;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MetaWaylandSubsurfacePlacement placement;
|
||||||
|
MetaWaylandSurface *sibling;
|
||||||
|
struct wl_listener sibling_destroy_listener;
|
||||||
|
} MetaWaylandSubsurfacePlacementOp;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
surface_process_damage (MetaWaylandSurface *surface,
|
surface_process_damage (MetaWaylandSurface *surface,
|
||||||
cairo_region_t *region)
|
cairo_region_t *region)
|
||||||
@ -1012,6 +1025,44 @@ wl_subsurface_parent_surface_committed (gpointer data, gpointer user_data)
|
|||||||
surface->sub.pending_y);
|
surface->sub.pending_y);
|
||||||
surface->sub.pending_pos = FALSE;
|
surface->sub.pending_pos = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (surface->sub.pending_placement_ops)
|
||||||
|
{
|
||||||
|
GSList *it;
|
||||||
|
for (it = surface->sub.pending_placement_ops; it; it = it->next)
|
||||||
|
{
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op = it->data;
|
||||||
|
ClutterActor *surface_actor;
|
||||||
|
ClutterActor *parent_actor;
|
||||||
|
ClutterActor *sibling_actor;
|
||||||
|
|
||||||
|
if (!op->sibling)
|
||||||
|
{
|
||||||
|
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||||
|
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->sub.parent));
|
||||||
|
sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
|
||||||
|
|
||||||
|
switch (op->placement)
|
||||||
|
{
|
||||||
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE:
|
||||||
|
clutter_actor_set_child_above_sibling (parent_actor, surface_actor, sibling_actor);
|
||||||
|
break;
|
||||||
|
case META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW:
|
||||||
|
clutter_actor_set_child_below_sibling (parent_actor, surface_actor, sibling_actor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_remove (&op->sibling_destroy_listener.link);
|
||||||
|
g_slice_free (MetaWaylandSubsurfacePlacementOp, op);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free (surface->sub.pending_placement_ops);
|
||||||
|
surface->sub.pending_placement_ops = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1062,12 +1113,39 @@ is_valid_sibling (MetaWaylandSurface *surface, MetaWaylandSurface *sibling)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
subsurface_handle_pending_sibling_destroyed (struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op =
|
||||||
|
wl_container_of (listener, op, sibling_destroy_listener);
|
||||||
|
|
||||||
|
op->sibling = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
queue_subsurface_placement (MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandSurface *sibling,
|
||||||
|
MetaWaylandSubsurfacePlacement placement)
|
||||||
|
{
|
||||||
|
MetaWaylandSubsurfacePlacementOp *op =
|
||||||
|
g_slice_new (MetaWaylandSubsurfacePlacementOp);
|
||||||
|
|
||||||
|
op->placement = placement;
|
||||||
|
op->sibling = sibling;
|
||||||
|
op->sibling_destroy_listener.notify =
|
||||||
|
subsurface_handle_pending_sibling_destroyed;
|
||||||
|
wl_resource_add_destroy_listener (sibling->resource,
|
||||||
|
&op->sibling_destroy_listener);
|
||||||
|
|
||||||
|
surface->sub.pending_placement_ops =
|
||||||
|
g_slist_append (surface->sub.pending_placement_ops, op);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wl_subsurface_place_above (struct wl_client *client,
|
wl_subsurface_place_above (struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
struct wl_resource *sibling_resource)
|
struct wl_resource *sibling_resource)
|
||||||
{
|
{
|
||||||
ClutterActor *parent_actor;
|
|
||||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
||||||
@ -1081,11 +1159,9 @@ wl_subsurface_place_above (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
queue_subsurface_placement (surface,
|
||||||
|
sibling,
|
||||||
clutter_actor_set_child_above_sibling (parent_actor,
|
META_WAYLAND_SUBSURFACE_PLACEMENT_ABOVE);
|
||||||
CLUTTER_ACTOR (surface->surface_actor),
|
|
||||||
CLUTTER_ACTOR (sibling->surface_actor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1093,7 +1169,6 @@ wl_subsurface_place_below (struct wl_client *client,
|
|||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
struct wl_resource *sibling_resource)
|
struct wl_resource *sibling_resource)
|
||||||
{
|
{
|
||||||
ClutterActor *parent_actor;
|
|
||||||
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
|
||||||
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
|
||||||
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
|
||||||
@ -1107,11 +1182,9 @@ wl_subsurface_place_below (struct wl_client *client,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
|
queue_subsurface_placement (surface,
|
||||||
|
sibling,
|
||||||
clutter_actor_set_child_below_sibling (parent_actor,
|
META_WAYLAND_SUBSURFACE_PLACEMENT_BELOW);
|
||||||
CLUTTER_ACTOR (surface->surface_actor),
|
|
||||||
CLUTTER_ACTOR (sibling->surface_actor));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -94,6 +94,7 @@ struct _MetaWaylandSurface
|
|||||||
int32_t pending_x;
|
int32_t pending_x;
|
||||||
int32_t pending_y;
|
int32_t pending_y;
|
||||||
gboolean pending_pos;
|
gboolean pending_pos;
|
||||||
|
GSList *pending_placement_ops;
|
||||||
} sub;
|
} sub;
|
||||||
|
|
||||||
/* All the pending state, that wl_surface.commit will apply. */
|
/* All the pending state, that wl_surface.commit will apply. */
|
||||||
|
Loading…
Reference in New Issue
Block a user