diff -Nru feh-3.3/ChangeLog feh-3.4/ChangeLog --- feh-3.3/ChangeLog 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/ChangeLog 2020-04-11 07:52:58.000000000 +0000 @@ -1,3 +1,21 @@ +Sat, 11 Apr 2020 09:51:01 +0200 Daniel Friesel + +* Release v3.4 + * Images loaded via HTTPS/curl, ImageMagick, and dcraw are now cached + by default to decrease image load time on subsequent slideshow passes. + Caching is disabled when using `--reload` and can also be disabled with + the new `--no-conversion-cache` option. Suggestion and initial patch by + Awal Garg. + * Handle SIGINT/SIGTERM/SIGQUIT signals while loading images using libcurl + < v7.32. Patch by . + * "feh --start-at URL" now loads a single-image slideshow displaying URL. + This allows feh.desktop to handle URLs as well as ordinary files. + file:/// URLs are treated as local files, so "feh --start-at file:///..." + without filelist arguments behaves just like "feh --start-at ..." + (i.e., feh will load the entire directory and start the slideshow at ...) + * Fix a memory leak when repeatedly cycling through slideshows containing + images loaded via libcurl, ImageMagick or dcraw. + Tue, 03 Dec 2019 17:27:46 +0100 Daniel Friesel * Release v3.3 diff -Nru feh-3.3/config.mk feh-3.4/config.mk --- feh-3.3/config.mk 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/config.mk 2020-04-11 07:52:58.000000000 +0000 @@ -1,5 +1,5 @@ PACKAGE ?= feh -VERSION ?= 3.3 +VERSION ?= 3.4 app ?= 0 curl ?= 1 @@ -93,7 +93,7 @@ MAN_INOTIFY = disabled endif -MAN_DATE ?= December 03, 2019 +MAN_DATE ?= April 11, 2020 # Uncomment this to use dmalloc #CFLAGS += -DWITH_DMALLOC diff -Nru feh-3.3/debian/changelog feh-3.4/debian/changelog --- feh-3.3/debian/changelog 2020-01-12 22:07:18.000000000 +0000 +++ feh-3.4/debian/changelog 2020-04-16 20:03:50.000000000 +0000 @@ -1,3 +1,13 @@ +feh (3.4-1) unstable; urgency=medium + + * New upstream release. + * Remove outdated feh-cam man page (closes: #944708). + * Rename NEWS.Debian to NEWS. + * Remove quotes from mailcap entries. + * Update Standards-Version to 4.5.0 . + + -- Laszlo Boszormenyi (GCS) Thu, 16 Apr 2020 20:03:50 +0000 + feh (3.3-1) unstable; urgency=medium * New upstream release. diff -Nru feh-3.3/debian/control feh-3.4/debian/control --- feh-3.3/debian/control 2020-01-12 22:07:18.000000000 +0000 +++ feh-3.4/debian/control 2020-04-16 20:03:50.000000000 +0000 @@ -13,7 +13,7 @@ libtest-command-perl, libcurl4-openssl-dev | libcurl-dev, libexif-dev -Standards-Version: 4.4.1 +Standards-Version: 4.5.0 Vcs-Browser: https://salsa.debian.org/debian-phototools-team/feh Vcs-Git: https://salsa.debian.org/debian-phototools-team/feh.git Homepage: https://feh.finalrewind.org/ diff -Nru feh-3.3/debian/feh-cam.1 feh-3.4/debian/feh-cam.1 --- feh-3.3/debian/feh-cam.1 2018-12-07 19:27:44.000000000 +0000 +++ feh-3.4/debian/feh-cam.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -.TH feh-cam 1 "29 Oct 2000" "feh-cam" -.SH NAME -.HP -feh-cam - a utility for viewing live webcam images -.HP -gen_cam_menu.sh - a utility for updating Enlightenment user -menus for feh-cam. -.SH SYNOPSIS -.HP -feh-cam [options] -.P -.SH DESCRIPTION -.HP -.I feh-cam -is a Perl wrapper for feh that simplifies viewing webcams. -feh-cam uses keyed bookmarks. It helps manage viewing your -favorite webcam sites with feh. -.HP -.I gen_cam_menu.sh -is a shell script that creates Enlightenment user menu entries -in $HOME/.enlightenment/. -.HP -Type -.I "feh-cam -h" -at a command line for usage information. -.P -.SH SEE ALSO -.HP -feh(1) - diff -Nru feh-3.3/debian/feh.docs feh-3.4/debian/feh.docs --- feh-3.3/debian/feh.docs 2018-12-11 11:48:04.000000000 +0000 +++ feh-3.4/debian/feh.docs 2020-04-16 20:03:50.000000000 +0000 @@ -1 +1 @@ -debian/NEWS.Debian +debian/NEWS diff -Nru feh-3.3/debian/feh.links feh-3.4/debian/feh.links --- feh-3.3/debian/feh.links 2018-12-07 19:27:44.000000000 +0000 +++ feh-3.4/debian/feh.links 2020-04-16 20:03:50.000000000 +0000 @@ -1,2 +1 @@ -usr/share/man/man1/feh-cam.1 usr/share/man/man1/gen_cam_menu.1 usr/share/yudit/fonts/yudit.ttf usr/share/feh/fonts/yudit.ttf diff -Nru feh-3.3/debian/feh.manpages feh-3.4/debian/feh.manpages --- feh-3.3/debian/feh.manpages 2018-12-07 19:27:44.000000000 +0000 +++ feh-3.4/debian/feh.manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/feh-cam.1 diff -Nru feh-3.3/debian/feh.mime feh-3.4/debian/feh.mime --- feh-3.3/debian/feh.mime 2018-12-07 19:27:44.000000000 +0000 +++ feh-3.4/debian/feh.mime 2020-04-16 20:03:50.000000000 +0000 @@ -1,9 +1,9 @@ -image/gif; feh '%s'; test=test -n "$DISPLAY" ; description=GIF Image; nametemplate=%s.gif; priority=2 -image/jpeg; feh '%s'; test=test -n "$DISPLAY" ; description=JPEG Image; nametemplate=%s.jpeg; priority=2 -image/png; feh '%s'; test=test -n "$DISPLAY" ; description=PNG Image; nametemplate=%s.png; priority=2 -image/tiff; feh '%s'; test=test -n "$DISPLAY" ; description=TIFF Image; nametemplate=%s.tiff; priority=2 -image/x-portable-anymap; feh '%s'; test=test -n "$DISPLAY" ; description=PNM Image; nametemplate=%s.pnm; priority=2 -image/targa; feh '%s'; test=test -n "$DISPLAY" ; description=TGA Image; nametemplate=%s.tga; priority=2 -image/x-ms-bmp; feh '%s'; test=test -n "$DISPLAY" ; description=BMP Image; nametemplate=%s.bmp; priority=2 -image/x-xpixmap; feh '%s'; test=test -n "$DISPLAY" ; description=XPM Image; nametemplate=%s.xpm; priority=2 -image/pjpeg; feh '%s'; test=test -n "$DISPLAY" ; description=JPEG Image; nametemplate=%s.jpeg; priority=2 +image/gif; feh %s; test=test -n "$DISPLAY" ; description=GIF Image; nametemplate=%s.gif; priority=2 +image/jpeg; feh %s; test=test -n "$DISPLAY" ; description=JPEG Image; nametemplate=%s.jpeg; priority=2 +image/png; feh %s; test=test -n "$DISPLAY" ; description=PNG Image; nametemplate=%s.png; priority=2 +image/tiff; feh %s; test=test -n "$DISPLAY" ; description=TIFF Image; nametemplate=%s.tiff; priority=2 +image/x-portable-anymap; feh %s; test=test -n "$DISPLAY" ; description=PNM Image; nametemplate=%s.pnm; priority=2 +image/targa; feh %s; test=test -n "$DISPLAY" ; description=TGA Image; nametemplate=%s.tga; priority=2 +image/x-ms-bmp; feh %s; test=test -n "$DISPLAY" ; description=BMP Image; nametemplate=%s.bmp; priority=2 +image/x-xpixmap; feh %s; test=test -n "$DISPLAY" ; description=XPM Image; nametemplate=%s.xpm; priority=2 +image/pjpeg; feh %s; test=test -n "$DISPLAY" ; description=JPEG Image; nametemplate=%s.jpeg; priority=2 diff -Nru feh-3.3/debian/NEWS feh-3.4/debian/NEWS --- feh-3.3/debian/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ feh-3.4/debian/NEWS 2018-12-11 11:36:30.000000000 +0000 @@ -0,0 +1,10 @@ +feh (3.1-1) unstable; urgency=medium + + Flip and rotation (keys "<", ">", "|", and "_") no longer change the + underlying file. This leaves delete ("Ctrl+Delete") as the only + destructive action which is enabled by default. + Add option --edit, which makes flip and rotation change the underlying + file as well as the displayed image. This was the default behaviour in + feh 1.x and 2.x". + + -- Andreas Tille Tue, 11 Dec 2018 12:35:10 +0100 diff -Nru feh-3.3/debian/NEWS.Debian feh-3.4/debian/NEWS.Debian --- feh-3.3/debian/NEWS.Debian 2018-12-11 11:36:30.000000000 +0000 +++ feh-3.4/debian/NEWS.Debian 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -feh (3.1-1) unstable; urgency=medium - - Flip and rotation (keys "<", ">", "|", and "_") no longer change the - underlying file. This leaves delete ("Ctrl+Delete") as the only - destructive action which is enabled by default. - Add option --edit, which makes flip and rotation change the underlying - file as well as the displayed image. This was the default behaviour in - feh 1.x and 2.x". - - -- Andreas Tille Tue, 11 Dec 2018 12:35:10 +0100 diff -Nru feh-3.3/debian/rules feh-3.4/debian/rules --- feh-3.3/debian/rules 2018-12-07 19:27:44.000000000 +0000 +++ feh-3.4/debian/rules 2020-04-16 20:03:50.000000000 +0000 @@ -10,7 +10,7 @@ dh_auto_build --parallel -- PREFIX=/usr exif=1 override_dh_auto_install: - dh_auto_install -- DESTDIR=debian/feh PREFIX=/usr cam=1 + dh_auto_install -- DESTDIR=debian/feh PREFIX=/usr override_dh_installchangelogs: dh_installchangelogs -k ChangeLog diff -Nru feh-3.3/.github/workflows/c.yml feh-3.4/.github/workflows/c.yml --- feh-3.3/.github/workflows/c.yml 1970-01-01 00:00:00.000000000 +0000 +++ feh-3.4/.github/workflows/c.yml 2020-04-11 07:52:58.000000000 +0000 @@ -0,0 +1,36 @@ +name: linux + +on: + push: + branches: + - '*' + pull_request: + branches: + - '*' + +jobs: + c: + + runs-on: ubuntu-latest + + strategy: + matrix: + curl: [0, 1] + exif: [0, 1] + xinerama: [0, 1] + + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: sudo apt install build-essential libx11-dev libxt-dev libimlib2-dev libtest-command-perl libtest-simple-perl + - name: Install libcurl + if: matrix.curl + run: sudo apt install libcurl4-openssl-dev + - name: Install libexif + if: matrix.exif + run: sudo apt install libexif-dev + - name: Install Xinerama + if: matrix.xinerama + run: sudo apt install libxinerama-dev + - name: Build and Test + run: for inotify in 0 1; do for verscmp in 0 1; do make curl=${{ matrix.curl }} exif=${{ matrix.exif }} inotify=$inotify verscmp=$verscmp xinerama=${{ matrix.xinerama }} && make test && make clean; done; done diff -Nru feh-3.3/man/feh.pre feh-3.4/man/feh.pre --- feh-3.3/man/feh.pre 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/man/feh.pre 2020-04-11 07:52:58.000000000 +0000 @@ -468,6 +468,8 @@ as background for transparent image parts and the like. Accepted values: default, checks, or an XColor .Pq e.g. Qo black Qc or Qo #428bdd Qc . +Note that some shells treat the hash symbol as a special character, so you +may need to quote or escape it for the XColor code to work. . In windowed mode, the default is checks .Pq a checkered background so transparent image parts are easy to see . @@ -576,6 +578,19 @@ With this setting, instead of opening multiple files in slideshow mode, multiple windows will be opened; one per file. . +.It Cm --no-conversion-cache +. +When loading images via HTTP, ImageMagick or dcraw, +.Nm +will only load/convert them once and re-use the cached file on subsequent +slideshow passes. +This option disables the cache. It is also disabled when +.Cm --reload +is used. +Use it if you rely on frequently changing files loaded via one of these +sources. +Note that it will impair performance. +. .It Cm --no-jump-on-resort . Don't jump to the first image after resorting the filelist. @@ -789,6 +804,13 @@ See .Sx USAGE EXAMPLES for examples. +If +.Ar filename +is a remote URL and no files or filelists were specified, +.Nm +will show +.Ar filename +and not attempt to load additional files or directories. . .Pp . diff -Nru feh-3.3/share/applications/feh.pre feh-3.4/share/applications/feh.pre --- feh-3.3/share/applications/feh.pre 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/share/applications/feh.pre 2020-04-11 07:52:58.000000000 +0000 @@ -4,10 +4,10 @@ GenericName=Image viewer GenericName[en_US]=Image viewer Comment=Image viewer and cataloguer -Exec=feh --start-at %f +Exec=feh --start-at %u Terminal=false Type=Application Icon=feh Categories=Graphics;2DGraphics;Viewer; -MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-pcx;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-tga;image/x-xbitmap; +MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/webp;image/x-bmp;image/x-pcx;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-tga;image/x-xbitmap; NoDisplay=true diff -Nru feh-3.3/src/deps.mk feh-3.4/src/deps.mk --- feh-3.3/src/deps.mk 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/src/deps.mk 2020-04-11 07:52:58.000000000 +0000 @@ -1,57 +1,57 @@ events.o: events.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ - timers.h options.h events.h thumbnail.h + structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ + timers.h options.h events.h thumbnail.h feh_png.o: feh_png.c feh_png.h feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.o: filelist.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ - signals.h options.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ + signals.h options.h getopt.o: getopt.c getopt1.o: getopt1.c getopt.h gib_hash.o: gib_hash.c gib_hash.h gib_list.h utils.h debug.h gib_imlib.o: gib_imlib.c gib_imlib.h gib_style.h gib_list.h utils.h \ - debug.h + debug.h gib_list.o: gib_list.c gib_list.h utils.h debug.h gib_style.o: gib_style.c gib_style.h gib_list.h utils.h debug.h imlib.o: imlib.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h signals.h \ - winwidget.h options.h + structs.h menu.h utils.h getopt.h debug.h filelist.h signals.h \ + winwidget.h options.h index.o: index.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ - options.h index.h + structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ + options.h index.h keyevents.o: keyevents.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h thumbnail.h \ - filelist.h winwidget.h options.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h thumbnail.h \ + filelist.h winwidget.h options.h list.o: list.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h options.h + structs.h menu.h utils.h getopt.h debug.h filelist.h options.h main.o: main.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ - timers.h options.h events.h signals.h wallpaper.h + structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ + timers.h options.h events.h signals.h wallpaper.h md5.o: md5.c md5.h menu.o: menu.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h thumbnail.h filelist.h \ - winwidget.h wallpaper.h options.h + structs.h menu.h utils.h getopt.h debug.h thumbnail.h filelist.h \ + winwidget.h wallpaper.h options.h multiwindow.o: multiwindow.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h winwidget.h \ - timers.h filelist.h options.h signals.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h winwidget.h \ + timers.h filelist.h options.h signals.h options.o: options.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h options.h + structs.h menu.h utils.h getopt.h debug.h filelist.h options.h signals.o: signals.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ - options.h + structs.h menu.h utils.h getopt.h debug.h filelist.h winwidget.h \ + options.h slideshow.o: slideshow.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ - timers.h winwidget.h options.h signals.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ + timers.h winwidget.h options.h signals.h thumbnail.o: thumbnail.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ - winwidget.h options.h thumbnail.h md5.h feh_png.h index.h signals.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ + winwidget.h options.h thumbnail.h md5.h feh_png.h index.h signals.h timers.o: timers.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h options.h timers.h + structs.h menu.h utils.h getopt.h debug.h options.h timers.h utils.o: utils.c feh.h gib_hash.h gib_list.h gib_imlib.h gib_style.h \ - structs.h menu.h utils.h getopt.h debug.h options.h + structs.h menu.h utils.h getopt.h debug.h options.h wallpaper.o: wallpaper.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ - options.h wallpaper.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ + options.h wallpaper.h winwidget.o: winwidget.c feh.h gib_hash.h gib_list.h gib_imlib.h \ - gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ - winwidget.h options.h events.h + gib_style.h structs.h menu.h utils.h getopt.h debug.h filelist.h \ + winwidget.h options.h events.h diff -Nru feh-3.3/src/imlib.c feh-3.4/src/imlib.c --- feh-3.3/src/imlib.c 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/src/imlib.c 2020-04-11 07:52:58.000000000 +0000 @@ -60,6 +60,8 @@ int num_xinerama_screens; #endif /* HAVE_LIBXINERAMA */ +gib_hash* conversion_cache = NULL; + int childpid = 0; static int feh_file_is_raw(char *filename); @@ -252,16 +254,33 @@ if (!err && im) { real_filename = file->filename; file->filename = tmpname; + + /* + * feh does not associate a non-native image with its temporary + * filename and may delete the temporary file right after loading. + * To ensure that it is still aware of image size, dimensions, etc., + * file_info is preloaded here. To avoid a memory leak when loading + * a non-native file multiple times in a slideshow, the file_info + * struct is freed first. If file->info is not set, feh_file_info_free + * is a no-op. + */ + feh_file_info_free(file->info); feh_file_info_load(file, *im); + file->filename = real_filename; #ifdef HAVE_LIBEXIF file->ed = exif_get_data(tmpname); #endif } - if ((image_source != SRC_HTTP) || !opt.keep_http) + if (!opt.use_conversion_cache && ((image_source != SRC_HTTP) || !opt.keep_http)) unlink(tmpname); + // keep_http already performs an add_file_to_rm_filelist call + else if (opt.use_conversion_cache && !opt.keep_http) + // add_file_to_rm_filelist duplicates tmpname + add_file_to_rm_filelist(tmpname); - free(tmpname); + if (image_source != SRC_HTTP && !opt.use_conversion_cache) + free(tmpname); } if ((err) || (!im)) { @@ -319,6 +338,89 @@ return(1); } +void feh_reload_image(winwidget w, int resize, int force_new) +{ + char *new_title; + int len; + Imlib_Image tmp; + int old_w, old_h; + + if (!w->file) { + im_weprintf(w, "couldn't reload, this image has no file associated with it."); + winwidget_render_image(w, 0, 0); + return; + } + + D(("resize %d, force_new %d\n", resize, force_new)); + + free(FEH_FILE(w->file->data)->caption); + FEH_FILE(w->file->data)->caption = NULL; + + len = strlen(w->name) + sizeof("Reloading: ") + 1; + new_title = emalloc(len); + snprintf(new_title, len, "Reloading: %s", w->name); + winwidget_rename(w, new_title); + free(new_title); + + old_w = gib_imlib_image_get_width(w->im); + old_h = gib_imlib_image_get_height(w->im); + + /* + * If we don't free the old image before loading the new one, Imlib2's + * caching will get in our way. + * However, if --reload is used (force_new == 0), we want to continue if + * the new image cannot be loaded, so we must not free the old image yet. + */ + if (force_new) + winwidget_free_image(w); + + // if it's an external image, our own cache will also get in your way + char *sfn; + if (opt.use_conversion_cache && conversion_cache && (sfn = gib_hash_get(conversion_cache, FEH_FILE(w->file->data)->filename)) != NULL) { + free(sfn); + gib_hash_set(conversion_cache, FEH_FILE(w->file->data)->filename, NULL); + } + + if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) { + if (force_new) + eprintf("failed to reload image\n"); + else { + im_weprintf(w, "Couldn't reload image. Is it still there?"); + winwidget_render_image(w, 0, 0); + } + return; + } + + if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) || + (old_h != gib_imlib_image_get_height(tmp)))) + resize = 1; + + if (!force_new) + winwidget_free_image(w); + + w->im = tmp; + winwidget_reset_image(w); + + w->mode = MODE_NORMAL; + if ((w->im_w != gib_imlib_image_get_width(w->im)) + || (w->im_h != gib_imlib_image_get_height(w->im))) + w->had_resize = 1; + if (w->has_rotated) { + Imlib_Image temp; + + temp = gib_imlib_create_rotated_image(w->im, 0.0); + w->im_w = gib_imlib_image_get_width(temp); + w->im_h = gib_imlib_image_get_height(temp); + gib_imlib_free_image_and_decache(temp); + } else { + w->im_w = gib_imlib_image_get_width(w->im); + w->im_h = gib_imlib_image_get_height(w->im); + } + winwidget_render_image(w, resize, 0); + + return; +} + static int feh_file_is_raw(char *filename) { childpid = fork(); @@ -355,6 +457,13 @@ char *sfn; int fd = -1; + if (opt.use_conversion_cache) { + if (!conversion_cache) + conversion_cache = gib_hash_new(); + if ((sfn = gib_hash_get(conversion_cache, filename)) != NULL) + return sfn; + } + basename = strrchr(filename, '/'); if (basename == NULL) @@ -405,6 +514,9 @@ weprintf("%s - Conversion took too long, skipping", filename); } + if ((sfn != NULL) && opt.use_conversion_cache) + gib_hash_set(conversion_cache, filename, sfn); + return sfn; } @@ -419,6 +531,13 @@ int status; char created_tempdir = 0; + if (opt.use_conversion_cache) { + if (!conversion_cache) + conversion_cache = gib_hash_new(); + if ((sfn = gib_hash_get(conversion_cache, filename)) != NULL) + return sfn; + } + basename = strrchr(filename, '/'); if (basename == NULL) @@ -537,12 +656,20 @@ } free(argv_fn); + + if ((sfn != NULL) && opt.use_conversion_cache) + gib_hash_set(conversion_cache, filename, sfn); + return sfn; } #ifdef HAVE_LIBCURL +#if LIBCURL_VERSION_NUM >= 0x072000 /* 07.32.0 */ static int curl_quit_function(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) +#else +static int curl_quit_function(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +#endif { // ignore "unused parameter" warnings (void)clientp; @@ -572,6 +699,13 @@ char *basename; char *path = NULL; + if (opt.use_conversion_cache) { + if (!conversion_cache) + conversion_cache = gib_hash_new(); + if ((sfn = gib_hash_get(conversion_cache, url)) != NULL) + return sfn; + } + if (opt.keep_http) { if (opt.output_dir) path = opt.output_dir; @@ -617,6 +751,8 @@ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); #if LIBCURL_VERSION_NUM >= 0x072000 /* 07.32.0 */ curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curl_quit_function); +#else + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_quit_function); #endif curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); if (opt.insecure_ssl) { @@ -642,6 +778,8 @@ free(ebuff); fclose(sfp); + if (opt.use_conversion_cache) + gib_hash_set(conversion_cache, url, sfn); return sfn; } else { weprintf("open url: fdopen failed:"); diff -Nru feh-3.3/src/keyevents.c feh-3.4/src/keyevents.c --- feh-3.3/src/keyevents.c 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/src/keyevents.c 2020-04-11 07:52:58.000000000 +0000 @@ -691,7 +691,10 @@ slideshow_change_image(winwid, SLIDE_RAND, 1); } else if (feh_is_kp(EVENT_toggle_caption, state, keysym, button)) { - if (opt.caption_path) { + if (opt.caption_path && path_is_url(FEH_FILE(winwid->file->data)->filename)) { + im_weprintf(winwid, "Caption entry is not supported on URLs"); + } + else if (opt.caption_path) { /* * editing captions in slideshow mode does not make any sense * at all; this is just in case someone accidentally does it... diff -Nru feh-3.3/src/options.c feh-3.4/src/options.c --- feh-3.3/src/options.c 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/src/options.c 2020-04-11 07:52:58.000000000 +0000 @@ -76,6 +76,7 @@ #ifdef HAVE_INOTIFY opt.auto_reload = 1; #endif /* HAVE_INOTIFY */ + opt.use_conversion_cache = 1; feh_getopt_theme(argc, argv); @@ -431,6 +432,7 @@ {"auto-reload" , 0, 0, 248}, #endif {"class" , 1, 0, 249}, + {"no-conversion-cache", 0, 0, 250}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -523,6 +525,7 @@ break; case 'R': opt.reload = atof(optarg); + opt.use_conversion_cache = 0; #ifdef HAVE_INOTIFY opt.auto_reload = 0; #endif @@ -827,6 +830,9 @@ case 249: opt.x11_class = estrdup(optarg); break; + case 250: + opt.use_conversion_cache = 0; + break; default: break; } @@ -843,7 +849,18 @@ } } else if (finalrun && !opt.filelistfile && !opt.bgmode) { - if (opt.start_list_at && !path_is_url(opt.start_list_at) && strrchr(opt.start_list_at, '/')) { + /* + * if --start-at is a non-local URL (i.e., does not start with file:///), + * behave as if "feh URL" was called (there is no directory we can load) + */ + if (opt.start_list_at && path_is_url(opt.start_list_at) && (strlen(opt.start_list_at) <= 8 || strncmp(opt.start_list_at, "file:///", 8) != 0)) { + add_file_to_filelist_recursively(opt.start_list_at, FILELIST_FIRST); + } else if (opt.start_list_at && strrchr(opt.start_list_at, '/')) { + if (strlen(opt.start_list_at) > 8 && strncmp(opt.start_list_at, "file:///", 8) == 0) { + char *start_at_path = estrdup(opt.start_list_at + 7); + free(opt.start_list_at); + opt.start_list_at = start_at_path; + } char *target_directory = estrdup(opt.start_list_at); char *filename_start = strrchr(target_directory, '/'); if (filename_start) { diff -Nru feh-3.3/src/options.h feh-3.4/src/options.h --- feh-3.3/src/options.h 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/src/options.h 2020-04-11 07:52:58.000000000 +0000 @@ -49,6 +49,7 @@ unsigned char aspect; unsigned char stretch; unsigned char keep_http; + unsigned char use_conversion_cache; unsigned char borderless; unsigned char randomize; unsigned char jump_on_resort; diff -Nru feh-3.3/src/slideshow.c feh-3.4/src/slideshow.c --- feh-3.3/src/slideshow.c 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/src/slideshow.c 2020-04-11 07:52:58.000000000 +0000 @@ -182,82 +182,6 @@ return; } -void feh_reload_image(winwidget w, int resize, int force_new) -{ - char *new_title; - int len; - Imlib_Image tmp; - int old_w, old_h; - - if (!w->file) { - im_weprintf(w, "couldn't reload, this image has no file associated with it."); - winwidget_render_image(w, 0, 0); - return; - } - - D(("resize %d, force_new %d\n", resize, force_new)); - - free(FEH_FILE(w->file->data)->caption); - FEH_FILE(w->file->data)->caption = NULL; - - len = strlen(w->name) + sizeof("Reloading: ") + 1; - new_title = emalloc(len); - snprintf(new_title, len, "Reloading: %s", w->name); - winwidget_rename(w, new_title); - free(new_title); - - old_w = gib_imlib_image_get_width(w->im); - old_h = gib_imlib_image_get_height(w->im); - - /* - * If we don't free the old image before loading the new one, Imlib2's - * caching will get in our way. - * However, if --reload is used (force_new == 0), we want to continue if - * the new image cannot be loaded, so we must not free the old image yet. - */ - if (force_new) - winwidget_free_image(w); - - if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) { - if (force_new) - eprintf("failed to reload image\n"); - else { - im_weprintf(w, "Couldn't reload image. Is it still there?"); - winwidget_render_image(w, 0, 0); - } - return; - } - - if (!resize && ((old_w != gib_imlib_image_get_width(tmp)) || - (old_h != gib_imlib_image_get_height(tmp)))) - resize = 1; - - if (!force_new) - winwidget_free_image(w); - - w->im = tmp; - winwidget_reset_image(w); - - w->mode = MODE_NORMAL; - if ((w->im_w != gib_imlib_image_get_width(w->im)) - || (w->im_h != gib_imlib_image_get_height(w->im))) - w->had_resize = 1; - if (w->has_rotated) { - Imlib_Image temp; - - temp = gib_imlib_create_rotated_image(w->im, 0.0); - w->im_w = gib_imlib_image_get_width(temp); - w->im_h = gib_imlib_image_get_height(temp); - gib_imlib_free_image_and_decache(temp); - } else { - w->im_w = gib_imlib_image_get_width(w->im); - w->im_h = gib_imlib_image_get_height(w->im); - } - winwidget_render_image(w, resize, 0); - - return; -} - void slideshow_change_image(winwidget winwid, int change, int render) { gib_list *last = NULL; diff -Nru feh-3.3/.travis.yml feh-3.4/.travis.yml --- feh-3.3/.travis.yml 2019-12-03 16:33:06.000000000 +0000 +++ feh-3.4/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -language: c -addons: - apt: - packages: - - libcurl4-openssl-dev - - libx11-dev - - libxt-dev - - libimlib2-dev - - libxinerama-dev - - libjpeg-progs - - libtest-command-perl - - libtest-simple-perl - - libexif-dev - - libexif12 -script: - - make - - make test -compiler: - - clang - - gcc -env: - - default=1 - - app=1 - - curl=0 - - exif=1 - - help=1 - - stat64=1 - - verscmp=0 - - xinerama=0 - - inotify=1