From ace849747817af24c6c94717223d5e2d5bf4d87f Mon Sep 17 00:00:00 2001 From: Rakarake Date: Sun, 22 Feb 2026 17:56:44 +0100 Subject: [PATCH] creating layers after output name event works --- wayland.c | 186 ++++++++++++++++++++++++++---------------------------- 1 file changed, 91 insertions(+), 95 deletions(-) diff --git a/wayland.c b/wayland.c index 0fb2750..4fe4c7e 100644 --- a/wayland.c +++ b/wayland.c @@ -162,8 +162,99 @@ void egl_init_surface(struct client_state *state, struct surface *surface) { } } +static const struct wl_callback_listener wl_surface_frame_listener; + +static void +wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) { + struct surface *surface = data; + surface->time = time; + + /* Destroy this callback */ + wl_callback_destroy(cb); + + surface->dirty = true; +} + +static const struct wl_callback_listener wl_surface_frame_listener = { + .done = wl_surface_frame_done, +}; + +static void zwlr_layer_surface_v1_configure(void *data, struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial, uint32_t width, uint32_t height) { + struct client_state *state = data; + struct surface_list *next = state->surface_list; + while (next->data.zwlr_layer_surface_v1 != zwlr_layer_surface_v1) { next = next->next; } + next->data.width = width; + next->data.height = height; + wl_egl_window_resize(next->data.egl_window, width, height, 0, 0); + zwlr_layer_surface_v1_ack_configure(zwlr_layer_surface_v1, serial); + // draw new frame! + next->data.dirty = true; +} + +static void zwlr_layer_surface_v1_closed(void *data, struct zwlr_layer_surface_v1 * zwlr_layer_surface_v1) { + struct client_state *state = data; + state->running = 0; +} + +static const struct zwlr_layer_surface_v1_listener zwlr_layer_surface_v1_listener = { + .configure = zwlr_layer_surface_v1_configure, + .closed = zwlr_layer_surface_v1_closed, +}; + +void layer_new(struct client_state *state, struct wl_output *wl_output) { + struct wl_surface *wl_surface = wl_compositor_create_surface(state->wl_compositor); + + // wlr_layer_shell + int layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; + struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1 = + zwlr_layer_shell_v1_get_layer_surface( + state->zwlr_layer_shell_v1, + wl_surface, + wl_output, + layer, + "wallpaper" + ); + zwlr_layer_surface_v1_set_anchor(zwlr_layer_surface_v1, + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP + | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); + zwlr_layer_surface_v1_set_size(zwlr_layer_surface_v1, 0, 0); + zwlr_layer_surface_v1_add_listener(zwlr_layer_surface_v1, &zwlr_layer_surface_v1_listener, state); + + struct surface surface = { + .wl_surface = wl_surface, + .zwlr_layer_surface_v1 = zwlr_layer_surface_v1, + .dirty = false, + .width = DEFAULT_WIDTH, + .height = DEFAULT_HEIGHT, + }; + // persistent pointer for the callback + struct surface *surface_location; + if (state->surface_list == NULL) { + state->surface_list = malloc(sizeof(struct surface_list)); + state->surface_list->data = surface; + state->surface_list->next = NULL; + surface_location = &state->surface_list->data; + } else { + struct surface_list *next = state->surface_list; + while (next->next != NULL) { next = next->next; } + next->next = malloc(sizeof(struct surface_list)); + next->next->data = surface; + next->next->next = NULL; + surface_location = &next->next->data; + } + + // frame callback + struct wl_callback *cb = wl_surface_frame(wl_surface); + wl_callback_add_listener(cb, &wl_surface_frame_listener, surface_location); + egl_init_surface(state, surface_location); + wl_surface_commit(wl_surface); +} + + static void wl_output_name(void *data, struct wl_output *wl_output, const char *name) { + struct client_state *state = data; printf("output name: %s\n", name); + layer_new(state, wl_output); } static void wl_output_description(void *data, struct wl_output *wl_output, const char *description) { @@ -260,45 +351,6 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = { .wm_capabilities = xdg_toplevel_wm_capabilities, }; -static void zwlr_layer_surface_v1_configure(void *data, struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial, uint32_t width, uint32_t height) { - struct client_state *state = data; - struct surface_list *next = state->surface_list; - while (next->data.zwlr_layer_surface_v1 != zwlr_layer_surface_v1) { next = next->next; } - next->data.width = width; - next->data.height = height; - wl_egl_window_resize(next->data.egl_window, width, height, 0, 0); - zwlr_layer_surface_v1_ack_configure(zwlr_layer_surface_v1, serial); - // draw new frame! - next->data.dirty = true; -} - -static void zwlr_layer_surface_v1_closed(void *data, struct zwlr_layer_surface_v1 * zwlr_layer_surface_v1) { - struct client_state *state = data; - state->running = 0; -} - -static const struct zwlr_layer_surface_v1_listener zwlr_layer_surface_v1_listener = { - .configure = zwlr_layer_surface_v1_configure, - .closed = zwlr_layer_surface_v1_closed, -}; - -static const struct wl_callback_listener wl_surface_frame_listener; - -static void -wl_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time) { - struct surface *surface = data; - surface->time = time; - - /* Destroy this callback */ - wl_callback_destroy(cb); - - surface->dirty = true; -} - -static const struct wl_callback_listener wl_surface_frame_listener = { - .done = wl_surface_frame_done, -}; - void pointer_enter_handler ( void *data, struct wl_pointer *pointer, @@ -385,55 +437,6 @@ void xdg_tolevel_new(struct client_state *state) { wl_surface_commit(wl_surface); } -void layer_new(struct client_state *state, struct wl_output *wl_output) { - struct wl_surface *wl_surface = wl_compositor_create_surface(state->wl_compositor); - - // wlr_layer_shell - int layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; - struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1 = - zwlr_layer_shell_v1_get_layer_surface( - state->zwlr_layer_shell_v1, - wl_surface, - wl_output, - layer, - "wallpaper" - ); - zwlr_layer_surface_v1_set_anchor(zwlr_layer_surface_v1, - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP - | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); - zwlr_layer_surface_v1_set_size(zwlr_layer_surface_v1, 0, 0); - zwlr_layer_surface_v1_add_listener(zwlr_layer_surface_v1, &zwlr_layer_surface_v1_listener, state); - - struct surface surface = { - .wl_surface = wl_surface, - .zwlr_layer_surface_v1 = zwlr_layer_surface_v1, - .dirty = false, - .width = DEFAULT_WIDTH, - .height = DEFAULT_HEIGHT, - }; - // persistent pointer for the callback - struct surface *surface_location; - if (state->surface_list == NULL) { - state->surface_list = malloc(sizeof(struct surface_list)); - state->surface_list->data = surface; - state->surface_list->next = NULL; - surface_location = &state->surface_list->data; - } else { - struct surface_list *next = state->surface_list; - while (next->next != NULL) { next = next->next; } - next->next = malloc(sizeof(struct surface_list)); - next->next->data = surface; - next->next->next = NULL; - surface_location = &next->next->data; - } - - // frame callback - struct wl_callback *cb = wl_surface_frame(wl_surface); - wl_callback_add_listener(cb, &wl_surface_frame_listener, surface_location); - egl_init_surface(state, surface_location); - wl_surface_commit(wl_surface); -} - static void registry_handle_global( void *data, struct wl_registry *registry, @@ -487,7 +490,6 @@ static void registry_handle_global( struct wl_output *wl_output = wl_registry_bind( registry, name, &wl_output_interface, 4); wl_output_add_listener(wl_output, &wl_output_listener, state); - layer_new(state, wl_output); } } @@ -519,12 +521,6 @@ struct client_state* wayland_init(int output_type) { wl_seat_get_pointer(state->wl_seat); - //struct surface_list *next = state->surface_list; - //while (next != NULL) { - // wl_surface_commit(next->data.wl_surface); - // next = next->next; - //} - if (state->output_type == OUTPUT_WINDOW) { xdg_tolevel_new(state); }