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)) {