Only call render_menu once per frame - 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 0947765fc9a4f6fc4287acfcd2efcaf4fef1ffb8
 (DIR) parent 260eaba88ec8f54fe2bdbe391b18fcd2db70836f
 (HTM) Author: M Stoeckl <code@mstoeckl.com>
       Date:   Thu, 31 Oct 2024 10:27:47 -0400
       
       Only call render_menu once per frame
       
       An actual surface is not needed to estimate font sizes; a 1x1 image
       will do, as long as the cairo context has the same options.
       
       Diffstat:
         M menu.c                              |       5 ++++-
         M menu.h                              |       5 +++++
         M render.c                            |       9 +++++++--
       
       3 files changed, 16 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/menu.c b/menu.c
       @@ -34,6 +34,8 @@ struct menu *menu_create(menu_callback callback) {
                menu->selectionbg = 0x005577ff;
                menu->selectionfg = 0xeeeeeeff;
                menu->callback = callback;
       +        menu->test_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
       +        menu->test_cairo = cairo_create(menu->test_surface);
                return menu;
        }
        
       @@ -58,6 +60,8 @@ static void free_items(struct menu *menu) {
        void menu_destroy(struct menu *menu) {
                free_pages(menu);
                free_items(menu);
       +        cairo_destroy(menu->test_cairo);
       +        cairo_surface_destroy(menu->test_surface);
                free(menu);
        }
        
       @@ -374,7 +378,6 @@ static void match_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);
 (DIR) diff --git a/menu.h b/menu.h
       @@ -1,6 +1,7 @@
        #ifndef WMENU_MENU_H
        #define WMENU_MENU_H
        
       +#include <cairo/cairo.h>
        #include <stdbool.h>
        #include <sys/types.h>
        #include <xkbcommon/xkbcommon.h>
       @@ -51,6 +52,10 @@ struct menu {
        
                struct wl_context *context;
        
       +        // 1x1 surface used estimate text sizes with pango
       +        cairo_surface_t *test_surface;
       +        cairo_t *test_cairo;
       +
                int width;
                int height;
                int line_height;
 (DIR) diff --git a/render.c b/render.c
       @@ -13,8 +13,13 @@
        // Calculate text widths.
        void calc_widths(struct menu *menu) {
                struct wl_context *context = menu->context;
       -        struct pool_buffer *current = context_get_current_buffer(context);
       -        cairo_t *cairo = current->cairo;
       +        int scale = context_get_scale(context);
       +        cairo_surface_set_device_scale(menu->test_surface, scale, scale);
       +        cairo_set_antialias(menu->test_cairo, CAIRO_ANTIALIAS_BEST);
       +        cairo_font_options_t *fo = cairo_font_options_create();
       +        cairo_set_font_options(menu->test_cairo, fo);
       +        cairo_font_options_destroy(fo);
       +        cairo_t *cairo = menu->test_cairo;
        
                // Calculate prompt width
                if (menu->prompt) {