shithub: puzzles

Download patch

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;