Subject: bug#6372: 24.0.50; C-mouse-1 activates region

From: Cecilio Pardo <[email-masked]>
Date: Fri, 16 Aug 2024 03:18:42 +0200

This seems to happen because TrackPopupMenu returns as
soon as the WM_LBUTTONDOWN is received. That message is
correctly purged. The problem comes from the subsequent
WM_LBUTTONUP message.

This patch is not a clean solution, but keeps the problem local.

diff --git a/src/w32fns.c b/src/w32fns.c
index bd65aa48a14..ae33f959dd2 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5669,9 +5669,36 @@ #define WM_TOUCH 576
 			    0, hwnd, NULL))
 	  {
 	    MSG amsg;
-	    /* Eat any mouse messages during popupmenu */
+	    bool have_lbuttondown = false;
+	    /* Eat any mouse messages during popupmenu. If there is a
+	       WM_LBUTTONDOWN, then we need to wait for the
+	       corresponding WM_LBUTTONUP to suppress it, or it will be
+	       handled elsewhere */
 	    while (PeekMessage (&amsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST,
-				PM_REMOVE));
+				PM_REMOVE))
+	      {
+		if (amsg.message == WM_LBUTTONDOWN)
+		  {
+		    have_lbuttondown = true;
+		    SetCapture(hwnd);
+		  }
+	      }
+
+	    if (have_lbuttondown)
+	      {
+		/* WM_LBUTTONUP should arrive, but we can't risk hanging
+		   here if it does not, so we wait only for so long */
+		struct timespec start = current_timespec();
+		while (!PeekMessage (&amsg, hwnd, WM_LBUTTONUP, WM_LBUTTONUP,
+				     PM_REMOVE))
+		  {
+		    if (timespectod (timespec_sub (current_timespec (),
+						   start)) > 2.0 )
+		      break;
+		  }
+		ReleaseCapture();
+	      }
+
 	    /* Get the menu selection, if any */
 	    if (PeekMessage (&amsg, hwnd, WM_COMMAND, WM_COMMAND, PM_REMOVE))
 	      {