wlr_xdg_toplevel: reparent on parent unmap
From the xdg-shell specification: If the parent is unmapped then its children are managed as though the parent of the now-unmapped parent has become the parent of this surface. If no parent exists for the now-unmapped parent then the children are managed as though they have no parent surface.
This commit is contained in:
parent
8d2ea9544b
commit
9914784594
|
@ -117,9 +117,11 @@ struct wlr_xdg_toplevel_state {
|
|||
struct wlr_xdg_toplevel {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_xdg_surface *base;
|
||||
struct wlr_xdg_surface *parent;
|
||||
bool added;
|
||||
|
||||
struct wlr_xdg_surface *parent;
|
||||
struct wl_listener parent_unmap;
|
||||
|
||||
struct wlr_xdg_toplevel_state client_pending;
|
||||
struct wlr_xdg_toplevel_state server_pending;
|
||||
struct wlr_xdg_toplevel_state current;
|
||||
|
|
|
@ -41,6 +41,10 @@ void unmap_xdg_surface(struct wlr_xdg_surface *surface) {
|
|||
|
||||
switch (surface->role) {
|
||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
if (surface->toplevel->parent) {
|
||||
wl_list_remove(&surface->toplevel->parent_unmap.link);
|
||||
surface->toplevel->parent = NULL;
|
||||
}
|
||||
free(surface->toplevel->title);
|
||||
surface->toplevel->title = NULL;
|
||||
free(surface->toplevel->app_id);
|
||||
|
|
|
@ -207,6 +207,34 @@ struct wlr_xdg_surface *wlr_xdg_surface_from_toplevel_resource(
|
|||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static void set_parent(struct wlr_xdg_surface *surface,
|
||||
struct wlr_xdg_surface *parent);
|
||||
|
||||
static void handle_parent_unmap(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_toplevel *toplevel =
|
||||
wl_container_of(listener, toplevel, parent_unmap);
|
||||
set_parent(toplevel->base, toplevel->parent->toplevel->parent);
|
||||
}
|
||||
|
||||
static void set_parent(struct wlr_xdg_surface *surface,
|
||||
struct wlr_xdg_surface *parent) {
|
||||
assert(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
|
||||
assert(!parent || parent->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL);
|
||||
|
||||
if (surface->toplevel->parent) {
|
||||
wl_list_remove(&surface->toplevel->parent_unmap.link);
|
||||
}
|
||||
|
||||
surface->toplevel->parent = parent;
|
||||
if (surface->toplevel->parent) {
|
||||
surface->toplevel->parent_unmap.notify = handle_parent_unmap;
|
||||
wl_signal_add(&surface->toplevel->parent->events.unmap,
|
||||
&surface->toplevel->parent_unmap);
|
||||
}
|
||||
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.set_parent, surface);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_set_parent(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *parent_resource) {
|
||||
struct wlr_xdg_surface *surface =
|
||||
|
@ -217,8 +245,7 @@ static void xdg_toplevel_handle_set_parent(struct wl_client *client,
|
|||
parent = wlr_xdg_surface_from_toplevel_resource(parent_resource);
|
||||
}
|
||||
|
||||
surface->toplevel->parent = parent;
|
||||
wlr_signal_emit_safe(&surface->toplevel->events.set_parent, surface);
|
||||
set_parent(surface, parent);
|
||||
}
|
||||
|
||||
static void xdg_toplevel_handle_set_title(struct wl_client *client,
|
||||
|
|
Loading…
Reference in New Issue