@@ -255,13 +255,21 @@ void read_dir_rec(const char *dirname) { | |||||
/* event handling */ | /* event handling */ | ||||
int timeout; | int timeout; | ||||
unsigned char hidecur; | |||||
int mox, moy; | int mox, moy; | ||||
unsigned char drag; | |||||
void redraw() { | void redraw() { | ||||
if (mode == MODE_NORMAL) | |||||
if (mode == MODE_NORMAL) { | |||||
if (!drag && hidecur) { | |||||
win_set_cursor(&win, CURSOR_NONE); | |||||
hidecur = 0; | |||||
} | |||||
img_render(&img, &win); | img_render(&img, &win); | ||||
else | |||||
} else { | |||||
tns_render(&tns, &win); | tns_render(&tns, &win); | ||||
} | |||||
update_title(); | update_title(); | ||||
timeout = 0; | timeout = 0; | ||||
} | } | ||||
@@ -377,11 +385,12 @@ void on_keypress(XKeyEvent *kev) { | |||||
} | } | ||||
break; | break; | ||||
/* switch to thumnail mode */ | |||||
/* switch to thumbnail mode */ | |||||
case XK_Return: | case XK_Return: | ||||
if (!tns.thumbs) | if (!tns.thumbs) | ||||
tns_init(&tns, filecnt); | tns_init(&tns, filecnt); | ||||
mode = MODE_THUMBS; | mode = MODE_THUMBS; | ||||
win_set_cursor(&win, CURSOR_ARROW); | |||||
tns.sel = fileidx; | tns.sel = fileidx; | ||||
changed = tns.dirty = 1; | changed = tns.dirty = 1; | ||||
break; | break; | ||||
@@ -403,7 +412,7 @@ void on_keypress(XKeyEvent *kev) { | |||||
fileidx = tns.sel; | fileidx = tns.sel; | ||||
load_image(); | load_image(); | ||||
mode = MODE_NORMAL; | mode = MODE_NORMAL; | ||||
win_set_cursor(&win, CURSOR_ARROW); | |||||
win_set_cursor(&win, CURSOR_NONE); | |||||
changed = 1; | changed = 1; | ||||
break; | break; | ||||
@@ -479,6 +488,8 @@ void on_buttonpress(XButtonEvent *bev) { | |||||
mox = bev->x; | mox = bev->x; | ||||
moy = bev->y; | moy = bev->y; | ||||
win_set_cursor(&win, CURSOR_HAND); | win_set_cursor(&win, CURSOR_HAND); | ||||
hidecur = 0; | |||||
drag = 1; | |||||
break; | break; | ||||
case Button3: | case Button3: | ||||
if (fileidx > 0) { | if (fileidx > 0) { | ||||
@@ -518,7 +529,7 @@ void on_buttonpress(XButtonEvent *bev) { | |||||
fileidx = tns.sel; | fileidx = tns.sel; | ||||
load_image(); | load_image(); | ||||
mode = MODE_NORMAL; | mode = MODE_NORMAL; | ||||
win_set_cursor(&win, CURSOR_ARROW); | |||||
win_set_cursor(&win, CURSOR_NONE); | |||||
} else { | } else { | ||||
tns_highlight(&tns, &win, tns.sel, False); | tns_highlight(&tns, &win, tns.sel, False); | ||||
tns_highlight(&tns, &win, sel, True); | tns_highlight(&tns, &win, sel, True); | ||||
@@ -542,7 +553,7 @@ void on_buttonpress(XButtonEvent *bev) { | |||||
} | } | ||||
void on_motionnotify(XMotionEvent *mev) { | void on_motionnotify(XMotionEvent *mev) { | ||||
if (!mev || mode != MODE_NORMAL) | |||||
if (!mev) | |||||
return; | return; | ||||
if (mev->x >= 0 && mev->x <= win.w && mev->y >= 0 && mev->y <= win.h) { | if (mev->x >= 0 && mev->x <= win.w && mev->y >= 0 && mev->y <= win.h) { | ||||
@@ -560,7 +571,12 @@ void run() { | |||||
struct timeval t, t0; | struct timeval t, t0; | ||||
XEvent ev; | XEvent ev; | ||||
timeout = 0; | |||||
drag = timeout = 0; | |||||
if (mode == MODE_NORMAL) { | |||||
hidecur = 1; | |||||
timeout = 1500000; | |||||
} | |||||
while (1) { | while (1) { | ||||
if (mode == MODE_THUMBS && tns.cnt < filecnt) { | if (mode == MODE_THUMBS && tns.cnt < filecnt) { | ||||
@@ -582,15 +598,21 @@ void run() { | |||||
timeout = 75000; | timeout = 75000; | ||||
} | } | ||||
} else if (timeout) { | } else if (timeout) { | ||||
t.tv_sec = 0; | |||||
t.tv_usec = timeout; | |||||
t.tv_sec = timeout / 1000000; | |||||
t.tv_usec = timeout % 1000000; | |||||
xfd = ConnectionNumber(win.env.dpy); | xfd = ConnectionNumber(win.env.dpy); | ||||
FD_ZERO(&fds); | FD_ZERO(&fds); | ||||
FD_SET(xfd, &fds); | FD_SET(xfd, &fds); | ||||
if (!XPending(win.env.dpy) && !select(xfd + 1, &fds, 0, 0, &t)) | |||||
if (!XPending(win.env.dpy) && !select(xfd + 1, &fds, 0, 0, &t)) { | |||||
/* timeout fired */ | /* timeout fired */ | ||||
redraw(); | |||||
if (hidecur) { | |||||
win_set_cursor(&win, CURSOR_NONE); | |||||
hidecur = 0; | |||||
} else { | |||||
redraw(); | |||||
} | |||||
} | |||||
} | } | ||||
if (!XNextEvent(win.env.dpy, &ev)) { | if (!XNextEvent(win.env.dpy, &ev)) { | ||||
@@ -602,11 +624,25 @@ void run() { | |||||
on_buttonpress(&ev.xbutton); | on_buttonpress(&ev.xbutton); | ||||
break; | break; | ||||
case ButtonRelease: | case ButtonRelease: | ||||
if (ev.xbutton.button == Button2) | |||||
win_set_cursor(&win, CURSOR_ARROW); | |||||
if (ev.xbutton.button == Button2) { | |||||
drag = 0; | |||||
if (mode == MODE_NORMAL) { | |||||
win_set_cursor(&win, CURSOR_ARROW); | |||||
hidecur = 1; | |||||
timeout = 1500000; | |||||
} | |||||
} | |||||
break; | break; | ||||
case MotionNotify: | case MotionNotify: | ||||
on_motionnotify(&ev.xmotion); | |||||
if (drag) { | |||||
on_motionnotify(&ev.xmotion); | |||||
} else if (mode == MODE_NORMAL) { | |||||
if (!hidecur) { | |||||
win_set_cursor(&win, CURSOR_ARROW); | |||||
hidecur = 1; | |||||
} | |||||
timeout = 1500000; | |||||
} | |||||
break; | break; | ||||
case ConfigureNotify: | case ConfigureNotify: | ||||
if (win_configure(&win, &ev.xconfigure)) { | if (win_configure(&win, &ev.xconfigure)) { | ||||
@@ -27,6 +27,7 @@ | |||||
#include "window.h" | #include "window.h" | ||||
static Cursor carrow; | static Cursor carrow; | ||||
static Cursor cnone; | |||||
static Cursor chand; | static Cursor chand; | ||||
static Cursor cwatch; | static Cursor cwatch; | ||||
static GC gc; | static GC gc; | ||||
@@ -52,6 +53,8 @@ void win_open(win_t *win) { | |||||
XClassHint classhint; | XClassHint classhint; | ||||
XColor col; | XColor col; | ||||
XGCValues gcval; | XGCValues gcval; | ||||
char none_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; | |||||
Pixmap none; | |||||
int gmask; | int gmask; | ||||
if (!win) | if (!win) | ||||
@@ -69,12 +72,12 @@ void win_open(win_t *win) { | |||||
e->depth = DefaultDepth(e->dpy, e->scr); | e->depth = DefaultDepth(e->dpy, e->scr); | ||||
if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), BG_COLOR, | if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), BG_COLOR, | ||||
&col, &col)) | |||||
&col, &col)) | |||||
win->bgcol = col.pixel; | win->bgcol = col.pixel; | ||||
else | else | ||||
die("could not allocate color: %s", BG_COLOR); | die("could not allocate color: %s", BG_COLOR); | ||||
if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), SEL_COLOR, | if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), SEL_COLOR, | ||||
&col, &col)) | |||||
&col, &col)) | |||||
win->selcol = col.pixel; | win->selcol = col.pixel; | ||||
else | else | ||||
die("could not allocate color: %s", BG_COLOR); | die("could not allocate color: %s", BG_COLOR); | ||||
@@ -112,12 +115,18 @@ void win_open(win_t *win) { | |||||
die("could not create window"); | die("could not create window"); | ||||
XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask | | XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask | | ||||
ButtonPressMask | ButtonReleaseMask | Button2MotionMask); | |||||
ButtonPressMask | ButtonReleaseMask | PointerMotionMask); | |||||
carrow = XCreateFontCursor(e->dpy, XC_left_ptr); | carrow = XCreateFontCursor(e->dpy, XC_left_ptr); | ||||
chand = XCreateFontCursor(e->dpy, XC_fleur); | chand = XCreateFontCursor(e->dpy, XC_fleur); | ||||
cwatch = XCreateFontCursor(e->dpy, XC_watch); | cwatch = XCreateFontCursor(e->dpy, XC_watch); | ||||
if (!XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), "black", | |||||
&col, &col)) | |||||
die("could not allocate color: black"); | |||||
none = XCreateBitmapFromData(e->dpy, win->xwin, none_data, 8, 8); | |||||
cnone = XCreatePixmapCursor(e->dpy, none, none, &col, &col, 0, 0); | |||||
gcval.line_width = 2; | gcval.line_width = 2; | ||||
gc = XCreateGC(e->dpy, win->xwin, GCLineWidth, &gcval); | gc = XCreateGC(e->dpy, win->xwin, GCLineWidth, &gcval); | ||||
@@ -145,6 +154,7 @@ void win_close(win_t *win) { | |||||
return; | return; | ||||
XFreeCursor(win->env.dpy, carrow); | XFreeCursor(win->env.dpy, carrow); | ||||
XFreeCursor(win->env.dpy, cnone); | |||||
XFreeCursor(win->env.dpy, chand); | XFreeCursor(win->env.dpy, chand); | ||||
XFreeCursor(win->env.dpy, cwatch); | XFreeCursor(win->env.dpy, cwatch); | ||||
@@ -307,6 +317,9 @@ void win_set_cursor(win_t *win, win_cur_t cursor) { | |||||
return; | return; | ||||
switch (cursor) { | switch (cursor) { | ||||
case CURSOR_NONE: | |||||
XDefineCursor(win->env.dpy, win->xwin, cnone); | |||||
break; | |||||
case CURSOR_HAND: | case CURSOR_HAND: | ||||
XDefineCursor(win->env.dpy, win->xwin, chand); | XDefineCursor(win->env.dpy, win->xwin, chand); | ||||
break; | break; | ||||
@@ -25,6 +25,7 @@ | |||||
typedef enum win_cur_e { | typedef enum win_cur_e { | ||||
CURSOR_ARROW = 0, | CURSOR_ARROW = 0, | ||||
CURSOR_NONE, | |||||
CURSOR_HAND, | CURSOR_HAND, | ||||
CURSOR_WATCH | CURSOR_WATCH | ||||
} win_cur_t; | } win_cur_t; | ||||