ref: 0c13787c2a17adc891f8e47c06b259f80bc8251a
parent: bd20565c94d20e531900c299a71bc6475c27d03f
author: Simon Tatham <anakin@pobox.com>
date: Wed Feb 8 18:31:58 EST 2012
David Nickerson reports odd behaviour involving a drag start point persisting between separate mouse actions. Revamp all uses of the ndragcoords field in an attempt to stamp that out: we now distinguish between active drags (>0), a valid click but no drag yet (0), and a totally invalid situation in which all mouse activity will be ignored until the next fresh attempt (-1). [originally from svn r9405]
--- a/pearl.c
+++ b/pearl.c
@@ -1717,7 +1717,8 @@
struct game_ui {
int *dragcoords; /* list of (y*w+x) coords in drag so far */
- int ndragcoords; /* number of entries in dragcoords. 0 = no drag. */
+ int ndragcoords; /* number of entries in dragcoords.
+ * 0 = click but no drag yet. -1 = no drag at all */
int clickx, clicky; /* pixel position of initial click */
};
@@ -1726,7 +1727,7 @@
game_ui *ui = snew(game_ui);
int sz = state->shared->sz;
- ui->ndragcoords = 0;
+ ui->ndragcoords = -1;
ui->dragcoords = snewn(sz, int);
return ui;
@@ -1805,6 +1806,9 @@
if (!INGRID(state, gx, gy))
return; /* square is outside grid */
+ if (ui->ndragcoords < 0)
+ return; /* drag not in progress anyway */
+
pos = gy * w + gx;
lastpos = ui->dragcoords[ui->ndragcoords > 0 ? ui->ndragcoords-1 : 0];
@@ -1916,7 +1920,10 @@
char tmpbuf[80];
if (IS_MOUSE_DOWN(button)) {
- if (!INGRID(state, gx, gy)) return NULL;
+ if (!INGRID(state, gx, gy)) {
+ ui->ndragcoords = -1;
+ return NULL;
+ }
ui->clickx = x; ui->clicky = y;
ui->dragcoords[0] = gy * w + gx;
@@ -1925,13 +1932,13 @@
return "";
}
- if (button == LEFT_DRAG) {
+ if (button == LEFT_DRAG && ui->ndragcoords >= 0) {
update_ui_drag(state, ui, gx, gy);
return "";
}
if (IS_MOUSE_RELEASE(button)) {
- if (ui->ndragcoords) {
+ if (ui->ndragcoords > 0) {
/* End of a drag: process the cached line data. */
int buflen = 0, bufsize = 256, tmplen;
char *buf = NULL;
@@ -1957,10 +1964,10 @@
}
}
- ui->ndragcoords = 0;
+ ui->ndragcoords = -1;
return buf ? buf : "";
- } else {
+ } else if (ui->dragcoords == 0) {
/* Click (or tiny drag). Work out which edge we were
* closest to. */
int cx, cy;
@@ -1967,6 +1974,8 @@
int gx2, gy2, l1, l2, ismark = (button == RIGHT_RELEASE);
char movec = ismark ? 'M' : 'F';
+ ui->ndragcoords = -1;
+
/*
* We process clicks based on the mouse-down location,
* because that's more natural for a user to carefully
@@ -2321,7 +2330,7 @@
flashing = DS_FLASH;
memset(ds->draglines, 0, sz);
- if (ui->dragcoords) {
+ if (ui->ndragcoords > 0) {
int i, clearing = TRUE;
for (i = 0; i < ui->ndragcoords - 1; i++) {
int sx, sy, dx, dy, dir, oldstate, newstate;