From e4433eefc781a90e6d03914423c1dad2aaa7f0e1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 23 Jul 2024 15:29:19 +0530 Subject: [PATCH] Also allow using other image formats for window_logo_path --- docs/changelog.rst | 2 ++ kitty/options/definition.py | 2 +- kitty/window_logo.c | 19 +++++++++++++++---- kitty/window_logo.h | 5 +++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 1779d156a..0116239e3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -84,6 +84,8 @@ Detailed list of changes - Sessions: A new command ``focus_matching_window`` to shift focus to a specific window, useful when creating complex layouts with splits (:disc:`7635`) +- Speed up loading of large background images by caching the decoded image data. Also allow using images in JPEG/WEBP/TIFF/GIF/BMP formats in addition to PNG + - Wayland: Allow fractional scales less than one (:pull:`7549`) - Wayland: Fix specifying the output name for the panel kitten not working (:iss:`7573`) diff --git a/kitty/options/definition.py b/kitty/options/definition.py index e4f031098..75e9c09c1 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -1134,7 +1134,7 @@ corners from clipping text. Or use :code:`titlebar-and-corners`. opt('window_logo_path', 'none', option_type='config_or_absolute_path', ctype='!window_logo_path', long_text=''' -Path to a logo image. Must be in PNG format. Relative paths are interpreted +Path to a logo image. Must be in PNG/JPEG/WEBP/GIF/TIFF/BMP format. Relative paths are interpreted relative to the kitty config directory. The logo is displayed in a corner of every kitty window. The position is controlled by :opt:`window_logo_position`. Individual windows can be configured to have different logos either using the diff --git a/kitty/window_logo.c b/kitty/window_logo.c index 5b71c11f6..496dfb242 100644 --- a/kitty/window_logo.c +++ b/kitty/window_logo.c @@ -8,6 +8,7 @@ #include "state.h" #include "window_logo.h" +#include typedef struct WindowLogoItem { WindowLogo wl; @@ -33,19 +34,29 @@ struct WindowLogoTable { hash_by_path by_path; }; +static void +free_window_logo_bitmap(WindowLogo *wl) { + if (!wl->bitmap) return; + if (wl->mmap_size) { + if (munmap(wl->bitmap, wl->mmap_size) != 0) log_error("Failed to unmap window logo bitmap with error: %s", strerror(errno)); + } else free(wl->bitmap); + wl->bitmap = NULL; wl->mmap_size = 0; +} + static void free_window_logo(WindowLogoItem **itemref) { WindowLogoItem *item = *itemref; free(item->path); - free(item->wl.bitmap); + free_window_logo_bitmap(&item->wl); if (item->wl.texture_id) free_texture(&item->wl.texture_id); free(item); itemref = NULL; } static void send_logo_to_gpu(WindowLogo *s) { - send_image_to_gpu(&s->texture_id, s->bitmap, s->width, s->height, false, true, true, REPEAT_CLAMP); - free(s->bitmap); s->bitmap = NULL; + size_t off = s->mmap_size ? 8 : 0; + send_image_to_gpu(&s->texture_id, s->bitmap + off, s->width, s->height, false, true, true, REPEAT_CLAMP); + free_window_logo_bitmap(s); } @@ -68,7 +79,7 @@ find_or_create_window_logo(WindowLogoTable *head, const char *path, void *png_da size_t size; bool ok = false; if (png_data == NULL || !png_data_size) { - ok = png_path_to_bitmap(path, &s->wl.bitmap, &s->wl.width, &s->wl.height, &size); + ok = image_path_to_bitmap(path, &s->wl.bitmap, &s->wl.width, &s->wl.height, &s->wl.mmap_size); } else { ok = png_from_data(png_data, png_data_size, path, &s->wl.bitmap, &s->wl.width, &s->wl.height, &size); } diff --git a/kitty/window_logo.h b/kitty/window_logo.h index 0dca701cb..c8e11b7fc 100644 --- a/kitty/window_logo.h +++ b/kitty/window_logo.h @@ -6,6 +6,10 @@ #pragma once +#include +#include +#include + typedef unsigned int window_logo_id_t; typedef struct WindowLogo { @@ -13,6 +17,7 @@ typedef struct WindowLogo { bool load_from_disk_ok; uint32_t texture_id; uint8_t* bitmap; + size_t mmap_size; } WindowLogo; typedef struct WindowLogoTable WindowLogoTable;