Skip to content

Commit

Permalink
layer_shell: Implement handle_layer_shell_v1_surface_new
Browse files Browse the repository at this point in the history
  • Loading branch information
OctopusET committed Aug 18, 2024
1 parent 5a72543 commit d202b65
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 1 deletion.
71 changes: 70 additions & 1 deletion layer_shell_v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,90 @@
*/

#include "layer_shell_v1.h"
#include "output.h"
#include "server.h"

#include <assert.h>
#include <complex.h>
#include <wayland-server-core.h>
#include <wayland-util.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/util/log.h>

static struct wlr_scene_tree *
cg_layer_get_scene(struct cg_output *output, enum zwlr_layer_shell_v1_layer layer_type)
{
assert(layer_type <= NUM_LAYERS);
switch (layer_type) {
case ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND:
return output->layers.shell_background;
case ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM:
return output->layers.shell_bottom;
case ZWLR_LAYER_SHELL_V1_LAYER_TOP:
return output->layers.shell_top;
case ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY:
return output->layers.shell_overlay;
}
return NULL;
}

void
handle_layer_shell_v1_surface_new(struct wl_listener *listener, void *data)
{
struct cg_server *server = wl_container_of(listener, server, new_layer_shell_v1_surface);
struct cg_seat *seat = server->seat;
struct wlr_layer_surface_v1 *layer_surface = data;

wlr_log(WLR_DEBUG, "New layer shell surface: namespace %s layer %d anchor %d size %dx%d margin %d,%d,%d,%d",
wlr_log(WLR_DEBUG,
"New layer shell surface: namespace %s layer %d anchor %" PRIu32 " size %" PRIu32 "x%" PRIu32
" margin %" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",",
layer_surface->namespace, layer_surface->pending.layer, layer_surface->pending.anchor,
layer_surface->pending.desired_width, layer_surface->pending.desired_height,
layer_surface->pending.margin.top, layer_surface->pending.margin.right,
layer_surface->pending.margin.bottom, layer_surface->pending.margin.left);

if (layer_surface->output) {
struct wlr_output *wlr_output =
wlr_output_layout_output_at(server->output_layout, seat->cursor->x, seat->cursor->y);
if (wlr_output) {
layer_surface->output = wlr_output;
} else {
struct cg_output *output = wl_container_of(server->outputs.prev, output, link);
layer_surface->output = output->wlr_output;
}
}
struct cg_output *output = layer_surface->output->data;

enum zwlr_layer_shell_v1_layer layer_type = layer_surface->pending.layer;
struct wlr_scene_tree *output_layer = cg_layer_get_scene(output, layer_type);

struct cg_layer_surface *cg_surface = calloc(1, sizeof(*cg_surface));
if (!cg_surface) {
wlr_layer_surface_v1_destroy(layer_surface);
wlr_log(WLR_ERROR, "Failed to allocate layer shell");
return;
}

struct wlr_scene_layer_surface_v1 *scene = wlr_scene_layer_surface_v1_create(output_layer, layer_surface);
if (!scene) {
wlr_log(WLR_ERROR, "Could not allocate a layer_surface_v1");
return;
}

cg_surface->server = server;
cg_surface->layer_surface = scene->layer_surface;
cg_surface->scene = scene;
cg_surface->tree = scene->tree;
cg_surface->layer_surface->data = cg_surface;
cg_surface->output = output;

cg_surface->map.notify = handle_map;
wl_signal_add(&layer_surface->surface->events.map, &cg_surface->map);
cg_surface->unmap.notify = handle_unmap;
wl_signal_add(&layer_surface->surface->events.unmap, &cg_surface->unmap);
cg_surface->surface_commit.notify = handle_surface_commit;
wl_signal_add(&layer_surface->surface->events.commit, &cg_surface->surface_commit);

cg_surface->output_destroy.notify = handle_output_destroy;
wl_signal_add(&output->events.disable, &surface->output_destroy);
}
19 changes: 19 additions & 0 deletions layer_shell_v1.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,26 @@
#define CG_LAYER_SHELL_V1_H

#include <wayland-server-core.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_scene.h>

void handle_layer_shell_v1_surface_new(struct wl_listener *listener, void *data);

struct cg_layer_surface {
struct cg_server *server;
struct wl_list link; // cg_output::layers

struct wl_listener map;
struct wl_listener unmap;
struct wl_listener surface_commit;
// struct wl_listener destroy;

struct wl_listener output_destroy;

struct cg_output *output;
struct wlr_scene_tree *tree;
struct wlr_scene_layer_surface_v1 *scene;
struct wlr_layer_surface_v1 *layer_surface;
};

#endif
22 changes: 22 additions & 0 deletions output.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ output_destroy(struct cg_output *output)
wl_list_remove(&output->frame.link);
wl_list_remove(&output->link);

wlr_scene_node_destroy(&output->layers.shell_background->node);
wlr_scene_node_destroy(&output->layers.shell_bottom->node);
wlr_scene_node_destroy(&output->layers.shell_top->node);
wlr_scene_node_destroy(&output->layers.shell_overlay->node);

output_layout_remove(output);

free(output);
Expand All @@ -255,6 +260,18 @@ handle_output_destroy(struct wl_listener *listener, void *data)
output_destroy(output);
}

static struct wlr_scene_tree *
create_layer_for_output(struct cg_output *output)
{
struct cg_server *server = output->server;
struct wlr_scene_tree *layer = wlr_scene_tree_create(&server->scene->tree);
if (layer == NULL) {
return NULL;
}
layer->node.data = output->wlr_output;
return layer;
}

void
handle_new_output(struct wl_listener *listener, void *data)
{
Expand Down Expand Up @@ -320,6 +337,11 @@ handle_new_output(struct wl_listener *listener, void *data)
output_disable(next);
}

output->layers.shell_background = create_layer_for_output(output);
output->layers.shell_bottom = create_layer_for_output(output);
output->layers.shell_top = create_layer_for_output(output);
output->layers.shell_overlay = create_layer_for_output(output);

if (!wlr_xcursor_manager_load(server->seat->xcursor_manager, wlr_output->scale)) {
wlr_log(WLR_ERROR, "Cannot load XCursor theme for output '%s' with scale %f", wlr_output->name,
wlr_output->scale);
Expand Down
9 changes: 9 additions & 0 deletions output.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ struct cg_output {
struct wl_listener destroy;
struct wl_listener frame;

struct {
struct wlr_scene_tree *shell_background;
struct wlr_scene_tree *shell_bottom;
struct wlr_scene_tree *shell_top;
struct wlr_scene_tree *shell_overlay;
} layers;

struct wlr_box usable_area;

struct wl_list link; // cg_server::outputs
};

Expand Down

0 comments on commit d202b65

Please sign in to comment.