aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert Münnich <ber.t@posteo.de>2017-10-04 18:12:27 +0200
committerBert Münnich <ber.t@posteo.de>2017-10-04 18:22:43 +0200
commite310136e02ada4862c250280034d36fbfa24fc61 (patch)
tree496db891475c1b9670ab49e5f025012d05f4b37a
parent9b6acc781e3fc2994bde60db397cfd82e2e050d1 (diff)
Mouse drag translates pointer position to image area
This makes mouse panning more direct and faster.
-rw-r--r--Makefile2
-rw-r--r--commands.c77
-rw-r--r--image.c11
-rw-r--r--image.h1
-rw-r--r--main.c1
-rw-r--r--types.h2
-rw-r--r--window.c10
7 files changed, 40 insertions, 64 deletions
diff --git a/Makefile b/Makefile
index 8a893c6..cc447de 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION := git-20170908
+VERSION := git-20171004
all: sxiv
diff --git a/commands.c b/commands.c
index 44a6cf5..2e1d66c 100644
--- a/commands.c
+++ b/commands.c
@@ -320,72 +320,41 @@ bool ci_scroll_to_edge(arg_t dir)
return img_pan_edge(&img, dir);
}
-/* Xlib helper function for i_drag() */
-Bool is_motionnotify(Display *d, XEvent *e, XPointer a)
-{
- return e != NULL && e->type == MotionNotify;
-}
-
-#define WARP(x,y) \
- XWarpPointer(win.env.dpy, None, win.xwin, 0, 0, 0, 0, x, y); \
- ox = x, oy = y; \
- break
-
bool ci_drag(arg_t _)
{
- int dx = 0, dy = 0, i, ox, oy, x, y;
+ int i, x, y;
+ float px, py;
unsigned int ui;
- bool dragging = true, next = false;
XEvent e;
Window w;
- if (!XQueryPointer(win.env.dpy, win.xwin, &w, &w, &i, &i, &ox, &oy, &ui))
+ if ((int)(img.w * img.zoom) < win.w && (int)(img.h * img.zoom) < win.h)
+ return false;
+ if (!XQueryPointer(win.env.dpy, win.xwin, &w, &w, &i, &i, &x, &y, &ui))
return false;
- win_set_cursor(&win, CURSOR_HAND);
-
- while (dragging) {
- if (!next)
- XMaskEvent(win.env.dpy,
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e);
- switch (e.type) {
- case ButtonPress:
- case ButtonRelease:
- dragging = false;
- break;
- case MotionNotify:
- x = e.xmotion.x;
- y = e.xmotion.y;
-
- /* wrap the mouse around */
- if (x <= 0) {
- WARP(win.w - 2, y);
- } else if (x >= win.w - 1) {
- WARP(1, y);
- } else if (y <= 0) {
- WARP(x, win.h - 2);
- } else if (y >= win.h - 1) {
- WARP(x, 1);
- }
- dx += x - ox;
- dy += y - oy;
- ox = x;
- oy = y;
- break;
- }
- if (dragging)
- next = XCheckIfEvent(win.env.dpy, &e, is_motionnotify, None);
- if ((!dragging || !next) && (dx != 0 || dy != 0)) {
- if (img_move(&img, dx, dy)) {
- img_render(&img);
- win_draw(&win);
- }
- dx = dy = 0;
+ win_set_cursor(&win, CURSOR_DRAG);
+
+ for (;;) {
+ px = MIN(MAX(0.0, x - win.w*0.1), win.w*0.8) / (win.w*0.8)
+ * (win.w - img.w * img.zoom);
+ py = MIN(MAX(0.0, y - win.h*0.1), win.h*0.8) / (win.h*0.8)
+ * (win.h - img.h * img.zoom);
+
+ if (img_pos(&img, px, py)) {
+ img_render(&img);
+ win_draw(&win);
}
+ XMaskEvent(win.env.dpy,
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &e);
+ if (e.type == ButtonPress || e.type == ButtonRelease)
+ break;
+ while (XCheckTypedEvent(win.env.dpy, MotionNotify, &e));
+ x = e.xmotion.x;
+ y = e.xmotion.y;
}
win_set_cursor(&win, CURSOR_ARROW);
set_timeout(reset_cursor, TO_CURSOR_HIDE, true);
- reset_timeout(redraw);
return true;
}
diff --git a/image.c b/image.c
index 36a232e..6ace9bd 100644
--- a/image.c
+++ b/image.c
@@ -567,15 +567,15 @@ bool img_zoom_out(img_t *img)
return false;
}
-bool img_move(img_t *img, float dx, float dy)
+bool img_pos(img_t *img, float x, float y)
{
float ox, oy;
ox = img->x;
oy = img->y;
- img->x += dx;
- img->y += dy;
+ img->x = x;
+ img->y = y;
img_check_pan(img, true);
@@ -587,6 +587,11 @@ bool img_move(img_t *img, float dx, float dy)
}
}
+bool img_move(img_t *img, float dx, float dy)
+{
+ return img_pos(img, img->x + dx, img->y + dy);
+}
+
bool img_pan(img_t *img, direction_t dir, int d)
{
/* d < 0: screen-wise
diff --git a/image.h b/image.h
index 2813c9b..37bc4a2 100644
--- a/image.h
+++ b/image.h
@@ -80,6 +80,7 @@ bool img_zoom(img_t*, float);
bool img_zoom_in(img_t*);
bool img_zoom_out(img_t*);
+bool img_pos(img_t*, float, float);
bool img_move(img_t*, float, float);
bool img_pan(img_t*, direction_t, int);
bool img_pan_edge(img_t*, direction_t);
diff --git a/main.c b/main.c
index aa11616..f7e5762 100644
--- a/main.c
+++ b/main.c
@@ -741,6 +741,7 @@ void run(void)
XPeekEvent(win.env.dpy, &nextev);
switch (ev.type) {
case ConfigureNotify:
+ case MotionNotify:
discard = ev.type == nextev.type;
break;
case KeyPress:
diff --git a/types.h b/types.h
index 6c87105..57402e0 100644
--- a/types.h
+++ b/types.h
@@ -66,7 +66,7 @@ typedef enum {
typedef enum {
CURSOR_ARROW,
CURSOR_NONE,
- CURSOR_HAND,
+ CURSOR_DRAG,
CURSOR_WATCH
} cursor_t;
diff --git a/window.c b/window.c
index c6d22d6..6ed4bfc 100644
--- a/window.c
+++ b/window.c
@@ -37,7 +37,7 @@ enum {
static Cursor carrow;
static Cursor cnone;
-static Cursor chand;
+static Cursor cdrag;
static Cursor cwatch;
static GC gc;
@@ -210,7 +210,7 @@ void win_open(win_t *win)
PointerMotionMask | StructureNotifyMask);
carrow = XCreateFontCursor(e->dpy, XC_left_ptr);
- chand = XCreateFontCursor(e->dpy, XC_fleur);
+ cdrag = XCreateFontCursor(e->dpy, XC_dotbox);
cwatch = XCreateFontCursor(e->dpy, XC_watch);
if (XAllocNamedColor(e->dpy, DefaultColormap(e->dpy, e->scr), "black",
@@ -277,7 +277,7 @@ CLEANUP void win_close(win_t *win)
{
XFreeCursor(win->env.dpy, carrow);
XFreeCursor(win->env.dpy, cnone);
- XFreeCursor(win->env.dpy, chand);
+ XFreeCursor(win->env.dpy, cdrag);
XFreeCursor(win->env.dpy, cwatch);
XFreeGC(win->env.dpy, gc);
@@ -465,8 +465,8 @@ void win_set_cursor(win_t *win, cursor_t cursor)
case CURSOR_NONE:
XDefineCursor(win->env.dpy, win->xwin, cnone);
break;
- case CURSOR_HAND:
- XDefineCursor(win->env.dpy, win->xwin, chand);
+ case CURSOR_DRAG:
+ XDefineCursor(win->env.dpy, win->xwin, cdrag);
break;
case CURSOR_WATCH:
XDefineCursor(win->env.dpy, win->xwin, cwatch);