Krolyxon
Commit e267dc7

Branches

Refs →

nsxive267dc7

Pass marked files to external key handler in thumbnail mode; fixes issue #135

Author
Bert Münnich
Date
2014-08-16 21:31 +0200
Committer
Bert Münnich · 2014-08-16 21:49 +0200
Parent
284be74
Commit
e267dc7793df0c3d8b1dcc48575a11d402df5499

+76 −56

6 files changed

  1. M commands.c +1 −1
  2. M exec/key-handler +17 −14
  3. M main.c +49 −32
  4. M sxiv.1 +6 −4
  5. M thumbs.c +2 −4
  6. M thumbs.h +1 −1
M commands.c View
@@ -130,7 +130,7 @@ bool cg_reload_image(arg_t a)
130130 load_image(fileidx);
131131 } else {
132132 win_set_cursor(&win, CURSOR_WATCH);
133− if (!tns_load(&tns, fileidx, &files[fileidx], true, false)) {
133+ if (!tns_load(&tns, fileidx, &files[fileidx], true)) {
134134 remove_file(fileidx, false);
135135 tns.dirty = true;
136136 }
M exec/key-handler View
@@ -2,33 +2,36 @@
22
33 # Example for $XDG_CONFIG_HOME/sxiv/exec/key-handler
44 # Called by sxiv(1) after the external prefix key (C-x by default) is pressed.
5−# The next key combo is passed as its first argument and the path of the
6−# current image as its second argument.
7−# sxiv(1) blocks until this script terminates. It then checks if the image
8−# has been modified and reloads it.
5+# The next key combo is passed as its first argument, followed by the paths of
6+# all marked images or the path of the current image, if no image is marked.
7+# sxiv(1) blocks until this script terminates. It then checks which images
8+# have been modified and reloads them.
99
1010 # The key combo argument has the following form: "[C-][M-][S-]KEY",
1111 # where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X
1212 # keysym as listed in /usr/include/X11/keysymdef.h without the "XK_" prefix.
1313
14−case "$1" in
14+key="$1"
15+shift
16+
17+case "$key" in
1518 "C-c")
16− echo -n "$2" | xsel -i ;;
19+ echo -n "$@" | xsel -i ;;
1720 "C-e")
18− urxvt -bg "#444" -fg "#eee" -sl 0 -title "$2" -e sh -c "exiv2 pr -q -pa '$2' | less" & ;;
21+ for file in "$@"; do urxvt -bg "#444" -fg "#eee" -sl 0 -title "$file" -e sh -c "exiv2 pr -q -pa '$file' | less" & done ;;
1922 "C-g")
20− gimp "$2" & ;;
23+ gimp "$@" & ;;
2124 "C-comma")
22− exec jpegtran -rotate 270 -copy all -outfile "$2" "$2" ;;
25+ for file in "$@"; do jpegtran -rotate 270 -copy all -outfile "$file" "$file"; done ;;
2326 "C-period")
24− exec jpegtran -rotate 90 -copy all -outfile "$2" "$2" ;;
27+ for file in "$@"; do jpegtran -rotate 90 -copy all -outfile "$file" "$file"; done ;;
2528 "C-slash")
26− exec jpegtran -rotate 180 -copy all -outfile "$2" "$2" ;;
29+ for file in "$@"; do jpegtran -rotate 180 -copy all -outfile "$file" "$file"; done ;;
2730 "C-less")
28− exec mogrify -rotate -90 "$2" ;;
31+ exec mogrify -rotate -90 "$@" ;;
2932 "C-greater")
30− exec mogrify -rotate +90 "$2" ;;
33+ exec mogrify -rotate +90 "$@" ;;
3134 "C-question")
32− exec mogrify -rotate 180 "$2" ;;
35+ exec mogrify -rotate 180 "$@" ;;
3336 esac
3437
M main.c View
@@ -467,10 +467,12 @@ void clear_resize(void)
467467 void run_key_handler(const char *key, unsigned int mask)
468468 {
469469 pid_t pid;
470− int retval, status;
471− char kstr[32], oldbar[sizeof(win.bar.l)];
472− bool restore_bar = mode == MODE_IMAGE && info.cmd != NULL;
473− struct stat oldst, newst;
470+ int i, j, retval, status;
471+ int fcnt = mode == MODE_THUMB && markcnt > 0 ? markcnt : 1;
472+ bool changed = false;
473+ char **args, kstr[32], oldbar[sizeof(win.bar.l)];
474+ struct stat *oldst, newst;
475+ struct { int fn; struct stat st; } *finfo;
474476
475477 if (keyhandler.cmd == NULL) {
476478 if (!keyhandler.warned) {
@@ -482,20 +484,34 @@ void run_key_handler(const char *key, unsigned int mask)
482484 if (key == NULL)
483485 return;
484486
487+ finfo = s_malloc(fcnt * sizeof(*finfo));
488+ args = s_malloc((fcnt + 3) * sizeof(*args));
489+ args[0] = keyhandler.cmd;
490+ args[1] = kstr;
491+ args[fcnt+2] = NULL;
492+ if (mode == MODE_IMAGE || markcnt == 0) {
493+ finfo[0].fn = fileidx;
494+ stat(files[fileidx].path, &finfo[0].st);
495+ args[2] = (char*) files[fileidx].path;
496+ } else for (i = j = 0; i < filecnt; i++) {
497+ if (files[i].marked) {
498+ finfo[j].fn = i;
499+ stat(files[i].path, &finfo[j++].st);
500+ args[j+1] = (char*) files[i].path;
501+ }
502+ }
485503 snprintf(kstr, sizeof(kstr), "%s%s%s%s",
486504 mask & ControlMask ? "C-" : "",
487505 mask & Mod1Mask ? "M-" : "",
488506 mask & ShiftMask ? "S-" : "", key);
489507
490− if (restore_bar)
491− memcpy(oldbar, win.bar.l, sizeof(win.bar.l));
508+ memcpy(oldbar, win.bar.l, sizeof(win.bar.l));
492509 strncpy(win.bar.l, "Running key handler...", sizeof(win.bar.l));
493510 win_draw(&win);
494511 win_set_cursor(&win, CURSOR_WATCH);
495− stat(files[fileidx].path, &oldst);
496512
497513 if ((pid = fork()) == 0) {
498− execl(keyhandler.cmd, keyhandler.cmd, kstr, files[fileidx].path, NULL);
514+ execv(keyhandler.cmd, args);
499515 warn("could not exec key handler");
500516 exit(EXIT_FAILURE);
501517 } else if (pid < 0) {
@@ -507,31 +523,31 @@ void run_key_handler(const char *key, unsigned int mask)
507523 if (WIFEXITED(status) == 0 || retval != 0)
508524 warn("key handler exited with non-zero return value: %d", retval);
509525
510− if (stat(files[fileidx].path, &newst) == 0 &&
511− memcmp(&oldst.st_mtime, &newst.st_mtime, sizeof(oldst.st_mtime)) == 0)
512− {
513− /* file has not changed */
514− goto end;
526+ for (i = 0; i < fcnt; i++) {
527+ oldst = &finfo[i].st;
528+ if (stat(files[finfo[i].fn].path, &newst) != 0 ||
529+ memcmp(&oldst->st_mtime, &newst.st_mtime, sizeof(newst.st_mtime)) != 0)
530+ {
531+ if (tns.thumbs != NULL) {
532+ tns.thumbs[finfo[i].fn].loaded = false;
533+ tns.loadnext = MIN(tns.loadnext, finfo[i].fn);
534+ }
535+ changed = true;
536+ }
515537 }
516− restore_bar = false;
517− strncpy(win.bar.l, "Reloading image...", sizeof(win.bar.l));
518− win_draw(&win);
519−
538+end:
520539 if (mode == MODE_IMAGE) {
521− img_close(&img, true);
522− load_image(fileidx);
523− }
524− if (!tns_load(&tns, fileidx, &files[fileidx], true, mode == MODE_IMAGE) &&
525− mode == MODE_THUMB)
526− {
527− remove_file(fileidx, false);
528− tns.dirty = true;
540+ if (changed) {
541+ img_close(&img, true);
542+ load_image(fileidx);
543+ } else if (info.cmd != NULL) {
544+ memcpy(win.bar.l, oldbar, sizeof(win.bar.l));
545+ }
529546 }
530−end:
531− if (restore_bar)
532− memcpy(win.bar.l, oldbar, sizeof(win.bar.l));
533547 reset_cursor();
534548 redraw();
549+ free(finfo);
550+ free(args);
535551 }
536552
537553 #define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask))
@@ -651,7 +667,7 @@ void run(void)
651667 int xfd;
652668 fd_set fds;
653669 struct timeval timeout;
654− bool discard, to_set;
670+ bool discard, reload, to_set;
655671 XEvent ev, nextev;
656672
657673 set_timeout(redraw, 25, false);
@@ -661,9 +677,10 @@ void run(void)
661677 XPending(win.env.dpy) == 0)
662678 {
663679 /* load thumbnails */
680+ reload = tns.loadnext != tns.cnt;
664681 set_timeout(redraw, TO_REDRAW_THUMBS, false);
665− if (tns_load(&tns, tns.loadnext, &files[tns.loadnext], false, false)) {
666− if (tns.cnt == tns.loadnext)
682+ if (tns_load(&tns, tns.loadnext, &files[tns.loadnext], reload)) {
683+ if (!reload)
667684 tns.cnt++;
668685 } else {
669686 remove_file(tns.loadnext, false);
@@ -860,7 +877,7 @@ int main(int argc, char **argv)
860877 if (options->thumb_mode) {
861878 mode = MODE_THUMB;
862879 tns_init(&tns, filecnt, &win, &fileidx);
863− while (!tns_load(&tns, 0, &files[0], false, false))
880+ while (!tns_load(&tns, 0, &files[0], false))
864881 remove_file(0, false);
865882 tns.cnt = 1;
866883 } else {
M sxiv.1 View
@@ -112,7 +112,8 @@ Toggle fullscreen mode.
112112 Toggle visibility of info bar on bottom of window.
113113 .TP
114114 .B Ctrl-x
115−Send the next key to the external key-handler.
115+Send the next key to the external key-handler. See section EXTERNAL KEY HANDLER
116+for more information.
116117 .TP
117118 .B g
118119 Go to the first image.
@@ -354,9 +355,10 @@ located in
354355 .IR $XDG_CONFIG_HOME/sxiv/exec/key-handler .
355356 The handler is invoked by pressing
356357 .BR Ctrl-x .
357−The next key combo is then passed as its first argument and the path of the
358−current image as its second argument. sxiv(1) will block until the handler
359−terminates. It then checks if the image has been modified and reloads it.
358+The next key combo is then passed as its first argument, followed by the paths
359+of all marked images or the path of the current image, if no image is marked.
360+sxiv(1) will block until the handler terminates. It then checks which images
361+have been modified and reloads them.
360362
361363 The key combo argument has the following form: "[C-][M-][S-]KEY",
362364 where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X
M thumbs.c View
@@ -209,8 +209,7 @@ void tns_free(tns_t *tns)
209209 }
210210 }
211211
212−bool tns_load(tns_t *tns, int n, const fileinfo_t *file,
213− bool force, bool silent)
212+bool tns_load(tns_t *tns, int n, const fileinfo_t *file, bool force)
214213 {
215214 int w, h;
216215 bool cache_hit = false;
@@ -295,8 +294,7 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file,
295294 if (im == NULL && (access(file->path, R_OK) < 0 ||
296295 (im = imlib_load_image(file->path)) == NULL))
297296 {
298− if (!silent)
299− warn("could not open image: %s", file->name);
297+ warn("could not open image: %s", file->name);
300298 return false;
301299 }
302300 }
M thumbs.h View
@@ -57,7 +57,7 @@ void tns_clean_cache(tns_t*);
5757 void tns_init(tns_t*, int, win_t*, int*);
5858 void tns_free(tns_t*);
5959
60−bool tns_load(tns_t*, int, const fileinfo_t*, bool, bool);
60+bool tns_load(tns_t*, int, const fileinfo_t*, bool);
6161
6262 void tns_render(tns_t*);
6363 void tns_mark(tns_t*, int, bool);