diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 05:02:43 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 05:02:43 +0000 |
commit | 1255a3e4bb4f30978c79497e4f05db615e197505 (patch) | |
tree | d1575c5c0ae3672dd379d6d67838c673b4d7824e /views/window | |
parent | 5ce3da1ef045e25ef4c34cfc925fb8a48ad2e87c (diff) | |
download | chromium_src-1255a3e4bb4f30978c79497e4f05db615e197505.zip chromium_src-1255a3e4bb4f30978c79497e4f05db615e197505.tar.gz chromium_src-1255a3e4bb4f30978c79497e4f05db615e197505.tar.bz2 |
Support app menu and double-click close on upper left corner of window, part one.
This makes things work right for windows that have an icon. The behavior of the main window is unchanged because right now it never returns HTSYSMENU anywhere. Part two of this change will be figuring out how to return that at the right place, which will make things Just Work.
BUG=6961
TEST=Open an app or popup window. Single click the icon. The app menu should appear. Close it, then click-and-drag into the app menu. The item you release on should execute. Double-click the icon. The window should close.
Review URL: http://codereview.chromium.org/577018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38187 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/window')
-rw-r--r-- | views/window/custom_frame_view.cc | 10 | ||||
-rw-r--r-- | views/window/custom_frame_view.h | 3 | ||||
-rw-r--r-- | views/window/native_frame_view.cc | 8 | ||||
-rw-r--r-- | views/window/native_frame_view.h | 3 | ||||
-rw-r--r-- | views/window/non_client_view.cc | 6 | ||||
-rw-r--r-- | views/window/non_client_view.h | 7 | ||||
-rw-r--r-- | views/window/window_win.cc | 103 | ||||
-rw-r--r-- | views/window/window_win.h | 13 |
8 files changed, 25 insertions, 128 deletions
diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc index d3fd085..6670a1d 100644 --- a/views/window/custom_frame_view.cc +++ b/views/window/custom_frame_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -138,14 +138,6 @@ gfx::Rect CustomFrameView::GetWindowBoundsForClientBounds( client_bounds.height() + top_height + border_thickness); } -gfx::Point CustomFrameView::GetSystemMenuPoint() const { - gfx::Point system_menu_point( - MirroredXCoordinateInsideView(FrameBorderThickness()), - NonClientTopBorderHeight() - BottomEdgeThicknessWithinNonClientHeight()); - ConvertPointToScreen(this, &system_menu_point); - return system_menu_point; -} - int CustomFrameView::NonClientHitTest(const gfx::Point& point) { // Then see if the point is within any of the window controls. if (close_button_->GetBounds(APPLY_MIRRORING_TRANSFORMATION).Contains(point)) diff --git a/views/window/custom_frame_view.h b/views/window/custom_frame_view.h index 9de22f0..867507f 100644 --- a/views/window/custom_frame_view.h +++ b/views/window/custom_frame_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -38,7 +38,6 @@ class CustomFrameView : public NonClientFrameView, virtual gfx::Rect GetBoundsForClientView() const; virtual gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const; - virtual gfx::Point GetSystemMenuPoint() const; virtual int NonClientHitTest(const gfx::Point& point); virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); virtual void EnableClose(bool enable); diff --git a/views/window/native_frame_view.cc b/views/window/native_frame_view.cc index 05a8dcb..7ee81f1 100644 --- a/views/window/native_frame_view.cc +++ b/views/window/native_frame_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -34,12 +34,6 @@ gfx::Rect NativeFrameView::GetWindowBoundsForClientBounds( return gfx::Rect(rect); } -gfx::Point NativeFrameView::GetSystemMenuPoint() const { - POINT temp = {0, -kFrameShadowThickness }; - MapWindowPoints(frame_->GetNativeView(), HWND_DESKTOP, &temp, 1); - return gfx::Point(temp); -} - int NativeFrameView::NonClientHitTest(const gfx::Point& point) { return HTNOWHERE; } diff --git a/views/window/native_frame_view.h b/views/window/native_frame_view.h index e2efa9d..c68941b 100644 --- a/views/window/native_frame_view.h +++ b/views/window/native_frame_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -20,7 +20,6 @@ class NativeFrameView : public NonClientFrameView { virtual gfx::Rect GetBoundsForClientView() const; virtual gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const; - virtual gfx::Point GetSystemMenuPoint() const; virtual int NonClientHitTest(const gfx::Point& point); virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask); diff --git a/views/window/non_client_view.cc b/views/window/non_client_view.cc index 3fca8bc..23fda99 100644 --- a/views/window/non_client_view.cc +++ b/views/window/non_client_view.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -91,10 +91,6 @@ gfx::Rect NonClientView::GetWindowBoundsForClientBounds( return frame_view_->GetWindowBoundsForClientBounds(client_bounds); } -gfx::Point NonClientView::GetSystemMenuPoint() const { - return frame_view_->GetSystemMenuPoint(); -} - int NonClientView::NonClientHitTest(const gfx::Point& point) { // Sanity check. if (!bounds().Contains(point)) diff --git a/views/window/non_client_view.h b/views/window/non_client_view.h index 0956442..ddb1786 100644 --- a/views/window/non_client_view.h +++ b/views/window/non_client_view.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -56,7 +56,6 @@ class NonClientFrameView : public View { virtual gfx::Rect GetWindowBoundsForClientBounds( const gfx::Rect& client_bounds) const = 0; - virtual gfx::Point GetSystemMenuPoint() const = 0; virtual int NonClientHitTest(const gfx::Point& point) = 0; virtual void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) = 0; @@ -170,10 +169,6 @@ class NonClientView : public View { // the specified bounds. gfx::Rect GetWindowBoundsForClientBounds(const gfx::Rect client_bounds) const; - // Returns the point, in screen coordinates, where the system menu should - // be shown so it shows up anchored to the system menu icon. - gfx::Point GetSystemMenuPoint() const; - // Determines the windows HT* code when the mouse cursor is at the // specified point, in window coordinates. int NonClientHitTest(const gfx::Point& point); diff --git a/views/window/window_win.cc b/views/window/window_win.cc index e1a10af..40781a8 100644 --- a/views/window/window_win.cc +++ b/views/window/window_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -499,7 +499,6 @@ WindowWin::WindowWin(WindowDelegate* window_delegate) ignore_pos_changes_factory_(this), force_hidden_count_(0), is_right_mouse_pressed_on_caption_(false), - last_time_system_menu_clicked_(0), last_monitor_(NULL) { is_window_ = true; InitClass(); @@ -576,23 +575,6 @@ gfx::Insets WindowWin::GetClientAreaInsets() const { return gfx::Insets(0, 0, IsFullscreen() ? 0 : 1, 0); } -void WindowWin::RunSystemMenu(const gfx::Point& point) { - // We need to reset and clean up any currently created system menu objects. - // We need to call this otherwise there's a small chance that we aren't going - // to get a system menu. We also can't take the return value of this - // function. We need to call it *again* to get a valid HMENU. - //::GetSystemMenu(GetNativeView(), TRUE); - UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; - if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) - flags |= TPM_RIGHTALIGN; - HMENU system_menu = ::GetSystemMenu(GetNativeView(), FALSE); - int id = ::TrackPopupMenu(system_menu, flags, - point.x(), point.y(), 0, GetNativeView(), NULL); - ExecuteSystemMenuCommand(id); - if (id) // something was selected - last_time_system_menu_clicked_ = 0; -} - /////////////////////////////////////////////////////////////////////////////// // WindowWin, WidgetWin overrides: @@ -962,23 +944,7 @@ void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) { } } - // TODO(beng): figure out why we need to run the system menu manually - // ourselves. This is wrong and causes many subtle bugs. - // From my initial research, it looks like DefWindowProc tries - // to run it but fails before sending the initial WM_MENUSELECT - // for the sysmenu. - // TODO(georgey): Remove the fix for double click when we figure out why - // system menu does not open automatically and pass it to - // default processing. - if (ht_component == HTSYSMENU) { - // We use 0 as a special value. If user is "lucky" and double clicks on - // system icon exactly 49.7x days after PC was started we ignore that - // click. - last_time_system_menu_clicked_ = GetTickCount(); - RunSystemMenu(non_client_view_->GetSystemMenuPoint()); - } else { - WidgetWin::OnNCLButtonDown(ht_component, point); - } + WidgetWin::OnNCLButtonDown(ht_component, point); /* TODO(beng): Fix the standard non-client over-painting bug. This code doesn't work but identifies the problem. @@ -996,64 +962,36 @@ void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) { */ } -void WindowWin::OnNCLButtonUp(UINT ht_component, const CPoint& point) { - // georgey : fix for double click on system icon not working - // As we do track on system menu, the following sequence occurs, when user - // double clicks: - // 1. Window gets WM_NCLBUTTONDOWN with ht_component == HTSYSMENU - // 2. We call TrackPopupMenu, that captures the mouse - // 3. Menu, not window, gets WM_NCLBUTTONUP - // 4. Menu gets WM_NCLBUTTONDOWN and closes returning 0 (canceled) from - // TrackPopupMenu. - // 5. Window gets WM_NCLBUTTONUP with ht_component == HTSYSMENU - if (ht_component == HTSYSMENU) { - if (last_time_system_menu_clicked_) { - if ((GetTickCount() - last_time_system_menu_clicked_) <= - GetDoubleClickTime()) { - // User double clicked left mouse button on system menu - close - // window - ExecuteSystemMenuCommand(SC_CLOSE); - } - last_time_system_menu_clicked_ = 0; - } - } - - WidgetWin::OnNCLButtonUp(ht_component, point); -} - void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& 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. + // We SetCapture() to ensure we only show the menu when the button down and + // up are both on the caption. Note: this causes the button up to be + // WM_RBUTTONUP instead of WM_NCRBUTTONUP. 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() + // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() // 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)); + 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)); + UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) + flags |= TPM_RIGHTALIGN; + HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); + int id = TrackPopupMenu(system_menu, flags, screen_point.x, + screen_point.y, 0, GetNativeView(), NULL); + ExecuteSystemMenuCommand(id); return; } } @@ -1146,14 +1084,9 @@ void WindowWin::OnSysCommand(UINT notification_code, CPoint click) { if (window_delegate_->ExecuteWindowsCommand(notification_code)) return; - if ((notification_code == SC_KEYMENU) && (click.x == VK_SPACE)) { - // Run the system menu at the NonClientView's desired location. - RunSystemMenu(non_client_view_->GetSystemMenuPoint()); - } else { - // Use the default implementation for any other command. - DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, - MAKELPARAM(click.y, click.x)); - } + // Use the default implementation for any other command. + DefWindowProc(GetNativeView(), WM_SYSCOMMAND, notification_code, + MAKELPARAM(click.x, click.y)); } void WindowWin::OnWindowPosChanging(WINDOWPOS* window_pos) { diff --git a/views/window/window_win.h b/views/window/window_win.h index 12e3d2e..02812aa 100644 --- a/views/window/window_win.h +++ b/views/window/window_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -108,9 +108,6 @@ class WindowWin : public WidgetWin, // crazily complicated. virtual gfx::Insets GetClientAreaInsets() const; - // Shows the system menu at the specified screen point. - void RunSystemMenu(const gfx::Point& point); - // Overridden from WidgetWin: virtual void OnActivate(UINT action, BOOL minimized, HWND window); virtual void OnActivateApp(BOOL active, DWORD thread_id); @@ -129,9 +126,7 @@ class WindowWin : public WidgetWin, virtual LRESULT OnNCHitTest(const CPoint& point); virtual void OnNCPaint(HRGN rgn); virtual void OnNCLButtonDown(UINT ht_component, const CPoint& point); - virtual void OnNCLButtonUp(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); @@ -294,12 +289,6 @@ class WindowWin : public WidgetWin, // area. We need this so we can correctly show the context menu on mouse-up. bool is_right_mouse_pressed_on_caption_; - // With our current behavior when we track popup menu we capture the mouse - // so doubleclick does not work. If user doubleclicks on the system icon - // the menu will be canceled and user will receive WM_NCLBUTTONUP. - // So we store the last time system menu was opened and canceled - DWORD last_time_system_menu_clicked_; - // 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_; |