From 06164c29b759c3e21e79be03b285bdf3da6f5a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Wed, 23 Jul 2014 21:50:31 +0200 Subject: [PATCH] Revised command structure and key and mouse button mappings --- Makefile | 2 +- README.md | 43 +++---- commands.c | 320 +++++++++++++++++++++++---------------------------- commands.h | 59 +++------- commands.lst | 34 ++++++ config.def.h | 96 ++++++++-------- main.c | 18 +-- sxiv.1 | 156 ++++++++++++------------- 8 files changed, 336 insertions(+), 392 deletions(-) create mode 100644 commands.lst diff --git a/Makefile b/Makefile index 7a2d9e3..8bd57ab 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION = git-20140615 +VERSION = git-20140723 PREFIX = /usr/local MANPREFIX = $(PREFIX)/share/man diff --git a/README.md b/README.md index 97d43c1..90ccec9 100644 --- a/README.md +++ b/README.md @@ -89,24 +89,17 @@ of small previews is displayed, making it easy to choose an image to open. **Key mappings:** + 0-9 Prefix the next command with a number (denoted via [count]) q Quit sxiv Return Switch to thumbnail mode / open selected image - - 0-9 Prefix the next command with a number (denoted via [count]) - + f Toggle fullscreen mode + b Toggle visibility of info bar on bottom of window Ctrl-x Send the next key to the external key-handler - g Go to first image G Go to the last image, or image number [count] - - f Toggle fullscreen mode (requires an EWMH/NetWM compliant - window manager) - b Toggle visibility of info bar on bottom of window - r Reload image - R Reload all thumbnails D Remove image from file list and go to next image - + Ctrl-h,j,k,l Scroll one window width/height left/down/up/right m Mark/unmark current image M Reverse all image marks N Go [count] marked images forward @@ -114,18 +107,20 @@ of small previews is displayed, making it easy to choose an image to open. *Thumbnail mode:* - h,j,k,l Move selection left/down/up/right [count] times - Ctrl-j,k Scroll thumbnail grid one window height down/up + h,j,k,l Move selection left/down/up/right [count] times (also with + arrow keys) + R Reload all thumbnails *Image mode:* n,Space Go [count] images forward p,Backspace Go [count] images backward [,] Go [count] * 10 images backward/forward - Ctrl-n,p Go to the next/previous frame of a multi-frame image Ctrl-Space Play/pause animation of a multi-frame image - + h,j,k,l Scroll image 1/5 of window width/height or [count] pixels + left/down/up/right (also with arrow keys) + H,J,K,L Scroll to left/bottom/top/right image edge + Zoom in - Zoom out = Set zoom level to 100%, or [count]% @@ -133,23 +128,13 @@ of small previews is displayed, making it easy to choose an image to open. W Fit image to window e Fit image to window width E Fit image to window height - - h,j,k,l Pan image 1/5 of window width/height or [count] pixels - left/down/up/right (also with arrow keys) - H,J,K,L Pan to left/bottom/top/right image edge - Ctrl-h,j,k,l Pan image one window width/height left/down/up/right - (also with Ctrl-arrow keys) - <,> Rotate image (counter-)clockwise by 90 degrees ? Rotate image by 180 degrees |,_ Flip image horizontally/vertically - {,} Decrease/increase gamma Ctrl-g Reset gamma - a Toggle anti-aliasing A Toggle visibility of alpha-channel, i.e. transparency - s Toggle slideshow or set delay to [count] seconds @@ -158,11 +143,11 @@ of small previews is displayed, making it easy to choose an image to open. *Image mode:* Button1 Go to the next image - Button2 Drag image with mouse while keeping it pressed Button3 Go to the previous image - Scroll Pan image up/down - Shift+Scroll Pan image left/right - Ctrl+Scroll Zoom in/out + Button2 Drag image with mouse while keeping it pressed + Wheel Scroll image up/down + Shift+Wheel Scroll image left/right + Ctrl+Wheel Zoom in/out Download & Changelog diff --git a/commands.c b/commands.c index ecc3c4c..cfcd1b1 100644 --- a/commands.c +++ b/commands.c @@ -1,4 +1,4 @@ -/* Copyright 2011, 2012 Bert Muennich +/* Copyright 2011, 2012, 2014 Bert Muennich * * This file is part of sxiv. * @@ -58,7 +58,7 @@ const int ss_delays[] = { 1, 2, 3, 5, 10, 15, 20, 30, 60, 120, 180, 300, 600 }; -cmdreturn_t it_quit(arg_t a) +bool cg_quit(arg_t a) { unsigned int i; @@ -72,7 +72,7 @@ cmdreturn_t it_quit(arg_t a) exit(EXIT_SUCCESS); } -cmdreturn_t it_switch_mode(arg_t a) +bool cg_switch_mode(arg_t a) { if (mode == MODE_IMAGE) { if (tns.thumbs == NULL) @@ -90,10 +90,10 @@ cmdreturn_t it_switch_mode(arg_t a) load_image(tns.sel); mode = MODE_IMAGE; } - return CMD_DIRTY; + return true; } -cmdreturn_t it_toggle_fullscreen(arg_t a) +bool cg_toggle_fullscreen(arg_t a) { win_toggle_fullscreen(&win); /* redraw after next ConfigureNotify event */ @@ -102,10 +102,10 @@ cmdreturn_t it_toggle_fullscreen(arg_t a) img.checkpan = img.dirty = true; else tns.dirty = true; - return CMD_OK; + return false; } -cmdreturn_t it_toggle_bar(arg_t a) +bool cg_toggle_bar(arg_t a) { win_toggle_bar(&win); if (mode == MODE_IMAGE) { @@ -115,27 +115,16 @@ cmdreturn_t it_toggle_bar(arg_t a) } else { tns.dirty = true; } - return CMD_DIRTY; + return true; } -cmdreturn_t it_prefix_external(arg_t a) +bool cg_prefix_external(arg_t a) { extprefix = true; - return CMD_OK; + return false; } -cmdreturn_t t_reload_all(arg_t a) -{ - if (mode == MODE_THUMB) { - tns_free(&tns); - tns_init(&tns, filecnt, &win); - return CMD_DIRTY; - } else { - return CMD_INVALID; - } -} - -cmdreturn_t it_reload_image(arg_t a) +bool cg_reload_image(arg_t a) { if (mode == MODE_IMAGE) { load_image(fileidx); @@ -148,120 +137,77 @@ cmdreturn_t it_reload_image(arg_t a) tns.sel = tns.cnt - 1; } } - return CMD_DIRTY; + return true; } -cmdreturn_t it_remove_image(arg_t a) +bool cg_remove_image(arg_t a) { if (mode == MODE_IMAGE) { remove_file(fileidx, true); load_image(fileidx >= filecnt ? filecnt - 1 : fileidx); - return CMD_DIRTY; + return true; } else if (tns.sel < tns.cnt) { remove_file(tns.sel, true); tns.dirty = true; if (tns.sel >= tns.cnt) tns.sel = tns.cnt - 1; - return CMD_DIRTY; + return true; } else { - return CMD_OK; + return false; } } -cmdreturn_t i_navigate(arg_t a) -{ - long n = (long) a; - - if (mode == MODE_IMAGE) { - if (prefix > 0) - n *= prefix; - n += fileidx; - if (n < 0) - n = 0; - if (n >= filecnt) - n = filecnt - 1; - - if (n != fileidx) { - load_image(n); - return CMD_DIRTY; - } - } - return CMD_INVALID; -} - -cmdreturn_t i_alternate(arg_t a) -{ - if (mode == MODE_IMAGE) { - load_image(alternate); - return CMD_DIRTY; - } else { - return CMD_INVALID; - } -} - -cmdreturn_t it_first(arg_t a) +bool cg_first(arg_t a) { if (mode == MODE_IMAGE && fileidx != 0) { load_image(0); - return CMD_DIRTY; + return true; } else if (mode == MODE_THUMB && tns.sel != 0) { tns.sel = 0; tns.dirty = true; - return CMD_DIRTY; + return true; } else { - return CMD_OK; + return false; } } -cmdreturn_t it_n_or_last(arg_t a) +bool cg_n_or_last(arg_t a) { int n = prefix != 0 && prefix - 1 < filecnt ? prefix - 1 : filecnt - 1; if (mode == MODE_IMAGE && fileidx != n) { load_image(n); - return CMD_DIRTY; + return true; } else if (mode == MODE_THUMB && tns.sel != n) { tns.sel = n; tns.dirty = true; - return CMD_DIRTY; + return true; } else { - return CMD_OK; + return false; } } -cmdreturn_t i_navigate_frame(arg_t a) +bool cg_scroll_screen(arg_t a) { - if (mode != MODE_IMAGE) - return CMD_INVALID; + direction_t dir = (direction_t) a; + + if (mode == MODE_IMAGE) + return img_pan(&img, dir, -1); else - return !img.multi.animate && img_frame_navigate(&img, (long) a); + return tns_scroll(&tns, dir, true); } -cmdreturn_t i_toggle_animation(arg_t a) -{ - if (mode != MODE_IMAGE) - return CMD_INVALID; - - if (img.multi.animate) { - reset_timeout(animate); - img.multi.animate = false; - } else if (img_frame_animate(&img, true)) { - set_timeout(animate, img.multi.frames[img.multi.sel].delay, true); - } - return CMD_DIRTY; -} - -cmdreturn_t it_toggle_image_mark(arg_t a) +bool cg_toggle_image_mark(arg_t a) { int sel = mode == MODE_IMAGE ? fileidx : tns.sel; files[sel].marked = !files[sel].marked; if (mode == MODE_THUMB) tns_mark(&tns, sel, files[sel].marked); - return CMD_DIRTY; + return true; } -cmdreturn_t it_reverse_marks(arg_t a) +bool cg_reverse_marks(arg_t a) { int i, cnt = mode == MODE_IMAGE ? filecnt : tns.cnt; @@ -269,10 +215,10 @@ cmdreturn_t it_reverse_marks(arg_t a) files[i].marked = !files[i].marked; if (mode == MODE_THUMB) tns.dirty = true; - return CMD_DIRTY; + return true; } -cmdreturn_t it_navigate_marked(arg_t a) +bool cg_navigate_marked(arg_t a) { long n = (long) a; int d, i, cnt, sel, new; @@ -297,40 +243,66 @@ cmdreturn_t it_navigate_marked(arg_t a) tns.sel = new; tns.dirty = true; } - return CMD_DIRTY; + return true; } else { - return CMD_OK; + return false; } } -cmdreturn_t it_scroll_move(arg_t a) +bool ci_navigate(arg_t a) { - direction_t dir = (direction_t) a; + long n = (long) a; - if (mode == MODE_IMAGE) - return img_pan(&img, dir, prefix); - else - return tns_move_selection(&tns, dir, prefix); + if (prefix > 0) + n *= prefix; + n += fileidx; + if (n < 0) + n = 0; + if (n >= filecnt) + n = filecnt - 1; + + if (n != fileidx) { + load_image(n); + return true; + } else { + return false; + } } -cmdreturn_t it_scroll_screen(arg_t a) +bool ci_alternate(arg_t a) { - direction_t dir = (direction_t) a; - - if (mode == MODE_IMAGE) - return img_pan(&img, dir, -1); - else - return tns_scroll(&tns, dir, true); + load_image(alternate); + return true; } -cmdreturn_t i_scroll_to_edge(arg_t a) +bool ci_navigate_frame(arg_t a) +{ + return !img.multi.animate && img_frame_navigate(&img, (long) a); +} + +bool ci_toggle_animation(arg_t a) +{ + if (img.multi.animate) { + reset_timeout(animate); + img.multi.animate = false; + } else if (img_frame_animate(&img, true)) { + set_timeout(animate, img.multi.frames[img.multi.sel].delay, true); + } + return true; +} + +bool ci_scroll(arg_t a) { direction_t dir = (direction_t) a; - if (mode == MODE_IMAGE) - return img_pan_edge(&img, dir); - else - return CMD_INVALID; + return img_pan(&img, dir, prefix); +} + +bool ci_scroll_to_edge(arg_t a) +{ + direction_t dir = (direction_t) a; + + return img_pan_edge(&img, dir); } /* Xlib helper function for i_drag() */ @@ -344,7 +316,7 @@ Bool is_motionnotify(Display *d, XEvent *e, XPointer a) ox = x, oy = y; \ break -cmdreturn_t i_drag(arg_t a) +bool ci_drag(arg_t a) { int dx = 0, dy = 0, i, ox, oy, x, y; unsigned int ui; @@ -352,10 +324,8 @@ cmdreturn_t i_drag(arg_t a) XEvent e; Window w; - if (mode != MODE_IMAGE) - return CMD_INVALID; if (!XQueryPointer(win.env.dpy, win.xwin, &w, &w, &i, &i, &ox, &oy, &ui)) - return CMD_OK; + return false; win_set_cursor(&win, CURSOR_HAND); @@ -398,117 +368,109 @@ cmdreturn_t i_drag(arg_t a) dx = dy = 0; } } - win_set_cursor(&win, CURSOR_ARROW); set_timeout(reset_cursor, TO_CURSOR_HIDE, true); reset_timeout(redraw); - return CMD_OK; + return true; } -cmdreturn_t i_zoom(arg_t a) +bool ci_zoom(arg_t a) { long scale = (long) a; - if (mode != MODE_IMAGE) - return CMD_INVALID; - if (scale > 0) return img_zoom_in(&img); else if (scale < 0) return img_zoom_out(&img); else - return CMD_OK; + return false; } -cmdreturn_t i_set_zoom(arg_t a) +bool ci_set_zoom(arg_t a) { - if (mode == MODE_IMAGE) - return img_zoom(&img, (prefix ? prefix : (long) a) / 100.0); - else - return CMD_INVALID; + return img_zoom(&img, (prefix ? prefix : (long) a) / 100.0); } -cmdreturn_t i_fit_to_win(arg_t a) +bool ci_fit_to_win(arg_t a) { scalemode_t sm = (scalemode_t) a; - if (mode == MODE_IMAGE) - return img_fit_win(&img, sm); - else - return CMD_INVALID; + return img_fit_win(&img, sm); } -cmdreturn_t i_rotate(arg_t a) +bool ci_rotate(arg_t a) { degree_t degree = (degree_t) a; - if (mode == MODE_IMAGE) { - img_rotate(&img, degree); - return CMD_DIRTY; - } else { - return CMD_INVALID; - } + img_rotate(&img, degree); + return true; } -cmdreturn_t i_flip(arg_t a) +bool ci_flip(arg_t a) { flipdir_t dir = (flipdir_t) a; - if (mode == MODE_IMAGE) { - img_flip(&img, dir); - return CMD_DIRTY; - } else { - return CMD_INVALID; - } + img_flip(&img, dir); + return true; } -cmdreturn_t i_slideshow(arg_t a) +bool ci_change_gamma(arg_t a) { - if (mode == MODE_IMAGE) { - if (prefix > 0) { - img.ss.on = true; - img.ss.delay = prefix; - set_timeout(slideshow, img.ss.delay * 1000, true); - } else if (img.ss.on) { - img.ss.on = false; - reset_timeout(slideshow); - } else { - img.ss.on = true; - } - return CMD_DIRTY; - } else { - return CMD_INVALID; - } + return img_change_gamma(&img, (long) a); } -cmdreturn_t i_toggle_antialias(arg_t a) +bool ci_toggle_antialias(arg_t a) { - if (mode == MODE_IMAGE) { - img_toggle_antialias(&img); - return CMD_DIRTY; - } else { - return CMD_INVALID; - } + img_toggle_antialias(&img); + return true; } -cmdreturn_t i_toggle_alpha(arg_t a) +bool ci_toggle_alpha(arg_t a) { - if (mode == MODE_IMAGE) { - img.alpha = !img.alpha; - img.dirty = true; - return CMD_DIRTY; - } else { - return CMD_INVALID; - } + img.alpha = !img.alpha; + img.dirty = true; + return true; } -cmdreturn_t i_change_gamma(arg_t a) +bool ci_slideshow(arg_t a) { - if (mode == MODE_IMAGE) { - return img_change_gamma(&img, (long) a); + if (prefix > 0) { + img.ss.on = true; + img.ss.delay = prefix; + set_timeout(slideshow, img.ss.delay * 1000, true); + } else if (img.ss.on) { + img.ss.on = false; + reset_timeout(slideshow); } else { - return CMD_INVALID; + img.ss.on = true; } + return true; } +bool ct_move_sel(arg_t a) +{ + direction_t dir = (direction_t) a; + + return tns_move_selection(&tns, dir, prefix); +} + +bool ct_reload_all(arg_t a) +{ + tns_free(&tns); + tns_init(&tns, filecnt, &win); + return false; +} + + +#undef G_CMD +#define G_CMD(c) { -1, cg_##c }, +#undef I_CMD +#define I_CMD(c) { MODE_IMAGE, ci_##c }, +#undef T_CMD +#define T_CMD(c) { MODE_THUMB, ct_##c }, + +const cmd_t cmds[CMD_COUNT] = { +#include "commands.lst" +}; + diff --git a/commands.h b/commands.h index 0593a3f..a06427a 100644 --- a/commands.h +++ b/commands.h @@ -1,4 +1,4 @@ -/* Copyright 2011 Bert Muennich +/* Copyright 2011, 2014 Bert Muennich * * This file is part of sxiv. * @@ -23,58 +23,37 @@ #include "types.h" -typedef enum { - CMD_INVALID = -1, - CMD_OK = 0, - CMD_DIRTY = 1 -} cmdreturn_t; - typedef void* arg_t; -typedef cmdreturn_t (*command_f)(arg_t); +typedef bool (*cmd_f)(arg_t); + +#define G_CMD(c) g_##c, +#define I_CMD(c) i_##c, +#define T_CMD(c) t_##c, + +typedef enum { +#include "commands.lst" + CMD_COUNT +} cmd_id_t; + +typedef struct { + int mode; + cmd_f func; +} cmd_t; typedef struct { unsigned int mask; KeySym ksym; - command_f cmd; + cmd_id_t cmd; arg_t arg; } keymap_t; typedef struct { unsigned int mask; unsigned int button; - command_f cmd; + cmd_id_t cmd; arg_t arg; } button_t; -cmdreturn_t it_quit(arg_t); -cmdreturn_t it_switch_mode(arg_t); -cmdreturn_t it_toggle_fullscreen(arg_t); -cmdreturn_t it_toggle_bar(arg_t); -cmdreturn_t it_prefix_external(arg_t); -cmdreturn_t t_reload_all(arg_t); -cmdreturn_t it_reload_image(arg_t); -cmdreturn_t it_remove_image(arg_t); -cmdreturn_t i_navigate(arg_t); -cmdreturn_t i_alternate(arg_t); -cmdreturn_t it_first(arg_t); -cmdreturn_t it_n_or_last(arg_t); -cmdreturn_t i_navigate_frame(arg_t); -cmdreturn_t i_toggle_animation(arg_t); -cmdreturn_t it_toggle_image_mark(arg_t); -cmdreturn_t it_reverse_marks(arg_t); -cmdreturn_t it_navigate_marked(arg_t); -cmdreturn_t it_scroll_move(arg_t); -cmdreturn_t it_scroll_screen(arg_t); -cmdreturn_t i_scroll_to_edge(arg_t); -cmdreturn_t i_drag(arg_t); -cmdreturn_t i_zoom(arg_t); -cmdreturn_t i_set_zoom(arg_t); -cmdreturn_t i_fit_to_win(arg_t); -cmdreturn_t i_rotate(arg_t); -cmdreturn_t i_flip(arg_t); -cmdreturn_t i_slideshow(arg_t); -cmdreturn_t i_toggle_antialias(arg_t); -cmdreturn_t i_toggle_alpha(arg_t); -cmdreturn_t i_change_gamma(arg_t); +const extern cmd_t cmds[CMD_COUNT]; #endif /* COMMANDS_H */ diff --git a/commands.lst b/commands.lst new file mode 100644 index 0000000..ece3f48 --- /dev/null +++ b/commands.lst @@ -0,0 +1,34 @@ +G_CMD(quit) +G_CMD(switch_mode) +G_CMD(toggle_fullscreen) +G_CMD(toggle_bar) +G_CMD(prefix_external) +G_CMD(reload_image) +G_CMD(remove_image) +G_CMD(first) +G_CMD(n_or_last) +G_CMD(scroll_screen) +G_CMD(toggle_image_mark) +G_CMD(reverse_marks) +G_CMD(navigate_marked) + +I_CMD(navigate) +I_CMD(alternate) +I_CMD(navigate_frame) +I_CMD(toggle_animation) +I_CMD(scroll) +I_CMD(scroll_to_edge) +I_CMD(drag) +I_CMD(zoom) +I_CMD(set_zoom) +I_CMD(fit_to_win) +I_CMD(rotate) +I_CMD(flip) +I_CMD(change_gamma) +I_CMD(toggle_antialias) +I_CMD(toggle_alpha) +I_CMD(slideshow) + +T_CMD(move_sel) +T_CMD(reload_all) + diff --git a/config.def.h b/config.def.h index 3fd459d..5d1a6e2 100644 --- a/config.def.h +++ b/config.def.h @@ -69,16 +69,37 @@ enum { THUMB_SIZE = 60 }; /* keyboard mappings for image and thumbnail mode: */ static const keymap_t keys[] = { /* modifiers key function argument */ - { 0, XK_q, it_quit, (arg_t) None }, - { 0, XK_Return, it_switch_mode, (arg_t) None }, - { 0, XK_f, it_toggle_fullscreen, (arg_t) None }, - { 0, XK_b, it_toggle_bar, (arg_t) None }, + { 0, XK_q, g_quit, (arg_t) None }, + { 0, XK_Return, g_switch_mode, (arg_t) None }, + { 0, XK_f, g_toggle_fullscreen, (arg_t) None }, + { 0, XK_b, g_toggle_bar, (arg_t) None }, + { ControlMask, XK_x, g_prefix_external, (arg_t) None }, + { 0, XK_g, g_first, (arg_t) None }, + { 0, XK_G, g_n_or_last, (arg_t) None }, + { 0, XK_r, g_reload_image, (arg_t) None }, + { 0, XK_D, g_remove_image, (arg_t) None }, + { ControlMask, XK_h, g_scroll_screen, (arg_t) DIR_LEFT }, + { ControlMask, XK_Left, g_scroll_screen, (arg_t) DIR_LEFT }, + { ControlMask, XK_j, g_scroll_screen, (arg_t) DIR_DOWN }, + { ControlMask, XK_Down, g_scroll_screen, (arg_t) DIR_DOWN }, + { ControlMask, XK_k, g_scroll_screen, (arg_t) DIR_UP }, + { ControlMask, XK_Up, g_scroll_screen, (arg_t) DIR_UP }, + { ControlMask, XK_l, g_scroll_screen, (arg_t) DIR_RIGHT }, + { ControlMask, XK_Right, g_scroll_screen, (arg_t) DIR_RIGHT }, + { 0, XK_m, g_toggle_image_mark, (arg_t) None }, + { 0, XK_M, g_reverse_marks, (arg_t) None }, + { 0, XK_N, g_navigate_marked, (arg_t) +1 }, + { 0, XK_P, g_navigate_marked, (arg_t) -1 }, - { ControlMask, XK_x, it_prefix_external, (arg_t) None }, - - { 0, XK_r, it_reload_image, (arg_t) None }, + { 0, XK_h, t_move_sel, (arg_t) DIR_LEFT }, + { 0, XK_Left, t_move_sel, (arg_t) DIR_LEFT }, + { 0, XK_j, t_move_sel, (arg_t) DIR_DOWN }, + { 0, XK_Down, t_move_sel, (arg_t) DIR_DOWN }, + { 0, XK_k, t_move_sel, (arg_t) DIR_UP }, + { 0, XK_Up, t_move_sel, (arg_t) DIR_UP }, + { 0, XK_l, t_move_sel, (arg_t) DIR_RIGHT }, + { 0, XK_Right, t_move_sel, (arg_t) DIR_RIGHT }, { 0, XK_R, t_reload_all, (arg_t) None }, - { 0, XK_D, it_remove_image, (arg_t) None }, { 0, XK_n, i_navigate, (arg_t) +1 }, { 0, XK_space, i_navigate, (arg_t) +1 }, @@ -87,41 +108,21 @@ static const keymap_t keys[] = { { 0, XK_bracketright, i_navigate, (arg_t) +10 }, { 0, XK_bracketleft, i_navigate, (arg_t) -10 }, { ControlMask, XK_6, i_alternate, (arg_t) None }, - { 0, XK_g, it_first, (arg_t) None }, - { 0, XK_G, it_n_or_last, (arg_t) None }, - { ControlMask, XK_n, i_navigate_frame, (arg_t) +1 }, { ControlMask, XK_p, i_navigate_frame, (arg_t) -1 }, { ControlMask, XK_space, i_toggle_animation, (arg_t) None }, - - { 0, XK_m, it_toggle_image_mark, (arg_t) None }, - { 0, XK_M, it_reverse_marks, (arg_t) None }, - { 0, XK_N, it_navigate_marked, (arg_t) +1 }, - { 0, XK_P, it_navigate_marked, (arg_t) -1 }, - - { 0, XK_h, it_scroll_move, (arg_t) DIR_LEFT }, - { 0, XK_Left, it_scroll_move, (arg_t) DIR_LEFT }, - { 0, XK_j, it_scroll_move, (arg_t) DIR_DOWN }, - { 0, XK_Down, it_scroll_move, (arg_t) DIR_DOWN }, - { 0, XK_k, it_scroll_move, (arg_t) DIR_UP }, - { 0, XK_Up, it_scroll_move, (arg_t) DIR_UP }, - { 0, XK_l, it_scroll_move, (arg_t) DIR_RIGHT }, - { 0, XK_Right, it_scroll_move, (arg_t) DIR_RIGHT }, - - { ControlMask, XK_h, it_scroll_screen, (arg_t) DIR_LEFT }, - { ControlMask, XK_Left, it_scroll_screen, (arg_t) DIR_LEFT }, - { ControlMask, XK_j, it_scroll_screen, (arg_t) DIR_DOWN }, - { ControlMask, XK_Down, it_scroll_screen, (arg_t) DIR_DOWN }, - { ControlMask, XK_k, it_scroll_screen, (arg_t) DIR_UP }, - { ControlMask, XK_Up, it_scroll_screen, (arg_t) DIR_UP }, - { ControlMask, XK_l, it_scroll_screen, (arg_t) DIR_RIGHT }, - { ControlMask, XK_Right, it_scroll_screen, (arg_t) DIR_RIGHT }, - + { 0, XK_h, i_scroll, (arg_t) DIR_LEFT }, + { 0, XK_Left, i_scroll, (arg_t) DIR_LEFT }, + { 0, XK_j, i_scroll, (arg_t) DIR_DOWN }, + { 0, XK_Down, i_scroll, (arg_t) DIR_DOWN }, + { 0, XK_k, i_scroll, (arg_t) DIR_UP }, + { 0, XK_Up, i_scroll, (arg_t) DIR_UP }, + { 0, XK_l, i_scroll, (arg_t) DIR_RIGHT }, + { 0, XK_Right, i_scroll, (arg_t) DIR_RIGHT }, { 0, XK_H, i_scroll_to_edge, (arg_t) DIR_LEFT }, { 0, XK_J, i_scroll_to_edge, (arg_t) DIR_DOWN }, { 0, XK_K, i_scroll_to_edge, (arg_t) DIR_UP }, { 0, XK_L, i_scroll_to_edge, (arg_t) DIR_RIGHT }, - { 0, XK_plus, i_zoom, (arg_t) +1 }, { 0, XK_KP_Add, i_zoom, (arg_t) +1 }, { 0, XK_minus, i_zoom, (arg_t) -1 }, @@ -131,22 +132,17 @@ static const keymap_t keys[] = { { 0, XK_W, i_fit_to_win, (arg_t) SCALE_FIT }, { 0, XK_e, i_fit_to_win, (arg_t) SCALE_WIDTH }, { 0, XK_E, i_fit_to_win, (arg_t) SCALE_HEIGHT }, - { 0, XK_less, i_rotate, (arg_t) DEGREE_270 }, { 0, XK_greater, i_rotate, (arg_t) DEGREE_90 }, { 0, XK_question, i_rotate, (arg_t) DEGREE_180 }, - { 0, XK_bar, i_flip, (arg_t) FLIP_HORIZONTAL }, { 0, XK_underscore, i_flip, (arg_t) FLIP_VERTICAL }, - - { 0, XK_s, i_slideshow, (arg_t) None }, - - { 0, XK_a, i_toggle_antialias, (arg_t) None }, - { 0, XK_A, i_toggle_alpha, (arg_t) None }, - { 0, XK_braceleft, i_change_gamma, (arg_t) -1 }, { 0, XK_braceright, i_change_gamma, (arg_t) +1 }, { ControlMask, XK_g, i_change_gamma, (arg_t) 0 }, + { 0, XK_a, i_toggle_antialias, (arg_t) None }, + { 0, XK_A, i_toggle_alpha, (arg_t) None }, + { 0, XK_s, i_slideshow, (arg_t) None }, }; /* mouse button mappings for image mode: */ @@ -155,12 +151,12 @@ static const button_t buttons[] = { { 0, 1, i_navigate, (arg_t) +1 }, { 0, 3, i_navigate, (arg_t) -1 }, { 0, 2, i_drag, (arg_t) None }, - { 0, 4, it_scroll_move, (arg_t) DIR_UP }, - { 0, 5, it_scroll_move, (arg_t) DIR_DOWN }, - { ShiftMask, 4, it_scroll_move, (arg_t) DIR_LEFT }, - { ShiftMask, 5, it_scroll_move, (arg_t) DIR_RIGHT }, - { 0, 6, it_scroll_move, (arg_t) DIR_LEFT }, - { 0, 7, it_scroll_move, (arg_t) DIR_RIGHT }, + { 0, 4, i_scroll, (arg_t) DIR_UP }, + { 0, 5, i_scroll, (arg_t) DIR_DOWN }, + { ShiftMask, 4, i_scroll, (arg_t) DIR_LEFT }, + { ShiftMask, 5, i_scroll, (arg_t) DIR_RIGHT }, + { 0, 6, i_scroll, (arg_t) DIR_LEFT }, + { 0, 7, i_scroll, (arg_t) DIR_RIGHT }, { ControlMask, 4, i_zoom, (arg_t) +1 }, { ControlMask, 5, i_zoom, (arg_t) -1 }, }; diff --git a/main.c b/main.c index ee84719..86b97b0 100644 --- a/main.c +++ b/main.c @@ -567,13 +567,10 @@ void on_keypress(XKeyEvent *kev) } else for (i = 0; i < ARRLEN(keys); i++) { if (keys[i].ksym == ksym && MODMASK(keys[i].mask | sh) == MODMASK(kev->state) && - keys[i].cmd != NULL) + keys[i].cmd >= 0 && keys[i].cmd < CMD_COUNT && + (cmds[keys[i].cmd].mode < 0 || cmds[keys[i].cmd].mode == mode)) { - cmdreturn_t ret = keys[i].cmd(keys[i].arg); - - if (ret == CMD_INVALID) - continue; - if (ret == CMD_DIRTY) + if (cmds[keys[i].cmd].func(keys[i].arg)) redraw(); break; } @@ -596,13 +593,10 @@ void on_buttonpress(XButtonEvent *bev) for (i = 0; i < ARRLEN(buttons); i++) { if (buttons[i].button == bev->button && MODMASK(buttons[i].mask) == MODMASK(bev->state) && - buttons[i].cmd != NULL) + buttons[i].cmd >= 0 && buttons[i].cmd < CMD_COUNT && + (cmds[buttons[i].cmd].mode < 0 || cmds[buttons[i].cmd].mode == mode)) { - cmdreturn_t ret = buttons[i].cmd(buttons[i].arg); - - if (ret == CMD_INVALID) - continue; - if (ret == CMD_DIRTY) + if (cmds[buttons[i].cmd].func(buttons[i].arg)) redraw(); break; } diff --git a/sxiv.1 b/sxiv.1 index a9e83a4..a238282 100644 --- a/sxiv.1 +++ b/sxiv.1 @@ -92,23 +92,16 @@ Set zoom level to ZOOM percent. .SH GENERAL KEYBOARD COMMANDS The following keyboard commands are available in both image and thumbnail mode: .TP +.BR 0 \- 9 +Prefix the next command with a number (denoted via +.IR count ). +.TP .B q Quit sxiv. .TP .B Return Switch to thumbnail mode / open selected image in image mode. .TP -.BR 0 \- 9 -Prefix the next command with a number (denoted via -.IR count ). -.TP -.B g -Go to the first image. -.TP -.B G -Go to the last image, or image number -.IR count . -.TP .B f Toggle fullscreen mode. .TP @@ -118,15 +111,31 @@ Toggle visibility of info bar on bottom of window. .B Ctrl-x Send the next key to the external key-handler. .TP +.B g +Go to the first image. +.TP +.B G +Go to the last image, or image number +.IR count . +.TP .B r Reload image. .TP -.B R -Reload all thumbnails. -.TP .B D Remove current image from file list and go to next image. .TP +.BR Ctrl-h ", " Ctrl-Left +Scroll left one screen width. +.TP +.BR Ctrl-j ", " Ctrl-Down +Scroll down one screen height. +.TP +.BR Ctrl-k ", " Ctrl-Up +Scroll up one screen height. +.TP +.BR Ctrl-l ", " Ctrl-Right +Scroll right one screen width. +.TP .B m Mark/unmark the current image. .TP @@ -165,11 +174,8 @@ Move selection right .I count times. .TP -.BR Ctrl-j ", " Ctrl-Down -Scroll thumbnail grid one window height down. -.TP -.BR Ctrl-k ", " Ctrl-Up -Scroll thumbnail grid one window height up. +.B R +Reload all thumbnails. .SH IMAGE KEYBOARD COMMANDS The following keyboard commands are only available in image mode: .SS Navigate image list @@ -203,6 +209,39 @@ Go to the previous frame of a multi-frame image. .TP .B Ctrl-Space Play/pause animation of a multi-frame image. +.SS Panning +.TP +.BR h ", " Left +Scroll image 1/5 of window width or +.I count +pixel left. +.TP +.BR j ", " Down +Scroll image 1/5 of window height or +.I count +pixel down. +.TP +.BR k ", " Up +Scroll image 1/5 of window height or +.I count +pixel up. +.TP +.BR l ", " Right +Scroll image 1/5 of window width or +.I count +pixel right. +.TP +.B H +Scroll to left image edge. +.TP +.B J +Scroll to bottom image edge. +.TP +.B K +Scroll to top image edge. +.TP +.B L +Scroll to right image edge. .SS Zooming .TP .BR + @@ -226,51 +265,6 @@ Fit image to window width. .TP .B E Fit image to window height. -.SS Panning -.TP -.BR h ", " Left -Pan image 1/5 of window width or -.I count -pixel left. -.TP -.BR j ", " Down -Pan image 1/5 of window height or -.I count -pixel down. -.TP -.BR k ", " Up -Pan image 1/5 of window height or -.I count -pixel up. -.TP -.BR l ", " Right -Pan image 1/5 of window width or -.I count -pixel right. -.TP -.B H -Pan to left image edge. -.TP -.B J -Pan to bottom image edge. -.TP -.B K -Pan to top image edge. -.TP -.B L -Pan to right image edge. -.TP -.BR Ctrl-h ", " Ctrl-Left -Pan image one window width left. -.TP -.BR Ctrl-j ", " Ctrl-Down -Pan image one window height down. -.TP -.BR Ctrl-k ", " Ctrl-Up -Pan image one window height up. -.TP -.BR Ctrl-l ", " Ctrl-Right -Pan image one window width right. .SS Rotation .TP .B < @@ -281,7 +275,7 @@ Rotate image clockwise by 90 degrees. .TP .B ? Rotate image by 180 degrees. -.SS Flip +.SS Flipping .TP .B | Flip image horizontally. @@ -319,6 +313,22 @@ Go to next image. .TP .B Button3 Go to the previous image. +.SS Panning +.TP +.B Button2 +Drag the image with the mouse while keeping this button pressed down. +.TP +.B ScrollUp +Scroll image up. +.TP +.B ScrollDown +Scroll image down. +.TP +.B Shift+ScrollUp +Scroll image left. +.TP +.B Shift+ScrollDown +Scroll image right. .SS Zooming .TP .B Ctrl+ScrollUp @@ -326,22 +336,6 @@ Zoom in. .TP .B Ctrl+ScrollDown Zoom out. -.SS Panning/Moving -.TP -.B Button2 -Drag the image with the mouse while keeping this button pressed down. -.TP -.B ScrollUp -Pan image up. -.TP -.B ScrollDown -Pan image down. -.TP -.B Shift+ScrollUp -Pan image left. -.TP -.B Shift+ScrollDown -Pan image right. .SH STATUS BAR The information displayed on the left side of the status bar can be replaced with the output of a user-provided script, which is called by sxiv whenever an