diff --git a/include/labwc.h b/include/labwc.h index 8f5aa989..ee5d72d0 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -196,6 +196,7 @@ struct output { struct wlr_scene_output *scene_output; struct wl_list layers[LAB_NR_LAYERS]; struct wlr_scene_tree *layer_tree[LAB_NR_LAYERS]; + struct wlr_scene_tree *layer_popup_tree; struct wlr_box usable_area; struct lab_data_buffer *osd_buffer; diff --git a/src/layers.c b/src/layers.c index 6f1d5292..060d5cca 100644 --- a/src/layers.c +++ b/src/layers.c @@ -247,12 +247,6 @@ create_popup(struct wlr_xdg_popup *wlr_popup, struct wlr_scene_node *parent) popup->new_popup.notify = popup_handle_new_popup; wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup); - /* - * FIXME: should we put popups in ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY - * or a dedicated output->layer_popup_tree - so that for example - * a panel in the bottom layer displays any popup above views. - */ - popup_unconstrain(popup); return popup; } @@ -272,7 +266,24 @@ new_popup_notify(struct wl_listener *listener, void *data) struct lab_layer_surface *lab_layer_surface = wl_container_of(listener, lab_layer_surface, new_popup); struct wlr_xdg_popup *wlr_popup = data; - create_popup(wlr_popup, lab_layer_surface->scene_layer_surface->node); + + /* + * We always put popups in a special popup_tree so that for example a + * panel in the bottom layer displays popups above views. + */ + struct server *server = lab_layer_surface->server; + struct wlr_output *wlr_output = + lab_layer_surface->scene_layer_surface->layer_surface->output; + struct output *output = output_from_wlr_output(server, wlr_output); + struct wlr_scene_node *node = &output->layer_popup_tree->node; + + create_popup(wlr_popup, node); + + struct wlr_box box = { 0 }; + wlr_output_layout_get_box(server->output_layout, wlr_output, &box); + box.x += lab_layer_surface->scene_layer_surface->node->state.x; + box.y += lab_layer_surface->scene_layer_surface->node->state.y; + wlr_scene_node_set_position(node, box.x, box.y); } static void diff --git a/src/output.c b/src/output.c index c9981af3..fbd629a1 100644 --- a/src/output.c +++ b/src/output.c @@ -111,6 +111,10 @@ new_output_notify(struct wl_listener *listener, void *data) output->frame.notify = output_frame_notify; wl_signal_add(&wlr_output->events.frame, &output->frame); + /* + * Create layer-trees (background, bottom, top and overlay) and + * a layer-popup-tree. + */ int nr_layers = sizeof(output->layers) / sizeof(output->layers[0]); for (int i = 0; i < nr_layers; i++) { wl_list_init(&output->layers[i]); @@ -118,10 +122,23 @@ new_output_notify(struct wl_listener *listener, void *data) wlr_scene_tree_create(&server->scene->node); output->layer_tree[i]->node.data = output->wlr_output; } + output->layer_popup_tree = wlr_scene_tree_create(&server->scene->node); + + /* + * Set the z-positions to achieve the following order (from top to + * bottom): + * - layer-shell popups + * - overlay layer + * - top layer + * - views + * - bottom layer + * - background layer + */ wlr_scene_node_lower_to_bottom(&output->layer_tree[1]->node); wlr_scene_node_lower_to_bottom(&output->layer_tree[0]->node); wlr_scene_node_raise_to_top(&output->layer_tree[2]->node); wlr_scene_node_raise_to_top(&output->layer_tree[3]->node); + wlr_scene_node_raise_to_top(&output->layer_popup_tree->node); if (rc.adaptive_sync) { wlr_log(WLR_INFO, "enable adaptive sync on %s",