Browse Source

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

master
Bert Münnich 10 years ago
parent
commit
e267dc7793
6 changed files with 76 additions and 56 deletions
  1. +1
    -1
      commands.c
  2. +17
    -14
      exec/key-handler
  3. +49
    -32
      main.c
  4. +6
    -4
      sxiv.1
  5. +2
    -4
      thumbs.c
  6. +1
    -1
      thumbs.h

+ 1
- 1
commands.c View File

@@ -130,7 +130,7 @@ bool cg_reload_image(arg_t a)
load_image(fileidx); load_image(fileidx);
} else { } else {
win_set_cursor(&win, CURSOR_WATCH); win_set_cursor(&win, CURSOR_WATCH);
if (!tns_load(&tns, fileidx, &files[fileidx], true, false)) {
if (!tns_load(&tns, fileidx, &files[fileidx], true)) {
remove_file(fileidx, false); remove_file(fileidx, false);
tns.dirty = true; tns.dirty = true;
} }


+ 17
- 14
exec/key-handler View File

@@ -2,33 +2,36 @@


# Example for $XDG_CONFIG_HOME/sxiv/exec/key-handler # Example for $XDG_CONFIG_HOME/sxiv/exec/key-handler
# Called by sxiv(1) after the external prefix key (C-x by default) is pressed. # Called by sxiv(1) after the external prefix key (C-x by default) is pressed.
# The next key combo is passed as its first argument and the path of the
# current image as its second argument.
# sxiv(1) blocks until this script terminates. It then checks if the image
# has been modified and reloads it.
# The next key combo is passed as its first argument, followed by the paths of
# all marked images or the path of the current image, if no image is marked.
# sxiv(1) blocks until this script terminates. It then checks which images
# have been modified and reloads them.


# The key combo argument has the following form: "[C-][M-][S-]KEY", # The key combo argument has the following form: "[C-][M-][S-]KEY",
# where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X # where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X
# keysym as listed in /usr/include/X11/keysymdef.h without the "XK_" prefix. # keysym as listed in /usr/include/X11/keysymdef.h without the "XK_" prefix.


case "$1" in
key="$1"
shift

case "$key" in
"C-c") "C-c")
echo -n "$2" | xsel -i ;;
echo -n "$@" | xsel -i ;;
"C-e") "C-e")
urxvt -bg "#444" -fg "#eee" -sl 0 -title "$2" -e sh -c "exiv2 pr -q -pa '$2' | less" & ;;
for file in "$@"; do urxvt -bg "#444" -fg "#eee" -sl 0 -title "$file" -e sh -c "exiv2 pr -q -pa '$file' | less" & done ;;
"C-g") "C-g")
gimp "$2" & ;;
gimp "$@" & ;;
"C-comma") "C-comma")
exec jpegtran -rotate 270 -copy all -outfile "$2" "$2" ;;
for file in "$@"; do jpegtran -rotate 270 -copy all -outfile "$file" "$file"; done ;;
"C-period") "C-period")
exec jpegtran -rotate 90 -copy all -outfile "$2" "$2" ;;
for file in "$@"; do jpegtran -rotate 90 -copy all -outfile "$file" "$file"; done ;;
"C-slash") "C-slash")
exec jpegtran -rotate 180 -copy all -outfile "$2" "$2" ;;
for file in "$@"; do jpegtran -rotate 180 -copy all -outfile "$file" "$file"; done ;;
"C-less") "C-less")
exec mogrify -rotate -90 "$2" ;;
exec mogrify -rotate -90 "$@" ;;
"C-greater") "C-greater")
exec mogrify -rotate +90 "$2" ;;
exec mogrify -rotate +90 "$@" ;;
"C-question") "C-question")
exec mogrify -rotate 180 "$2" ;;
exec mogrify -rotate 180 "$@" ;;
esac esac



+ 49
- 32
main.c View File

@@ -467,10 +467,12 @@ void clear_resize(void)
void run_key_handler(const char *key, unsigned int mask) void run_key_handler(const char *key, unsigned int mask)
{ {
pid_t pid; pid_t pid;
int retval, status;
char kstr[32], oldbar[sizeof(win.bar.l)];
bool restore_bar = mode == MODE_IMAGE && info.cmd != NULL;
struct stat oldst, newst;
int i, j, retval, status;
int fcnt = mode == MODE_THUMB && markcnt > 0 ? markcnt : 1;
bool changed = false;
char **args, kstr[32], oldbar[sizeof(win.bar.l)];
struct stat *oldst, newst;
struct { int fn; struct stat st; } *finfo;


if (keyhandler.cmd == NULL) { if (keyhandler.cmd == NULL) {
if (!keyhandler.warned) { if (!keyhandler.warned) {
@@ -482,20 +484,34 @@ void run_key_handler(const char *key, unsigned int mask)
if (key == NULL) if (key == NULL)
return; return;


finfo = s_malloc(fcnt * sizeof(*finfo));
args = s_malloc((fcnt + 3) * sizeof(*args));
args[0] = keyhandler.cmd;
args[1] = kstr;
args[fcnt+2] = NULL;
if (mode == MODE_IMAGE || markcnt == 0) {
finfo[0].fn = fileidx;
stat(files[fileidx].path, &finfo[0].st);
args[2] = (char*) files[fileidx].path;
} else for (i = j = 0; i < filecnt; i++) {
if (files[i].marked) {
finfo[j].fn = i;
stat(files[i].path, &finfo[j++].st);
args[j+1] = (char*) files[i].path;
}
}
snprintf(kstr, sizeof(kstr), "%s%s%s%s", snprintf(kstr, sizeof(kstr), "%s%s%s%s",
mask & ControlMask ? "C-" : "", mask & ControlMask ? "C-" : "",
mask & Mod1Mask ? "M-" : "", mask & Mod1Mask ? "M-" : "",
mask & ShiftMask ? "S-" : "", key); mask & ShiftMask ? "S-" : "", key);


if (restore_bar)
memcpy(oldbar, win.bar.l, sizeof(win.bar.l));
memcpy(oldbar, win.bar.l, sizeof(win.bar.l));
strncpy(win.bar.l, "Running key handler...", sizeof(win.bar.l)); strncpy(win.bar.l, "Running key handler...", sizeof(win.bar.l));
win_draw(&win); win_draw(&win);
win_set_cursor(&win, CURSOR_WATCH); win_set_cursor(&win, CURSOR_WATCH);
stat(files[fileidx].path, &oldst);


if ((pid = fork()) == 0) { if ((pid = fork()) == 0) {
execl(keyhandler.cmd, keyhandler.cmd, kstr, files[fileidx].path, NULL);
execv(keyhandler.cmd, args);
warn("could not exec key handler"); warn("could not exec key handler");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (pid < 0) { } else if (pid < 0) {
@@ -507,31 +523,31 @@ void run_key_handler(const char *key, unsigned int mask)
if (WIFEXITED(status) == 0 || retval != 0) if (WIFEXITED(status) == 0 || retval != 0)
warn("key handler exited with non-zero return value: %d", retval); warn("key handler exited with non-zero return value: %d", retval);


if (stat(files[fileidx].path, &newst) == 0 &&
memcmp(&oldst.st_mtime, &newst.st_mtime, sizeof(oldst.st_mtime)) == 0)
{
/* file has not changed */
goto end;
for (i = 0; i < fcnt; i++) {
oldst = &finfo[i].st;
if (stat(files[finfo[i].fn].path, &newst) != 0 ||
memcmp(&oldst->st_mtime, &newst.st_mtime, sizeof(newst.st_mtime)) != 0)
{
if (tns.thumbs != NULL) {
tns.thumbs[finfo[i].fn].loaded = false;
tns.loadnext = MIN(tns.loadnext, finfo[i].fn);
}
changed = true;
}
} }
restore_bar = false;
strncpy(win.bar.l, "Reloading image...", sizeof(win.bar.l));
win_draw(&win);

end:
if (mode == MODE_IMAGE) { if (mode == MODE_IMAGE) {
img_close(&img, true);
load_image(fileidx);
}
if (!tns_load(&tns, fileidx, &files[fileidx], true, mode == MODE_IMAGE) &&
mode == MODE_THUMB)
{
remove_file(fileidx, false);
tns.dirty = true;
if (changed) {
img_close(&img, true);
load_image(fileidx);
} else if (info.cmd != NULL) {
memcpy(win.bar.l, oldbar, sizeof(win.bar.l));
}
} }
end:
if (restore_bar)
memcpy(win.bar.l, oldbar, sizeof(win.bar.l));
reset_cursor(); reset_cursor();
redraw(); redraw();
free(finfo);
free(args);
} }


#define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask)) #define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask))
@@ -651,7 +667,7 @@ void run(void)
int xfd; int xfd;
fd_set fds; fd_set fds;
struct timeval timeout; struct timeval timeout;
bool discard, to_set;
bool discard, reload, to_set;
XEvent ev, nextev; XEvent ev, nextev;


set_timeout(redraw, 25, false); set_timeout(redraw, 25, false);
@@ -661,9 +677,10 @@ void run(void)
XPending(win.env.dpy) == 0) XPending(win.env.dpy) == 0)
{ {
/* load thumbnails */ /* load thumbnails */
reload = tns.loadnext != tns.cnt;
set_timeout(redraw, TO_REDRAW_THUMBS, false); set_timeout(redraw, TO_REDRAW_THUMBS, false);
if (tns_load(&tns, tns.loadnext, &files[tns.loadnext], false, false)) {
if (tns.cnt == tns.loadnext)
if (tns_load(&tns, tns.loadnext, &files[tns.loadnext], reload)) {
if (!reload)
tns.cnt++; tns.cnt++;
} else { } else {
remove_file(tns.loadnext, false); remove_file(tns.loadnext, false);
@@ -860,7 +877,7 @@ int main(int argc, char **argv)
if (options->thumb_mode) { if (options->thumb_mode) {
mode = MODE_THUMB; mode = MODE_THUMB;
tns_init(&tns, filecnt, &win, &fileidx); tns_init(&tns, filecnt, &win, &fileidx);
while (!tns_load(&tns, 0, &files[0], false, false))
while (!tns_load(&tns, 0, &files[0], false))
remove_file(0, false); remove_file(0, false);
tns.cnt = 1; tns.cnt = 1;
} else { } else {


+ 6
- 4
sxiv.1 View File

@@ -112,7 +112,8 @@ Toggle fullscreen mode.
Toggle visibility of info bar on bottom of window. Toggle visibility of info bar on bottom of window.
.TP .TP
.B Ctrl-x .B Ctrl-x
Send the next key to the external key-handler.
Send the next key to the external key-handler. See section EXTERNAL KEY HANDLER
for more information.
.TP .TP
.B g .B g
Go to the first image. Go to the first image.
@@ -354,9 +355,10 @@ located in
.IR $XDG_CONFIG_HOME/sxiv/exec/key-handler . .IR $XDG_CONFIG_HOME/sxiv/exec/key-handler .
The handler is invoked by pressing The handler is invoked by pressing
.BR Ctrl-x . .BR Ctrl-x .
The next key combo is then passed as its first argument and the path of the
current image as its second argument. sxiv(1) will block until the handler
terminates. It then checks if the image has been modified and reloads it.
The next key combo is then passed as its first argument, followed by the paths
of all marked images or the path of the current image, if no image is marked.
sxiv(1) will block until the handler terminates. It then checks which images
have been modified and reloads them.


The key combo argument has the following form: "[C-][M-][S-]KEY", The key combo argument has the following form: "[C-][M-][S-]KEY",
where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X


+ 2
- 4
thumbs.c View File

@@ -209,8 +209,7 @@ void tns_free(tns_t *tns)
} }
} }


bool tns_load(tns_t *tns, int n, const fileinfo_t *file,
bool force, bool silent)
bool tns_load(tns_t *tns, int n, const fileinfo_t *file, bool force)
{ {
int w, h; int w, h;
bool cache_hit = false; bool cache_hit = false;
@@ -295,8 +294,7 @@ bool tns_load(tns_t *tns, int n, const fileinfo_t *file,
if (im == NULL && (access(file->path, R_OK) < 0 || if (im == NULL && (access(file->path, R_OK) < 0 ||
(im = imlib_load_image(file->path)) == NULL)) (im = imlib_load_image(file->path)) == NULL))
{ {
if (!silent)
warn("could not open image: %s", file->name);
warn("could not open image: %s", file->name);
return false; return false;
} }
} }


+ 1
- 1
thumbs.h View File

@@ -57,7 +57,7 @@ void tns_clean_cache(tns_t*);
void tns_init(tns_t*, int, win_t*, int*); void tns_init(tns_t*, int, win_t*, int*);
void tns_free(tns_t*); void tns_free(tns_t*);


bool tns_load(tns_t*, int, const fileinfo_t*, bool, bool);
bool tns_load(tns_t*, int, const fileinfo_t*, bool);


void tns_render(tns_t*); void tns_render(tns_t*);
void tns_mark(tns_t*, int, bool); void tns_mark(tns_t*, int, bool);


Loading…
Cancel
Save