ソースを参照

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

master
Bert Münnich 10年前
コミット
e267dc7793
6個のファイルの変更76行の追加56行の削除
  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 ファイルの表示

@@ -130,7 +130,7 @@ bool cg_reload_image(arg_t a)
load_image(fileidx);
} else {
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);
tns.dirty = true;
}


+ 17
- 14
exec/key-handler ファイルの表示

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

# Example for $XDG_CONFIG_HOME/sxiv/exec/key-handler
# 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",
# 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.

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

case "$key" in
"C-c")
echo -n "$2" | xsel -i ;;
echo -n "$@" | xsel -i ;;
"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")
gimp "$2" & ;;
gimp "$@" & ;;
"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")
exec jpegtran -rotate 90 -copy all -outfile "$2" "$2" ;;
for file in "$@"; do jpegtran -rotate 90 -copy all -outfile "$file" "$file"; done ;;
"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")
exec mogrify -rotate -90 "$2" ;;
exec mogrify -rotate -90 "$@" ;;
"C-greater")
exec mogrify -rotate +90 "$2" ;;
exec mogrify -rotate +90 "$@" ;;
"C-question")
exec mogrify -rotate 180 "$2" ;;
exec mogrify -rotate 180 "$@" ;;
esac


+ 49
- 32
main.c ファイルの表示

@@ -467,10 +467,12 @@ void clear_resize(void)
void run_key_handler(const char *key, unsigned int mask)
{
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.warned) {
@@ -482,20 +484,34 @@ void run_key_handler(const char *key, unsigned int mask)
if (key == NULL)
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",
mask & ControlMask ? "C-" : "",
mask & Mod1Mask ? "M-" : "",
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));
win_draw(&win);
win_set_cursor(&win, CURSOR_WATCH);
stat(files[fileidx].path, &oldst);

if ((pid = fork()) == 0) {
execl(keyhandler.cmd, keyhandler.cmd, kstr, files[fileidx].path, NULL);
execv(keyhandler.cmd, args);
warn("could not exec key handler");
exit(EXIT_FAILURE);
} else if (pid < 0) {
@@ -507,31 +523,31 @@ void run_key_handler(const char *key, unsigned int mask)
if (WIFEXITED(status) == 0 || retval != 0)
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) {
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();
redraw();
free(finfo);
free(args);
}

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

set_timeout(redraw, 25, false);
@@ -661,9 +677,10 @@ void run(void)
XPending(win.env.dpy) == 0)
{
/* load thumbnails */
reload = tns.loadnext != tns.cnt;
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++;
} else {
remove_file(tns.loadnext, false);
@@ -860,7 +877,7 @@ int main(int argc, char **argv)
if (options->thumb_mode) {
mode = MODE_THUMB;
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);
tns.cnt = 1;
} else {


+ 6
- 4
sxiv.1 ファイルの表示

@@ -112,7 +112,8 @@ Toggle fullscreen mode.
Toggle visibility of info bar on bottom of window.
.TP
.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
.B g
Go to the first image.
@@ -354,9 +355,10 @@ located in
.IR $XDG_CONFIG_HOME/sxiv/exec/key-handler .
The handler is invoked by pressing
.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",
where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X


+ 2
- 4
thumbs.c ファイルの表示

@@ -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;
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 ||
(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;
}
}


+ 1
- 1
thumbs.h ファイルの表示

@@ -57,7 +57,7 @@ void tns_clean_cache(tns_t*);
void tns_init(tns_t*, int, win_t*, int*);
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_mark(tns_t*, int, bool);


読み込み中…
キャンセル
保存