From deb1e6a2083609a24a8030f5c09877ccdfe27339 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Tue, 20 Oct 2020 20:38:13 +0200 Subject: [RofiIconFetcher] Switch to gdk-pixbuf. --- INSTALL.md | 4 +- Makefile.am | 13 +- configure.ac | 35 +--- meson.build | 4 +- source/helper.c | 45 ------ source/rofi-icon-fetcher.c | 395 +++++++++++++++++---------------------------- source/xcb.c | 1 - 7 files changed, 159 insertions(+), 338 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index c4332ced..6c358490 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -31,17 +31,15 @@ You can also use [Meson](https://mesonbuild.com/) as an alternative. * libglib2.0 >= 2.40 * gmodule-2.0 * gio-unix-2.0 -* librsvg2.0 +* libgdk-pixbuf-2.0 * libstartup-notification-1.0 * libxkbcommon >= 0.4.1 * libxkbcommon-x11 -* libjpeg * libxcb (sometimes split, you need libxcb, libxcb-xkb and libxcb-randr libxcb-xinerama) * xcb-util * xcb-util-wm (sometimes split as libxcb-ewmh and libxcb-icccm) * xcb-util-xrm [new module might not be available in your distribution. The source can be found here](https://github.com/Airblader/xcb-util-xrm/) -* libgif (optional) On debian based systems, the developer packages are in the form of: `-dev` on rpm based `-devel`. diff --git a/Makefile.am b/Makefile.am index d979dba8..72d32534 100644 --- a/Makefile.am +++ b/Makefile.am @@ -145,7 +145,7 @@ rofi_CFLAGS=\ $(pango_CFLAGS)\ $(libsn_CFLAGS)\ $(cairo_CFLAGS)\ - $(librsvg_CFLAGS)\ + $(gdkpixbuf_CFLAGS)\ -DMANPAGE_PATH="\"$(mandir)/\""\ -I$(top_srcdir)/include/\ -I$(top_builddir)/lexer/\ @@ -166,9 +166,7 @@ rofi_LDADD=\ $(libsn_LIBS)\ $(pango_LIBS)\ $(cairo_LIBS)\ - $(librsvg_LIBS)\ - $(libjpeg_LIBS)\ - $(libgif_LIBS)\ + $(gdkpixbuf_LIBS)\ $(LIBS) ## @@ -326,8 +324,7 @@ textbox_test_CFLAGS=\ $(GW_XCB_CFLAGS)\ $(cairo_CFLAGS)\ $(libsn_CFLAGS)\ - $(librsvg_CFLAGS)\ - $(libjpeg_CFLAGS)\ + $(gdkpixbuf_CFLAGS)\ -DPLUGIN_PATH=\"${libdir}/rofi\"\ -DTHEME_DIR=\"$(themedir)\"\ -I$(top_srcdir)/include/\ @@ -342,7 +339,6 @@ textbox_test_LDADD=\ $(NKUTILS_LIBS)\ $(GW_XCB_LIBS)\ $(cairo_LIBS)\ - $(librsvg_LIBS)\ $(libsn_LIBS) helper_pidfile_CFLAGS=$(textbox_test_CFLAGS) @@ -479,7 +475,7 @@ helper_test_CFLAGS=\ $(NKUTILS_CFLAGS)\ $(GW_XCB_CFLAGS)\ $(cairo_CFLAGS)\ - $(librsvg_CFLAGS)\ + $(gdkpixbuf_CFLAGS)\ $(libsn_CFLAGS)\ -DPLUGIN_PATH=\"${libdir}/rofi\"\ -DTHEME_DIR=\"$(themedir)\"\ @@ -495,7 +491,6 @@ helper_test_LDADD=\ $(NKUTILS_LIBS)\ $(GW_XCB_LIBS)\ $(libsn_LIBS)\ - $(librsvg_LIBS)\ $(cairo_LIBS) diff --git a/configure.ac b/configure.ac index bb9ac057..ad64dec9 100644 --- a/configure.ac +++ b/configure.ac @@ -148,8 +148,7 @@ GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11 xcb-ewmh xcb-icccm xcb-xrm PKG_CHECK_MODULES([pango], [pango pangocairo]) PKG_CHECK_MODULES([cairo], [cairo cairo-xcb]) PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0 ]) -PKG_CHECK_MODULES([librsvg], [librsvg-2.0 ]) -PKG_CHECK_MODULES([libjpeg], [libjpeg]) +PKG_CHECK_MODULES([gdkpixbuf], [gdk-pixbuf-2.0]) dnl --------------------------------------------------------------------- dnl check - Unit testing. @@ -165,38 +164,6 @@ dnl Gets the resource compile tool path. dnl --------------------------------------------------------------------- AM_PATH_GLIB_2_0 -dnl Test for libgif or libungif -AC_ARG_WITH([libgif], - AS_HELP_STRING([--with-libgif=PREFIX], - [Prefix where libgif is installed, or 'no' to disable]), - [libgif_prefix="$withval"], [libgif_prefix="${prefix}"]) - - if test x$with_libgif != xno && test -z "$libgif_LIBS"; then - GIF_CFLAGS="-I${libgif_prefix}/include" - GIF_LIBS="-L${libgif_prefix}/lib" - save_cflags=$CFLAGS; CFLAGS=$GIF_CFLAGS - save_libs=$LIBS; LIBS=$GIF_LIBS - AC_CHECK_LIB(gif, DGifOpenFileName, - [AC_CHECK_HEADER(gif_lib.h, - GIF='gif'; libgif_LIBS='-lgif'; gif_ok=yes, - AC_MSG_WARN(*** GIF loader will not be built (giflibrary not found) ***))], - AC_MSG_WARN(*** GIF loader will not be built (giflibrary not found) ***)) - - AC_CHECK_LIB(ungif, DGifOpenFileName, - [AC_CHECK_HEADER(gif_lib.h, - GIF='ungif'; libgif_LIBS='-lungif'; gif_ok=yes, - AC_MSG_WARN(*** GIF loader will not be built (ungiflibrary not found) ***))], - AC_MSG_WARN(*** GIF loader will not be built (ungiflibrary not found) ***)) - CFLAGS+=$save_cflags - LIBS+=$save_libs - fi - -if test x$GIF != x; then - AC_SUBST(libgif_LIBS) - AC_DEFINE(HAVE_LIBGIF, 1, Define if gif support is available) -else - gif_ok="no (See http://sourceforge.net/projects/libgif)" -fi dnl --------------------------------------------------------------------- dnl Add extra compiler flags dnl --------------------------------------------------------------------- diff --git a/meson.build b/meson.build index 09335107..d4419988 100644 --- a/meson.build +++ b/meson.build @@ -47,9 +47,7 @@ deps = [ dependency('pango'), dependency('pangocairo'), dependency('xkbcommon'), - dependency('librsvg-2.0'), - dependency('libjpeg'), - c_compiler.find_library('m', required: false), + dependency('gdk-pixbuf-2.0'), ] diff --git a/source/helper.c b/source/helper.c index 0a5e86ca..33e94d25 100644 --- a/source/helper.c +++ b/source/helper.c @@ -47,7 +47,6 @@ #include #include #include -#include #include "display.h" #include "xcb.h" #include "helper.h" @@ -1137,50 +1136,6 @@ char *helper_get_theme_path ( const char *file ) return filename; } -cairo_surface_t* cairo_image_surface_create_from_svg ( const gchar* file, int height ) -{ - GError *error = NULL; - cairo_surface_t *surface = NULL; - RsvgHandle * handle; - - handle = rsvg_handle_new_from_file ( file, &error ); - if ( G_LIKELY ( handle != NULL ) ) { - RsvgDimensionData dimensions; - // Update DPI. - rsvg_handle_set_dpi ( handle, config.dpi ); - // Get size. - rsvg_handle_get_dimensions ( handle, &dimensions ); - // Create cairo surface in the right size. - double scale = (double) height / dimensions.height; - surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, - (double) dimensions.width * scale, - (double) dimensions.height * scale ); - gboolean failed = cairo_surface_status ( surface ) != CAIRO_STATUS_SUCCESS; - if ( G_LIKELY ( failed == FALSE ) ) { - cairo_t *cr = cairo_create ( surface ); - cairo_scale ( cr, scale, scale ); - failed = rsvg_handle_render_cairo ( handle, cr ) == FALSE; - cairo_destroy ( cr ); - } - - rsvg_handle_close ( handle, &error ); - g_object_unref ( handle ); - - /** Rendering fails */ - if ( G_UNLIKELY ( failed ) ) { - g_warning ( "Failed to render file: '%s'", file ); - cairo_surface_destroy ( surface ); - surface = NULL; - } - } - if ( G_UNLIKELY ( error != NULL ) ) { - g_warning ( "Failed to render SVG file: '%s': %s", file, error->message ); - g_error_free ( error ); - } - - return surface; -} - static void parse_pair ( char *input, rofi_range_pair *item ) { // Skip leading blanks. diff --git a/source/rofi-icon-fetcher.c b/source/rofi-icon-fetcher.c index 2f0630e0..5f5d004a 100644 --- a/source/rofi-icon-fetcher.c +++ b/source/rofi-icon-fetcher.c @@ -44,9 +44,8 @@ #include "nkutils-enum.h" #include -#include -#include +#include typedef struct { @@ -58,6 +57,8 @@ typedef struct // On uid. GHashTable *icon_cache_uid; + // list extensions + GList *supported_extensions; uint32_t last_uid; } IconFetcher; @@ -87,6 +88,7 @@ typedef struct */ IconFetcher *rofi_icon_fetcher_data = NULL; + static void rofi_icon_fetch_entry_free ( gpointer data ) { IconFetcherNameEntry *entry = (IconFetcherNameEntry *) data; @@ -123,6 +125,22 @@ void rofi_icon_fetcher_init ( void ) rofi_icon_fetcher_data->icon_cache_uid = g_hash_table_new ( g_direct_hash, g_direct_equal ); rofi_icon_fetcher_data->icon_cache = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, rofi_icon_fetch_entry_free ); + + + GSList *l = gdk_pixbuf_get_formats(); + for ( GSList *li = l; li != NULL; li = g_slist_next(li)) + { + gchar **exts = gdk_pixbuf_format_get_extensions ( (GdkPixbufFormat *)li->data ); + + for ( unsigned int i = 0; exts && exts[i]; i ++ ) { + rofi_icon_fetcher_data->supported_extensions = g_list_append ( rofi_icon_fetcher_data->supported_extensions, exts[i]); + exts[i] = NULL; + } + + g_free ( exts ); + + } + } void rofi_icon_fetcher_destroy ( void ) @@ -136,180 +154,106 @@ void rofi_icon_fetcher_destroy ( void ) g_hash_table_unref ( rofi_icon_fetcher_data->icon_cache_uid ); g_hash_table_unref ( rofi_icon_fetcher_data->icon_cache ); + + g_list_foreach ( rofi_icon_fetcher_data->supported_extensions, (GFunc)g_free, NULL ); + g_list_free ( rofi_icon_fetcher_data->supported_extensions ); g_free ( rofi_icon_fetcher_data ); } -static cairo_surface_t* cairo_image_surface_create_from_jpeg_private ( struct jpeg_decompress_struct* cinfo ) -{ - cairo_surface_t* surface = 0; - unsigned char * data = 0; - unsigned char * rgb = 0; - - jpeg_read_header ( cinfo, TRUE ); - jpeg_start_decompress ( cinfo ); - - surface = cairo_image_surface_create ( CAIRO_FORMAT_RGB24, cinfo->image_width, cinfo->image_height ); - data = cairo_image_surface_get_data ( surface ); - rgb = (unsigned char *) ( malloc ( cinfo->output_width * cinfo->output_components ) ); - - while ( cinfo->output_scanline < cinfo->output_height ) { - unsigned int i; - int scanline = cinfo->output_scanline * cairo_image_surface_get_stride ( surface ); - - jpeg_read_scanlines ( cinfo, &rgb, 1 ); - - for ( i = 0; i < cinfo->output_width; i++ ) { - int offset = scanline + ( i * 4 ); - - data[offset + 3] = 255; - data[offset + 2] = rgb[( i * 3 )]; - data[offset + 1] = rgb[( i * 3 ) + 1]; - data[offset ] = rgb[( i * 3 ) + 2]; - } - } - - free ( rgb ); - - jpeg_finish_decompress ( cinfo ); - jpeg_destroy_decompress ( cinfo ); - - cairo_surface_mark_dirty ( surface ); +/* + * _rofi_icon_fetcher_get_icon_surface and alpha_mult + * are inspired by gdk_cairo_set_source_pixbuf + * GDK is: + * Copyright (C) 2011-2018 Red Hat, Inc. + */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define RED_BYTE 2 +#define GREEN_BYTE 1 +#define BLUE_BYTE 0 +#define ALPHA_BYTE 3 +#else +#define RED_BYTE 1 +#define GREEN_BYTE 2 +#define BLUE_BYTE 3 +#define ALPHA_BYTE 0 +#endif - return surface; -} -struct jpegErrorManager { - /* "public" fields */ - struct jpeg_error_mgr pub; - /* for return to caller */ - jmp_buf setjmp_buffer; -}; -char jpegLastErrorMsg[JMSG_LENGTH_MAX]; -static void jpegErrorExit (j_common_ptr cinfo) +static inline guchar alpha_mult(guchar c, guchar a) { - /* cinfo->err actually points to a jpegErrorManager struct */ - struct jpegErrorManager* myerr = (struct jpegErrorManager*) cinfo->err; - - /* Create the message */ - ( *(cinfo->err->format_message) ) (cinfo, jpegLastErrorMsg); - g_warning ( jpegLastErrorMsg, NULL ); - - /* Jump to the setjmp point */ - longjmp(myerr->setjmp_buffer, 1); + guint16 t; + switch ( a ) + { + case 0xff: + return c; + case 0x00: + return 0x00; + default: + t = c * a + 0x7f; + return ((t >> 8) + t) >> 8; + } } -static cairo_surface_t* cairo_image_surface_create_from_jpeg ( const char* file ) +static cairo_surface_t * rofi_icon_fetcher_get_surface_from_pixbuf(GdkPixbuf + *pixbuf) { - struct jpeg_decompress_struct cinfo; - cairo_surface_t * surface; - FILE * infile; - - if ( ( infile = fopen ( file, "rb" ) ) == NULL ) { - return NULL; - } - - struct jpegErrorManager jerr; - cinfo.err = jpeg_std_error( &jerr.pub); - jerr.pub.error_exit = jpegErrorExit; - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp(jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - jpeg_destroy_decompress(&cinfo); - fclose(infile); - return NULL; - } - - jpeg_create_decompress ( &cinfo ); - jpeg_stdio_src ( &cinfo, infile ); + gint width, height; + const guchar *pixels; + gint stride; + gboolean alpha; - surface = cairo_image_surface_create_from_jpeg_private ( &cinfo ); + if ( pixbuf == NULL ) + return NULL; - fclose ( infile ); + width = gdk_pixbuf_get_width(pixbuf); + height = gdk_pixbuf_get_height(pixbuf); + pixels = gdk_pixbuf_read_pixels(pixbuf); + stride = gdk_pixbuf_get_rowstride(pixbuf); + alpha = gdk_pixbuf_get_has_alpha(pixbuf); - return surface; -} + cairo_surface_t *surface = NULL; -#ifdef HAVE_LIBGIF -#include + gint cstride; + guint lo, o; + guchar a = 0xff; + const guchar *pixels_end, *line, *line_end; + guchar *cpixels, *cline; -static cairo_surface_t* cairo_image_surface_create_from_gif(const char* file ) -{ - cairo_surface_t* img = NULL; + pixels_end = pixels + height * stride; + o = alpha ? 4 : 3; + lo = o * width; - int err; - GifFileType* gif = DGifOpenFileName(file, &err); - if (!gif) { - g_warning( "[%i] %s", err, GifErrorString(err)); - return NULL; - } + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cpixels = cairo_image_surface_get_data(surface); + cstride = cairo_image_surface_get_stride(surface); - // decode with high-level API - if (DGifSlurp(gif) != GIF_OK) { - g_warning("Decoder error: %s", GifErrorString(gif->Error)); - goto done; - } - if (!gif->SavedImages) { - g_warning("No saved images"); - goto done; - } - - // create canvas - img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, gif->SWidth, gif->SHeight); - if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) { - g_warning("Unable to create surface: %s", - cairo_status_to_string(cairo_surface_status(img))); - cairo_surface_destroy(img); - img = NULL; - goto done; - } + cairo_surface_flush(surface); + while ( pixels < pixels_end ) + { + line = pixels; + line_end = line + lo; + cline = cpixels; - // we don't support animation, show the first frame only - const GifImageDesc* frame = &gif->SavedImages->ImageDesc; - const GifColorType* colors = gif->SColorMap ? gif->SColorMap->Colors : - frame->ColorMap->Colors; - uint32_t* base = (uint32_t*)(cairo_image_surface_get_data(img) + - frame->Top * cairo_image_surface_get_stride(img)); - for (int y = 0; y < frame->Height; ++y) { - uint32_t* pixel = base + y * gif->SWidth + frame->Left; - const uint8_t* raster = &gif->SavedImages->RasterBits[y * gif->SWidth]; - for (int x = 0; x < frame->Width; ++x) { - const uint8_t color = raster[x]; - if (color != gif->SBackGroundColor) { - const GifColorType* rgb = &colors[color]; - *pixel = 0xff000000 | - rgb->Red << 16 | rgb->Green << 8 | rgb->Blue; - } - ++pixel; - } + while ( line < line_end ) + { + if ( alpha ) + a = line[3]; + cline[RED_BYTE] = alpha_mult(line[0], a); + cline[GREEN_BYTE] = alpha_mult(line[1], a); + cline[BLUE_BYTE] = alpha_mult(line[2], a); + cline[ALPHA_BYTE] = a; + + line += o; + cline += 4; } - cairo_surface_mark_dirty(img); + pixels += stride; + cpixels += cstride; + } + cairo_surface_mark_dirty(surface); + cairo_surface_flush(surface); -done: - DGifCloseFile(gif, NULL); - return img; + return surface; } -#endif - -enum { - IMAGE_PNG, - IMAGE_JPG, - IMAGE_JPEG, - IMAGE_SVG, -#ifdef HAVE_LIBGIF - IMAGE_GIF, -#endif - IMAGE_MAX_VALUES -} RofiIconFetchDecoder; - -static const gchar * const _image_exts[IMAGE_MAX_VALUES] = { - [IMAGE_PNG] = ".png", - [IMAGE_JPG] = ".jpg", - [IMAGE_JPEG] = ".jpeg", - [IMAGE_SVG] = ".svg", -#ifdef HAVE_LIBGIF - [IMAGE_GIF] = ".gif", -#endif -}; gboolean rofi_icon_fetcher_file_is_image ( const char * const path ) { @@ -320,101 +264,66 @@ gboolean rofi_icon_fetcher_file_is_image ( const char * const path ) if ( suf == NULL ) { return FALSE; } + suf++; - guint64 type; - gboolean r = nk_enum_parse ( suf, _image_exts, G_N_ELEMENTS(_image_exts), TRUE, FALSE, &type ); - return r; + for ( GList *iter = rofi_icon_fetcher_data->supported_extensions; iter != NULL ; iter = g_list_next ( iter ) ) { + if ( g_ascii_strcasecmp(iter->data, suf ) == 0 ) { + return TRUE; + } + } + return FALSE; } static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpointer user_data ) { - g_debug ( "starting up icon fetching thread." ); - // as long as dr->icon is updated atomicly.. (is a pointer write atomic?) - // this should be fine running in another thread. - IconFetcherEntry *sentry = (IconFetcherEntry *) sdata; - const gchar *themes[] = { - config.icon_theme, - NULL - }; - - const gchar *icon_path; - gchar *icon_path_ = NULL; - - if ( g_path_is_absolute ( sentry->entry->name ) ) { - icon_path = sentry->entry->name; + g_debug ( "starting up icon fetching thread." ); + // as long as dr->icon is updated atomicly.. (is a pointer write atomic?) + // this should be fine running in another thread. + IconFetcherEntry *sentry = (IconFetcherEntry *) sdata; + const gchar *themes[] = { + config.icon_theme, + NULL + }; + + const gchar *icon_path; + gchar *icon_path_ = NULL; + + if ( g_path_is_absolute ( sentry->entry->name ) ) { + icon_path = sentry->entry->name; + } + else { + icon_path = icon_path_ = nk_xdg_theme_get_icon ( rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name, sentry->size, 1, TRUE ); + if ( icon_path_ == NULL ) { + g_debug ( "failed to get icon %s(%d): n/a", sentry->entry->name, sentry->size ); + return; } - else { - icon_path = icon_path_ = nk_xdg_theme_get_icon ( rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name, sentry->size, 1, TRUE ); - if ( icon_path_ == NULL ) { - g_debug ( "failed to get icon %s(%d): n/a", sentry->entry->name, sentry->size ); - return; - } - else{ - g_debug ( "found icon %s(%d): %s", sentry->entry->name, sentry->size, icon_path ); - } + else{ + g_debug ( "found icon %s(%d): %s", sentry->entry->name, sentry->size, icon_path ); } - cairo_surface_t *icon_surf = NULL; - - const char *suf = strrchr(icon_path, '.'); - if ( suf == NULL ) { - return ; - } - - guint64 type; - gboolean is_image = nk_enum_parse ( suf, _image_exts, G_N_ELEMENTS(_image_exts), TRUE, FALSE, &type ); - if ( is_image ) - { - if ( type == IMAGE_PNG ) { - icon_surf = cairo_image_surface_create_from_png ( icon_path ); - } -#ifdef HAVE_LIBGIF - else if ( type == IMAGE_GIF ) { - icon_surf = cairo_image_surface_create_from_gif ( icon_path ); - } -#endif - else if ( type == IMAGE_JPG || type == IMAGE_JPEG ) { - icon_surf = cairo_image_surface_create_from_jpeg ( icon_path ); - } - else if ( type == IMAGE_SVG ) { - icon_surf = cairo_image_surface_create_from_svg ( icon_path, sentry->size ); - } - else { - g_debug ( "icon type not yet supported: %s", icon_path ); - } - } - if ( icon_surf ) { - if ( cairo_surface_status ( icon_surf ) == CAIRO_STATUS_SUCCESS ) { - float sw = sentry->size / (float) cairo_image_surface_get_width ( icon_surf ); - float sh = sentry->size / (float) cairo_image_surface_get_height ( icon_surf ); - - float scale = ( sw > sh ) ? sh : sw; - if ( scale < 0.5 ) { - cairo_surface_t * surface = cairo_image_surface_create ( - cairo_image_surface_get_format ( icon_surf ), - cairo_image_surface_get_width ( icon_surf ) * scale, - cairo_image_surface_get_height ( icon_surf ) * scale ); - - cairo_t *d = cairo_create ( surface ); - cairo_scale ( d, scale, scale ); - cairo_set_source_surface ( d, icon_surf, 0.0, 0.0 ); - cairo_pattern_set_filter ( cairo_get_source ( d ), CAIRO_FILTER_FAST ); - cairo_paint ( d ); - - cairo_destroy ( d ); - cairo_surface_destroy ( icon_surf ); - icon_surf = surface; - } - } - // check if surface is valid. - if ( cairo_surface_status ( icon_surf ) != CAIRO_STATUS_SUCCESS ) { - g_debug ( "icon failed to open: %s(%d): %s", sentry->entry->name, sentry->size, icon_path ); - cairo_surface_destroy ( icon_surf ); - icon_surf = NULL; - } - sentry->surface = icon_surf; + } + cairo_surface_t *icon_surf = NULL; + + const char *suf = strrchr(icon_path, '.'); + if ( suf == NULL ) { + return ; + } + + GError *error = NULL; + GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale ( icon_path, sentry->size, sentry->size, TRUE, &error ); + if ( error != NULL ) { + g_warning ( "Failed to load image: %s", error->message); + g_error_free( error ); + if ( pb ) { + g_object_unref ( pb ); } - g_free ( icon_path_ ); - rofi_view_reload (); + } else { + icon_surf = rofi_icon_fetcher_get_surface_from_pixbuf(pb ); + g_object_unref ( pb ); + } + + sentry->surface = icon_surf; + g_free ( icon_path_ ); + rofi_view_reload (); } uint32_t rofi_icon_fetcher_query ( const char *name, const int size ) diff --git a/source/xcb.c b/source/xcb.c index dd42e98b..b5f25a47 100644 --- a/source/xcb.c +++ b/source/xcb.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3