diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-14 23:09:11 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-14 23:09:11 +0000 |
commit | 0d62def999bb7ffe731256a98cdb6be184e067b2 (patch) | |
tree | 7a449bb520e67921a7a5257a1e4627e48c1e4e13 /chrome | |
parent | bb69e9b391b68274089c5a6148548683af54bb19 (diff) | |
download | chromium_src-0d62def999bb7ffe731256a98cdb6be184e067b2.zip chromium_src-0d62def999bb7ffe731256a98cdb6be184e067b2.tar.gz chromium_src-0d62def999bb7ffe731256a98cdb6be184e067b2.tar.bz2 |
Hook up the system menu in new frames.
BUG=1319684
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@908 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/views/frame/browser_view2.cc | 80 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view2.h | 20 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_frame.cc | 19 | ||||
-rw-r--r-- | chrome/browser/views/frame/opaque_frame.h | 3 | ||||
-rw-r--r-- | chrome/views/custom_frame_window.cc | 5 | ||||
-rw-r--r-- | chrome/views/hwnd_view_container.h | 6 | ||||
-rw-r--r-- | chrome/views/menu.cc | 4 | ||||
-rw-r--r-- | chrome/views/menu.h | 3 |
8 files changed, 139 insertions, 1 deletions
diff --git a/chrome/browser/views/frame/browser_view2.cc b/chrome/browser/views/frame/browser_view2.cc index 60603fb..40d5a50 100644 --- a/chrome/browser/views/frame/browser_view2.cc +++ b/chrome/browser/views/frame/browser_view2.cc @@ -57,6 +57,31 @@ static const int kSeparationLineHeight = 1; static const SkColor kSeparationLineColor = SkColorSetRGB(178, 178, 178); static const wchar_t* kBrowserWindowKey = L"__BROWSER_WINDOW__"; + +static const struct { bool separator; int command; int label; } kMenuLayout[] = { + { true, 0, 0 }, + { false, IDC_TASKMANAGER, IDS_TASKMANAGER }, + { true, 0, 0 }, + { false, 0, IDS_ENCODING }, + { false, 0, IDS_ZOOM }, + { false, IDC_PRINT, IDS_PRINT }, + { false, IDC_SAVEPAGE, IDS_SAVEPAGEAS }, + { false, IDC_FIND, IDS_FIND_IN_PAGE }, + { true, 0, 0 }, + { false, IDC_PASTE, IDS_PASTE }, + { false, IDC_COPY, IDS_COPY }, + { false, IDC_CUT, IDS_CUT }, + { true, 0, 0 }, + { false, IDC_NEWTAB, IDS_APP_MENU_NEW_WEB_PAGE }, + { false, IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB }, + { false, IDC_COPY_URL, IDS_APP_MENU_COPY_URL }, + { false, IDC_DUPLICATE, IDS_APP_MENU_DUPLICATE }, + { true, 0, 0 }, + { false, IDC_RELOAD, IDS_APP_MENU_RELOAD }, + { false, IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD }, + { false, IDC_BACK, IDS_CONTENT_CONTEXT_BACK } +}; + /////////////////////////////////////////////////////////////////////////////// // BrowserView2, public: @@ -145,6 +170,18 @@ bool BrowserView2::GetAccelerator(int cmd_id, return false; } +bool BrowserView2::SystemCommandReceived(UINT notification_code, + const gfx::Point& point) { + bool handled = false; + + if (browser_->SupportsCommand(notification_code)) { + browser_->ExecuteCommand(notification_code); + handled = true; + } + + return handled; +} + void BrowserView2::AddViewToDropList(ChromeViews::View* view) { dropable_views_.insert(view); } @@ -172,6 +209,27 @@ bool BrowserView2::SupportsWindowFeature(WindowFeature feature) const { return !!(FeaturesForBrowserType(browser_->GetType()) & feature); } +void BrowserView2::PrepareToRunSystemMenu(Menu* menu) { + int insertion_index = std::max(0, menu->ItemCount() - 1); + system_menu_.reset(menu); + // We add the menu items in reverse order so that insertion_index never needs + // to change. + if (browser_->GetType() == BrowserType::TABBED_BROWSER) { + system_menu_->AddSeparator(insertion_index); + system_menu_->AddMenuItemWithLabel(insertion_index, IDC_TASKMANAGER, + l10n_util::GetString(IDS_TASKMANAGER)); + // If it's a regular browser window with tabs, we don't add any more items, + // since it already has menus (Page, Chrome). + return; + } else { + BuildMenuForTabStriplessWindow(system_menu_.get(), insertion_index); + } +} + +void BrowserView2::SystemMenuEnded() { + system_menu_.reset(); +} + // static unsigned int BrowserView2::FeaturesForBrowserType(BrowserType::Type type) { unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF; @@ -918,6 +976,28 @@ void BrowserView2::LoadAccelerators() { free(accelerators); } +void BrowserView2::BuildMenuForTabStriplessWindow(Menu* menu, + int insertion_index) { + for (int i = 0; i < arraysize(kMenuLayout); ++i) { + if (kMenuLayout[i].separator) { + menu->AddSeparator(insertion_index); + } else { + int command = kMenuLayout[i].command; + + menu->AddMenuItemWithLabel(insertion_index, command, + l10n_util::GetString(kMenuLayout[i].label)); + + // |command| can be zero on submenu items (IDS_ENCODING, + // IDS_ZOOM) and on separators. + if (command != 0) { + menu->EnableMenuItemAt( + insertion_index, + browser_->IsCommandEnabled(command)); + } + } + } +} + // static void BrowserView2::InitClass() { static bool initialized = false; diff --git a/chrome/browser/views/frame/browser_view2.h b/chrome/browser/views/frame/browser_view2.h index eb9b33c..312d710 100644 --- a/chrome/browser/views/frame/browser_view2.h +++ b/chrome/browser/views/frame/browser_view2.h @@ -44,6 +44,7 @@ class BookmarkBarView; class Browser; class BrowserToolbarView; +class Menu; class StatusBubble; class TabContentsContainerView; @@ -92,6 +93,10 @@ class BrowserView2 : public BrowserWindow, // otherwise. bool GetAccelerator(int cmd_id, ChromeViews::Accelerator* accelerator); + // Handles incoming system messages. Returns true if the message was + // handled. + bool SystemCommandReceived(UINT notification_code, const gfx::Point& point); + // Adds view to the set of views that drops are allowed to occur on. You only // need invoke this for views whose y-coordinate extends above the tab strip // and you want to allow drops on. @@ -120,6 +125,15 @@ class BrowserView2 : public BrowserWindow, // supports the specified feature. bool SupportsWindowFeature(WindowFeature feature) const; + // Called right before displaying the system menu to allow the + // BrowserView to add or delete entries. BrowserView takes ownership + // of the passed in Menu object. + void PrepareToRunSystemMenu(Menu* menu); + + // Called after the system menu has ended, and disposes of the + // current System menu object. + void SystemMenuEnded(); + // Returns the set of WindowFeatures supported by the specified BrowserType. static unsigned int FeaturesForBrowserType(BrowserType::Type type); @@ -275,6 +289,9 @@ class BrowserView2 : public BrowserWindow, // use. void LoadAccelerators(); + // Builds the correct menu for when we have minimal chrome. + void BuildMenuForTabStriplessWindow(Menu* menu, int insertion_index); + // Initialize class statics. static void InitClass(); @@ -313,6 +330,9 @@ class BrowserView2 : public BrowserWindow, // True if we have already been initialized. bool initialized_; + // Lazily created representation of the system menu. + scoped_ptr<Menu> system_menu_; + // The default favicon image. static SkBitmap default_favicon_; diff --git a/chrome/browser/views/frame/opaque_frame.cc b/chrome/browser/views/frame/opaque_frame.cc index dd8a37b..56a26ad 100644 --- a/chrome/browser/views/frame/opaque_frame.cc +++ b/chrome/browser/views/frame/opaque_frame.cc @@ -103,6 +103,16 @@ void OpaqueFrame::OnEndSession(BOOL ending, UINT logoff) { FrameUtil::EndSession(); } +void OpaqueFrame::OnExitMenuLoop(bool is_track_popup_menu) { + browser_view_->SystemMenuEnded(); +} + +void OpaqueFrame::OnInitMenuPopup(HMENU menu, UINT position, + BOOL is_system_menu) { + Menu* menu_obj = new Menu(menu); + browser_view_->PrepareToRunSystemMenu(menu_obj); +} + LRESULT OpaqueFrame::OnMouseActivate(HWND window, UINT hittest_code, UINT message) { return browser_view_->ActivateAppModalDialog() ? MA_NOACTIVATEANDEAT @@ -126,6 +136,14 @@ LRESULT OpaqueFrame::OnNCActivate(BOOL active) { return TRUE; } +void OpaqueFrame::OnSysCommand(UINT notification_code, CPoint click) { + if (!browser_view_->SystemCommandReceived(notification_code, + gfx::Point(click))) { + // Use the default implementation for any other command. + SetMsgHandled(FALSE); + } +} + /////////////////////////////////////////////////////////////////////////////// // OpaqueFrame, private: @@ -133,4 +151,3 @@ OpaqueNonClientView* OpaqueFrame::GetOpaqueNonClientView() const { // We can safely assume that this conversion is true. return static_cast<OpaqueNonClientView*>(non_client_view_); } - diff --git a/chrome/browser/views/frame/opaque_frame.h b/chrome/browser/views/frame/opaque_frame.h index 5d2889d..ebf6ce9 100644 --- a/chrome/browser/views/frame/opaque_frame.h +++ b/chrome/browser/views/frame/opaque_frame.h @@ -73,13 +73,16 @@ class OpaqueFrame : public BrowserFrame, virtual bool AcceleratorPressed(ChromeViews::Accelerator* accelerator); virtual bool GetAccelerator(int cmd_id, ChromeViews::Accelerator* accelerator); + virtual void OnExitMenuLoop(bool is_track_popup_menu); virtual void OnEndSession(BOOL ending, UINT logoff); + virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu); virtual LRESULT OnMouseActivate(HWND window, UINT hittest_code, UINT message); virtual void OnMove(const CPoint& point); virtual void OnMoving(UINT param, const RECT* new_bounds); virtual LRESULT OnNCActivate(BOOL active); + virtual void OnSysCommand(UINT notification_code, CPoint click); private: // Return a pointer to the concrete type of our non-client view. diff --git a/chrome/views/custom_frame_window.cc b/chrome/views/custom_frame_window.cc index 5dc425a..2a96cb9 100644 --- a/chrome/views/custom_frame_window.cc +++ b/chrome/views/custom_frame_window.cc @@ -1180,6 +1180,11 @@ void CustomFrameWindow::OnSize(UINT param, const CSize& size) { // CustomFrameWindow, private: void CustomFrameWindow::RunSystemMenu(const CPoint& 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(GetHWND(), TRUE); HMENU system_menu = ::GetSystemMenu(GetHWND(), FALSE); int id = ::TrackPopupMenu(system_menu, TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, diff --git a/chrome/views/hwnd_view_container.h b/chrome/views/hwnd_view_container.h index 1ce41f2..3c792d1 100644 --- a/chrome/views/hwnd_view_container.h +++ b/chrome/views/hwnd_view_container.h @@ -193,9 +193,11 @@ class HWNDViewContainer : public ViewContainer, MSG_WM_DESTROY(OnDestroy) MSG_WM_ERASEBKGND(OnEraseBkgnd) MSG_WM_ENDSESSION(OnEndSession) + MSG_WM_EXITMENULOOP(OnExitMenuLoop) MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo) MSG_WM_HSCROLL(OnHScroll) MSG_WM_INITMENU(OnInitMenu) + MSG_WM_INITMENUPOPUP(OnInitMenuPopup) MSG_WM_KEYDOWN(OnKeyDown) MSG_WM_KEYUP(OnKeyUp) MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) @@ -351,6 +353,7 @@ class HWNDViewContainer : public ViewContainer, // leak a few things. virtual void OnDestroy(); virtual void OnEndSession(BOOL ending, UINT logoff) { SetMsgHandled(FALSE); } + virtual void OnExitMenuLoop(BOOL is_track_popup_menu) { SetMsgHandled(FALSE); } virtual LRESULT OnEraseBkgnd(HDC dc); virtual void OnGetMinMaxInfo(LPMINMAXINFO mm_info) { } virtual LRESULT OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param); @@ -358,6 +361,9 @@ class HWNDViewContainer : public ViewContainer, SetMsgHandled(FALSE); } virtual void OnInitMenu(HMENU menu) { SetMsgHandled(FALSE); } + virtual void OnInitMenuPopup(HMENU menu, UINT position, BOOL is_system_menu) { + SetMsgHandled(FALSE); + } virtual void OnKeyDown(TCHAR c, UINT rep_cnt, UINT flags); virtual void OnKeyUp(TCHAR c, UINT rep_cnt, UINT flags); virtual void OnLButtonDblClk(UINT flags, const CPoint& point); diff --git a/chrome/views/menu.cc b/chrome/views/menu.cc index d36ba76..0b3b72f 100644 --- a/chrome/views/menu.cc +++ b/chrome/views/menu.cc @@ -582,3 +582,7 @@ void Menu::Cancel() { DCHECK(is_menu_visible_); EndMenu(); } + +int Menu::ItemCount() { + return GetMenuItemCount(menu_); +} diff --git a/chrome/views/menu.h b/chrome/views/menu.h index 3894a5b..44a69c2 100644 --- a/chrome/views/menu.h +++ b/chrome/views/menu.h @@ -316,6 +316,9 @@ class Menu { // Cancels the menu. virtual void Cancel(); + // Returns the number of menu items. + int ItemCount(); + protected: // The delegate that is being used to get information about the presentation. Delegate* delegate_; |