Commit 55c27c4b authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

--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
parent 05ab8b33
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -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
.
+46 −0
Original line number Diff line number Diff line
@@ -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);