Revised command structure and key and mouse button mappings

This commit is contained in:
Bert Münnich 2014-07-23 21:50:31 +02:00
parent 5d0679b855
commit 06164c29b7
8 changed files with 336 additions and 392 deletions

View File

@ -1,4 +1,4 @@
VERSION = git-20140615 VERSION = git-20140723
PREFIX = /usr/local PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man MANPREFIX = $(PREFIX)/share/man

View File

@ -89,24 +89,17 @@ of small previews is displayed, making it easy to choose an image to open.
**Key mappings:** **Key mappings:**
0-9 Prefix the next command with a number (denoted via [count])
q Quit sxiv q Quit sxiv
Return Switch to thumbnail mode / open selected image Return Switch to thumbnail mode / open selected image
f Toggle fullscreen mode
0-9 Prefix the next command with a number (denoted via [count]) b Toggle visibility of info bar on bottom of window
Ctrl-x Send the next key to the external key-handler Ctrl-x Send the next key to the external key-handler
g Go to first image g Go to first image
G Go to the last image, or image number [count] 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 image
R Reload all thumbnails
D Remove image from file list and go to next image 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 Mark/unmark current image
M Reverse all image marks M Reverse all image marks
N Go [count] marked images forward 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:* *Thumbnail mode:*
h,j,k,l Move selection left/down/up/right [count] times h,j,k,l Move selection left/down/up/right [count] times (also with
Ctrl-j,k Scroll thumbnail grid one window height down/up arrow keys)
R Reload all thumbnails
*Image mode:* *Image mode:*
n,Space Go [count] images forward n,Space Go [count] images forward
p,Backspace Go [count] images backward p,Backspace Go [count] images backward
[,] Go [count] * 10 images backward/forward [,] Go [count] * 10 images backward/forward
Ctrl-n,p Go to the next/previous frame of a multi-frame image Ctrl-n,p Go to the next/previous frame of a multi-frame image
Ctrl-Space Play/pause animation 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 in
- Zoom out - Zoom out
= Set zoom level to 100%, or [count]% = 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 W Fit image to window
e Fit image to window width e Fit image to window width
E Fit image to window height 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 (counter-)clockwise by 90 degrees
? Rotate image by 180 degrees ? Rotate image by 180 degrees
|,_ Flip image horizontally/vertically |,_ Flip image horizontally/vertically
{,} Decrease/increase gamma {,} Decrease/increase gamma
Ctrl-g Reset gamma Ctrl-g Reset gamma
a Toggle anti-aliasing a Toggle anti-aliasing
A Toggle visibility of alpha-channel, i.e. transparency A Toggle visibility of alpha-channel, i.e. transparency
s Toggle slideshow or set delay to [count] seconds 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:* *Image mode:*
Button1 Go to the next image Button1 Go to the next image
Button2 Drag image with mouse while keeping it pressed
Button3 Go to the previous image Button3 Go to the previous image
Scroll Pan image up/down Button2 Drag image with mouse while keeping it pressed
Shift+Scroll Pan image left/right Wheel Scroll image up/down
Ctrl+Scroll Zoom in/out Shift+Wheel Scroll image left/right
Ctrl+Wheel Zoom in/out
Download & Changelog Download & Changelog

View File

@ -1,4 +1,4 @@
/* Copyright 2011, 2012 Bert Muennich /* Copyright 2011, 2012, 2014 Bert Muennich
* *
* This file is part of sxiv. * 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 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; unsigned int i;
@ -72,7 +72,7 @@ cmdreturn_t it_quit(arg_t a)
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
cmdreturn_t it_switch_mode(arg_t a) bool cg_switch_mode(arg_t a)
{ {
if (mode == MODE_IMAGE) { if (mode == MODE_IMAGE) {
if (tns.thumbs == NULL) if (tns.thumbs == NULL)
@ -90,10 +90,10 @@ cmdreturn_t it_switch_mode(arg_t a)
load_image(tns.sel); load_image(tns.sel);
mode = MODE_IMAGE; 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); win_toggle_fullscreen(&win);
/* redraw after next ConfigureNotify event */ /* redraw after next ConfigureNotify event */
@ -102,10 +102,10 @@ cmdreturn_t it_toggle_fullscreen(arg_t a)
img.checkpan = img.dirty = true; img.checkpan = img.dirty = true;
else else
tns.dirty = true; 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); win_toggle_bar(&win);
if (mode == MODE_IMAGE) { if (mode == MODE_IMAGE) {
@ -115,27 +115,16 @@ cmdreturn_t it_toggle_bar(arg_t a)
} else { } else {
tns.dirty = true; 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; extprefix = true;
return CMD_OK; return false;
} }
cmdreturn_t t_reload_all(arg_t a) bool cg_reload_image(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)
{ {
if (mode == MODE_IMAGE) { if (mode == MODE_IMAGE) {
load_image(fileidx); load_image(fileidx);
@ -148,120 +137,77 @@ cmdreturn_t it_reload_image(arg_t a)
tns.sel = tns.cnt - 1; 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) { if (mode == MODE_IMAGE) {
remove_file(fileidx, true); remove_file(fileidx, true);
load_image(fileidx >= filecnt ? filecnt - 1 : fileidx); load_image(fileidx >= filecnt ? filecnt - 1 : fileidx);
return CMD_DIRTY; return true;
} else if (tns.sel < tns.cnt) { } else if (tns.sel < tns.cnt) {
remove_file(tns.sel, true); remove_file(tns.sel, true);
tns.dirty = true; tns.dirty = true;
if (tns.sel >= tns.cnt) if (tns.sel >= tns.cnt)
tns.sel = tns.cnt - 1; tns.sel = tns.cnt - 1;
return CMD_DIRTY; return true;
} else { } else {
return CMD_OK; return false;
} }
} }
cmdreturn_t i_navigate(arg_t a) bool cg_first(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)
{ {
if (mode == MODE_IMAGE && fileidx != 0) { if (mode == MODE_IMAGE && fileidx != 0) {
load_image(0); load_image(0);
return CMD_DIRTY; return true;
} else if (mode == MODE_THUMB && tns.sel != 0) { } else if (mode == MODE_THUMB && tns.sel != 0) {
tns.sel = 0; tns.sel = 0;
tns.dirty = true; tns.dirty = true;
return CMD_DIRTY; return true;
} else { } 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; int n = prefix != 0 && prefix - 1 < filecnt ? prefix - 1 : filecnt - 1;
if (mode == MODE_IMAGE && fileidx != n) { if (mode == MODE_IMAGE && fileidx != n) {
load_image(n); load_image(n);
return CMD_DIRTY; return true;
} else if (mode == MODE_THUMB && tns.sel != n) { } else if (mode == MODE_THUMB && tns.sel != n) {
tns.sel = n; tns.sel = n;
tns.dirty = true; tns.dirty = true;
return CMD_DIRTY; return true;
} else { } 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) direction_t dir = (direction_t) a;
return CMD_INVALID;
if (mode == MODE_IMAGE)
return img_pan(&img, dir, -1);
else 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) bool cg_toggle_image_mark(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)
{ {
int sel = mode == MODE_IMAGE ? fileidx : tns.sel; int sel = mode == MODE_IMAGE ? fileidx : tns.sel;
files[sel].marked = !files[sel].marked; files[sel].marked = !files[sel].marked;
if (mode == MODE_THUMB) if (mode == MODE_THUMB)
tns_mark(&tns, sel, files[sel].marked); 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; 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; files[i].marked = !files[i].marked;
if (mode == MODE_THUMB) if (mode == MODE_THUMB)
tns.dirty = true; 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; long n = (long) a;
int d, i, cnt, sel, new; int d, i, cnt, sel, new;
@ -297,40 +243,66 @@ cmdreturn_t it_navigate_marked(arg_t a)
tns.sel = new; tns.sel = new;
tns.dirty = true; tns.dirty = true;
} }
return CMD_DIRTY; return true;
} else { } 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) if (prefix > 0)
return img_pan(&img, dir, prefix); n *= prefix;
else n += fileidx;
return tns_move_selection(&tns, dir, prefix); 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; load_image(alternate);
return true;
if (mode == MODE_IMAGE)
return img_pan(&img, dir, -1);
else
return tns_scroll(&tns, dir, 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; direction_t dir = (direction_t) a;
if (mode == MODE_IMAGE) return img_pan(&img, dir, prefix);
return img_pan_edge(&img, dir); }
else
return CMD_INVALID; 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() */ /* Xlib helper function for i_drag() */
@ -344,7 +316,7 @@ Bool is_motionnotify(Display *d, XEvent *e, XPointer a)
ox = x, oy = y; \ ox = x, oy = y; \
break break
cmdreturn_t i_drag(arg_t a) bool ci_drag(arg_t a)
{ {
int dx = 0, dy = 0, i, ox, oy, x, y; int dx = 0, dy = 0, i, ox, oy, x, y;
unsigned int ui; unsigned int ui;
@ -352,10 +324,8 @@ cmdreturn_t i_drag(arg_t a)
XEvent e; XEvent e;
Window w; Window w;
if (mode != MODE_IMAGE)
return CMD_INVALID;
if (!XQueryPointer(win.env.dpy, win.xwin, &w, &w, &i, &i, &ox, &oy, &ui)) 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); win_set_cursor(&win, CURSOR_HAND);
@ -398,117 +368,109 @@ cmdreturn_t i_drag(arg_t a)
dx = dy = 0; dx = dy = 0;
} }
} }
win_set_cursor(&win, CURSOR_ARROW); win_set_cursor(&win, CURSOR_ARROW);
set_timeout(reset_cursor, TO_CURSOR_HIDE, true); set_timeout(reset_cursor, TO_CURSOR_HIDE, true);
reset_timeout(redraw); 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; long scale = (long) a;
if (mode != MODE_IMAGE)
return CMD_INVALID;
if (scale > 0) if (scale > 0)
return img_zoom_in(&img); return img_zoom_in(&img);
else if (scale < 0) else if (scale < 0)
return img_zoom_out(&img); return img_zoom_out(&img);
else 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);
return img_zoom(&img, (prefix ? prefix : (long) a) / 100.0);
else
return CMD_INVALID;
} }
cmdreturn_t i_fit_to_win(arg_t a) bool ci_fit_to_win(arg_t a)
{ {
scalemode_t sm = (scalemode_t) a; scalemode_t sm = (scalemode_t) a;
if (mode == MODE_IMAGE) return img_fit_win(&img, sm);
return img_fit_win(&img, sm);
else
return CMD_INVALID;
} }
cmdreturn_t i_rotate(arg_t a) bool ci_rotate(arg_t a)
{ {
degree_t degree = (degree_t) a; degree_t degree = (degree_t) a;
if (mode == MODE_IMAGE) { img_rotate(&img, degree);
img_rotate(&img, degree); return true;
return CMD_DIRTY;
} else {
return CMD_INVALID;
}
} }
cmdreturn_t i_flip(arg_t a) bool ci_flip(arg_t a)
{ {
flipdir_t dir = (flipdir_t) a; flipdir_t dir = (flipdir_t) a;
if (mode == MODE_IMAGE) { img_flip(&img, dir);
img_flip(&img, dir); return true;
return CMD_DIRTY;
} else {
return CMD_INVALID;
}
} }
cmdreturn_t i_slideshow(arg_t a) bool ci_change_gamma(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 {
img.ss.on = true;
}
return CMD_DIRTY;
} else {
return CMD_INVALID;
}
} }
cmdreturn_t i_toggle_antialias(arg_t a) bool ci_toggle_antialias(arg_t a)
{ {
if (mode == MODE_IMAGE) { img_toggle_antialias(&img);
img_toggle_antialias(&img); return true;
return CMD_DIRTY;
} else {
return CMD_INVALID;
}
} }
cmdreturn_t i_toggle_alpha(arg_t a) bool ci_toggle_alpha(arg_t a)
{ {
if (mode == MODE_IMAGE) { img.alpha = !img.alpha;
img.alpha = !img.alpha; img.dirty = true;
img.dirty = true; return true;
return CMD_DIRTY;
} else {
return CMD_INVALID;
}
} }
cmdreturn_t i_change_gamma(arg_t a) bool ci_slideshow(arg_t a)
{ {
if (mode == MODE_IMAGE) { if (prefix > 0) {
return img_change_gamma(&img, (long) a); 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 { } 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"
};

View File

@ -1,4 +1,4 @@
/* Copyright 2011 Bert Muennich /* Copyright 2011, 2014 Bert Muennich
* *
* This file is part of sxiv. * This file is part of sxiv.
* *
@ -23,58 +23,37 @@
#include "types.h" #include "types.h"
typedef enum {
CMD_INVALID = -1,
CMD_OK = 0,
CMD_DIRTY = 1
} cmdreturn_t;
typedef void* arg_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 { typedef struct {
unsigned int mask; unsigned int mask;
KeySym ksym; KeySym ksym;
command_f cmd; cmd_id_t cmd;
arg_t arg; arg_t arg;
} keymap_t; } keymap_t;
typedef struct { typedef struct {
unsigned int mask; unsigned int mask;
unsigned int button; unsigned int button;
command_f cmd; cmd_id_t cmd;
arg_t arg; arg_t arg;
} button_t; } button_t;
cmdreturn_t it_quit(arg_t); const extern cmd_t cmds[CMD_COUNT];
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);
#endif /* COMMANDS_H */ #endif /* COMMANDS_H */

34
commands.lst Normal file
View File

@ -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)

View File

@ -69,16 +69,37 @@ enum { THUMB_SIZE = 60 };
/* keyboard mappings for image and thumbnail mode: */ /* keyboard mappings for image and thumbnail mode: */
static const keymap_t keys[] = { static const keymap_t keys[] = {
/* modifiers key function argument */ /* modifiers key function argument */
{ 0, XK_q, it_quit, (arg_t) None }, { 0, XK_q, g_quit, (arg_t) None },
{ 0, XK_Return, it_switch_mode, (arg_t) None }, { 0, XK_Return, g_switch_mode, (arg_t) None },
{ 0, XK_f, it_toggle_fullscreen, (arg_t) None }, { 0, XK_f, g_toggle_fullscreen, (arg_t) None },
{ 0, XK_b, it_toggle_bar, (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_h, t_move_sel, (arg_t) DIR_LEFT },
{ 0, XK_Left, t_move_sel, (arg_t) DIR_LEFT },
{ 0, XK_r, it_reload_image, (arg_t) None }, { 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_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_n, i_navigate, (arg_t) +1 },
{ 0, XK_space, 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_bracketright, i_navigate, (arg_t) +10 },
{ 0, XK_bracketleft, i_navigate, (arg_t) -10 }, { 0, XK_bracketleft, i_navigate, (arg_t) -10 },
{ ControlMask, XK_6, i_alternate, (arg_t) None }, { 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_n, i_navigate_frame, (arg_t) +1 },
{ ControlMask, XK_p, i_navigate_frame, (arg_t) -1 }, { ControlMask, XK_p, i_navigate_frame, (arg_t) -1 },
{ ControlMask, XK_space, i_toggle_animation, (arg_t) None }, { ControlMask, XK_space, i_toggle_animation, (arg_t) None },
{ 0, XK_h, i_scroll, (arg_t) DIR_LEFT },
{ 0, XK_m, it_toggle_image_mark, (arg_t) None }, { 0, XK_Left, i_scroll, (arg_t) DIR_LEFT },
{ 0, XK_M, it_reverse_marks, (arg_t) None }, { 0, XK_j, i_scroll, (arg_t) DIR_DOWN },
{ 0, XK_N, it_navigate_marked, (arg_t) +1 }, { 0, XK_Down, i_scroll, (arg_t) DIR_DOWN },
{ 0, XK_P, it_navigate_marked, (arg_t) -1 }, { 0, XK_k, i_scroll, (arg_t) DIR_UP },
{ 0, XK_Up, i_scroll, (arg_t) DIR_UP },
{ 0, XK_h, it_scroll_move, (arg_t) DIR_LEFT }, { 0, XK_l, i_scroll, (arg_t) DIR_RIGHT },
{ 0, XK_Left, it_scroll_move, (arg_t) DIR_LEFT }, { 0, XK_Right, i_scroll, (arg_t) DIR_RIGHT },
{ 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_to_edge, (arg_t) DIR_LEFT }, { 0, XK_H, i_scroll_to_edge, (arg_t) DIR_LEFT },
{ 0, XK_J, i_scroll_to_edge, (arg_t) DIR_DOWN }, { 0, XK_J, i_scroll_to_edge, (arg_t) DIR_DOWN },
{ 0, XK_K, i_scroll_to_edge, (arg_t) DIR_UP }, { 0, XK_K, i_scroll_to_edge, (arg_t) DIR_UP },
{ 0, XK_L, i_scroll_to_edge, (arg_t) DIR_RIGHT }, { 0, XK_L, i_scroll_to_edge, (arg_t) DIR_RIGHT },
{ 0, XK_plus, i_zoom, (arg_t) +1 }, { 0, XK_plus, i_zoom, (arg_t) +1 },
{ 0, XK_KP_Add, i_zoom, (arg_t) +1 }, { 0, XK_KP_Add, i_zoom, (arg_t) +1 },
{ 0, XK_minus, 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_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_WIDTH },
{ 0, XK_E, i_fit_to_win, (arg_t) SCALE_HEIGHT }, { 0, XK_E, i_fit_to_win, (arg_t) SCALE_HEIGHT },
{ 0, XK_less, i_rotate, (arg_t) DEGREE_270 }, { 0, XK_less, i_rotate, (arg_t) DEGREE_270 },
{ 0, XK_greater, i_rotate, (arg_t) DEGREE_90 }, { 0, XK_greater, i_rotate, (arg_t) DEGREE_90 },
{ 0, XK_question, i_rotate, (arg_t) DEGREE_180 }, { 0, XK_question, i_rotate, (arg_t) DEGREE_180 },
{ 0, XK_bar, i_flip, (arg_t) FLIP_HORIZONTAL }, { 0, XK_bar, i_flip, (arg_t) FLIP_HORIZONTAL },
{ 0, XK_underscore, i_flip, (arg_t) FLIP_VERTICAL }, { 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_braceleft, i_change_gamma, (arg_t) -1 },
{ 0, XK_braceright, i_change_gamma, (arg_t) +1 }, { 0, XK_braceright, i_change_gamma, (arg_t) +1 },
{ ControlMask, XK_g, i_change_gamma, (arg_t) 0 }, { 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: */ /* mouse button mappings for image mode: */
@ -155,12 +151,12 @@ static const button_t buttons[] = {
{ 0, 1, i_navigate, (arg_t) +1 }, { 0, 1, i_navigate, (arg_t) +1 },
{ 0, 3, i_navigate, (arg_t) -1 }, { 0, 3, i_navigate, (arg_t) -1 },
{ 0, 2, i_drag, (arg_t) None }, { 0, 2, i_drag, (arg_t) None },
{ 0, 4, it_scroll_move, (arg_t) DIR_UP }, { 0, 4, i_scroll, (arg_t) DIR_UP },
{ 0, 5, it_scroll_move, (arg_t) DIR_DOWN }, { 0, 5, i_scroll, (arg_t) DIR_DOWN },
{ ShiftMask, 4, it_scroll_move, (arg_t) DIR_LEFT }, { ShiftMask, 4, i_scroll, (arg_t) DIR_LEFT },
{ ShiftMask, 5, it_scroll_move, (arg_t) DIR_RIGHT }, { ShiftMask, 5, i_scroll, (arg_t) DIR_RIGHT },
{ 0, 6, it_scroll_move, (arg_t) DIR_LEFT }, { 0, 6, i_scroll, (arg_t) DIR_LEFT },
{ 0, 7, it_scroll_move, (arg_t) DIR_RIGHT }, { 0, 7, i_scroll, (arg_t) DIR_RIGHT },
{ ControlMask, 4, i_zoom, (arg_t) +1 }, { ControlMask, 4, i_zoom, (arg_t) +1 },
{ ControlMask, 5, i_zoom, (arg_t) -1 }, { ControlMask, 5, i_zoom, (arg_t) -1 },
}; };

18
main.c
View File

@ -567,13 +567,10 @@ void on_keypress(XKeyEvent *kev)
} else for (i = 0; i < ARRLEN(keys); i++) { } else for (i = 0; i < ARRLEN(keys); i++) {
if (keys[i].ksym == ksym && if (keys[i].ksym == ksym &&
MODMASK(keys[i].mask | sh) == MODMASK(kev->state) && 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 (cmds[keys[i].cmd].func(keys[i].arg))
if (ret == CMD_INVALID)
continue;
if (ret == CMD_DIRTY)
redraw(); redraw();
break; break;
} }
@ -596,13 +593,10 @@ void on_buttonpress(XButtonEvent *bev)
for (i = 0; i < ARRLEN(buttons); i++) { for (i = 0; i < ARRLEN(buttons); i++) {
if (buttons[i].button == bev->button && if (buttons[i].button == bev->button &&
MODMASK(buttons[i].mask) == MODMASK(bev->state) && 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 (cmds[buttons[i].cmd].func(buttons[i].arg))
if (ret == CMD_INVALID)
continue;
if (ret == CMD_DIRTY)
redraw(); redraw();
break; break;
} }

156
sxiv.1
View File

@ -92,23 +92,16 @@ Set zoom level to ZOOM percent.
.SH GENERAL KEYBOARD COMMANDS .SH GENERAL KEYBOARD COMMANDS
The following keyboard commands are available in both image and thumbnail mode: The following keyboard commands are available in both image and thumbnail mode:
.TP .TP
.BR 0 \- 9
Prefix the next command with a number (denoted via
.IR count ).
.TP
.B q .B q
Quit sxiv. Quit sxiv.
.TP .TP
.B Return .B Return
Switch to thumbnail mode / open selected image in image mode. Switch to thumbnail mode / open selected image in image mode.
.TP .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 .B f
Toggle fullscreen mode. Toggle fullscreen mode.
.TP .TP
@ -118,15 +111,31 @@ Toggle visibility of info bar on bottom of window.
.B Ctrl-x .B Ctrl-x
Send the next key to the external key-handler. Send the next key to the external key-handler.
.TP .TP
.B g
Go to the first image.
.TP
.B G
Go to the last image, or image number
.IR count .
.TP
.B r .B r
Reload image. Reload image.
.TP .TP
.B R
Reload all thumbnails.
.TP
.B D .B D
Remove current image from file list and go to next image. Remove current image from file list and go to next image.
.TP .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 .B m
Mark/unmark the current image. Mark/unmark the current image.
.TP .TP
@ -165,11 +174,8 @@ Move selection right
.I count .I count
times. times.
.TP .TP
.BR Ctrl-j ", " Ctrl-Down .B R
Scroll thumbnail grid one window height down. Reload all thumbnails.
.TP
.BR Ctrl-k ", " Ctrl-Up
Scroll thumbnail grid one window height up.
.SH IMAGE KEYBOARD COMMANDS .SH IMAGE KEYBOARD COMMANDS
The following keyboard commands are only available in image mode: The following keyboard commands are only available in image mode:
.SS Navigate image list .SS Navigate image list
@ -203,6 +209,39 @@ Go to the previous frame of a multi-frame image.
.TP .TP
.B Ctrl-Space .B Ctrl-Space
Play/pause animation of a multi-frame image. 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 .SS Zooming
.TP .TP
.BR + .BR +
@ -226,51 +265,6 @@ Fit image to window width.
.TP .TP
.B E .B E
Fit image to window height. 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 .SS Rotation
.TP .TP
.B < .B <
@ -281,7 +275,7 @@ Rotate image clockwise by 90 degrees.
.TP .TP
.B ? .B ?
Rotate image by 180 degrees. Rotate image by 180 degrees.
.SS Flip .SS Flipping
.TP .TP
.B | .B |
Flip image horizontally. Flip image horizontally.
@ -319,6 +313,22 @@ Go to next image.
.TP .TP
.B Button3 .B Button3
Go to the previous image. 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 .SS Zooming
.TP .TP
.B Ctrl+ScrollUp .B Ctrl+ScrollUp
@ -326,22 +336,6 @@ Zoom in.
.TP .TP
.B Ctrl+ScrollDown .B Ctrl+ScrollDown
Zoom out. 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 .SH STATUS BAR
The information displayed on the left side of the status bar can be replaced 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 with the output of a user-provided script, which is called by sxiv whenever an