From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Fri, 29 Jul 2022 00:29:35 +0900
Subject: chore: modify chromium handling of mouse events

This patch does the following:

1. When Windows Control Overlay is enabled, it allows chromium to handle synthetic mouse events generated for touch
actions in the non-client caption area.
2. It calls HandleMouseEvent on the delegate earlier in HandleMouseEventInternal, so that Electron can selectively disable
draggable regions to allow events to propagate to the underlying renderer.

diff --git a/ui/events/event.h b/ui/events/event.h
index 39b5a8fdd165efd74b00256552b51b5413107958..bfc4ef4f50efff4a77f2aef64335bb7e34c69f34 100644
--- a/ui/events/event.h
+++ b/ui/events/event.h
@@ -587,6 +587,9 @@ class EVENTS_EXPORT MouseEvent : public LocatedEvent {
 
   const PointerDetails& pointer_details() const { return pointer_details_; }
 
+  bool is_system_menu() const { return is_system_menu_; }
+  void set_is_system_menu(bool is_menu) { is_system_menu_ = is_menu; }
+
   // Event:
   std::string ToString() const override;
   std::unique_ptr<Event> Clone() const override;
@@ -619,6 +622,8 @@ class EVENTS_EXPORT MouseEvent : public LocatedEvent {
 
   // Structure for holding pointer details for implementing PointerEvents API.
   PointerDetails pointer_details_;
+
+  bool is_system_menu_ = false;
 };
 
 class ScrollEvent;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 2d05856687cd9669f72553d33c8033fd9083b4f8..645b7dd2cc20ce64ffa541c74930f541f083f931 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -1357,6 +1357,10 @@ void DesktopWindowTreeHostWin::HandleHeadlessWindowBoundsChanged(
   window()->SetProperty(aura::client::kHeadlessBoundsKey, bounds);
 }
 
+bool DesktopWindowTreeHostWin::HandleMouseEventForCaption(UINT message) const {
+  return false;
+}
+
 DesktopNativeCursorManager*
 DesktopWindowTreeHostWin::GetSingletonDesktopNativeCursorManager() {
   return new DesktopNativeCursorManagerWin();
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index 932351e288f37fd09ae1a43f44e8b51fb0caa4b8..4a0616bc210d234e51e564daabdd2ebd5ac9fc16 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -267,6 +267,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin : public DesktopWindowTreeHost,
   void HandleWindowSizeUnchanged() override;
   void HandleWindowScaleFactorChanged(float window_scale_factor) override;
   void HandleHeadlessWindowBoundsChanged(const gfx::Rect& bounds) override;
+  bool HandleMouseEventForCaption(UINT message) const override;
 
   // Overridden from WidgetObserver.
   void OnWidgetThemeChanged(Widget* widget) override;
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index c4d1d483454591031bd76dffced0c1d821800e13..e3bb491f218b2e5d96c424e40a071a618b345039 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -3165,15 +3165,19 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
     }
     // We must let Windows handle the caption buttons if it's drawing them, or
     // they won't work.
+    bool simulate_mouse_event_for_caption = false;
     if (delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN &&
         (hittest == HTCLOSE || hittest == HTMINBUTTON ||
          hittest == HTMAXBUTTON)) {
-      SetMsgHandled(FALSE);
+      simulate_mouse_event_for_caption =
+          delegate_->HandleMouseEventForCaption(message);
+      if (!simulate_mouse_event_for_caption)
+        SetMsgHandled(FALSE);
     }
     // Let resize events fall through. Ignore everything else, as we're either
     // letting Windows handle it above or we've already handled the equivalent
     // touch message.
-    if (!IsHitTestOnResizeHandle(hittest)) {
+    if (!IsHitTestOnResizeHandle(hittest) && !simulate_mouse_event_for_caption) {
       return 0;
     }
   }
@@ -3203,7 +3207,17 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
     w_param = static_cast<WPARAM>(SendMessage(
         hwnd(), WM_NCHITTEST, 0, MAKELPARAM(screen_point.x, screen_point.y)));
     if (w_param == HTCAPTION || w_param == HTSYSMENU) {
-      ShowSystemMenuAtScreenPixelLocation(hwnd(), gfx::Point(screen_point));
+      LONG message_time = GetMessageTime();
+      CHROME_MSG msg = {hwnd(),
+                        message,
+                        w_param,
+                        l_param,
+                        static_cast<DWORD>(message_time),
+                        {CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param)}};
+      ui::MouseEvent event(msg);
+      event.set_is_system_menu(true);
+      if (!delegate_->HandleMouseEvent(&event))
+        ShowSystemMenuAtScreenPixelLocation(hwnd(), gfx::Point(screen_point));
       return 0;
     }
   } else if (message == WM_NCLBUTTONDOWN &&
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h
index 04dea68d74ea4f559db60f716c919e555db9ec80..2f8bd1a3c156bb6c04663c74b7279bb59926fc3d 100644
--- a/ui/views/win/hwnd_message_handler_delegate.h
+++ b/ui/views/win/hwnd_message_handler_delegate.h
@@ -255,6 +255,10 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
   // Called when the headless window bounds has changed.
   virtual void HandleHeadlessWindowBoundsChanged(const gfx::Rect& bounds) = 0;
 
+  // Called when synthetic mouse event is generated for touch event on
+  // caption buttons.
+  virtual bool HandleMouseEventForCaption(UINT message) const = 0;
+
  protected:
   virtual ~HWNDMessageHandlerDelegate() = default;
 };
