summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/events.c13
-rw-r--r--src/events.h2
-rw-r--r--src/feh.h4
-rw-r--r--src/feh_png.c5
-rw-r--r--src/filelist.c58
-rw-r--r--src/filelist.h23
-rw-r--r--src/help.raw7
-rw-r--r--src/imlib.c107
-rw-r--r--src/keyevents.c26
-rw-r--r--src/main.c6
-rw-r--r--src/menu.c66
-rw-r--r--src/options.c43
-rw-r--r--src/options.h5
-rw-r--r--src/slideshow.c45
-rw-r--r--src/wallpaper.c113
-rw-r--r--src/winwidget.c76
-rw-r--r--src/winwidget.h2
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
diff --git a/src/feh.h b/src/feh.h
index a2a586a..73ef1f6 100644
--- a/src/feh.h
+++ b/src/feh.h
@@ -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;
diff --git a/src/main.c b/src/main.c
index 6634a88..46ab73d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
diff --git a/src/menu.c b/src/menu.c
index b8698ab..ddb2db1 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -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);