From 3c7a7eea4d391cfb1b20647164069b255c466b88 Mon Sep 17 00:00:00 2001
From: edgrif <edgrif>
Date: Wed, 5 May 2010 15:33:11 +0000
Subject: [PATCH] make double click work on button release NOT button press as
 then xremote loses our button release events.

---
 src/zmapWindow/zmapWindowFeature.c | 368 +++++++++++++++--------------
 1 file changed, 195 insertions(+), 173 deletions(-)

diff --git a/src/zmapWindow/zmapWindowFeature.c b/src/zmapWindow/zmapWindowFeature.c
index 1995b1b23..c6458db4c 100755
--- a/src/zmapWindow/zmapWindowFeature.c
+++ b/src/zmapWindow/zmapWindowFeature.c
@@ -28,9 +28,9 @@
  *
  * Exported functions: See zmapWindow_P.h
  * HISTORY:
- * Last edited: Apr 30 11:10 2010 (edgrif)
+ * Last edited: May  5 16:32 2010 (edgrif)
  * Created: Mon Jan  9 10:25:40 2006 (edgrif)
- * CVS info:   $Id: zmapWindowFeature.c,v 1.182 2010-04-30 10:11:05 edgrif Exp $
+ * CVS info:   $Id: zmapWindowFeature.c,v 1.183 2010-05-05 15:33:11 edgrif Exp $
  *-------------------------------------------------------------------
  */
 
@@ -175,6 +175,13 @@ static gboolean factoryFeatureSizeReq(ZMapFeature feature,
 static gboolean sequenceSelectionCB(FooCanvasItem *item, int start, int end, gpointer user_data) ;
 
 
+
+
+/* Local globals for debugging. */
+static gboolean mouse_debug_G = FALSE ;
+
+
+
 /* NOTE that we make some assumptions in this code including:
  *
  * - the caller has found the correct context, alignment, block and set
@@ -783,198 +790,213 @@ static void featureCopySelectedItem(ZMapFeature feature_in,
 
 static gboolean canvasItemEventCB(FooCanvasItem *item, GdkEvent *event, gpointer data)
 {
-  gboolean event_handled = FALSE ;
+  gboolean event_handled = FALSE ;			    /* By default we _don't_ handle events. */
   ZMapWindow window = (ZMapWindowStruct*)data ;
   ZMapFeature feature ;
   static guint32 last_but_press = 0 ;			    /* Used for double clicks... */
+  static gboolean second_press = FALSE ;		    /* Used for double clicks... */
 
-  switch (event->type)
+
+  if (event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS  || event->type == GDK_BUTTON_RELEASE)
     {
-    case GDK_BUTTON_PRESS:
-    case GDK_2BUTTON_PRESS:
-      {
-	GdkEventButton *but_event = (GdkEventButton *)event ;
-	ZMapFeatureSubPartSpan sub_feature ;
-	ZMapWindowCanvasItem canvas_item ;
-	FooCanvasItem *sub_item = NULL, *highlight_item = NULL ;
+      GdkEventButton *but_event = (GdkEventButton *)event ;
+      ZMapFeatureSubPartSpan sub_feature ;
+      ZMapWindowCanvasItem canvas_item ;
+      FooCanvasItem *sub_item = NULL, *highlight_item = NULL ;
 
-	if (!ZMAP_IS_CANVAS_ITEM(item))
-	  {
+      zMapDebugPrint(mouse_debug_G, "Start: %s %d",
+		     (event->type == GDK_BUTTON_PRESS ? "button_press"
+		      : event->type == GDK_2BUTTON_PRESS ? "button_2press" : "button_release"),
+		     but_event->button) ;
 
-#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
-	    g_warning("Not a ZMapWindowCanvasItem.");
-#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
 
-	    return FALSE;
-	  }
+      if (!ZMAP_IS_CANVAS_ITEM(item))
+	{
 
-	canvas_item = ZMAP_CANVAS_ITEM(item);
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
+	  g_warning("Not a ZMapWindowCanvasItem.");
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
 
-        /* Get the feature attached to the item, checking that its type is valid */
-	feature  = zMapWindowCanvasItemGetFeature(item);
+	  zMapDebugPrint(mouse_debug_G, "Leave (Not canvas item): %s %d - return FALSE",
+			 (event->type == GDK_BUTTON_PRESS ? "button_press"
+			  : event->type == GDK_2BUTTON_PRESS ? "button_2press" : "button_release"),
+			 but_event->button) ;
 
-	sub_item = zMapWindowCanvasItemGetInterval(canvas_item, but_event->x, but_event->y, &sub_feature);
+	  return FALSE;
+	}
 
-	if (but_event->type == GDK_BUTTON_PRESS)
-	  {
-	    /* Double clicks occur within 250 milliseconds so we ignore the second button
-	     * press generated by clicks but catch the button2 press (see below). */
-	    if (but_event->time - last_but_press > 250)
-	      {
-                GdkModifierType shift_mask = GDK_SHIFT_MASK,
-                  control_mask             = GDK_CONTROL_MASK,
-                  shift_control_mask       = GDK_SHIFT_MASK | GDK_CONTROL_MASK,
-                  unwanted_masks           = GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK,
-                  locks_mask;
-
-                /* In order to make the modifier only checks work we
-                 * need to OR in the unwanted masks that might be on.
-                 * This includes the shift lock and num lock.
-                 * Depending on the setup of X these might be mapped
-                 * to other things which is why MODs 2-5 are included
-                 * This in theory should include the new (since 2.10)
-                 * GDK_SUPER_MASK, GDK_HYPER_MASK and GDK_META_MASK */
-                if((locks_mask = (but_event->state & unwanted_masks)))
-                  {
-                    shift_mask         |= locks_mask;
-                    control_mask       |= locks_mask;
-                    shift_control_mask |= locks_mask;
-                  }
-
-		/* Button 1 and 3 are handled, 2 is left for a general handler which could be
-		 * the root handler. */
-		if (but_event->button == 1 || but_event->button == 3)
-		  {
-		    gboolean replace_highlight = TRUE, highlight_same_names = TRUE, externally_handled = FALSE;
-
-		    if (zMapGUITestModifiersOnly(but_event, shift_mask))
-		      {
-                        ZMapFeatureStruct feature_copy = {};
-
-			/* Only highlight the single item user clicked on. */
-			highlight_same_names = FALSE ;
-
-			/* Annotators say they don't want subparts sub selections + multiple
-			 * selections for alignments. */
-			if (feature->type == ZMAPSTYLE_MODE_ALIGNMENT)
-			  {
-			    highlight_item = item;
-			  }
-			else
-			  {
-			    highlight_item = sub_item ;
-			  }
-
-
-                        /* monkey around to get feature_copy to be the right correct data */
-                        featureCopySelectedItem(feature, &feature_copy, highlight_item);
-
-			if (zmapWindowFocusIsItemInHotColumn(window->focus, highlight_item)
-			    && window->multi_select)
-                          {
-                            replace_highlight = FALSE ;
-                            externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)(&feature_copy),
-									     "multiple_select", highlight_item);
-                          }
-                        else
-			  {
-			    externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)(&feature_copy),
-									     "single_select", highlight_item);
-			    window->multi_select = TRUE ;
-			  }
-		      }
+      canvas_item = ZMAP_CANVAS_ITEM(item);
 
+      /* Get the feature attached to the item, checking that its type is valid */
+      feature  = zMapWindowCanvasItemGetFeature(item);
 
+      sub_item = zMapWindowCanvasItemGetInterval(canvas_item, but_event->x, but_event->y, &sub_feature);
 
+      if (but_event->type == GDK_BUTTON_PRESS)
+	{
+	  /* Double clicks occur within 250 milliseconds so we ignore the second button
+	   * press generated by clicks but catch the button2 press (see below). */
+	  if (but_event->time - last_but_press > 250)
+	    {
+	      GdkModifierType shift_mask = GDK_SHIFT_MASK,
+		control_mask             = GDK_CONTROL_MASK,
+		shift_control_mask       = GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+		unwanted_masks           = GDK_LOCK_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK | GDK_MOD5_MASK,
+		locks_mask;
+
+	      /* In order to make the modifier only checks work we
+	       * need to OR in the unwanted masks that might be on.
+	       * This includes the shift lock and num lock.
+	       * Depending on the setup of X these might be mapped
+	       * to other things which is why MODs 2-5 are included
+	       * This in theory should include the new (since 2.10)
+	       * GDK_SUPER_MASK, GDK_HYPER_MASK and GDK_META_MASK */
+	      if((locks_mask = (but_event->state & unwanted_masks)))
+		{
+		  shift_mask         |= locks_mask;
+		  control_mask       |= locks_mask;
+		  shift_control_mask |= locks_mask;
+		}
+
+	      /* Button 1 and 3 are handled, 2 is left for a general handler which could be
+	       * the root handler. */
+	      if (but_event->button == 1 || but_event->button == 3)
+		{
+		  gboolean replace_highlight = TRUE, highlight_same_names = TRUE, externally_handled = FALSE;
+
+		  if (zMapGUITestModifiersOnly(but_event, shift_mask))
+		    {
+		      ZMapFeatureStruct feature_copy = {};
+
+		      /* Only highlight the single item user clicked on. */
+		      highlight_same_names = FALSE ;
+
+		      /* Annotators say they don't want subparts sub selections + multiple
+		       * selections for alignments. */
+		      if (feature->type == ZMAPSTYLE_MODE_ALIGNMENT)
+			{
+			  highlight_item = item;
+			}
+		      else
+			{
+			  highlight_item = sub_item ;
+			}
+
+
+		      /* monkey around to get feature_copy to be the right correct data */
+		      featureCopySelectedItem(feature, &feature_copy, highlight_item);
+
+		      if (zmapWindowFocusIsItemInHotColumn(window->focus, highlight_item)
+			  && window->multi_select)
+			{
+			  replace_highlight = FALSE ;
+			  externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)(&feature_copy),
+									   "multiple_select", highlight_item);
+			}
+		      else
+			{
+			  externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)(&feature_copy),
+									   "single_select", highlight_item);
+			  window->multi_select = TRUE ;
+			}
+		    }
 #ifdef ED_G_NEVER_INCLUDE_THIS_CODE
-		    /* I've left this in because we might want to use Cntl-xxx at some time .... */
-		    else if (zMapGUITestModifiersOnly(but_event, control_mask))
-		      {
-                        ZMapFeatureStruct feature_copy = {};
-
-			/* sub selections */
-			highlight_item = sub_item ;
-			highlight_same_names = FALSE ;
-
-                        /* monkey around to get feature_copy to be the right correct data */
-                        featureCopySelectedItem(feature, &feature_copy,
-                                                highlight_item);
-                        externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)(&feature_copy), "single_select", highlight_item);
-		      }
+		  /* I've left this in because we might want to use Cntl-xxx at some time .... */
+		  else if (zMapGUITestModifiersOnly(but_event, control_mask))
+		    {
+		      ZMapFeatureStruct feature_copy = {};
+
+		      /* sub selections */
+		      highlight_item = sub_item ;
+		      highlight_same_names = FALSE ;
+
+		      /* monkey around to get feature_copy to be the right correct data */
+		      featureCopySelectedItem(feature, &feature_copy,
+					      highlight_item);
+		      externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)(&feature_copy), "single_select", highlight_item);
+		    }
 #endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
+		  else if (zMapGUITestModifiersOnly(but_event, shift_control_mask))
+		    {
+		      /* multiple selections */
+		      highlight_item = item;
+
+		      if (zmapWindowFocusIsItemInHotColumn(window->focus, highlight_item)
+			  && window->multi_select)
+			{
+			  replace_highlight = FALSE ;
+			  externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature, "multiple_select", highlight_item);
+			}
+		      else
+			{
+			  externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature, "single_select", highlight_item);
+			  window->multi_select = TRUE ;
+			}
+		    }
+		  else
+		    {
+		      /* single select */
+		      highlight_item = item;
+		      externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature, "single_select", highlight_item);
+		      window->multi_select = FALSE ;
+		    }
+
+		  /* Pass information about the object clicked on back to the application. */
+		  zMapWindowUpdateInfoPanel(window, feature, sub_item, highlight_item, NULL,
+					    replace_highlight, highlight_same_names) ;
+
+		  if (but_event->button == 3)
+		    {
+		      /* Pop up an item menu. */
+		      zmapMakeItemMenu(but_event, window, highlight_item) ;
+		    }
+		}
+	    }
+
+	  last_but_press = but_event->time ;
+
+	  event_handled = TRUE ;
+	}
+      else if (but_event->type == GDK_2BUTTON_PRESS)
+	{
+	  second_press = TRUE ;
 
+	  event_handled = TRUE ;
+	}
+      else						    /* button release */
+	{
+	  if (second_press)
+	    {
+	      /* Handle second click of a double click. */
+	      if (but_event->button == 1)
+		{
+		  gboolean externally_handled = FALSE ;
+		    
+		  highlight_item = item;
+
+		  if (!(externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature,
+									 "edit", highlight_item)))
+		    {
+		      zmapWindowFeatureShow(window, highlight_item) ;
+		    }
+		}
+		
+	      second_press = FALSE ;
+	    }
+
+	  event_handled = TRUE ;
+	}
 
-
-		    else if (zMapGUITestModifiersOnly(but_event, shift_control_mask))
-		      {
-			/* multiple selections */
-			highlight_item = item;
-
-			if (zmapWindowFocusIsItemInHotColumn(window->focus, highlight_item)
-			    && window->multi_select)
-                          {
-                            replace_highlight = FALSE ;
-                            externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature, "multiple_select", highlight_item);
-                          }
-                        else
-			  {
-			    externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature, "single_select", highlight_item);
-			    window->multi_select = TRUE ;
-			  }
-		      }
-		    else
-		      {
-                        /* single select */
-			highlight_item = item;
-                        externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature, "single_select", highlight_item);
-			window->multi_select = FALSE ;
-		      }
-
-		    /* Pass information about the object clicked on back to the application. */
-		    zMapWindowUpdateInfoPanel(window, feature, sub_item, highlight_item, NULL,
-					      replace_highlight, highlight_same_names) ;
-
-		    if (but_event->button == 3)
-		      {
-			/* Pop up an item menu. */
-			zmapMakeItemMenu(but_event, window, highlight_item) ;
-		      }
-		  }
-	      }
-
-	    last_but_press = but_event->time ;
-
-	    event_handled = TRUE ;
-	  }
-	else
-	  {
-	    /* Handle second click of a double click. */
-	    if (but_event->button == 1)
-	      {
-		gboolean externally_handled = FALSE ;
-
-		highlight_item = item;
-
-                if (!(externally_handled = zmapWindowUpdateXRemoteData(window, (ZMapFeatureAny)feature,
-								       "edit", highlight_item)))
-                  {
-		    zmapWindowFeatureShow(window, highlight_item) ;
-                  }
-
-		event_handled = TRUE ;
-	      }
-	  }
-	break ;
-      }
-    default:
-      {
-	/* By default we _don't_ handle events. */
-	event_handled = FALSE ;
-
-	break ;
-      }
+      zMapDebugPrint(mouse_debug_G, "Leave: %s %d - return %s",
+		     (event->type == GDK_BUTTON_PRESS ? "button_press"
+		      : event->type == GDK_2BUTTON_PRESS ? "button_2press" : "button_release"),
+		     but_event->button,
+		     event_handled ? "TRUE" : "FALSE") ;
     }
 
+  if (mouse_debug_G)
+    fflush(stdout) ;
+
   return event_handled ;
 }
 
-- 
GitLab