aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert Münnich <ber.t@posteo.de>2014-07-23 21:50:31 +0200
committerBert Münnich <ber.t@posteo.de>2014-07-23 21:50:31 +0200
commit06164c29b759c3e21e79be03b285bdf3da6f5a25 (patch)
tree75b3c1a68da5271e89b84b7905339ff3f3283569
parent5d0679b855bb42aaaf3435a3182ac5ddb4412e1f (diff)
Revised command structure and key and mouse button mappings
-rw-r--r--Makefile2
-rw-r--r--README.md43
-rw-r--r--commands.c316
-rw-r--r--commands.h57
-rw-r--r--commands.lst34
-rw-r--r--config.def.h98
-rw-r--r--main.c18
-rw-r--r--sxiv.1136
8 files changed, 324 insertions, 380 deletions
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;
- } else {
- return CMD_OK;
- }
-}
-
-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;
+ return true;
} else {
- return CMD_INVALID;
+ return false;
}
}
-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;
- else
- return !img.multi.animate && img_frame_navigate(&img, (long) a);
-}
-
-cmdreturn_t i_toggle_animation(arg_t a)
-{
- if (mode != MODE_IMAGE)
- return CMD_INVALID;
+ direction_t dir = (direction_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 CMD_DIRTY;
+ if (mode == MODE_IMAGE)
+ return img_pan(&img, dir, -1);
+ else
+ return tns_scroll(&tns, dir, true);
}
-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;
+ }
+}
+
+bool ci_alternate(arg_t a)
+{
+ load_image(alternate);
+ return true;
+}
+
+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;
}
-cmdreturn_t it_scroll_screen(arg_t a)
+bool ci_scroll(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);
+ return img_pan(&img, dir, prefix);
}
-cmdreturn_t i_scroll_to_edge(arg_t a)
+bool ci_scroll_to_edge(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_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 void* 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 {
- CMD_INVALID = -1,
- CMD_OK = 0,
- CMD_DIRTY = 1
-} cmdreturn_t;
+#include "commands.lst"
+ CMD_COUNT
+} cmd_id_t;
-typedef void* arg_t;
-typedef cmdreturn_t (*command_f)(arg_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 },
-
- { ControlMask, XK_x, it_prefix_external, (arg_t) None },
-
- { 0, XK_r, it_reload_image, (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 },
+
+ { 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,22 +92,15 @@ Set zoom level to ZOOM percent.
.SH GENERAL KEYBOARD COMMANDS
The following keyboard commands are available in both image and thumbnail mode:
.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.
+.B q
+Quit sxiv.
.TP
-.B G
-Go to the last image, or image number
-.IR count .
+.B Return
+Switch to thumbnail mode / open selected image in image mode.
.TP
.B f
Toggle fullscreen mode.
@@ -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,74 +209,62 @@ Go to the previous frame of a multi-frame image.
.TP
.B Ctrl-Space
Play/pause animation of a multi-frame image.
-.SS Zooming
-.TP
-.BR +
-Zoom in.
-.TP
-.B \-
-Zoom out.
-.TP
-.B =
-Set zoom level to 100%, or
-.IR count %.
-.TP
-.B w
-Set zoom level to 100%, but fit large images into window.
-.TP
-.B W
-Fit image to window.
-.TP
-.B e
-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
+Scroll image 1/5 of window width or
.I count
pixel left.
.TP
.BR j ", " Down
-Pan image 1/5 of window height or
+Scroll image 1/5 of window height or
.I count
pixel down.
.TP
.BR k ", " Up
-Pan image 1/5 of window height or
+Scroll image 1/5 of window height or
.I count
pixel up.
.TP
.BR l ", " Right
-Pan image 1/5 of window width or
+Scroll image 1/5 of window width or
.I count
pixel right.
.TP
.B H
-Pan to left image edge.
+Scroll to left image edge.
.TP
.B J
-Pan to bottom image edge.
+Scroll to bottom image edge.
.TP
.B K
-Pan to top image edge.
+Scroll to top image edge.
.TP
.B L
-Pan to right image edge.
+Scroll to right image edge.
+.SS Zooming
.TP
-.BR Ctrl-h ", " Ctrl-Left
-Pan image one window width left.
+.BR +
+Zoom in.
.TP
-.BR Ctrl-j ", " Ctrl-Down
-Pan image one window height down.
+.B \-
+Zoom out.
.TP
-.BR Ctrl-k ", " Ctrl-Up
-Pan image one window height up.
+.B =
+Set zoom level to 100%, or
+.IR count %.
.TP
-.BR Ctrl-l ", " Ctrl-Right
-Pan image one window width right.
+.B w
+Set zoom level to 100%, but fit large images into window.
+.TP
+.B W
+Fit image to window.
+.TP
+.B e
+Fit image to window width.
+.TP
+.B E
+Fit image to window height.
.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,29 +313,29 @@ Go to next image.
.TP
.B Button3
Go to the previous image.
-.SS Zooming
-.TP
-.B Ctrl+ScrollUp
-Zoom in.
-.TP
-.B Ctrl+ScrollDown
-Zoom out.
-.SS Panning/Moving
+.SS Panning
.TP
.B Button2
Drag the image with the mouse while keeping this button pressed down.
.TP
.B ScrollUp
-Pan image up.
+Scroll image up.
.TP
.B ScrollDown
-Pan image down.
+Scroll image down.
.TP
.B Shift+ScrollUp
-Pan image left.
+Scroll image left.
.TP
.B Shift+ScrollDown
-Pan image right.
+Scroll image right.
+.SS Zooming
+.TP
+.B Ctrl+ScrollUp
+Zoom in.
+.TP
+.B Ctrl+ScrollDown
+Zoom out.
.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