From 71c7ff9ff8eca3008f4b08ef1c4a670b9eb7c7fa Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 30 Jan 2013 13:05:14 +0100 Subject: Add option and keybinding to keep zoom and viewport settings. Patch by sdaau on IRC. Thanks! --- src/help.raw | 1 + src/keyevents.c | 6 ++++++ src/menu.c | 12 +++++++++++- src/options.c | 4 ++++ src/options.h | 2 ++ src/slideshow.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 71 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/help.raw b/src/help.raw index 8e25b00..27e3b6c 100644 --- a/src/help.raw +++ b/src/help.raw @@ -28,6 +28,7 @@ OPTIONS mode or when window geometry is fixed. If combined with --auto-zoom, zooming will be limited to the the size. + --keep-zoom-vp Keep viewport zoom and settings while changing images -w, --multiwindow Open all files at once, one window per image -x, --borderless Create borderless windows -d, --draw-filename Show the filename in the image window diff --git a/src/keyevents.c b/src/keyevents.c index 470d624..9bda112 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -154,6 +154,7 @@ void init_keyevents(void) { feh_set_kb(&keys.mirror, 0, XK_bar, 0, 0, 0, 0); feh_set_kb(&keys.reload_minus, 0, XK_minus, 0, 0, 0, 0); feh_set_kb(&keys.reload_plus, 0, XK_plus, 0, 0, 0, 0); + feh_set_kb(&keys.toggle_keep_vp, 0, XK_k, 0, 0, 0, 0); home = getenv("HOME"); if (!home) @@ -307,6 +308,8 @@ void init_keyevents(void) { cur_kb = &keys.reload_minus; else if (!strcmp(action, "reload_plus")) cur_kb = &keys.reload_plus; + else if (!strcmp(action, "toggle_keep_vp")) + cur_kb = &keys.toggle_keep_vp; else weprintf("keys: Invalid action: %s", action); @@ -761,5 +764,8 @@ void feh_event_handle_keypress(XEvent * ev) else if (opt.verbose) weprintf("Cannot set RELOAD lower than 1 second."); } + else if (feh_is_kp(&keys.toggle_keep_vp, keysym, state)) { + opt.keep_zoom_vp = !opt.keep_zoom_vp; + } return; } diff --git a/src/menu.c b/src/menu.c index ee045ae..722ce02 100644 --- a/src/menu.c +++ b/src/menu.c @@ -56,7 +56,7 @@ enum { CB_SORT_FILENAME, CB_SORT_IMAGENAME, CB_SORT_FILESIZE, CB_SORT_RANDOMIZE, CB_SAVE_IMAGE, CB_SAVE_FILELIST, CB_FIT, CB_OPT_DRAW_FILENAME, CB_OPT_DRAW_ACTIONS, CB_OPT_KEEP_HTTP, CB_OPT_FREEZE_WINDOW, - CB_OPT_FULLSCREEN, CB_EDIT_ROTATE, CB_OPT_AUTO_ZOOM + CB_OPT_FULLSCREEN, CB_EDIT_ROTATE, CB_OPT_AUTO_ZOOM, CB_OPT_KEEP_ZOOM_VP }; feh_menu *feh_menu_new(void) @@ -1326,6 +1326,14 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat opt.zoom_mode = 0; winwidget_rerender_all(1); break; + case CB_OPT_KEEP_ZOOM_VP: + MENU_ITEM_TOGGLE(i); + if (MENU_ITEM_IS_ON(i)) + opt.keep_zoom_vp = 1; + else + opt.keep_zoom_vp = 0; + winwidget_rerender_all(1); + break; } return; } @@ -1381,6 +1389,8 @@ static feh_menu *feh_menu_func_gen_options(feh_menu * m) CB_OPT_FREEZE_WINDOW, 0, NULL, opt.geom_flags); feh_menu_add_toggle_entry(mm, "Fullscreen", NULL, CB_OPT_FULLSCREEN, 0, NULL, m->fehwin->full_screen); + feh_menu_add_toggle_entry(mm, "Keep viewport zoom & pos", NULL, + CB_OPT_KEEP_ZOOM_VP, 0, NULL, opt.keep_zoom_vp); feh_menu_add_entry(mm, NULL, NULL, 0, 0, NULL); diff --git a/src/options.c b/src/options.c index 240b0d6..cdd37d1 100644 --- a/src/options.c +++ b/src/options.c @@ -397,6 +397,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"info" , 1, 0, 234}, {"force-aliasing", 0, 0, 235}, {"no-fehbg" , 0, 0, 236}, + {"keep-zoom-vp" , 0, 0, 237}, {0, 0, 0, 0} }; @@ -722,6 +723,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) case 236: opt.no_fehbg = 1; break; + case 237: + opt.keep_zoom_vp = 1; + break; default: break; } diff --git a/src/options.h b/src/options.h index d30c396..f3f49eb 100644 --- a/src/options.h +++ b/src/options.h @@ -72,6 +72,7 @@ struct __fehoptions { unsigned char text_bg; unsigned char image_bg; unsigned char no_fehbg; + unsigned char keep_zoom_vp; char *output_file; char *output_dir; @@ -189,6 +190,7 @@ struct __fehkb { struct __fehkey toggle_fullscreen; struct __fehkey reload_minus; struct __fehkey reload_plus; + struct __fehkey toggle_keep_vp; }; struct __fehbutton { diff --git a/src/slideshow.c b/src/slideshow.c index d79c859..65aae3d 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -149,6 +149,16 @@ void feh_reload_image(winwidget w, int resize, int force_new) Imlib_Image tmp; int old_w, old_h; + unsigned char tmode =0; + int tim_x =0; + int tim_y =0; + double tzoom =0; + + tmode = w->mode; + tim_x = w->im_x; + tim_y = w->im_y; + tzoom = w->zoom; + if (!w->file) { im_weprintf(w, "couldn't reload, this image has no file associated with it."); winwidget_render_image(w, 0, 0); @@ -216,7 +226,16 @@ void feh_reload_image(winwidget w, int resize, int force_new) 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); + if (opt.keep_zoom_vp) { + /* put back in: */ + w->mode = tmode; + w->im_x = tim_x; + w->im_y = tim_y; + w->zoom = tzoom; + winwidget_render_image(w, 0, 0); + } else { + winwidget_render_image(w, resize, 0); + } winwidget_rename(w, title); free(title); @@ -236,6 +255,11 @@ void slideshow_change_image(winwidget winwid, int change, int render) int our_filelist_len = filelist_len; char *s; + unsigned char tmode =0; + int tim_x =0; + int tim_y =0; + double tzoom =0; + /* Without this, clicking a one-image slideshow reloads it. Not very * intelligent behaviour :-) */ if (filelist_len < 2 && opt.cycle_once == 0) @@ -308,6 +332,14 @@ void slideshow_change_image(winwidget winwid, int change, int render) last = NULL; } + if (opt.keep_zoom_vp) { + /* pre loadimage - record settings */ + tmode = winwid->mode; + tim_x = winwid->im_x; + tim_y = winwid->im_y; + tzoom = winwid->zoom; + } + if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data))) != 0) { winwid->mode = MODE_NORMAL; @@ -318,8 +350,20 @@ void slideshow_change_image(winwidget winwid, int change, int render) winwidget_reset_image(winwid); winwid->im_w = gib_imlib_image_get_width(winwid->im); winwid->im_h = gib_imlib_image_get_height(winwid->im); - if (render) - winwidget_render_image(winwid, 1, 0); + if (opt.keep_zoom_vp) { + /* put back in: */ + winwid->mode = tmode; + winwid->im_x = tim_x; + winwid->im_y = tim_y; + winwid->zoom = tzoom; + } + if (render) { + if (opt.keep_zoom_vp) { + winwidget_render_image(winwid, 0, 0); + } else { + winwidget_render_image(winwid, 1, 0); + } + } s = slideshow_create_name(FEH_FILE(current_file->data), winwid); winwidget_rename(winwid, s); -- cgit v1.2.3 From 4fae6007dd64d223cdae3f977003f38e3036bada Mon Sep 17 00:00:00 2001 From: guns Date: Fri, 18 Jan 2013 03:19:36 -0600 Subject: New sort option: mtime Sort filelist by modification time, newer files first. Useful for perusing a directory of images by most recently added or changed. --- man/feh.pre | 9 +++++++-- src/filelist.c | 24 +++++++++++++++++++++++- src/filelist.h | 3 ++- src/help.raw | 3 ++- src/options.c | 2 ++ 5 files changed, 36 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/man/feh.pre b/man/feh.pre index f24729d..cecc58f 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -532,10 +532,15 @@ in paused mode. .It Cm -S , --sort Ar sort_type . The file list may be sorted according to image parameters. Allowed sort -types are: name, filename, width, height, pixels, size, format. For sort -modes other than name or filename, a preload run will be necessary, +types are: name, filename, mtime, width, height, pixels, size, format. For sort +modes other than name, filename, or mtime, a preload run will be necessary, causing a delay proportional to the number of images in the list. . +.Pp +. +The mtime sort mode sorts images by most recently modified. To sort by oldest +first, reverse the filelist with --reverse. +. .It Cm -| , --start-at Ar filename . Start the filelist at diff --git a/src/filelist.c b/src/filelist.c index 542dbdf..8f3bfe9 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -354,6 +354,25 @@ int feh_cmp_name(void *file1, void *file2) return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); } +/* Return -1 if file1 is _newer_ than file2 */ +int feh_cmp_mtime(void *file1, void *file2) +{ + struct stat s1, s2; + + if (stat(FEH_FILE(file1)->filename, &s1)) { + feh_print_stat_error(FEH_FILE(file1)->filename); + return(-1); + } + + if (stat(FEH_FILE(file2)->filename, &s2)) { + feh_print_stat_error(FEH_FILE(file2)->filename); + return(-1); + } + + /* gib_list_sort is not stable, so explicitly return 0 as -1 */ + return(s1.st_mtime >= s2.st_mtime ? -1 : 1); +} + int feh_cmp_width(void *file1, void *file2) { return((FEH_FILE(file1)->info->width - FEH_FILE(file2)->info->width)); @@ -381,7 +400,7 @@ int feh_cmp_format(void *file1, void *file2) void feh_prepare_filelist(void) { - if (opt.list || opt.customlist || (opt.sort > SORT_FILENAME) + if (opt.list || opt.customlist || (opt.sort > SORT_MTIME) || opt.preload || opt.min_width || opt.min_height || (opt.max_width != UINT_MAX) || (opt.max_height != UINT_MAX)) { /* For these sort options, we have to preload images */ @@ -407,6 +426,9 @@ void feh_prepare_filelist(void) case SORT_FILENAME: filelist = gib_list_sort(filelist, feh_cmp_filename); break; + case SORT_MTIME: + filelist = gib_list_sort(filelist, feh_cmp_mtime); + break; case SORT_WIDTH: filelist = gib_list_sort(filelist, feh_cmp_width); break; diff --git a/src/filelist.h b/src/filelist.h index 00e36e8..7bfd518 100644 --- a/src/filelist.h +++ b/src/filelist.h @@ -56,7 +56,7 @@ struct __feh_file_info { enum filelist_recurse { FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST }; -enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_WIDTH, +enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_MTIME, SORT_WIDTH, SORT_HEIGHT, SORT_PIXELS, SORT_SIZE, SORT_FORMAT @@ -82,6 +82,7 @@ void feh_save_filelist(); int feh_cmp_name(void *file1, void *file2); int feh_cmp_filename(void *file1, void *file2); +int feh_cmp_mtime(void *file1, void *file2); int feh_cmp_width(void *file1, void *file2); int feh_cmp_height(void *file1, void *file2); int feh_cmp_pixels(void *file1, void *file2); diff --git a/src/help.raw b/src/help.raw index 27e3b6c..462e715 100644 --- a/src/help.raw +++ b/src/help.raw @@ -46,7 +46,8 @@ OPTIONS -U, --loadable List all loadable files. No image display -u, --unloadable List all unloadable files. No image display -S, --sort SORT_TYPE Sort files by: - name, filename, width, height, pixels, size or format + name, filename, mtime, width, height, pixels, size, + or format -n, --reverse Reverse sort order -A, --action ACTION Specify action to perform when pressing . Executed by /bin/sh, may contain FORMAT SPECIFIERS diff --git a/src/options.c b/src/options.c index cdd37d1..469115e 100644 --- a/src/options.c +++ b/src/options.c @@ -501,6 +501,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) opt.sort = SORT_NAME; else if (!strcasecmp(optarg, "filename")) opt.sort = SORT_FILENAME; + else if (!strcasecmp(optarg, "mtime")) + opt.sort = SORT_MTIME; else if (!strcasecmp(optarg, "width")) opt.sort = SORT_WIDTH; else if (!strcasecmp(optarg, "height")) -- cgit v1.2.3 From 6ea43a3213bb264525e04c729c67204f82c7a2c8 Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 1 Feb 2013 17:46:50 +0100 Subject: support "feh -" to read from stdin. closes #118 --- ChangeLog | 1 + man/feh.pre | 4 ++++ src/filelist.c | 5 +++++ src/imlib.c | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/ChangeLog b/ChangeLog index 29238dd..561abfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ git HEAD images (patch by sdaau). Press 'k' to toggle it. * Add --sort mtime option (patch by guns) * Add a desktop file (installed to share/applications/feh.desktop) + * Use "feh -" to read image from stdin Mon, 24 Dec 2012 15:45:54 +0100 Daniel Friesel diff --git a/man/feh.pre b/man/feh.pre index cecc58f..a1df25a 100644 --- a/man/feh.pre +++ b/man/feh.pre @@ -72,6 +72,10 @@ image in it, the keyboard and mouse can be used to change slides In slideshow mode, images can be deleted either from the filelist or from the disk, the new filelist can then be saved to the disk and reopened at a later time. +An image can also be read from stdin via +.Qq feh - . +However, you should not combine reading from stdin with normal file / filelist +usage. . .Pp . diff --git a/src/filelist.c b/src/filelist.c index 8f3bfe9..3ea0928 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -185,6 +185,11 @@ void add_file_to_filelist_recursively(char *origpath, unsigned char level) /* We'll download it later... */ free(path); return; + } else if ((len == 1) && (path[0] == '-')) { + D(("Addig stdin (-) to filelist\n")); + filelist = gib_list_add_front(filelist, feh_file_new(path)); + free(path); + return; } else if (opt.filelistfile) { char *newpath = feh_absolute_path(path); diff --git a/src/imlib.c b/src/imlib.c index e9f92ad..bdf54ac 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -61,6 +61,7 @@ int num_xinerama_screens; int childpid = 0; +static char *feh_stdin_load_image(); static char *feh_http_load_image(char *url); static char *feh_magick_load_image(char *filename); @@ -209,7 +210,8 @@ void feh_imlib_print_load_error(char *file, winwidget w, Imlib_Load_Error err) int feh_load_image(Imlib_Image * im, feh_file * file) { Imlib_Load_Error err; - enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK } image_source = SRC_IMLIB; + enum { SRC_IMLIB, SRC_HTTP, SRC_MAGICK, SRC_STDIN } image_source = + SRC_IMLIB; char *tmpname = NULL; char *real_filename = NULL; @@ -225,6 +227,10 @@ int feh_load_image(Imlib_Image * im, feh_file * file) tmpname = feh_http_load_image(file->filename); } + if ((strlen(file->filename) == 1) && (file->filename[0] == '-')) { + image_source = SRC_STDIN; + tmpname = feh_stdin_load_image(); + } else *im = imlib_load_image_with_error_return(file->filename, &err); @@ -269,6 +275,38 @@ int feh_load_image(Imlib_Image * im, feh_file * file) return(1); } +static char *feh_stdin_load_image() +{ + char buf[1024]; + size_t readsize; + char *sfn = estrjoin("_", "/tmp/feh_stdin", "XXXXXX", NULL); + int fd = mkstemp(sfn); + FILE *outfile; + + if (fd == -1) { + free(sfn); + return NULL; + } + + outfile = fdopen(fd, "w"); + + if (outfile == NULL) { + free(sfn); + return NULL; + } + + while ((readsize = fread(buf, sizeof(char), sizeof(buf), stdin)) > 0) { + if (fwrite(buf, sizeof(char), readsize, outfile) < readsize) { + free(sfn); + return NULL; + } + } + + fclose(outfile); + + return sfn; +} + static char *feh_magick_load_image(char *filename) { char argv_fd[12]; -- cgit v1.2.3