void cb_reload_timer(void *data) { gib_list *l; char *current_filename; winwidget w = (winwidget) data; /* save the current filename for refinding it in new list */ current_filename = estrdup(FEH_FILE(current_file->data)->filename); for (l = filelist; l; l = l->next) { feh_file_free(l->data); l->data = NULL; } gib_list_free_and_data(filelist); filelist = NULL; filelist_len = 0; current_file = NULL; /* rebuild filelist from original_file_items */ if (gib_list_length(original_file_items) > 0) for (l = gib_list_last(original_file_items); l; l = l->prev) add_file_to_filelist_recursively(l->data, FILELIST_FIRST); else if (!opt.filelistfile && !opt.bgmode) add_file_to_filelist_recursively(".", FILELIST_FIRST); if (!(filelist_len = gib_list_length(filelist))) { eprintf("No files found to reload."); } /* find the previously current file */ for (l = filelist; l; l = l->next) if (strcmp(FEH_FILE(l->data)->filename, current_filename) == 0) { current_file = l; break; } free(current_filename); filelist = gib_list_first(gib_list_reverse(filelist)); if (!current_file) current_file = filelist; w->file = current_file; /* reset window name in case of current file order, * filename, or filelist_length has changed. */ current_filename = slideshow_create_name(FEH_FILE(current_file->data), w); winwidget_rename(w, current_filename); free(current_filename); feh_reload_image(w, 1, 0); if (opt.reload) feh_add_unique_timer(cb_reload_timer, w, opt.reload); return; }
void init_slideshow_mode(void) { winwidget w = NULL; int success = 0; char *s = NULL; gib_list *l = filelist, *last = NULL; feh_file *file = NULL; 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; break; } } if (opt.start_list_at) eprintf("--start-at %s: File not found in filelist", opt.start_list_at); mode = "slideshow"; for (; l; l = l->next) { file = FEH_FILE(l->data); if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } current_file = l; s = slideshow_create_name(file, NULL); if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SLIDESHOW)) != NULL) { free(s); success = 1; winwidget_show(w); if (opt.slideshow_delay > 0.0) feh_add_timer(cb_slide_timer, w, opt.slideshow_delay, "SLIDE_CHANGE"); if (opt.reload > 0) feh_add_unique_timer(cb_reload_timer, w, opt.reload); break; } else { free(s); last = l; } } if (!success) show_mini_usage(); return; }
void init_slideshow_mode(void) { winwidget w = NULL; 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; break; } } /* * 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); if (!opt.title) opt.title = PACKAGE " [%u of %l] - %f"; mode = "slideshow"; for (; l; l = l->next) { if (last) { filelist = feh_file_remove_from_list(filelist, last); last = NULL; } current_file = l; if ((w = winwidget_create_from_file(l, WIN_TYPE_SLIDESHOW)) != NULL) { success = 1; winwidget_show(w); if (opt.slideshow_delay > 0.0) feh_add_timer(cb_slide_timer, w, opt.slideshow_delay, "SLIDE_CHANGE"); if (opt.reload > 0) feh_add_unique_timer(cb_reload_timer, w, opt.reload); break; } else { last = l; } } if (!success) show_mini_usage(); return; }