From 05125029c69e002c4e1a59629d5c4e2fd2ae4bf5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Markus=20R=C3=83=C2=B8yset?= <maroider@protonmail.com>
Date: Tue, 19 Jan 2021 17:41:02 +0100
Subject: [PATCH]  On Windows, fix deadlock caused by mouse capture (#1830)

The issue was caused by calling SetCapture on a window which already
had the capture. The WM_CAPTURECHANGED handler assumed that it would
only run if the capture was lost, but that wasn't the case. This made
the handler to try to lock the window state mutex while it was already
locked.

The issue was introduced in #1797 (932cbe4).
---
 src/platform_impl/windows/event_loop.rs | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs
index 2b518e9e..022ce236 100644
--- a/src/platform_impl/windows/event_loop.rs
+++ b/src/platform_impl/windows/event_loop.rs
@@ -1394,8 +1394,13 @@ unsafe fn public_window_callback_inner<T: 'static>(
         }
 
         winuser::WM_CAPTURECHANGED => {
-            // window lost mouse capture
-            subclass_input.window_state.lock().mouse.capture_count = 0;
+            // lparam here is a handle to the window which is gaining mouse capture.
+            // If it is the same as our window, then we're essentially retaining the capture. This
+            // can happen if `SetCapture` is called on our window when it already has the mouse
+            // capture.
+            if lparam != window as isize {
+                subclass_input.window_state.lock().mouse.capture_count = 0;
+            }
             0
         }