From 6bdf2eef44b667298aa8f7bd61aa59e59050f588 Mon Sep 17 00:00:00 2001 From: Olof-Joachim Frahm Date: Wed, 3 Oct 2018 00:06:33 +0200 Subject: Use output directory for image saving command. --- src/slideshow.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/slideshow.c') diff --git a/src/slideshow.c b/src/slideshow.c index 3770677..63c0a11 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -615,18 +615,21 @@ void slideshow_save_image(winwidget win) { char *tmpname; Imlib_Load_Error err; + char *base_dir = estrjoin("", opt.output_dir ? opt.output_dir : "", "/", NULL); if (win->file) { - tmpname = feh_unique_filename("", FEH_FILE(win->file->data)->name); + tmpname = feh_unique_filename(base_dir, FEH_FILE(win->file->data)->name); } else if (mode) { char *tmp; tmp = estrjoin(".", mode, "png", NULL); - tmpname = feh_unique_filename("", tmp); + tmpname = feh_unique_filename(base_dir, tmp); free(tmp); } else { - tmpname = feh_unique_filename("", "noname.png"); + tmpname = feh_unique_filename(base_dir, "noname.png"); } + free(base_dir); + if (opt.verbose) fprintf(stderr, "saving image to filename '%s'\n", tmpname); -- cgit v1.2.3 From 9803fc41e8e6a820634f41d2196bdced7cbbc99f Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 17 Oct 2018 20:40:17 +0200 Subject: Use random() instead of rand() to increase portability Quoting glibc rand(3): The versions of rand() and srand() in the Linux C Library use the same random number generator as random(3) and srandom(3), so the lower-order bits should be as random as the higher-order bits. However, on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits. Do not use this function in applications intended to be portable when good randomness is needed. (Use random(3) instead.) --- src/collage.c | 4 ++-- src/gib_list.c | 2 +- src/keyevents.c | 2 +- src/main.c | 2 +- src/slideshow.c | 2 +- src/wallpaper.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/slideshow.c') diff --git a/src/collage.c b/src/collage.c index 2a4d9f9..b616bef 100644 --- a/src/collage.c +++ b/src/collage.c @@ -145,8 +145,8 @@ void init_collage_mode(void) } /* pick random coords for thumbnail */ - xxx = ((w - www) * ((double) rand() / RAND_MAX)); - yyy = ((h - hhh) * ((double) rand() / RAND_MAX)); + xxx = ((w - www) * ((double) random() / RAND_MAX)); + yyy = ((h - hhh) * ((double) random() / RAND_MAX)); D(("image going on at x=%d, y=%d\n", xxx, yyy)); im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, diff --git a/src/gib_list.c b/src/gib_list.c index 5384d98..a8ba1dd 100644 --- a/src/gib_list.c +++ b/src/gib_list.c @@ -362,7 +362,7 @@ gib_list_randomize(gib_list * list) } for (i = 0; i < len - 1; i++) { - r = i + rand() / (RAND_MAX / (len - i) + 1 ); + r = i + random() / (RAND_MAX / (len - i) + 1 ); t = farray[r]; farray[r] = farray[i]; farray[i] = t; diff --git a/src/keyevents.c b/src/keyevents.c index 689aebd..43bc82a 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -686,7 +686,7 @@ void feh_event_handle_generic(winwidget winwid, unsigned int state, KeySym keysy } else if (feh_is_kp(EVENT_jump_random, state, keysym, button)) { if (winwid->type == WIN_TYPE_THUMBNAIL) - feh_thumbnail_select_next(winwid, rand() % (filelist_len - 1)); + feh_thumbnail_select_next(winwid, random() % (filelist_len - 1)); else slideshow_change_image(winwid, SLIDE_RAND, 1); } diff --git a/src/main.c b/src/main.c index 1a76e2d..779e0bd 100644 --- a/src/main.c +++ b/src/main.c @@ -42,7 +42,7 @@ int main(int argc, char **argv) { atexit(feh_clean_exit); - srand(getpid() * time(NULL) % ((unsigned int) -1)); + srandom(getpid() * time(NULL) % ((unsigned int) -1)); setup_signal_handlers(); init_parse_options(argc, argv); diff --git a/src/slideshow.c b/src/slideshow.c index 3770677..b404318 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -258,7 +258,7 @@ void slideshow_change_image(winwidget winwid, int change, int render) case SLIDE_RAND: if (filelist_len > 1) { current_file = feh_list_jump(filelist, current_file, FORWARD, - (rand() % (filelist_len - 1)) + 1); + (random() % (filelist_len - 1)) + 1); change = SLIDE_NEXT; } break; diff --git a/src/wallpaper.c b/src/wallpaper.c index db14a8c..ef7ecca 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -252,7 +252,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XGCValues gcval; GC gc; char bgname[20]; - int num = (int) rand(); + int num = (int) random(); char bgfil[4096]; char sendbuf[4096]; -- cgit v1.2.3 From ddf90e154a33a4e15054d962124f381eb3608fa2 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 18 Nov 2018 20:19:49 +0100 Subject: Make slideshow_save_image work again when opt.output_dir is unset --- src/slideshow.c | 9 +++++++-- src/utils.c | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/slideshow.c') diff --git a/src/slideshow.c b/src/slideshow.c index 19aeaee..145bee1 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -615,7 +615,10 @@ void slideshow_save_image(winwidget win) { char *tmpname; Imlib_Load_Error err; - char *base_dir = estrjoin("", opt.output_dir ? opt.output_dir : "", "/", NULL); + char *base_dir = ""; + if (opt.output_dir) { + base_dir = estrjoin("", opt.output_dir, "/", NULL); + } if (win->file) { tmpname = feh_unique_filename(base_dir, FEH_FILE(win->file->data)->name); @@ -628,7 +631,9 @@ void slideshow_save_image(winwidget win) tmpname = feh_unique_filename(base_dir, "noname.png"); } - free(base_dir); + if (opt.output_dir) { + free(base_dir); + } if (opt.verbose) fprintf(stderr, "saving image to filename '%s'\n", tmpname); diff --git a/src/utils.c b/src/utils.c index ec30d4a..087e7f6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -152,6 +152,7 @@ char path_is_url(char *path) { return 0; } +/* Note: path must end with a trailing / or be an empty string */ /* free the result please */ char *feh_unique_filename(char *path, char *basename) { -- cgit v1.2.3 From 55c27c4babcf63989192f930ba7a75dac691e1e5 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Sun, 18 Nov 2018 21:26:43 +0100 Subject: --start-at: Compare basenames if exact match failed This more closely resembles the expected behaviour of --start-at, but may lead to mismatches if several files in the filelist have the same basename. Closes #206 Related to #372 and #420 --- man/feh.pre | 23 ++++++++++------------- src/slideshow.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 13 deletions(-) (limited to 'src/slideshow.c') diff --git a/man/feh.pre b/man/feh.pre index 173410e..e401ab5 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -729,20 +729,17 @@ to sort numbers naturally, so that e.g. 10.jpg comes after 2.jpg. Start the filelist at .Ar filename . . -Note that at the moment, +If you use relative paths in your filelist, .Ar filename -must match an -.Pq expanded -path in the filelist. -So, if the file to be matched is passed via an absolute path in the filelist, -.Ar filename -must be an absolute path. -If the file is passed via a relative path, -.Ar filename -must be an identical relative path. -This is a known issue. -See also -.Sx USAGE EXAMPLES . +should also be a relative path. +If you use absolute paths, it should also be an absolute path. +. +If +.Nm +cannot find an exact match, it will compare basenames +.Pq filenames without the directory suffix . +Note that this may lead to mismatches if several files in your filelist +have the same basename. . .It Cm -T , --theme Ar theme . diff --git a/src/slideshow.c b/src/slideshow.c index 145bee1..145ced1 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -37,6 +37,24 @@ void init_slideshow_mode(void) int success = 0; gib_list *l = filelist, *last = NULL; + /* + * In theory, --start-at FILENAME is simple: Look for a file called + * FILENAME, start the filelist there, done. + * + * In practice, there are cases where this isn't sufficient. For instance, + * a user running 'feh --start-at hello.jpg /tmp' will expect feh to start + * at /tmp/hello.jpg, as if they had used + * 'feh --start-at /tmp/hello.jpg /tmp'. Similarly, XDG Desktop files + * may lead to the invocation 'feh --start-at /tmp/hello.jpg .' in /tmp, + * expecting the behaviour of 'feh --start-at ./hello.jpg .'. + * + * Since a good user experience is not about being technically correct, but + * about delivering the expected behaviour, we do some fuzzy matching + * here. In the worst case, this will cause --start-at to start at the + * wrong file. + */ + + // Try finding an exact filename match first for (; l && opt.start_list_at; l = l->next) { if (!strcmp(opt.start_list_at, FEH_FILE(l->data)->filename)) { opt.start_list_at = NULL; @@ -44,6 +62,34 @@ void init_slideshow_mode(void) } } + /* + * If it didn't work (opt.start_list_at is still set): Fall back to + * comparing just the filenames without directory prefixes. This may lead + * to false positives, but for now that's just the way it is. + */ + if (opt.start_list_at) { + char *current_filename; + char *start_at_filename = strrchr(opt.start_list_at, '/'); + if (start_at_filename) { + start_at_filename++; // We only care about the part after the '/' + } else { + start_at_filename = opt.start_list_at; + } + for (l = filelist; l && opt.start_list_at; l = l->next) { + current_filename = strrchr(FEH_FILE(l->data)->filename, '/'); + if (current_filename) { + current_filename++; // We only care about the part after the '/' + } else { + current_filename = FEH_FILE(l->data)->filename; + } + if (!strcmp(start_at_filename, current_filename)) { + opt.start_list_at = NULL; + break; + } + } + } + + // If that didn't work either, we're out of luck. if (opt.start_list_at) eprintf("--start-at %s: File not found in filelist", opt.start_list_at); -- cgit v1.2.3