commit e91f3ae17b8994a92566413d0a8a0c19912957e9
parent a3764b4ccd67c4e0625e42917f0cbf159a51b746
Author: Luke Willis <lukejw@loquat.dev>
Date:   Mon, 30 Mar 2026 00:37:24 -0400

Refactor a little and get a better mental grip on buffers

Diffstat:
Msrc/main.c | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 55 insertions(+), 13 deletions(-)

diff --git a/src/main.c b/src/main.c @@ -10,11 +10,21 @@ #include "wlr-layer-shell-unstable-v1-client-protocol.h" struct wig_window { + int configured; + char* label; + uint32_t width; + uint32_t height; + + struct wl_shm* shm; + + struct wl_buffer* wl_buffer; + int wl_buffer_released; + struct wl_surface* wl_surface; struct zwlr_layer_surface_v1* wlr_layer_surface; - struct wl_shm* shm; + uint32_t* data; }; struct wig_state { @@ -33,30 +43,35 @@ struct wig_state { */ static void wl_buffer_release(void* data, struct wl_buffer* wl_buffer) { - wl_buffer_destroy(wl_buffer); + struct wig_window* window = data; + window->wl_buffer_released = 1; } static const struct wl_buffer_listener wl_buffer_listener = { .release = wl_buffer_release, }; -static struct wl_buffer* draw_frame(struct wig_window* state, int width, - int height) { +int reconfigure_window(struct wig_window* window, int width, int height) { + if (window->data != NULL) { + wl_buffer_destroy(window->wl_buffer); + munmap(window->data, window->width * window->height * 4); + } + int stride = width * 4; int size = stride * height; int fd = allocate_shm_file(size); if (fd == -1) { - return NULL; + return 0; } uint32_t* data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { close(fd); - return NULL; + return 0; } - struct wl_shm_pool* pool = wl_shm_create_pool(state->shm, fd, size); + struct wl_shm_pool* pool = wl_shm_create_pool(window->shm, fd, size); struct wl_buffer* buffer = wl_shm_pool_create_buffer( pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); @@ -71,10 +86,13 @@ static struct wl_buffer* draw_frame(struct wig_window* state, int width, data[y * width + x] = 0xFFEEEEEE; } } + wl_buffer_add_listener(buffer, &wl_buffer_listener, window); + + window->data = data; + window->wl_buffer = buffer; + window->configured = 1; - munmap(data, size); - wl_buffer_add_listener(buffer, &wl_buffer_listener, NULL); - return buffer; + return 0; } /* @@ -87,9 +105,22 @@ static void zwlr_layer_surface_configure( struct wig_window* window = data; zwlr_layer_surface_v1_ack_configure(zwlr_layer_surface_v1, serial); - struct wl_buffer* buffer = draw_frame(window, width, height); - wl_surface_attach(window->wl_surface, buffer, 0, 0); + /* Skip reconfiguration if the size hasn't changed */ + if (width == window->width && height == window->height) return; + + int result = reconfigure_window(window, width, height); + + if (result) { + fprintf(stderr, "Failed to reconfigure \"%s\"", window->label); + return; + } + + wl_surface_attach(window->wl_surface, window->wl_buffer, 0, 0); wl_surface_commit(window->wl_surface); + window->wl_buffer_released = 0; + + window->width = width; + window->height = height; fprintf(stderr, "\"%s\" reconfigured\n", window->label); fprintf(stderr, " %u x %u\n", width, height); @@ -179,8 +210,12 @@ static void inner_main(void* data, int argc, char** argv) { struct wig_window* window = &state->windows[i]; window->label = label; + window->width = width; + window->height = height; + window->shm = state->shm; + window->data = NULL; window->wl_surface = wl_compositor_create_surface(state->compositor); window->wlr_layer_surface = zwlr_layer_shell_v1_get_layer_surface( state->layer_shell, window->wl_surface, NULL, @@ -212,7 +247,14 @@ static void inner_main(void* data, int argc, char** argv) { /* Loop */ while (wl_display_dispatch(state->display) != -1) { - /* TODO */ + for (size_t i = 0; i < num_windows; i++) { + state->windows[i].data[1] = 0xFFFF00FF; + + wl_surface_attach(state->windows[i].wl_surface, + state->windows[i].wl_buffer, 0, 0); + wl_surface_damage_buffer(state->windows[i].wl_surface, 1, 0, 1, 1); + wl_surface_commit(state->windows[i].wl_surface); + } } /* Cleanup */