From 68e12c0dbf815fabf489875c7c20be5971f02593 Mon Sep 17 00:00:00 2001
From: "pkasting@chromium.org"
 <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Thu, 11 Jun 2009 17:21:35 +0000
Subject: Show caption area context menu on mouseup, not mousedown.  Original
 patch by Yong Shin (see http://codereview.chromium.org/18095 ), r=me,
 modified by me.

BUG=5695
TEST=Right-click the titlebar area; the menu should not appear until mouse up.

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18170 0039d316-1c4b-4281-b951-d872f2087c98
---
 views/window/window_win.cc | 42 ++++++++++++++++++++++++++++++++++++++----
 views/window/window_win.h  |  6 ++++++
 2 files changed, 44 insertions(+), 4 deletions(-)

(limited to 'views')

diff --git a/views/window/window_win.cc b/views/window/window_win.cc
index 12ef674..74807c8 100644
--- a/views/window/window_win.cc
+++ b/views/window/window_win.cc
@@ -513,6 +513,7 @@ WindowWin::WindowWin(WindowDelegate* window_delegate)
       ignore_window_pos_changes_(false),
       ignore_pos_changes_factory_(this),
       force_hidden_count_(0),
+      is_right_mouse_pressed_on_caption_(false),
       last_monitor_(NULL) {
   is_window_ = true;
   InitClass();
@@ -946,10 +947,43 @@ void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) {
 }
 
 void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& point) {
-  if (ht_component == HTCAPTION || ht_component == HTSYSMENU)
-    RunSystemMenu(gfx::Point(point));
-  else
-    WidgetWin::OnNCRButtonDown(ht_component, point);
+  if (ht_component == HTCAPTION || ht_component == HTSYSMENU) {
+    is_right_mouse_pressed_on_caption_ = true;
+    // Using SetCapture() here matches Windows native behavior for right-clicks
+    // on the title bar. It's not obvious why Windows does this.
+    SetCapture();
+  }
+
+  WidgetWin::OnNCRButtonDown(ht_component, point);
+}
+
+void WindowWin::OnNCRButtonUp(UINT ht_component, const CPoint& point) {
+  if (is_right_mouse_pressed_on_caption_)
+    is_right_mouse_pressed_on_caption_ = false;
+
+  WidgetWin::OnNCRButtonUp(ht_component, point);
+}
+
+void WindowWin::OnRButtonUp(UINT ht_component, const CPoint& point) {
+  // We handle running the system menu on mouseup here because calling
+  // SetCapture() on mousedown makes the mouseup generate WM_RBUTTONUP instead
+  // of WM_NCRBUTTONUP.
+  if (is_right_mouse_pressed_on_caption_) {
+    is_right_mouse_pressed_on_caption_ = false;
+    ReleaseCapture();
+    // |point| is in window coordinates, but WM_NCHITTEST and RunSystemMenu()
+    // expect screen coordinates.
+    CPoint screen_point(point);
+    MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1);
+    ht_component = ::SendMessage(GetNativeView(), WM_NCHITTEST, 0,
+                                 MAKELPARAM(screen_point.x, screen_point.y));
+    if (ht_component == HTCAPTION || ht_component == HTSYSMENU) {
+      RunSystemMenu(gfx::Point(screen_point));
+      return;
+    }
+  }
+
+  WidgetWin::OnRButtonUp(ht_component, point);
 }
 
 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param,
diff --git a/views/window/window_win.h b/views/window/window_win.h
index f799ae7..b6b9122 100644
--- a/views/window/window_win.h
+++ b/views/window/window_win.h
@@ -124,6 +124,8 @@ class WindowWin : public WidgetWin,
   virtual void OnNCPaint(HRGN rgn);
   virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point);
   virtual void OnNCRButtonDown(UINT ht_component, const CPoint& point);
+  virtual void OnNCRButtonUp(UINT ht_component, const CPoint& point);
+  virtual void OnRButtonUp(UINT ht_component, const CPoint& point);
   virtual LRESULT OnNCUAHDrawCaption(UINT msg, WPARAM w_param, LPARAM l_param);
   virtual LRESULT OnNCUAHDrawFrame(UINT msg, WPARAM w_param, LPARAM l_param);
   virtual LRESULT OnSetCursor(HWND window, UINT hittest_code, UINT message);
@@ -276,6 +278,10 @@ class WindowWin : public WidgetWin,
   // when all we want to do is restore it.
   int force_hidden_count_;
 
+  // Set to true when the user presses the right mouse button on the caption
+  // area. We need this so we can correctly show the context menu on mouse-up.
+  bool is_right_mouse_pressed_on_caption_;
+
   // The last-seen monitor containing us, and its rect and work area.  These are
   // used to catch updates to the rect and work area and react accordingly.
   HMONITOR last_monitor_;
-- 
cgit v1.1