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. --- src/filelist.c | 24 +++++++++++++++++++++++- src/filelist.h | 3 ++- src/help.raw | 3 ++- src/options.c | 2 ++ 4 files changed, 29 insertions(+), 3 deletions(-) (limited to 'src') 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 --- src/filelist.c | 5 +++++ src/imlib.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) (limited to 'src') 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