diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/events.c | 13 | ||||
-rw-r--r-- | src/events.h | 2 | ||||
-rw-r--r-- | src/feh.h | 4 | ||||
-rw-r--r-- | src/feh_png.c | 5 | ||||
-rw-r--r-- | src/filelist.c | 58 | ||||
-rw-r--r-- | src/filelist.h | 23 | ||||
-rw-r--r-- | src/help.raw | 7 | ||||
-rw-r--r-- | src/imlib.c | 107 | ||||
-rw-r--r-- | src/keyevents.c | 26 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/menu.c | 66 | ||||
-rw-r--r-- | src/options.c | 43 | ||||
-rw-r--r-- | src/options.h | 5 | ||||
-rw-r--r-- | src/slideshow.c | 45 | ||||
-rw-r--r-- | src/wallpaper.c | 113 | ||||
-rw-r--r-- | src/winwidget.c | 76 | ||||
-rw-r--r-- | src/winwidget.h | 2 |
17 files changed, 447 insertions, 154 deletions
diff --git a/src/events.c b/src/events.c index 76c3e64..23a14ba 100644 --- a/src/events.c +++ b/src/events.c @@ -41,7 +41,6 @@ feh_event_handler *ev_handler[LASTEvent]; static void feh_event_handle_ButtonPress(XEvent * ev); static void feh_event_handle_ButtonRelease(XEvent * ev); -static void feh_event_handle_ConfigureNotify(XEvent * ev); static void feh_event_handle_LeaveNotify(XEvent * ev); static void feh_event_handle_MotionNotify(XEvent * ev); static void feh_event_handle_ClientMessage(XEvent * ev); @@ -129,6 +128,7 @@ void init_buttonbindings(void) while (fgets(line, sizeof(line), conf)) { *action = '\0'; *button = '\0'; + cur_bb = NULL; read = sscanf(line, "%31s %7s\n", (char *) &action, (char *) &button); @@ -378,10 +378,13 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) y /= winwid->zoom; thumbfile = feh_thumbnail_get_file_from_coords(x, y); if (thumbfile) { - if (opt.actions[0]) + if (opt.actions[0]) { feh_action_run(thumbfile, opt.actions[0]); - else + if (!opt.hold_actions[0]) + feh_thumbnail_mark_removed(thumbfile, 0); + } else { feh_thumbnail_show_fullsize(thumbfile); + } } } } else { @@ -413,7 +416,7 @@ static void feh_event_handle_ButtonRelease(XEvent * ev) return; } -static void feh_event_handle_ConfigureNotify(XEvent * ev) +void feh_event_handle_ConfigureNotify(XEvent * ev) { while (XCheckTypedWindowEvent(disp, ev->xconfigure.window, ConfigureNotify, ev)); if (!menu_root) { @@ -636,7 +639,7 @@ static void feh_event_handle_MotionNotify(XEvent * ev) winwid->im_h = gib_imlib_image_get_height(temp); gib_imlib_free_image_and_decache(temp); if (!winwid->full_screen && !opt.geom_flags) - winwidget_resize(winwid, winwid->im_w, winwid->im_h); + winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); winwid->has_rotated = 1; } winwid->im_angle = (ev->xmotion.x - winwid->w / 2) / ((double) winwid->w / 2) * 3.1415926535; diff --git a/src/events.h b/src/events.h index 195f268..f334c58 100644 --- a/src/events.h +++ b/src/events.h @@ -32,4 +32,6 @@ extern feh_event_handler *ev_handler[]; void feh_event_init(void); +void feh_event_handle_ConfigureNotify(XEvent * ev); + #endif @@ -102,7 +102,9 @@ enum text_bg { TEXT_BG_CLEAR = 0, TEXT_BG_TINTED }; enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST, SLIDE_JUMP_FWD, - SLIDE_JUMP_BACK + SLIDE_JUMP_BACK, + SLIDE_JUMP_NEXT_DIR, + SLIDE_JUMP_PREV_DIR }; enum image_bg { IMAGE_BG_CHECKS = 1, IMAGE_BG_BLACK, IMAGE_BG_WHITE }; diff --git a/src/feh_png.c b/src/feh_png.c index f02aecb..129eb45 100644 --- a/src/feh_png.c +++ b/src/feh_png.c @@ -115,12 +115,15 @@ int feh_png_write_png(Imlib_Image image, char *file, ...) return 0; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) + if (!png_ptr) { + fclose(fp); return 0; + } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + fclose(fp); return 0; } diff --git a/src/filelist.c b/src/filelist.c index eaef54b..b569b8a 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -383,6 +383,20 @@ int feh_file_info_load(feh_file * file, Imlib_Image im) return(0); } +void feh_file_dirname(char *dst, feh_file * f, int maxlen) +{ + int n = strlen(f->filename) - strlen(f->name); + + /* Give up on long dirnames */ + if (n <= 0 || n >= maxlen) { + dst[0] = '\0'; + return; + } + + strncpy(dst, f->filename, n); + dst[n] = '\0'; +} + int feh_cmp_filename(void *file1, void *file2) { return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); @@ -393,6 +407,17 @@ int feh_cmp_name(void *file1, void *file2) return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); } +int feh_cmp_dirname(void *file1, void *file2) +{ + char dir1[PATH_MAX], dir2[PATH_MAX]; + int cmp; + feh_file_dirname(dir1, FEH_FILE(file1), PATH_MAX); + feh_file_dirname(dir2, FEH_FILE(file2), PATH_MAX); + if ((cmp = strcmp(dir1, dir2)) != 0) + return(cmp); + return(feh_cmp_name(file1, file2)); +} + /* Return -1 if file1 is _newer_ than file2 */ int feh_cmp_mtime(void *file1, void *file2) { @@ -465,6 +490,9 @@ void feh_prepare_filelist(void) case SORT_FILENAME: filelist = gib_list_sort(filelist, feh_cmp_filename); break; + case SORT_DIRNAME: + filelist = gib_list_sort(filelist, feh_cmp_dirname); + break; case SORT_MTIME: filelist = gib_list_sort(filelist, feh_cmp_mtime); break; @@ -523,6 +551,7 @@ gib_list *feh_read_filelist(char *filename) FILE *fp; gib_list *list = NULL; char s[1024], s1[1024]; + Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; Imlib_Image tmp_im; struct stat st; signed short tmp_magick_timeout; @@ -535,17 +564,26 @@ gib_list *feh_read_filelist(char *filename) */ tmp_magick_timeout = opt.magick_timeout; opt.magick_timeout = -1; - if (!stat(filename, &st) && S_ISREG(st.st_mode) && - feh_load_image_char(&tmp_im, filename)) { - weprintf("Filelist file %s is an image, refusing to use it.\n" - "Did you mix up -f and -F?", filename); - opt.filelistfile = NULL; - return NULL; + if (!stat(filename, &st) && S_ISREG(st.st_mode)) { + tmp_im = imlib_load_image_with_error_return(filename, &err); + if (err == IMLIB_LOAD_ERROR_NONE) { + gib_imlib_free_image_and_decache(tmp_im); + weprintf("Filelist file %s is an image, refusing to use it.\n" + "Did you mix up -f and -F?", filename); + opt.filelistfile = NULL; + return NULL; + } } opt.magick_timeout = tmp_magick_timeout; errno = 0; - if ((fp = fopen(filename, "r")) == NULL) { + + if (!strcmp(filename, "/dev/stdin")) + fp = stdin; + else + fp = fopen(filename, "r"); + + if (fp == NULL) { /* return quietly, as it's okay to specify a filelist file that doesn't exist. In that case we create it on exit. */ return(NULL); @@ -561,7 +599,8 @@ gib_list *feh_read_filelist(char *filename) /* Add it to the new list */ list = gib_list_add_front(list, feh_file_new(s1)); } - fclose(fp); + if (strcmp(filename, "/dev/stdin")) + fclose(fp); return(list); } @@ -584,7 +623,8 @@ char *feh_absolute_path(char *path) /* I SHOULD be able to just use a simple realpath() here, but dumb * old Solaris's realpath doesn't return an absolute path if the path you give it is relative. Linux and BSD get this right... */ - getcwd(cwd, sizeof(cwd)); + if (getcwd(cwd, sizeof(cwd)) == NULL) + eprintf("Cannot determine working directory:"); snprintf(temp, sizeof(temp), "%s/%s", cwd, path); if (realpath(temp, fullpath) != NULL) { ret = estrdup(fullpath); diff --git a/src/filelist.h b/src/filelist.h index 7bfd518..e24a6a6 100644 --- a/src/filelist.h +++ b/src/filelist.h @@ -54,12 +54,29 @@ struct __feh_file_info { #define FEH_FILE(l) ((feh_file *) l) +/* + * PATH_MAX may not be defined on all systems. Since we only use it in for a + * getcwd call in feh_absolute_path, it isn't really worth the effort to malloc + * ever-increasing buffers until it fits. Instead, we just set it to 4096 and + * have --filelist and --bg-* hiccup if the path is larger. + */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + enum filelist_recurse { FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST }; -enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_MTIME, SORT_WIDTH, +enum sort_type { + SORT_NONE, + SORT_NAME, + SORT_FILENAME, + SORT_DIRNAME, + SORT_MTIME, + SORT_WIDTH, SORT_HEIGHT, SORT_PIXELS, - SORT_SIZE, SORT_FORMAT + SORT_SIZE, + SORT_FORMAT }; feh_file *feh_file_new(char *filename); @@ -73,6 +90,7 @@ void add_file_to_rm_filelist(char *file); void delete_rm_files(void); gib_list *feh_file_info_preload(gib_list * list); int feh_file_info_load(feh_file * file, Imlib_Image im); +void feh_file_dirname(char *dst, feh_file * f, int maxlen); void feh_prepare_filelist(void); int feh_write_filelist(gib_list * list, char *filename); gib_list *feh_read_filelist(char *filename); @@ -81,6 +99,7 @@ gib_list *feh_file_remove_from_list(gib_list * list, gib_list * l); void feh_save_filelist(); int feh_cmp_name(void *file1, void *file2); +int feh_cmp_dirname(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); diff --git a/src/help.raw b/src/help.raw index 4232860..03c8348 100644 --- a/src/help.raw +++ b/src/help.raw @@ -11,7 +11,9 @@ OPTIONS -q, --quiet Hide non-fatal errors. May be used with --verbose -T, --theme THEME Load options with name THEME -r, --recursive Recursively expand any directories in FILE to - the content of those directories. (Take it easy) + the content of those directories + --no-recursive Do not recursively expand directories + (this is the default) -z, --randomize Randomize the filelist --no-jump-on-resort Don't jump to the first image when the filelist is resorted @@ -38,6 +40,7 @@ OPTIONS --cycle-once Exit after one loop through the slideshow -R, --reload NUM Reload images after NUM seconds -k, --keep-http Keep local copies when viewing HTTP/FTP files + --insecure Disable peer/host verification when using HTTPS. -K, --caption-path PATH Path to caption directory, enables caption display -j, --output-dir With -k: Output directory for saved files -l, --list list mode: ls-style output with image information @@ -184,7 +187,7 @@ KEYS This program is free software, see the file COPYING for licensing info. Copyright Tom Gilbert (and various contributors) 1999-2003. -Copyright Daniel Friesel 2010-2014. +Copyright Daniel Friesel (and various contributors) 2010-2016. Homepage: http://feh.finalrewind.org Report bugs to <derf+feh@finalrewind.org> or #feh on irc.oftc.net. diff --git a/src/imlib.c b/src/imlib.c index 10ab718..16fbfba 100644 --- a/src/imlib.c +++ b/src/imlib.c @@ -78,8 +78,8 @@ void init_xinerama(void) XineramaQueryVersion(disp, &major, &minor); xinerama_screens = XineramaQueryScreens(disp, &num_xinerama_screens); - if (getenv("XINERAMA_SCREEN")) - xinerama_screen = atoi(getenv("XINERAMA_SCREEN")); + if (opt.xinerama_index >= 0) + xinerama_screen = opt.xinerama_index; else { xinerama_screen = 0; XQueryPointer(disp, root, &dw, &dw, &px, &py, &di, &di, &du); @@ -312,7 +312,13 @@ static char *feh_magick_load_image(char *filename) snprintf(argv_fd, sizeof(argv_fd), "png:fd:%d", fd); - if ((childpid = fork()) == 0) { + if ((childpid = fork()) < 0) { + weprintf("%s: Can't load with imagemagick. Fork failed:", filename); + unlink(sfn); + free(sfn); + sfn = NULL; + } + else if (childpid == 0) { /* discard convert output */ devnull = open("/dev/null", O_WRONLY); @@ -326,7 +332,7 @@ static char *feh_magick_load_image(char *filename) setpgid(0, 0); execlp("convert", "convert", filename, argv_fd, NULL); - exit(1); + _exit(1); } else { alarm(opt.magick_timeout); @@ -394,7 +400,7 @@ static char *feh_http_load_image(char *url) if (strlen(tmpname) > (NAME_MAX-6)) tmpname[NAME_MAX-7] = '\0'; - + sfn = estrjoin("_", tmpname, "XXXXXX", NULL); free(tmpname); @@ -411,6 +417,10 @@ static char *feh_http_load_image(char *url) curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, ebuff); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + if (opt.insecure_ssl) { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + } res = curl_easy_perform(curl); curl_easy_cleanup(curl); @@ -597,8 +607,12 @@ void feh_draw_filename(winwidget w) len = snprintf(NULL, 0, "%d of %d", gib_list_length(filelist), gib_list_length(filelist)) + 1; s = emalloc(len); - snprintf(s, len, "%d of %d", gib_list_num(filelist, current_file) + - 1, gib_list_length(filelist)); + if (w->file) + snprintf(s, len, "%d of %d", gib_list_num(filelist, w->file) + + 1, gib_list_length(filelist)); + else + snprintf(s, len, "%d of %d", gib_list_num(filelist, current_file) + + 1, gib_list_length(filelist)); gib_imlib_get_text_size(fn, s, NULL, &nw, NULL, IMLIB_TEXT_TO_RIGHT); @@ -631,7 +645,7 @@ void feh_draw_filename(winwidget w) return; } -#ifdef HAVE_LIBEXIF +#ifdef HAVE_LIBEXIF void feh_draw_exif(winwidget w) { static Imlib_Font fn = NULL; @@ -656,13 +670,13 @@ void feh_draw_exif(winwidget w) fn = feh_load_font(w); - if (buffer == NULL) + if (buffer == NULL) { snprintf(buffer, EXIF_MAX_DATA, "%s", estrdup("Failed to run exif command")); gib_imlib_get_text_size(fn, &buffer[0], NULL, &width, &height, IMLIB_TEXT_TO_RIGHT); no_lines = 1; } - else + else { while ( (no_lines < 128) && (pos < EXIF_MAX_DATA) ) @@ -688,9 +702,9 @@ void feh_draw_exif(winwidget w) pos++; break; } - + pos++; - pos2++; + pos2++; } gib_imlib_get_text_size(fn, info_line, NULL, &line_width, @@ -720,7 +734,7 @@ void feh_draw_exif(winwidget w) feh_imlib_image_fill_text_bg(im, width, height); - for (i = 0; i < no_lines; i++) + for (i = 0; i < no_lines; i++) { gib_imlib_text_draw(im, fn, NULL, 2, (i * line_height) + 2, info_buf[i], IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255); @@ -1007,28 +1021,29 @@ void feh_display_status(char stat) void feh_edit_inplace(winwidget w, int op) { - int ret; - Imlib_Image old; - Imlib_Load_Error err; + int tmp; + Imlib_Image old = NULL; + Imlib_Load_Error err = IMLIB_LOAD_ERROR_NONE; if (!w->file || !w->file->data || !FEH_FILE(w->file->data)->filename) return; - if (!strcmp(gib_imlib_image_format(w->im), "jpeg")) { + if (!strcmp(gib_imlib_image_format(w->im), "jpeg") && + !path_is_url(FEH_FILE(w->file->data)->filename)) { feh_edit_inplace_lossless(w, op); feh_reload_image(w, 1, 1); return; } - ret = feh_load_image(&old, FEH_FILE(w->file->data)); - if (ret) { - if (op == INPLACE_EDIT_FLIP) { - imlib_context_set_image(old); + old = imlib_load_image_with_error_return(FEH_FILE(w->file->data)->filename, &err); + + if ((old != NULL) && (err == IMLIB_LOAD_ERROR_NONE)) { + imlib_context_set_image(old); + if (op == INPLACE_EDIT_FLIP) imlib_image_flip_vertical(); - } else if (op == INPLACE_EDIT_MIRROR) { - imlib_context_set_image(old); + else if (op == INPLACE_EDIT_MIRROR) imlib_image_flip_horizontal(); - } else - gib_imlib_image_orientate(old, op); + else + imlib_image_orientate(op); gib_imlib_save_image_with_error_return(old, FEH_FILE(w->file->data)->filename, &err); gib_imlib_free_image(old); @@ -1037,7 +1052,23 @@ void feh_edit_inplace(winwidget w, int op) w, err); feh_reload_image(w, 1, 1); } else { - im_weprintf(w, "failed to load image from disk to edit it in place"); + /* + * Image was opened using curl/magick or has been deleted after + * opening it + */ + imlib_context_set_image(w->im); + if (op == INPLACE_EDIT_FLIP) + imlib_image_flip_vertical(); + else if (op == INPLACE_EDIT_MIRROR) + imlib_image_flip_horizontal(); + else { + imlib_image_orientate(op); + tmp = w->im_w; + FEH_FILE(w->file->data)->info->width = w->im_w = w->im_h; + FEH_FILE(w->file->data)->info->height = w->im_h = tmp; + } + im_weprintf(w, "unable to edit in place. Changes have not been saved."); + winwidget_render_image(w, 1, 0); } return; @@ -1165,15 +1196,16 @@ void feh_edit_inplace_lossless(winwidget w, int op) if ((pid = fork()) < 0) { im_weprintf(w, "lossless %s: fork failed:", op_name); - exit(1); + free(file_str); + return; } else if (pid == 0) { execlp("jpegtran", "jpegtran", "-copy", "all", op_op, op_value, "-outfile", file_str, file_str, NULL); - im_weprintf(w, "lossless %s: Is 'jpegtran' installed? Failed to exec:", op_name); - exit(1); + weprintf("lossless %s: Is 'jpegtran' installed? Failed to exec:", op_name); + _exit(1); } else { waitpid(pid, &status, 0); @@ -1189,8 +1221,7 @@ void feh_edit_inplace_lossless(winwidget w, int op) } } if ((pid = fork()) < 0) { - im_weprintf(w, "lossless %s: cannot fix rotation: fork:", op_name); - exit(1); + im_weprintf(w, "lossless %s: fork failed while updating EXIF tags:", op_name); } else if (pid == 0) { @@ -1199,8 +1230,8 @@ void feh_edit_inplace_lossless(winwidget w, int op) dup2(devnull, 1); execlp("jpegexiforient", "jpegexiforient", "-1", file_str, NULL); - im_weprintf(w, "lossless %s: Failed to exec jpegexiforient:", op_name); - exit(1); + weprintf("lossless %s: Failed to exec jpegexiforient:", op_name); + _exit(1); } else { waitpid(pid, &status, 0); @@ -1253,9 +1284,9 @@ void feh_draw_actions(winwidget w) for (i = 0; i < 10; i++) { if (opt.actions[i]) { - line = emalloc(strlen(opt.actions[i]) + 5); + line = emalloc(strlen(opt.action_titles[i]) + 5); strcpy(line, "0: "); - line = strcat(line, opt.actions[i]); + line = strcat(line, opt.action_titles[i]); gib_imlib_get_text_size(fn, line, NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); free(line); if (tw > max_tw) @@ -1285,13 +1316,13 @@ void feh_draw_actions(winwidget w) gib_imlib_text_draw(im, fn, NULL, 1, 1, "defined actions:", IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); for (i = 0; i < 10; i++) { - if (opt.actions[i]) { + if (opt.action_titles[i]) { cur_action++; - line = emalloc(strlen(opt.actions[i]) + 5); + line = emalloc(strlen(opt.action_titles[i]) + 5); sprintf(index, "%d", i); strcpy(line, index); strcat(line, ": "); - strcat(line, opt.actions[i]); + strcat(line, opt.action_titles[i]); gib_imlib_text_draw(im, fn, NULL, 2, (cur_action * line_th) + 2, line, diff --git a/src/keyevents.c b/src/keyevents.c index 83fc358..4837c0b 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -110,6 +110,8 @@ void init_keyevents(void) { feh_set_kb(&keys.next_img , 0, XK_Right , 0, XK_n , 0, XK_space); feh_set_kb(&keys.jump_back , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0); feh_set_kb(&keys.jump_fwd , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0); + feh_set_kb(&keys.prev_dir , 0, XK_bracketleft, 0, 0 , 0, 0); + feh_set_kb(&keys.next_dir , 0, XK_bracketright, 0, 0 , 0, 0); feh_set_kb(&keys.jump_random,0, XK_z , 0, 0 , 0, 0); feh_set_kb(&keys.quit , 0, XK_Escape , 0, XK_q , 0, 0); feh_set_kb(&keys.close , 0, XK_x , 0, 0 , 0, 0); @@ -178,6 +180,7 @@ void init_keyevents(void) { *k1 = '\0'; *k2 = '\0'; *k3 = '\0'; + cur_kb = NULL; read = sscanf(line, "%31s %31s %31s %31s\n", (char *) &action, (char *) &k1, (char* ) &k2, (char *) &k3); @@ -221,6 +224,10 @@ void init_keyevents(void) { cur_kb = &keys.jump_back; else if (!strcmp(action, "jump_fwd")) cur_kb = &keys.jump_fwd; + else if (!strcmp(action, "prev_dir")) + cur_kb = &keys.prev_dir; + else if (!strcmp(action, "next_dir")) + cur_kb = &keys.next_dir; else if (!strcmp(action, "jump_random")) cur_kb = &keys.jump_random; else if (!strcmp(action, "quit")) @@ -531,6 +538,14 @@ void feh_event_handle_keypress(XEvent * ev) else if (winwid->type == WIN_TYPE_THUMBNAIL) feh_thumbnail_select_next(winwid, 10); } + else if (feh_is_kp(&keys.next_dir, keysym, state)) { + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1); + } + else if (feh_is_kp(&keys.prev_dir, keysym, state)) { + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1); + } else if (feh_is_kp(&keys.quit, keysym, state)) { winwidget_destroy_all(); } @@ -612,14 +627,8 @@ void feh_event_handle_keypress(XEvent * ev) } else if (feh_is_kp(&keys.zoom_default, keysym, state)) { winwid->zoom = 1.0; - /* --scale-down will revert our operation if old_zoom == 1.0 */ - if (opt.scale_down) - winwid->old_zoom = 1.001; winwidget_center_image(winwid); winwidget_render_image(winwid, 0, 0); - /* --scale-down will also do weird stuff if zoom is 1.0 */ - if (opt.scale_down) - winwid->zoom = 1.001; } else if (feh_is_kp(&keys.zoom_fit, keysym, state)) { feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); @@ -731,9 +740,8 @@ void feh_event_handle_keypress(XEvent * ev) break; } } - if (getenv("XINERAMA_SCREEN")) - curr_screen = xinerama_screen = - atoi(getenv("XINERAMA_SCREEN")); + if (opt.xinerama_index >= 0) + curr_screen = xinerama_screen = opt.xinerama_index; } #endif /* HAVE_LIBXINERAMA */ winwid->full_screen = !winwid->full_screen; @@ -193,6 +193,12 @@ void feh_clean_exit(void) { delete_rm_files(); + free(opt.menu_bg); + free(opt.menu_font); + + if(disp) + XCloseDisplay(disp); + if (opt.filelistfile) feh_write_filelist(filelist, opt.filelistfile); @@ -49,14 +49,39 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i); enum { - CB_CLOSE = 1, CB_EXIT, CB_RELOAD, CB_REMOVE, CB_DELETE, CB_RESET, - CB_REMOVE_THUMB, CB_DELETE_THUMB, CB_BG_TILED, CB_BG_SCALED, - CB_BG_CENTERED, CB_BG_FILLED, CB_BG_TILED_NOFILE, - CB_BG_SCALED_NOFILE, CB_BG_CENTERED_NOFILE, CB_BG_FILLED_NOFILE, - 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_KEEP_ZOOM_VP + CB_CLOSE = 1, + CB_EXIT, + CB_RELOAD, + CB_REMOVE, + CB_DELETE, + CB_RESET, + CB_REMOVE_THUMB, + CB_DELETE_THUMB, + CB_BG_TILED, + CB_BG_SCALED, + CB_BG_CENTERED, + CB_BG_FILLED, + CB_BG_TILED_NOFILE, + CB_BG_SCALED_NOFILE, + CB_BG_CENTERED_NOFILE, + CB_BG_FILLED_NOFILE, + CB_SORT_FILENAME, + CB_SORT_IMAGENAME, + CB_SORT_DIRNAME, + CB_SORT_MTIME, + 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_KEEP_ZOOM_VP }; feh_menu *feh_menu_new(void) @@ -914,7 +939,7 @@ void feh_menu_init_common() opt.menu_fn = gib_imlib_load_font(opt.menu_font); if (!opt.menu_fn) eprintf - ("couldn't load menu font %s, did you make install?\nAre you specifying a nonexistant font?\nDid you tell feh where to find it with --fontpath?", + ("couldn't load menu font %s, did you make install?\nAre you specifying a nonexistent font?\nDid you tell feh where to find it with --fontpath?", opt.menu_font); } @@ -923,7 +948,9 @@ void feh_menu_init_common() feh_menu_add_entry(m, "By File Name", NULL, CB_SORT_FILENAME, 0, NULL); feh_menu_add_entry(m, "By Image Name", NULL, CB_SORT_IMAGENAME, 0, NULL); - if (opt.preload || (opt.sort > SORT_FILENAME)) + feh_menu_add_entry(m, "By Directory Name", NULL, CB_SORT_DIRNAME, 0, NULL); + feh_menu_add_entry(m, "By Modification Date", NULL, CB_SORT_MTIME, 0, NULL); + if (opt.preload || (opt.sort > SORT_MTIME)) feh_menu_add_entry(m, "By File Size", NULL, CB_SORT_FILESIZE, 0, NULL); feh_menu_add_entry(m, "Randomize", NULL, CB_SORT_RANDOMIZE, 0, NULL); @@ -1154,9 +1181,8 @@ void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i) } } - if (getenv("XINERAMA_SCREEN")) - curr_screen = xinerama_screen = - atoi(getenv("XINERAMA_SCREEN")); + if (opt.xinerama_index >= 0) + curr_screen = xinerama_screen = opt.xinerama_index; } #endif /* HAVE_LIBXINERAMA */ @@ -1219,7 +1245,7 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat if (m->fehwin->has_rotated) { m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im); m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im); - winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); + winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h, 0); } winwidget_reset_image(m->fehwin); winwidget_render_image(m->fehwin, 1, 0); @@ -1253,6 +1279,18 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); } break; + case CB_SORT_DIRNAME: + filelist = gib_list_sort(filelist, feh_cmp_dirname); + if (opt.jump_on_resort) { + slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); + } + break; + case CB_SORT_MTIME: + filelist = gib_list_sort(filelist, feh_cmp_mtime); + if (opt.jump_on_resort) { + slideshow_change_image(m->fehwin, SLIDE_FIRST, 1); + } + break; case CB_SORT_FILESIZE: filelist = gib_list_sort(filelist, feh_cmp_size); if (opt.jump_on_resort) { diff --git a/src/options.c b/src/options.c index cbeb729..9e2ff5a 100644 --- a/src/options.c +++ b/src/options.c @@ -70,6 +70,7 @@ void init_parse_options(int argc, char **argv) #ifdef HAVE_LIBXINERAMA /* if we're using xinerama, then enable it by default */ opt.xinerama = 1; + opt.xinerama_index = -1; #endif /* HAVE_LIBXINERAMA */ feh_getopt_theme(argc, argv); @@ -404,7 +405,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) {"no-fehbg" , 0, 0, 236}, {"keep-zoom-vp" , 0, 0, 237}, {"scroll-step" , 1, 0, 238}, - + {"xinerama-index", 1, 0, 239}, + {"insecure" , 0, 0, 240}, + {"no-recursive" , 0, 0, 241}, {0, 0, 0, 0} }; int optch = 0, cmdx = 0; @@ -511,6 +514,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, "dirname")) + opt.sort = SORT_DIRNAME; else if (!strcasecmp(optarg, "mtime")) opt.sort = SORT_MTIME; else if (!strcasecmp(optarg, "width")) @@ -528,6 +533,11 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) "sort by filename", optarg); opt.sort = SORT_FILENAME; } + if (opt.randomize) { + weprintf("commandline contains --randomize and --sort. " + "--randomize has been unset"); + opt.randomize = 0; + } break; case 'T': theme = estrdup(optarg); @@ -642,6 +652,11 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) break; case 'z': opt.randomize = 1; + if (opt.sort != SORT_NONE) { + weprintf("commandline contains --sort and --randomize. " + "--sort has been unset"); + opt.sort = SORT_NONE; + } break; case '|': opt.start_list_at = estrdup(optarg); @@ -744,6 +759,13 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) case 238: opt.scroll_step = atoi(optarg); break; + case 239: + opt.xinerama_index = atoi(optarg); + break; + case 240: + opt.insecure_ssl = 1; + case 241: + opt.recursive = 0; default: break; } @@ -770,10 +792,21 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun) static void check_options(void) { int i; + char *endptr; + for (i = 0; i < 10; i++) { if (opt.actions[i] && !opt.hold_actions[i] && (opt.actions[i][0] == ';')) { opt.hold_actions[i] = 1; - opt.actions[i] = &opt.actions[i][1]; + opt.actions[i] = opt.actions[i] + 1; + } + opt.action_titles[i] = opt.actions[i]; + if (opt.actions[i] && (opt.actions[i][0] == '[')) { + if (((endptr = strchr(opt.actions[i], ']')) != NULL) + && (opt.actions[i][1] != ' ')) { + opt.action_titles[i] = opt.actions[i] + 1; + opt.actions[i] = endptr + 1; + *endptr = 0; + } } } @@ -791,12 +824,6 @@ static void check_options(void) eprintf("You cannot combine --list with other modes"); } - if (opt.sort && opt.randomize) { - weprintf("You cant sort AND randomize the filelist...\n" - "randomize mode has been unset\n"); - opt.randomize = 0; - } - if (opt.loadables && opt.unloadables) { eprintf("You cannot combine --loadable with --unloadable"); } diff --git a/src/options.h b/src/options.h index a22cc05..bbf129f 100644 --- a/src/options.h +++ b/src/options.h @@ -73,6 +73,7 @@ struct __fehoptions { unsigned char image_bg; unsigned char no_fehbg; unsigned char keep_zoom_vp; + unsigned char insecure_ssl; char *output_file; char *output_dir; @@ -82,6 +83,7 @@ struct __fehoptions { char *title; char *thumb_title; char *actions[10]; + char *action_titles[10]; char *fontpath; char *filelistfile; char *menu_font; @@ -109,6 +111,7 @@ struct __fehoptions { int default_zoom; int zoom_mode; unsigned char adjust_reload; + int xinerama_index; /* signed in case someone wants to invert scrolling real quick */ int scroll_step; @@ -150,6 +153,8 @@ struct __fehkb { struct __fehkey jump_back; struct __fehkey quit; struct __fehkey jump_fwd; + struct __fehkey prev_dir; + struct __fehkey next_dir; struct __fehkey remove; struct __fehkey delete; struct __fehkey jump_first; diff --git a/src/slideshow.c b/src/slideshow.c index e42bd23..7ff4f39 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -322,6 +322,44 @@ void slideshow_change_image(winwidget winwid, int change, int render) try the previous file, not another jmp */ change = SLIDE_NEXT; break; + case SLIDE_JUMP_NEXT_DIR: + { + char old_dir[PATH_MAX], new_dir[PATH_MAX]; + int j; + + feh_file_dirname(old_dir, FEH_FILE(current_file->data), PATH_MAX); + + for (j = 0; j < our_filelist_len; j++) { + current_file = feh_list_jump(filelist, current_file, FORWARD, 1); + feh_file_dirname(new_dir, FEH_FILE(current_file->data), PATH_MAX); + if (strcmp(old_dir, new_dir) != 0) + break; + } + } + change = SLIDE_NEXT; + break; + case SLIDE_JUMP_PREV_DIR: + { + char old_dir[PATH_MAX], new_dir[PATH_MAX]; + int j; + + /* Start the search from the previous file in case we are on + the first file of a directory */ + current_file = feh_list_jump(filelist, current_file, BACK, 1); + feh_file_dirname(old_dir, FEH_FILE(current_file->data), PATH_MAX); + + for (j = 0; j < our_filelist_len; j++) { + current_file = feh_list_jump(filelist, current_file, BACK, 1); + feh_file_dirname(new_dir, FEH_FILE(current_file->data), PATH_MAX); + if (strcmp(old_dir, new_dir) != 0) + break; + } + + /* Next file is the first entry of prev_dir */ + current_file = feh_list_jump(filelist, current_file, FORWARD, 1); + } + change = SLIDE_NEXT; + break; default: eprintf("BUG!\n"); break; @@ -621,7 +659,12 @@ void feh_filelist_image_remove(winwidget winwid, char do_delete) feh_file_rm_and_free(filelist, doomed); exit(0); } - slideshow_change_image(winwid, SLIDE_NEXT, 0); + if (doomed->next) { + slideshow_change_image(winwid, SLIDE_NEXT, 0); + } + else { + slideshow_change_image(winwid, SLIDE_PREV, 0); + } if (do_delete) filelist = feh_file_rm_and_free(filelist, doomed); else diff --git a/src/wallpaper.c b/src/wallpaper.c index 3e19c41..a11a50d 100644 --- a/src/wallpaper.c +++ b/src/wallpaper.c @@ -292,27 +292,36 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, Atom prop_root, prop_esetroot, type; int format, i; unsigned long length, after; - unsigned char *data_root, *data_esetroot; + unsigned char *data_root = NULL, *data_esetroot = NULL; Pixmap pmap_d1, pmap_d2; gib_list *l; /* string for sticking in ~/.fehbg */ char *fehbg = NULL; + char fehbg_args[512]; + fehbg_args[0] = '\0'; char *home; char filbuf[4096]; - char fehbg_xinerama[] = "--no-xinerama"; char *bgfill = NULL; bgfill = opt.image_bg == IMAGE_BG_WHITE ? "--image-bg white" : "--image-bg black" ; +#ifdef HAVE_LIBXINERAMA + if (opt.xinerama) { + if (opt.xinerama_index >= 0) { + snprintf(fehbg_args, sizeof(fehbg_args), + "--xinerama-index %d", opt.xinerama_index); + } + } + else + snprintf(fehbg_args, sizeof(fehbg_args), "--no-xinerama"); +#endif /* HAVE_LIBXINERAMA */ + /* local display to set closedownmode on */ Display *disp2; Window root2; int depth2; int in, out, w, h; - if (opt.xinerama) - fehbg_xinerama[0] = '\0'; - D(("Falling back to XSetRootWindowPixmap\n")); /* Put the filename in filbuf between ' and escape ' in the filename */ @@ -357,16 +366,30 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) - for (i = 0; i < num_xinerama_screens; i++) - feh_wm_set_bg_scaled(pmap_d1, im, use_filelist, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height); + if (opt.xinerama_index >= 0) { + if (opt.image_bg == IMAGE_BG_WHITE) + gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); + else + gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gc = XCreateGC(disp, root, GCForeground, &gcval); + XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); + XFreeGC(disp, gc); + } + + if (opt.xinerama && xinerama_screens) { + for (i = 0; i < num_xinerama_screens; i++) { + if (opt.xinerama_index < 0 || opt.xinerama_index == i) { + feh_wm_set_bg_scaled(pmap_d1, im, use_filelist, + xinerama_screens[i].x_org, xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height); + } + } + } else #endif /* HAVE_LIBXINERAMA */ feh_wm_set_bg_scaled(pmap_d1, im, use_filelist, 0, 0, scr->width, scr->height); - fehbg = estrjoin(" ", "feh", fehbg_xinerama, "--bg-scale", filbuf, NULL); + fehbg = estrjoin(" ", "feh", fehbg_args, "--bg-scale", filbuf, NULL); } else if (centered) { D(("centering\n")); @@ -380,11 +403,15 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) - for (i = 0; i < num_xinerama_screens; i++) - feh_wm_set_bg_centered(pmap_d1, im, use_filelist, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height); + if (opt.xinerama && xinerama_screens) { + for (i = 0; i < num_xinerama_screens; i++) { + if (opt.xinerama_index < 0 || opt.xinerama_index == i) { + feh_wm_set_bg_centered(pmap_d1, im, use_filelist, + xinerama_screens[i].x_org, xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height); + } + } + } else #endif /* HAVE_LIBXINERAMA */ feh_wm_set_bg_centered(pmap_d1, im, use_filelist, @@ -392,24 +419,38 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFreeGC(disp, gc); - fehbg = estrjoin(" ", "feh", fehbg_xinerama, bgfill, "--bg-center", filbuf, NULL); + fehbg = estrjoin(" ", "feh", fehbg_args, bgfill, "--bg-center", filbuf, NULL); } else if (filled == 1) { pmap_d1 = XCreatePixmap(disp, root, scr->width, scr->height, depth); #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) - for (i = 0; i < num_xinerama_screens; i++) - feh_wm_set_bg_filled(pmap_d1, im, use_filelist, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height); + if (opt.xinerama_index >= 0) { + if (opt.image_bg == IMAGE_BG_WHITE) + gcval.foreground = WhitePixel(disp, DefaultScreen(disp)); + else + gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gc = XCreateGC(disp, root, GCForeground, &gcval); + XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); + XFreeGC(disp, gc); + } + + if (opt.xinerama && xinerama_screens) { + for (i = 0; i < num_xinerama_screens; i++) { + if (opt.xinerama_index < 0 || opt.xinerama_index == i) { + feh_wm_set_bg_filled(pmap_d1, im, use_filelist, + xinerama_screens[i].x_org, xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height); + } + } + } else #endif /* HAVE_LIBXINERAMA */ feh_wm_set_bg_filled(pmap_d1, im, use_filelist , 0, 0, scr->width, scr->height); - fehbg = estrjoin(" ", "feh", fehbg_xinerama, "--bg-fill", filbuf, NULL); + fehbg = estrjoin(" ", "feh", fehbg_args, "--bg-fill", filbuf, NULL); } else if (filled == 2) { @@ -422,11 +463,15 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFillRectangle(disp, pmap_d1, gc, 0, 0, scr->width, scr->height); #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) - for (i = 0; i < num_xinerama_screens; i++) - feh_wm_set_bg_maxed(pmap_d1, im, use_filelist, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height); + if (opt.xinerama && xinerama_screens) { + for (i = 0; i < num_xinerama_screens; i++) { + if (opt.xinerama_index < 0 || opt.xinerama_index == i) { + feh_wm_set_bg_maxed(pmap_d1, im, use_filelist, + xinerama_screens[i].x_org, xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height); + } + } + } else #endif /* HAVE_LIBXINERAMA */ feh_wm_set_bg_maxed(pmap_d1, im, use_filelist, @@ -434,7 +479,7 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, XFreeGC(disp, gc); - fehbg = estrjoin(" ", "feh", fehbg_xinerama, bgfill, "--bg-max", filbuf, NULL); + fehbg = estrjoin(" ", "feh", fehbg_args, bgfill, "--bg-max", filbuf, NULL); } else { if (use_filelist) @@ -465,8 +510,9 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, } free(path); } - free(fehbg); } + + free(fehbg); /* create new display, copy pixmap to new display */ disp2 = XOpenDisplay(NULL); @@ -504,6 +550,13 @@ void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, } } } + + if (data_root) + XFree(data_root); + + if (data_esetroot) + XFree(data_esetroot); + /* This will locate the property, creating it if it doesn't exist */ prop_root = XInternAtom(disp2, "_XROOTPMAP_ID", False); prop_esetroot = XInternAtom(disp2, "ESETROOT_PMAP_ID", False); diff --git a/src/winwidget.c b/src/winwidget.c index 65cefca..f249694 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "filelist.h" #include "winwidget.h" #include "options.h" +#include "events.h" static void winwidget_unregister(winwidget win); static void winwidget_register(winwidget win); @@ -297,6 +298,13 @@ void winwidget_create_window(winwidget ret, int w, int h) XSetCommand(disp, ret->win, cmdargv, cmdargc); winwidget_register(ret); + + /* do not scale down a thumbnail list window, only those created from it */ + if (opt.scale_down && (ret->type != WIN_TYPE_THUMBNAIL)) { + opt.geom_w = w; + opt.geom_h = h; + opt.geom_flags |= WidthValue | HeightValue; + } return; } @@ -393,7 +401,7 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) int need_center = winwid->had_resize; if (!winwid->full_screen && resize) { - winwidget_resize(winwid, winwid->im_w, winwid->im_h); + winwidget_resize(winwid, winwid->im_w, winwid->im_h, 0); winwidget_reset_image(winwid); } @@ -408,28 +416,6 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwidget_setup_pixmaps(winwid); - if (!winwid->full_screen && opt.scale_down && - (winwid->type != WIN_TYPE_THUMBNAIL) && - (winwid->old_zoom == 1.0)) { - int max_w = winwid->w, max_h = winwid->h; - if (opt.geom_flags & WidthValue) { - max_w = opt.geom_w; - } - if (opt.geom_flags & HeightValue) { - max_h = opt.geom_h; - } - D(("max: %dx%d, size: %dx%d\n", max_w, max_h, winwid->im_w, winwid->im_h)); - if (max_w < winwid->im_w || max_h < winwid->im_h) { - D(("scaling down image %dx%d\n", max_w, max_h)); - - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, - max_w, max_h); - if (resize) - winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom); - D(("after scaling down image %dx%d\n", winwid->w, winwid->h)); - } - } - if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) || (opt.geom_flags & (WidthValue | HeightValue)) || (winwid->im_x || winwid->im_y) || (winwid->zoom != 1.0) @@ -438,13 +424,22 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) feh_draw_checks(winwid); if (!winwid->full_screen && opt.zoom_mode - && (winwid->zoom == 1.0) && ! (opt.geom_flags & (WidthValue | HeightValue)) - && (winwid->w > winwid->im_w) && (winwid->h > winwid->im_h)) + && (winwid->zoom == 1.0) && ! (opt.geom_flags & (WidthValue | HeightValue)) + && (winwid->w > winwid->im_w) && (winwid->h > winwid->im_h)) + feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); + + /* + * In case of a resize, the geomflags (and im_w, im_h) get updated by + * the ConfigureNotify handler. + */ + if (need_center && !winwid->full_screen + && (opt.geom_flags & (WidthValue | HeightValue)) + && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); if (resize && (winwid->full_screen - || (!opt.scale_down && (opt.geom_flags & (WidthValue | HeightValue))))) { + || (opt.geom_flags & (WidthValue | HeightValue)))) { int smaller; /* Is the image smaller than screen? */ int max_w = 0, max_h = 0; @@ -532,8 +527,8 @@ void winwidget_render_image(winwidget winwid, int resize, int force_alias) winwid->im_y = (int) (max_h - (winwid->im_h * winwid->zoom)) >> 1; } } - else if (need_center && !winwid->full_screen && opt.scale_down - && (winwid->type != WIN_TYPE_THUMBNAIL)) { + else if (need_center && !winwid->full_screen + && (winwid->type != WIN_TYPE_THUMBNAIL) && !opt.keep_zoom_vp) { winwid->im_x = (int) (winwid->w - (winwid->im_w * winwid->zoom)) >> 1; winwid->im_y = (int) (winwid->h - (winwid->im_h * winwid->zoom)) >> 1; } @@ -776,6 +771,15 @@ void winwidget_show(winwidget winwid) /* wait for the window to map */ D(("Waiting for window to map\n")); XMaskEvent(disp, StructureNotifyMask, &ev); + /* Unfortunately, StructureNotifyMask does not only mask + * the events of type MapNotify (which we want to mask here) + * but also such of type ConfigureNotify (and others, see + * https://tronche.com/gui/x/xlib/events/processing-overview.html), + * which should be handled, especially on tiling wm's. To + * remedy this, the handler is executed explicitly: + */ + if (ev.type == ConfigureNotify) + feh_event_handle_ConfigureNotify(&ev); D(("Window mapped\n")); winwid->visible = 1; } @@ -797,7 +801,7 @@ void winwidget_move(winwidget winwid, int x, int y) return; } -void winwidget_resize(winwidget winwid, int w, int h) +void winwidget_resize(winwidget winwid, int w, int h, int force_resize) { XWindowAttributes attributes; int tc_x, tc_y, px, py; @@ -826,8 +830,8 @@ void winwidget_resize(winwidget winwid, int w, int h) } } - if (getenv("XINERAMA_SCREEN")) - xinerama_screen = atoi(getenv("XINERAMA_SCREEN")); + if (opt.xinerama_index >= 0) + xinerama_screen = opt.xinerama_index; scr_width = xinerama_screens[xinerama_screen].width; scr_height = xinerama_screens[xinerama_screen].height; @@ -838,7 +842,7 @@ void winwidget_resize(winwidget winwid, int w, int h) D((" x %d y %d w %d h %d\n", attributes.x, attributes.y, winwid->w, winwid->h)); - if (!opt.scale_down && opt.geom_flags & (WidthValue | HeightValue)) { + if ((opt.geom_flags & (WidthValue | HeightValue)) && !force_resize) { winwid->had_resize = 1; return; } @@ -862,6 +866,12 @@ void winwidget_resize(winwidget winwid, int w, int h) winwid->had_resize = 1; XFlush(disp); + if (force_resize && (opt.geom_flags & (WidthValue | HeightValue)) + && (winwid->type != WIN_TYPE_THUMBNAIL)) { + opt.geom_w = winwid->w; + opt.geom_h = winwid->h; + } + D(("-> x %d y %d w %d h %d\n", winwid->x, winwid->y, winwid->w, winwid->h)); @@ -1051,7 +1061,7 @@ void winwidget_sanitise_offsets(winwidget winwid) void winwidget_size_to_image(winwidget winwid) { - winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom); + winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom, 1); winwid->im_x = winwid->im_y = 0; winwidget_render_image(winwid, 0, 0); return; diff --git a/src/winwidget.h b/src/winwidget.h index 89d5bcd..6a794e7 100644 --- a/src/winwidget.h +++ b/src/winwidget.h @@ -128,7 +128,7 @@ void winwidget_center_image(winwidget w); void winwidget_render_image(winwidget winwid, int resize, int force_alias); void winwidget_rotate_image(winwidget winid, double angle); void winwidget_move(winwidget winwid, int x, int y); -void winwidget_resize(winwidget winwid, int w, int h); +void winwidget_resize(winwidget winwid, int w, int h, int force_resize); void winwidget_setup_pixmaps(winwidget winwid); void winwidget_update_title(winwidget ret); void winwidget_update_caption(winwidget winwid); |