wayland: defer layer-shell configure to initial commit
wlroots 0.19 asserts that the surface is initialized before wlr_layer_surface_v1_configure is called. Defer the configure to the initial commit, matching the pattern used for xdg_toplevel surfaces. Fixes screenshot tool crash.
This commit is contained in:
parent
143b8906bb
commit
c1927f0948
|
|
@ -112,6 +112,8 @@ handle_layer_surface_destroy(struct wl_listener *listener, void *data)
|
|||
wl_list_remove(&lv->map_listener.link);
|
||||
wl_list_remove(&lv->unmap_listener.link);
|
||||
wl_list_remove(&lv->destroy_listener.link);
|
||||
if (lv->commit_listener.link.next)
|
||||
wl_list_remove(&lv->commit_listener.link);
|
||||
if (lv->scene_node) {
|
||||
wlr_scene_node_destroy(&lv->scene_node->node);
|
||||
lv->scene_node = NULL;
|
||||
|
|
@ -120,6 +122,36 @@ handle_layer_surface_destroy(struct wl_listener *listener, void *data)
|
|||
free(lv);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_layer_surface_initial_commit(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wl_layer_view *lv = wl_container_of(listener, lv, commit_listener);
|
||||
struct wlr_layer_surface_v1 *ls = lv->layer_surface;
|
||||
(void)data;
|
||||
|
||||
if (!ls->initial_commit)
|
||||
return;
|
||||
|
||||
/* Only need this once. */
|
||||
wl_list_remove(&lv->commit_listener.link);
|
||||
wl_list_init(&lv->commit_listener.link);
|
||||
|
||||
uint32_t ow = 1920, oh = 1080;
|
||||
if (ls->output) {
|
||||
ow = ls->output->width > 0 ? (uint32_t)ls->output->width : 1920;
|
||||
oh = ls->output->height > 0 ? (uint32_t)ls->output->height : 1080;
|
||||
}
|
||||
uint32_t fw, fh;
|
||||
layer_surface_compute_geometry(ls, ow, oh, &fw, &fh);
|
||||
wlr_layer_surface_v1_configure(ls, fw, fh);
|
||||
|
||||
if (lv->scene_node) {
|
||||
int sx, sy;
|
||||
layer_surface_compute_position(ls, ow, oh, fw, fh, &sx, &sy);
|
||||
wlr_scene_node_set_position(&lv->scene_node->node, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* handle_layer_shell_new_surface — a client created a layer surface.
|
||||
* Assign the output if unset, compute geometry, send configure, and
|
||||
|
|
@ -162,23 +194,6 @@ handle_layer_shell_new_surface(struct wl_listener *listener, void *data)
|
|||
lv->scene_node = wlr_scene_subsurface_tree_create(_lp, ls->surface);
|
||||
}
|
||||
|
||||
/* Compute and send initial configure. */
|
||||
uint32_t ow = 1920, oh = 1080;
|
||||
if (ls->output) {
|
||||
ow = ls->output->width > 0 ? (uint32_t)ls->output->width : 1920;
|
||||
oh = ls->output->height > 0 ? (uint32_t)ls->output->height : 1080;
|
||||
}
|
||||
uint32_t fw, fh;
|
||||
layer_surface_compute_geometry(ls, ow, oh, &fw, &fh);
|
||||
wlr_layer_surface_v1_configure(ls, fw, fh);
|
||||
|
||||
/* Position the scene node. */
|
||||
if (lv->scene_node) {
|
||||
int sx, sy;
|
||||
layer_surface_compute_position(ls, ow, oh, fw, fh, &sx, &sy);
|
||||
wlr_scene_node_set_position(&lv->scene_node->node, sx, sy);
|
||||
}
|
||||
|
||||
/* Wire lifecycle listeners. */
|
||||
lv->map_listener.notify = handle_layer_surface_map;
|
||||
lv->unmap_listener.notify = handle_layer_surface_unmap;
|
||||
|
|
@ -187,10 +202,15 @@ handle_layer_shell_new_surface(struct wl_listener *listener, void *data)
|
|||
wl_signal_add(&ls->surface->events.unmap, &lv->unmap_listener);
|
||||
wl_signal_add(&ls->events.destroy, &lv->destroy_listener);
|
||||
|
||||
/* Defer configure until the surface's initial commit (wlroots 0.19
|
||||
* requires the surface to be initialized before configure). */
|
||||
lv->commit_listener.notify = handle_layer_surface_initial_commit;
|
||||
wl_signal_add(&ls->surface->events.commit, &lv->commit_listener);
|
||||
|
||||
wl_list_insert(&wl_state.layer_list, &lv->link);
|
||||
|
||||
wwarning("wl_backend: layer surface new layer=%d %ux%u namespace=%s",
|
||||
ls->current.layer, fw, fh,
|
||||
wwarning("wl_backend: layer surface new layer=%d namespace=%s",
|
||||
ls->pending.layer,
|
||||
ls->namespace ? ls->namespace : "");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ struct wl_layer_view {
|
|||
struct wl_listener map_listener;
|
||||
struct wl_listener unmap_listener;
|
||||
struct wl_listener destroy_listener;
|
||||
struct wl_listener commit_listener;
|
||||
struct wl_list link; /* wl_state.layer_list */
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue