static void layer_surface_commit(struct wl_listener *listener, void *data) { struct diyac_layer_surface *layer = wl_container_of(listener, layer, surface_commit); struct wlr_layer_surface_v1 *layer_surface = layer->scene_layer_surface->layer_surface; struct wlr_output *wlr_output = layer->scene_layer_surface->layer_surface->output; if (!wlr_output) { return; } uint32_t committed = layer_surface->current.committed; struct diyac_output *output = (struct diyac_output *)wlr_output->data; /* Process layer change */ if (committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) { wlr_scene_node_reparent(&layer->scene_layer_surface->tree->node, output->layer_tree[layer_surface->current.layer]); } /* Process keyboard-interactivity change */ if (committed & WLR_LAYER_SURFACE_V1_STATE_KEYBOARD_INTERACTIVITY) { //process_keyboard_interactivity(layer); } if (committed || layer->mapped != layer_surface->surface->mapped) { layer->mapped = layer_surface->surface->mapped; //output_update_usable_area(output); /* * Update cursor focus here to ensure we * enter a new/moved/resized layer surface. */ //cursor_update_focus(layer->server); } } static void layer_surface_unmap(struct wl_listener *listener, void *data) { struct diyac_layer_surface *layer = wl_container_of(listener, layer, unmap); struct wlr_layer_surface_v1 *layer_surface = layer->scene_layer_surface->layer_surface; if (layer_surface->output) { //output_update_usable_area(layer_surface->output->data); } struct wlr_seat *seat = layer->server->seat; //if (seat->focused_layer == layer_surface) { //seat_set_focus_layer(seat, NULL); //} } static void layer_surface_map(struct wl_listener *listener, void *data) { struct diyac_layer_surface *layer = wl_container_of(listener, layer, map); struct wlr_output *wlr_output = layer->scene_layer_surface->layer_surface->output; if (wlr_output) { //output_update_usable_area(wlr_output->data); } /* * Since moving to the wlroots scene-graph API, there is no need to * call wlr_surface_send_enter() from here since that will be done * automatically based on the position of the surface and outputs in * the scene. See wlr_scene_surface_create() documentation. */ //process_keyboard_interactivity(layer); } static void layer_surface_node_destroy(struct wl_listener *listener, void *data) { struct diyac_layer_surface *layer = wl_container_of(listener, layer, node_destroy); /* * TODO: Determine if this layer is being used by an exclusive client. * If it is, try and find another layer owned by this client to pass * focus to. */ wl_list_remove(&layer->map.link); wl_list_remove(&layer->unmap.link); wl_list_remove(&layer->surface_commit.link); wl_list_remove(&layer->new_popup.link); wl_list_remove(&layer->output_destroy.link); wl_list_remove(&layer->node_destroy.link); free(layer); } static void layer_surface_output_destroy(struct wl_listener *listener, void *data) { struct diyac_layer_surface *layer = wl_container_of(listener, layer, output_destroy); layer->scene_layer_surface->layer_surface->output = NULL; wlr_layer_surface_v1_destroy(layer->scene_layer_surface->layer_surface); } /* This popup's parent is a layer popup */ static void layer_surface_new_popup(struct wl_listener *listener, void *data) { /*struct lab_layer_popup *lab_layer_popup = wl_container_of(listener, lab_layer_popup, new_popup); struct wlr_xdg_popup *wlr_popup = data; struct lab_layer_popup *new_popup = create_popup(wlr_popup, lab_layer_popup->scene_tree); new_popup->output_toplevel_sx_box = lab_layer_popup->output_toplevel_sx_box;*/ } static void server_new_layer_surface(struct wl_listener *listener, void *data) { struct diyac_server *server = wl_container_of(listener, server, new_layer_surface); struct wlr_layer_surface_v1 *layer_surface = data; if (!layer_surface->output) { struct wlr_output *output = wlr_output_layout_output_at( server->output_layout, server->seat.cursor->x, server->seat.cursor->y); if (!output) { wlr_log(WLR_INFO, "No output available to assign layer surface"); wlr_layer_surface_v1_destroy(layer_surface); return; } layer_surface->output = output; } struct diyac_layer_surface *surface = calloc(1, sizeof(*surface)); struct diyac_output *output = layer_surface->output->data; struct wlr_scene_tree *selected_layer = output->layer_tree[layer_surface->current.layer]; surface->scene_layer_surface = wlr_scene_layer_surface_v1_create( selected_layer, layer_surface); if (!surface->scene_layer_surface) { wlr_layer_surface_v1_destroy(layer_surface); wlr_log(WLR_ERROR, "could not create layer surface"); return; } //node_descriptor_create(&surface->scene_layer_surface->tree->node, // LAB_NODE_DESC_LAYER_SURFACE, surface); surface->server = server; surface->scene_layer_surface->layer_surface = layer_surface; surface->surface_commit.notify = layer_surface_commit; wl_signal_add(&layer_surface->surface->events.commit, &surface->surface_commit); surface->map.notify = layer_surface_map; wl_signal_add(&layer_surface->surface->events.map, &surface->map); surface->unmap.notify = layer_surface_unmap; wl_signal_add(&layer_surface->surface->events.unmap, &surface->unmap); surface->new_popup.notify = layer_surface_new_popup; wl_signal_add(&layer_surface->events.new_popup, &surface->new_popup); surface->output_destroy.notify = layer_surface_output_destroy; wl_signal_add(&layer_surface->output->events.destroy, &surface->output_destroy); surface->node_destroy.notify = layer_surface_node_destroy; wl_signal_add(&surface->scene_layer_surface->tree->node.events.destroy, &surface->node_destroy); /* * Temporarily set the layer's current state to pending so that * it can easily be arranged. */ //struct wlr_layer_surface_v1_state old_state = layer_surface->current; //layer_surface->current = layer_surface->pending; //output_update_usable_area(output); //layer_surface->current = old_state; }