diyac/layer.c
2024-03-30 00:18:51 +01:00

178 lines
5.9 KiB
C

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;
}