178 lines
5.9 KiB
C
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;
|
|
}
|