Fix destruction of pool buffers - wmenu - 🔧 fork of wmenu
 (HTM) git clone git@git.drkhsh.at/wmenu.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 1f221a73cf290ff509ef6c066ff692bb48f8625e
 (DIR) parent 6284eea24b44d05260f96fe842fa9dd752185942
 (HTM) Author: adnano <me@adnano.co>
       Date:   Thu,  2 May 2024 18:45:49 -0400
       
       Fix destruction of pool buffers
       
       Diffstat:
         M main.c                              |       6 +++++-
         M menu.c                              |      10 +++++-----
         M menu.h                              |      10 ++++------
         M render.c                            |      14 ++++++++------
         M wayland.c                           |      24 ++++++++++++++++--------
         M wayland.h                           |       3 ++-
       
       6 files changed, 40 insertions(+), 27 deletions(-)
       ---
 (DIR) diff --git a/main.c b/main.c
       @@ -1,5 +1,7 @@
        #define _POSIX_C_SOURCE 200809L
        
       +#include <string.h>
       +
        #include "menu.h"
        #include "wayland.h"
        
       @@ -20,5 +22,7 @@ int main(int argc, char *argv[]) {
                if (!menu->passwd) {
                        read_items(menu);
                }
       -        return menu_run(menu);
       +        int status = menu_run(menu);
       +        menu_destroy(menu);
       +        return status;
        }
 (DIR) diff --git a/menu.c b/menu.c
       @@ -320,10 +320,12 @@ static void match_items(struct menu *menu) {
                }
        }
        
       -// Process menu items.
       -void menu_process_items(struct menu *menu) {
       +// Render menu items.
       +void menu_render_items(struct menu *menu) {
       +        render_menu(menu);
                calc_widths(menu);
                match_items(menu);
       +        render_menu(menu);
        }
        
        static void insert(struct menu *menu, const char *text, ssize_t len) {
       @@ -659,7 +661,5 @@ static void free_items(struct menu *menu) {
        void menu_destroy(struct menu *menu) {
                free_pages(menu);
                free_items(menu);
       -
       -        destroy_buffer(&menu->buffers[0]);
       -        destroy_buffer(&menu->buffers[1]);
       +        free(menu);
        }
 (DIR) diff --git a/menu.h b/menu.h
       @@ -1,9 +1,10 @@
        #ifndef WMENU_MENU_H
        #define WMENU_MENU_H
        
       +#include <stdbool.h>
       +#include <sys/types.h>
        #include <xkbcommon/xkbcommon.h>
       -
       -#include "pool-buffer.h"
       +#include <wayland-client.h>
        
        // A menu item.
        struct item {
       @@ -48,9 +49,6 @@ struct menu {
        
                struct wl_context *context;
        
       -        struct pool_buffer buffers[2];
       -        struct pool_buffer *current;
       -
                int width;
                int height;
                int line_height;
       @@ -77,7 +75,7 @@ struct menu {
        struct menu *menu_create();
        void menu_getopts(struct menu *menu, int argc, char *argv[]);
        void menu_add_item(struct menu *menu, char *text);
       -void menu_process_items(struct menu *menu);
       +void menu_render_items(struct menu *menu);
        void menu_paste(struct menu *menu, const char *text, ssize_t len);
        void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
                        xkb_keysym_t sym);
 (DIR) diff --git a/render.c b/render.c
       @@ -7,11 +7,14 @@
        
        #include "menu.h"
        #include "pango.h"
       +#include "pool-buffer.h"
        #include "wayland.h"
        
        // Calculate text widths.
        void calc_widths(struct menu *menu) {
       -        cairo_t *cairo = menu->current->cairo;
       +        struct wl_context *context = menu->context;
       +        struct pool_buffer *current = context_get_current_buffer(context);
       +        cairo_t *cairo = current->cairo;
        
                // Calculate prompt width
                if (menu->prompt) {
       @@ -195,13 +198,12 @@ void render_menu(struct menu *menu) {
                render_to_cairo(menu, cairo);
        
                int scale = context_get_scale(context);
       -        menu->current = get_next_buffer(context_get_shm(context),
       -                menu->buffers, menu->width, menu->height, scale);
       -        if (!menu->current) {
       +        struct pool_buffer *buffer = context_get_next_buffer(context, scale);
       +        if (!buffer) {
                        goto cleanup;
                }
        
       -        cairo_t *shm = menu->current->cairo;
       +        cairo_t *shm = buffer->cairo;
                cairo_save(shm);
                cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR);
                cairo_paint(shm);
       @@ -211,7 +213,7 @@ void render_menu(struct menu *menu) {
        
                struct wl_surface *surface = context_get_surface(context);
                wl_surface_set_buffer_scale(surface, scale);
       -        wl_surface_attach(surface, menu->current->buffer, 0, 0);
       +        wl_surface_attach(surface, buffer->buffer, 0, 0);
                wl_surface_damage(surface, 0, 0, menu->width, menu->height);
                wl_surface_commit(surface);
        
 (DIR) diff --git a/wayland.c b/wayland.c
       @@ -17,7 +17,7 @@
        #include <xkbcommon/xkbcommon.h>
        
        #include "menu.h"
       -#include "render.h"
       +#include "pool-buffer.h"
        #include "wayland.h"
        #include "xdg-activation-v1-client-protocol.h"
        #include "wlr-layer-shell-unstable-v1-client-protocol.h"
       @@ -96,6 +96,9 @@ struct wl_context {
                struct zwlr_layer_surface_v1 *layer_surface;
                struct wl_data_offer *data_offer;
                struct output *output;
       +
       +        struct pool_buffer buffers[2];
       +        struct pool_buffer *current;
        };
        
        // Returns the current output_scale.
       @@ -103,9 +106,16 @@ int context_get_scale(struct wl_context *context) {
                return context->output ? context->output->scale : 1;
        }
        
       -// Returns the shared memory for the context.
       -struct wl_shm *context_get_shm(struct wl_context *context) {
       -        return context->shm;
       +// Returns the current buffer from the pool.
       +struct pool_buffer *context_get_current_buffer(struct wl_context *context) {
       +        return context->current;
       +}
       +
       +// Returns the next buffer from the pool.
       +struct pool_buffer *context_get_next_buffer(struct wl_context *context, int scale) {
       +        struct menu *menu = context->menu;
       +        context->current = get_next_buffer(context->shm, context->buffers, menu->width, menu->height, scale);
       +        return context->current;
        }
        
        // Returns the Wayland surface for the context.
       @@ -446,9 +456,7 @@ int menu_run(struct menu *menu) {
        
                wl_surface_commit(context->surface);
                wl_display_roundtrip(context->display);
       -        render_menu(menu);
       -        menu_process_items(menu);
       -        render_menu(menu);
       +        menu_render_items(menu);
        
                struct pollfd fds[] = {
                        { wl_display_get_fd(context->display), POLLIN },
       @@ -482,8 +490,8 @@ int menu_run(struct menu *menu) {
                }
        
                bool failure = menu->failure;
       -        menu_destroy(menu);
                context_destroy(context);
       +        menu->context = NULL;
        
                if (failure) {
                        return EXIT_FAILURE;
 (DIR) diff --git a/wayland.h b/wayland.h
       @@ -9,7 +9,8 @@ struct wl_context;
        int menu_run(struct menu *menu);
        
        int context_get_scale(struct wl_context *context);
       -struct wl_shm *context_get_shm(struct wl_context *context);
       +struct pool_buffer *context_get_current_buffer(struct wl_context *context);
       +struct pool_buffer *context_get_next_buffer(struct wl_context *context, int scale);
        struct wl_surface *context_get_surface(struct wl_context *context);
        struct xkb_state *context_get_xkb_state(struct wl_context *context);
        bool context_paste(struct wl_context *context);