diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 1b608c1..eb699ab 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -219,7 +219,7 @@ extern void handle_text_input_new(struct wl_listener *listener, void *data); extern void handle_input_method_new(struct wl_listener *listener, void *data); extern void handle_virtual_keyboard_new(struct wl_listener *listener, void *data); extern void handle_xdg_activation_request(struct wl_listener *listener, void *data); -static void handle_layer_shell_new_surface(struct wl_listener *listener, void *data); +extern void handle_layer_shell_new_surface(struct wl_listener *listener, void *data); extern void handle_xdg_new_toplevel(struct wl_listener *listener, void *data); extern void handle_new_toplevel_decoration(struct wl_listener *listener, void *data); extern void handle_virtual_pointer_new(struct wl_listener *listener, void *data); @@ -1536,188 +1536,6 @@ handle_new_shortcuts_inhibitor(struct wl_listener *listener, void *data) -#define LAYER_VIEW_FROM(l, field) \ - ((struct wl_layer_view *)((char *)(l) - offsetof(struct wl_layer_view, field))) - -/* - * Compute the geometry for a layer surface given its anchor, margins, - * desired size and the output dimensions. - */ -static void -layer_surface_compute_geometry(struct wlr_layer_surface_v1 *ls, - uint32_t ow, uint32_t oh, - uint32_t *out_w, uint32_t *out_h) -{ - const struct wlr_layer_surface_v1_state *s = &ls->current; - uint32_t w = s->desired_width; - uint32_t h = s->desired_height; - - bool anchor_lr = (s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT) && - (s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); - bool anchor_tb = (s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) && - (s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM); - - if (w == 0 && anchor_lr) - w = ow - s->margin.left - s->margin.right; - if (h == 0 && anchor_tb) - h = oh - s->margin.top - s->margin.bottom; - - /* Ensure minimum 1×1. */ - *out_w = w > 0 ? w : 1; - *out_h = h > 0 ? h : 1; -} - -/* - * Compute the position of a layer surface on the output given its - * anchor, margins and final dimensions. - */ -static void -layer_surface_compute_position(struct wlr_layer_surface_v1 *ls, - uint32_t ow, uint32_t oh, - uint32_t fw, uint32_t fh, - int *out_x, int *out_y) -{ - const struct wlr_layer_surface_v1_state *s = &ls->current; - int x = 0, y = 0; - - bool anchor_l = s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; - bool anchor_r = s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - bool anchor_t = s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; - bool anchor_b = s->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - - if (anchor_l && anchor_r) - x = s->margin.left; - else if (anchor_l) - x = s->margin.left; - else if (anchor_r) - x = (int)ow - (int)fw - s->margin.right; - else - x = ((int)ow - (int)fw) / 2; - - if (anchor_t && anchor_b) - y = s->margin.top; - else if (anchor_t) - y = s->margin.top; - else if (anchor_b) - y = (int)oh - (int)fh - s->margin.bottom; - else - y = ((int)oh - (int)fh) / 2; - - *out_x = x; - *out_y = y; -} - -static void -handle_layer_surface_map(struct wl_listener *listener, void *data) -{ - (void)data; - struct wl_layer_view *lv = LAYER_VIEW_FROM(listener, map_listener); - wwarning("wl_backend: layer surface mapped (layer=%d namespace=%s)", - lv->layer_surface->current.layer, - lv->layer_surface->namespace ? lv->layer_surface->namespace : ""); -} - -static void -handle_layer_surface_unmap(struct wl_listener *listener, void *data) -{ - (void)data; - struct wl_layer_view *lv = LAYER_VIEW_FROM(listener, unmap_listener); - wwarning("wl_backend: layer surface unmapped"); - if (lv->scene_node) { - wlr_scene_node_destroy(&lv->scene_node->node); - lv->scene_node = NULL; - } -} - -static void -handle_layer_surface_destroy(struct wl_listener *listener, void *data) -{ - (void)data; - struct wl_layer_view *lv = LAYER_VIEW_FROM(listener, destroy_listener); - wl_list_remove(&lv->map_listener.link); - wl_list_remove(&lv->unmap_listener.link); - wl_list_remove(&lv->destroy_listener.link); - if (lv->scene_node) { - wlr_scene_node_destroy(&lv->scene_node->node); - lv->scene_node = NULL; - } - wl_list_remove(&lv->link); - free(lv); -} - -/* - * handle_layer_shell_new_surface — a client created a layer surface. - * Assign the output if unset, compute geometry, send configure, and - * wire map/unmap/destroy lifecycle. - */ -static void -handle_layer_shell_new_surface(struct wl_listener *listener, void *data) -{ - (void)listener; - struct wlr_layer_surface_v1 *ls = data; - - /* Assign output if client did not specify one. */ - if (!ls->output && wl_state.output) - ls->output = wl_state.output; - - struct wl_layer_view *lv = calloc(1, sizeof(*lv)); - if (!lv) { - wlr_layer_surface_v1_destroy(ls); - return; - } - lv->layer_surface = ls; - - /* Add to scene graph in the correct level bucket. - * Layer-shell layer enum maps to WL_LAYER_* buckets: - * BACKGROUND -> WL_LAYER_BACKGROUND - * BOTTOM -> WL_LAYER_DESKTOP - * TOP -> WL_LAYER_DOCK - * OVERLAY -> WL_LAYER_OVERLAY */ - if (wl_state.scene) { - int _lb; - switch (ls->pending.layer) { - case ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND: _lb = WL_LAYER_BACKGROUND; break; - case ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM: _lb = WL_LAYER_DESKTOP; break; - case ZWLR_LAYER_SHELL_V1_LAYER_TOP: _lb = WL_LAYER_DOCK; break; - case ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY: _lb = WL_LAYER_OVERLAY; break; - default: _lb = WL_LAYER_NORMAL; break; - } - struct wlr_scene_tree *_lp = wl_state.level_trees[_lb] - ? wl_state.level_trees[_lb] : &wl_state.scene->tree; - 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; - lv->destroy_listener.notify = handle_layer_surface_destroy; - wl_signal_add(&ls->surface->events.map, &lv->map_listener); - wl_signal_add(&ls->surface->events.unmap, &lv->unmap_listener); - wl_signal_add(&ls->events.destroy, &lv->destroy_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, - ls->namespace ? ls->namespace : ""); -} /* ------------------------------------------------------------------ */ /* Keyboard grabs */