subcompositor: use unified map logic
This commit is contained in:
parent
6b40e08148
commit
c590bb600f
|
@ -37,7 +37,6 @@ struct wlr_subsurface {
|
||||||
|
|
||||||
bool synchronized;
|
bool synchronized;
|
||||||
bool reordered;
|
bool reordered;
|
||||||
bool mapped;
|
|
||||||
bool added;
|
bool added;
|
||||||
|
|
||||||
struct wl_listener surface_client_commit;
|
struct wl_listener surface_client_commit;
|
||||||
|
@ -45,8 +44,6 @@ struct wlr_subsurface {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
struct wl_signal map;
|
|
||||||
struct wl_signal unmap;
|
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
|
|
|
@ -18,6 +18,8 @@ struct wlr_scene_subsurface_tree {
|
||||||
struct wl_listener tree_destroy;
|
struct wl_listener tree_destroy;
|
||||||
struct wl_listener surface_destroy;
|
struct wl_listener surface_destroy;
|
||||||
struct wl_listener surface_commit;
|
struct wl_listener surface_commit;
|
||||||
|
struct wl_listener surface_map;
|
||||||
|
struct wl_listener surface_unmap;
|
||||||
struct wl_listener surface_new_subsurface;
|
struct wl_listener surface_new_subsurface;
|
||||||
|
|
||||||
struct wlr_scene_subsurface_tree *parent; // NULL for the top-level surface
|
struct wlr_scene_subsurface_tree *parent; // NULL for the top-level surface
|
||||||
|
@ -27,8 +29,6 @@ struct wlr_scene_subsurface_tree {
|
||||||
struct wlr_addon surface_addon;
|
struct wlr_addon surface_addon;
|
||||||
|
|
||||||
struct wl_listener subsurface_destroy;
|
struct wl_listener subsurface_destroy;
|
||||||
struct wl_listener subsurface_map;
|
|
||||||
struct wl_listener subsurface_unmap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void subsurface_tree_handle_tree_destroy(struct wl_listener *listener,
|
static void subsurface_tree_handle_tree_destroy(struct wl_listener *listener,
|
||||||
|
@ -39,12 +39,12 @@ static void subsurface_tree_handle_tree_destroy(struct wl_listener *listener,
|
||||||
if (subsurface_tree->parent) {
|
if (subsurface_tree->parent) {
|
||||||
wlr_addon_finish(&subsurface_tree->surface_addon);
|
wlr_addon_finish(&subsurface_tree->surface_addon);
|
||||||
wl_list_remove(&subsurface_tree->subsurface_destroy.link);
|
wl_list_remove(&subsurface_tree->subsurface_destroy.link);
|
||||||
wl_list_remove(&subsurface_tree->subsurface_map.link);
|
|
||||||
wl_list_remove(&subsurface_tree->subsurface_unmap.link);
|
|
||||||
}
|
}
|
||||||
wl_list_remove(&subsurface_tree->tree_destroy.link);
|
wl_list_remove(&subsurface_tree->tree_destroy.link);
|
||||||
wl_list_remove(&subsurface_tree->surface_destroy.link);
|
wl_list_remove(&subsurface_tree->surface_destroy.link);
|
||||||
wl_list_remove(&subsurface_tree->surface_commit.link);
|
wl_list_remove(&subsurface_tree->surface_commit.link);
|
||||||
|
wl_list_remove(&subsurface_tree->surface_map.link);
|
||||||
|
wl_list_remove(&subsurface_tree->surface_unmap.link);
|
||||||
wl_list_remove(&subsurface_tree->surface_new_subsurface.link);
|
wl_list_remove(&subsurface_tree->surface_new_subsurface.link);
|
||||||
free(subsurface_tree);
|
free(subsurface_tree);
|
||||||
}
|
}
|
||||||
|
@ -121,18 +121,18 @@ static void subsurface_tree_handle_subsurface_destroy(struct wl_listener *listen
|
||||||
wlr_scene_node_destroy(&subsurface_tree->tree->node);
|
wlr_scene_node_destroy(&subsurface_tree->tree->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_tree_handle_subsurface_map(struct wl_listener *listener,
|
static void subsurface_tree_handle_surface_map(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_scene_subsurface_tree *subsurface_tree =
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
wl_container_of(listener, subsurface_tree, subsurface_map);
|
wl_container_of(listener, subsurface_tree, surface_map);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, true);
|
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_tree_handle_subsurface_unmap(struct wl_listener *listener,
|
static void subsurface_tree_handle_surface_unmap(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_scene_subsurface_tree *subsurface_tree =
|
struct wlr_scene_subsurface_tree *subsurface_tree =
|
||||||
wl_container_of(listener, subsurface_tree, subsurface_unmap);
|
wl_container_of(listener, subsurface_tree, surface_unmap);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, false);
|
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, false);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,6 @@ static bool subsurface_tree_create_subsurface(
|
||||||
}
|
}
|
||||||
|
|
||||||
child->parent = parent;
|
child->parent = parent;
|
||||||
wlr_scene_node_set_enabled(&child->tree->node, subsurface->mapped);
|
|
||||||
|
|
||||||
wlr_addon_init(&child->surface_addon, &subsurface->surface->addons,
|
wlr_addon_init(&child->surface_addon, &subsurface->surface->addons,
|
||||||
parent, &subsurface_tree_addon_impl);
|
parent, &subsurface_tree_addon_impl);
|
||||||
|
@ -169,12 +168,6 @@ static bool subsurface_tree_create_subsurface(
|
||||||
child->subsurface_destroy.notify = subsurface_tree_handle_subsurface_destroy;
|
child->subsurface_destroy.notify = subsurface_tree_handle_subsurface_destroy;
|
||||||
wl_signal_add(&subsurface->events.destroy, &child->subsurface_destroy);
|
wl_signal_add(&subsurface->events.destroy, &child->subsurface_destroy);
|
||||||
|
|
||||||
child->subsurface_map.notify = subsurface_tree_handle_subsurface_map;
|
|
||||||
wl_signal_add(&subsurface->events.map, &child->subsurface_map);
|
|
||||||
|
|
||||||
child->subsurface_unmap.notify = subsurface_tree_handle_subsurface_unmap;
|
|
||||||
wl_signal_add(&subsurface->events.unmap, &child->subsurface_unmap);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,11 +228,19 @@ static struct wlr_scene_subsurface_tree *scene_surface_tree_create(
|
||||||
subsurface_tree->surface_commit.notify = subsurface_tree_handle_surface_commit;
|
subsurface_tree->surface_commit.notify = subsurface_tree_handle_surface_commit;
|
||||||
wl_signal_add(&surface->events.commit, &subsurface_tree->surface_commit);
|
wl_signal_add(&surface->events.commit, &subsurface_tree->surface_commit);
|
||||||
|
|
||||||
|
subsurface_tree->surface_map.notify = subsurface_tree_handle_surface_map;
|
||||||
|
wl_signal_add(&surface->events.map, &subsurface_tree->surface_map);
|
||||||
|
|
||||||
|
subsurface_tree->surface_unmap.notify = subsurface_tree_handle_surface_unmap;
|
||||||
|
wl_signal_add(&surface->events.unmap, &subsurface_tree->surface_unmap);
|
||||||
|
|
||||||
subsurface_tree->surface_new_subsurface.notify =
|
subsurface_tree->surface_new_subsurface.notify =
|
||||||
subsurface_tree_handle_surface_new_subsurface;
|
subsurface_tree_handle_surface_new_subsurface;
|
||||||
wl_signal_add(&surface->events.new_subsurface,
|
wl_signal_add(&surface->events.new_subsurface,
|
||||||
&subsurface_tree->surface_new_subsurface);
|
&subsurface_tree->surface_new_subsurface);
|
||||||
|
|
||||||
|
wlr_scene_node_set_enabled(&subsurface_tree->tree->node, surface->mapped);
|
||||||
|
|
||||||
return subsurface_tree;
|
return subsurface_tree;
|
||||||
|
|
||||||
error_scene_surface:
|
error_scene_surface:
|
||||||
|
|
|
@ -859,7 +859,7 @@ struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
|
||||||
struct wlr_subsurface *subsurface;
|
struct wlr_subsurface *subsurface;
|
||||||
wl_list_for_each_reverse(subsurface, &surface->current.subsurfaces_above,
|
wl_list_for_each_reverse(subsurface, &surface->current.subsurfaces_above,
|
||||||
current.link) {
|
current.link) {
|
||||||
if (!subsurface->mapped) {
|
if (!subsurface->surface->mapped) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +884,7 @@ struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
|
||||||
|
|
||||||
wl_list_for_each_reverse(subsurface, &surface->current.subsurfaces_below,
|
wl_list_for_each_reverse(subsurface, &surface->current.subsurfaces_below,
|
||||||
current.link) {
|
current.link) {
|
||||||
if (!subsurface->mapped) {
|
if (!subsurface->surface->mapped) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,7 +994,7 @@ static void surface_for_each_surface(struct wlr_surface *surface, int x, int y,
|
||||||
wlr_surface_iterator_func_t iterator, void *user_data) {
|
wlr_surface_iterator_func_t iterator, void *user_data) {
|
||||||
struct wlr_subsurface *subsurface;
|
struct wlr_subsurface *subsurface;
|
||||||
wl_list_for_each(subsurface, &surface->current.subsurfaces_below, current.link) {
|
wl_list_for_each(subsurface, &surface->current.subsurfaces_below, current.link) {
|
||||||
if (!subsurface->mapped) {
|
if (!subsurface->surface->mapped) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,7 +1009,7 @@ static void surface_for_each_surface(struct wlr_surface *surface, int x, int y,
|
||||||
iterator(surface, x, y, user_data);
|
iterator(surface, x, y, user_data);
|
||||||
|
|
||||||
wl_list_for_each(subsurface, &surface->current.subsurfaces_above, current.link) {
|
wl_list_for_each(subsurface, &surface->current.subsurfaces_above, current.link) {
|
||||||
if (!subsurface->mapped) {
|
if (!subsurface->surface->mapped) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_unmap(struct wlr_subsurface *subsurface);
|
|
||||||
|
|
||||||
static const struct wl_subsurface_interface subsurface_implementation;
|
static const struct wl_subsurface_interface subsurface_implementation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -192,22 +190,16 @@ const struct wlr_surface_role subsurface_role;
|
||||||
* - Its parent is mapped
|
* - Its parent is mapped
|
||||||
*/
|
*/
|
||||||
static void subsurface_consider_map(struct wlr_subsurface *subsurface) {
|
static void subsurface_consider_map(struct wlr_subsurface *subsurface) {
|
||||||
if (subsurface->mapped || !wlr_surface_has_buffer(subsurface->surface)) {
|
if (subsurface->surface->mapped || !wlr_surface_has_buffer(subsurface->surface)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: unify "mapped" flag
|
if (!subsurface->parent->mapped) {
|
||||||
if (subsurface->parent->role == &subsurface_role) {
|
|
||||||
struct wlr_subsurface *parent =
|
|
||||||
wlr_subsurface_try_from_wlr_surface(subsurface->parent);
|
|
||||||
if (parent == NULL || !parent->mapped) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Now we can map the subsurface
|
// Now we can map the subsurface
|
||||||
subsurface->mapped = true;
|
wlr_surface_map(subsurface->surface);
|
||||||
wl_signal_emit_mutable(&subsurface->events.map, subsurface);
|
|
||||||
|
|
||||||
// Try mapping all children too
|
// Try mapping all children too
|
||||||
struct wlr_subsurface *child;
|
struct wlr_subsurface *child;
|
||||||
|
@ -221,26 +213,6 @@ static void subsurface_consider_map(struct wlr_subsurface *subsurface) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_unmap(struct wlr_subsurface *subsurface) {
|
|
||||||
if (!subsurface->mapped) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
subsurface->mapped = false;
|
|
||||||
wl_signal_emit_mutable(&subsurface->events.unmap, subsurface);
|
|
||||||
|
|
||||||
// Unmap all children
|
|
||||||
struct wlr_subsurface *child;
|
|
||||||
wl_list_for_each(child, &subsurface->surface->current.subsurfaces_below,
|
|
||||||
current.link) {
|
|
||||||
subsurface_unmap(child);
|
|
||||||
}
|
|
||||||
wl_list_for_each(child, &subsurface->surface->current.subsurfaces_above,
|
|
||||||
current.link) {
|
|
||||||
subsurface_unmap(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void subsurface_role_commit(struct wlr_surface *surface) {
|
static void subsurface_role_commit(struct wlr_surface *surface) {
|
||||||
struct wlr_subsurface *subsurface = wlr_subsurface_try_from_wlr_surface(surface);
|
struct wlr_subsurface *subsurface = wlr_subsurface_try_from_wlr_surface(surface);
|
||||||
assert(subsurface != NULL);
|
assert(subsurface != NULL);
|
||||||
|
@ -248,14 +220,19 @@ static void subsurface_role_commit(struct wlr_surface *surface) {
|
||||||
subsurface_consider_map(subsurface);
|
subsurface_consider_map(subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsurface_role_precommit(struct wlr_surface *surface,
|
static void subsurface_role_unmap(struct wlr_surface *surface) {
|
||||||
const struct wlr_surface_state *state) {
|
|
||||||
struct wlr_subsurface *subsurface = wlr_subsurface_try_from_wlr_surface(surface);
|
struct wlr_subsurface *subsurface = wlr_subsurface_try_from_wlr_surface(surface);
|
||||||
assert(subsurface != NULL);
|
assert(subsurface != NULL);
|
||||||
|
|
||||||
if (state->committed & WLR_SURFACE_STATE_BUFFER && state->buffer == NULL) {
|
// Unmap all children
|
||||||
// This is a NULL commit
|
struct wlr_subsurface *child;
|
||||||
subsurface_unmap(subsurface);
|
wl_list_for_each(child, &subsurface->surface->current.subsurfaces_below,
|
||||||
|
current.link) {
|
||||||
|
wlr_surface_unmap(child->surface);
|
||||||
|
}
|
||||||
|
wl_list_for_each(child, &subsurface->surface->current.subsurfaces_above,
|
||||||
|
current.link) {
|
||||||
|
wlr_surface_unmap(child->surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +245,6 @@ static void subsurface_role_destroy(struct wlr_surface *surface) {
|
||||||
subsurface->cached_seq);
|
subsurface->cached_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
subsurface_unmap(subsurface);
|
|
||||||
|
|
||||||
wl_signal_emit_mutable(&subsurface->events.destroy, subsurface);
|
wl_signal_emit_mutable(&subsurface->events.destroy, subsurface);
|
||||||
|
|
||||||
wl_list_remove(&subsurface->surface_client_commit.link);
|
wl_list_remove(&subsurface->surface_client_commit.link);
|
||||||
|
@ -284,7 +259,7 @@ static void subsurface_role_destroy(struct wlr_surface *surface) {
|
||||||
const struct wlr_surface_role subsurface_role = {
|
const struct wlr_surface_role subsurface_role = {
|
||||||
.name = "wl_subsurface",
|
.name = "wl_subsurface",
|
||||||
.commit = subsurface_role_commit,
|
.commit = subsurface_role_commit,
|
||||||
.precommit = subsurface_role_precommit,
|
.unmap = subsurface_role_unmap,
|
||||||
.destroy = subsurface_role_destroy,
|
.destroy = subsurface_role_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -332,7 +307,7 @@ void subsurface_handle_parent_commit(struct wlr_subsurface *subsurface) {
|
||||||
|
|
||||||
bool moved = subsurface->current.x != subsurface->pending.x ||
|
bool moved = subsurface->current.x != subsurface->pending.x ||
|
||||||
subsurface->current.y != subsurface->pending.y;
|
subsurface->current.y != subsurface->pending.y;
|
||||||
if (subsurface->mapped && moved) {
|
if (subsurface->surface->mapped && moved) {
|
||||||
wlr_surface_for_each_surface(surface,
|
wlr_surface_for_each_surface(surface,
|
||||||
collect_damage_iter, subsurface);
|
collect_damage_iter, subsurface);
|
||||||
}
|
}
|
||||||
|
@ -344,7 +319,7 @@ void subsurface_handle_parent_commit(struct wlr_subsurface *subsurface) {
|
||||||
|
|
||||||
subsurface->current.x = subsurface->pending.x;
|
subsurface->current.x = subsurface->pending.x;
|
||||||
subsurface->current.y = subsurface->pending.y;
|
subsurface->current.y = subsurface->pending.y;
|
||||||
if (subsurface->mapped && (moved || subsurface->reordered)) {
|
if (subsurface->surface->mapped && (moved || subsurface->reordered)) {
|
||||||
subsurface->reordered = false;
|
subsurface->reordered = false;
|
||||||
wlr_surface_for_each_surface(surface,
|
wlr_surface_for_each_surface(surface,
|
||||||
collect_damage_iter, subsurface);
|
collect_damage_iter, subsurface);
|
||||||
|
@ -381,8 +356,6 @@ static struct wlr_subsurface *subsurface_create(struct wlr_surface *surface,
|
||||||
&subsurface_implementation, subsurface, subsurface_resource_destroy);
|
&subsurface_implementation, subsurface, subsurface_resource_destroy);
|
||||||
|
|
||||||
wl_signal_init(&subsurface->events.destroy);
|
wl_signal_init(&subsurface->events.destroy);
|
||||||
wl_signal_init(&subsurface->events.map);
|
|
||||||
wl_signal_init(&subsurface->events.unmap);
|
|
||||||
|
|
||||||
wl_signal_add(&surface->events.client_commit,
|
wl_signal_add(&surface->events.client_commit,
|
||||||
&subsurface->surface_client_commit);
|
&subsurface->surface_client_commit);
|
||||||
|
|
Loading…
Reference in New Issue