# Fix https://bugzilla.gnome.org/show_bug.cgi?id=333470
# (Do not close combobox/menu-popup at small motion-notify-events.)
#
# Author: Roland Koebler <rk@simple-is-better.org>

diff -ru gtk+-3.20.6/gtk/gtkmenu.c gtk+-3.20.6-fix333470/gtk/gtkmenu.c
--- gtk+-3.20.6/gtk/gtkmenu.c
+++ gtk+-3.20.6-fix333470/gtk/gtkmenu.c
@@ -102,6 +102,7 @@
 #include "config.h"
 
 #include <string.h>
+#include <math.h>   // for fabs()
 
 #include  <gobject/gvaluecollector.h>
 
@@ -1119,6 +1120,7 @@
   priv = gtk_menu_get_instance_private (menu);
 
   menu->priv = priv;
+  menu->priv->motion_threshold = 20; // TODO: make this configurable?
 
   priv->toplevel = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
                                                    "type", GTK_WINDOW_POPUP,
@@ -1716,6 +1718,17 @@
           (current_event->type != GDK_ENTER_NOTIFY))
         menu_shell->priv->ignore_enter = TRUE;
 
+      /* store pointer-position at popup and a motion-threshold, so that
+       * press + small move + release does not close the menu/combobox again.
+       * (Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=703069)
+       */
+      if ((current_event->type == GDK_BUTTON_PRESS) ||
+          (current_event->type == GDK_BUTTON_RELEASE))
+        {
+          priv->press_x = ((GdkEventButton*)current_event)->x;
+          priv->press_y = ((GdkEventButton*)current_event)->y;
+        }
+
       source_device = gdk_event_get_source_device (current_event);
       gdk_event_free (current_event);
     }
@@ -3434,7 +3447,18 @@
   menu = GTK_MENU (menu_shell);
 
   if (definitely_within_item (menu_item, event->x, event->y))
-    menu_shell->priv->activate_time = 0;
+    {
+      /* Close popup only, if the movement was larger than a threshold.
+       * Necessary to compensate zero-movement-motion-notify-events of
+       * touchscreens and small movements during the click.
+       * (Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=703069)
+       */
+      gdouble moved;
+      moved = fabs(event->x - menu->priv->press_x) +
+              fabs(event->y - menu->priv->press_y);
+      if (moved >= menu->priv->motion_threshold)
+        menu_shell->priv->activate_time = 0;
+    }
 
   need_enter = (gtk_menu_has_navigation_triangle (menu) || menu_shell->priv->ignore_enter);
 
diff -ru gtk+-3.20.6/gtk/gtkmenuprivate.h gtk+-3.20.6-fix333470/gtk/gtkmenuprivate.h
--- gtk+-3.20.6/gtk/gtkmenuprivate.h
+++ gtk+-3.20.6-fix333470/gtk/gtkmenuprivate.h
@@ -53,6 +53,15 @@
   gint                position_x;
   gint                position_y;
 
+  /* store pointer-position at popup and a motion-threshold, so that
+   * press + small move + release does not close the menu/combobox again.
+   * (Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=703069)
+   * Note: motion_threshold could be made configurable
+   */
+  gdouble press_x;
+  gdouble press_y;
+  gdouble motion_threshold;
+
   guint toggle_size;
   guint accel_size;
 
