diff options
| -rw-r--r-- | man/feh.pre | 23 | ||||
| -rw-r--r-- | src/slideshow.c | 46 | 
2 files changed, 56 insertions, 13 deletions
| 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); | 
