From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: clavin <cwatford@slack-corp.com>
Date: Fri, 11 Feb 2022 15:05:42 -0700
Subject: fix: non-client mouse tracking and message bubbling on windows

It is not known why, but for some reason calling |DefWindowProc| on the parent
window handle causes a WM_NCMOUSELEAVE (non-client mouse exit) message to be
sent to the parent window, even though |TrackMouseEvent| is never called on it.

This patch also adds some boilerplate for properly tracking non-client mouse
messages in the legacy window handle layer.

These conditions are regularly hit with WCO-enabled windows on Windows.

diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc
index 475629d48e8807547e0c79f6fa00d458bac3416c..97f4520fbf7797b19747b5101097d93cf475fb5c 100644
--- a/content/browser/renderer_host/legacy_render_widget_host_win.cc
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -375,12 +375,12 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
                                                  WPARAM w_param,
                                                  LPARAM l_param,
                                                  BOOL& handled) {
-  if (message == WM_MOUSEMOVE) {
+  if (message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE) {
     if (!mouse_tracking_enabled_) {
       mouse_tracking_enabled_ = true;
       TRACKMOUSEEVENT tme;
       tme.cbSize = sizeof(tme);
-      tme.dwFlags = TME_LEAVE;
+      tme.dwFlags = message == WM_NCMOUSEMOVE ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE;
       tme.hwndTrack = hwnd();
       tme.dwHoverTime = 0;
       TrackMouseEvent(&tme);
@@ -413,7 +413,10 @@ LRESULT LegacyRenderWidgetHostHWND::OnMouseRange(UINT message,
   // the picture.
   if (!handled &&
       (message >= WM_NCMOUSEMOVE && message <= WM_NCXBUTTONDBLCLK)) {
-    ret = ::DefWindowProc(GetParent(), message, w_param, l_param);
+    // Send WM_NCMOUSEMOVE messages using the LegacyRenderWidgetHostHWND's
+    // handle so mouse tracking on non-client areas doesn't break.
+    HWND target = message == WM_NCMOUSEMOVE ? hwnd() : GetParent();
+    ret = ::DefWindowProc(target, message, w_param, l_param);
     handled = TRUE;
   }
   return ret;
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.h b/content/browser/renderer_host/legacy_render_widget_host_win.h
index f9699ff0abf9036e9e1cabf626aa6395584cf896..94a8a50cb630182103c4256352d7a8a2acc8c76a 100644
--- a/content/browser/renderer_host/legacy_render_widget_host_win.h
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.h
@@ -105,6 +105,7 @@ class CONTENT_EXPORT LegacyRenderWidgetHostHWND
     MESSAGE_HANDLER_EX(WM_VSCROLL, OnScroll)
     MESSAGE_HANDLER_EX(WM_NCHITTEST, OnNCHitTest)
     MESSAGE_RANGE_HANDLER(WM_NCMOUSEMOVE, WM_NCXBUTTONDBLCLK, OnMouseRange)
+    MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnMouseLeave)
     MESSAGE_HANDLER_EX(WM_NCCALCSIZE, OnNCCalcSize)
     MESSAGE_HANDLER_EX(WM_SIZE, OnSize)
     MESSAGE_HANDLER_EX(WM_DESTROY, OnDestroy)
