diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-31 13:46:57 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-31 13:46:57 +0000 |
commit | f6b96f5d51352e6f55e723dd15c8793f73a9cee0 (patch) | |
tree | 33e7c05e1f202f1735befffdc43a5254e28fbda5 | |
parent | ca72f097519271d23f24a6336056ad07c67f192c (diff) | |
download | chromium_src-f6b96f5d51352e6f55e723dd15c8793f73a9cee0.zip chromium_src-f6b96f5d51352e6f55e723dd15c8793f73a9cee0.tar.gz chromium_src-f6b96f5d51352e6f55e723dd15c8793f73a9cee0.tar.bz2 |
views: Some MenuController cleanup.
Notable changes:
* Move code out of menu_controller_aura.cc into menu_controller.cc since it
doesn't make sense to have separate files anymore.
* Move the message-pump dispatching code out of MenuController into a separate
MenuMessagePumpDispatcher object.
BUG=343577
R=sky@chromium.org
Review URL: https://codereview.chromium.org/216423015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260540 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/views/controls/menu/menu_controller.cc | 195 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_controller.h | 19 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_controller_aura.cc | 114 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_message_pump_dispatcher.cc | 16 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_message_pump_dispatcher.h | 36 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc | 48 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_message_pump_dispatcher_win.cc | 78 | ||||
-rw-r--r-- | ui/views/views.gyp | 5 |
8 files changed, 287 insertions, 224 deletions
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 5d58c69..ea854a2 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc @@ -21,8 +21,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/events/event_constants.h" #include "ui/events/event_utils.h" -#include "ui/events/keycodes/keyboard_code_conversion.h" -#include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/screen.h" @@ -32,6 +30,7 @@ #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_controller_delegate.h" #include "ui/views/controls/menu/menu_host_root_view.h" +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" #include "ui/views/controls/menu/menu_scroll_view_container.h" #include "ui/views/controls/menu/submenu_view.h" #include "ui/views/drag_utils.h" @@ -43,17 +42,16 @@ #include "ui/views/widget/root_view.h" #include "ui/views/widget/tooltip_manager.h" #include "ui/views/widget/widget.h" +#include "ui/wm/public/activation_change_observer.h" +#include "ui/wm/public/activation_client.h" #include "ui/wm/public/dispatcher_client.h" +#include "ui/wm/public/drag_drop_client.h" #if defined(OS_WIN) #include "ui/base/win/internal_constants.h" #include "ui/views/win/hwnd_util.h" #endif -#if defined(USE_X11) -#include <X11/Xlib.h> -#endif - using base::Time; using base::TimeDelta; using ui::OSExchangeData; @@ -101,6 +99,67 @@ bool TitleMatchesMnemonic(MenuItemView* menu, base::char16 key) { return !lower_title.empty() && lower_title[0] == key; } +aura::Window* GetOwnerRootWindow(views::Widget* owner) { + return owner ? owner->GetNativeWindow()->GetRootWindow() : NULL; +} + +// ActivationChangeObserverImpl is used to observe activation changes and close +// the menu. Additionally it listens for the root window to be destroyed and +// cancel the menu as well. +class ActivationChangeObserverImpl + : public aura::client::ActivationChangeObserver, + public aura::WindowObserver, + public ui::EventHandler { + public: + ActivationChangeObserverImpl(MenuController* controller, aura::Window* root) + : controller_(controller), + root_(root) { + aura::client::GetActivationClient(root_)->AddObserver(this); + root_->AddObserver(this); + root_->AddPreTargetHandler(this); + } + + virtual ~ActivationChangeObserverImpl() { + Cleanup(); + } + + // aura::client::ActivationChangeObserver: + virtual void OnWindowActivated(aura::Window* gained_active, + aura::Window* lost_active) OVERRIDE { + if (!controller_->drag_in_progress()) + controller_->CancelAll(); + } + + // aura::WindowObserver: + virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { + Cleanup(); + } + + // ui::EventHandler: + virtual void OnCancelMode(ui::CancelModeEvent* event) OVERRIDE { + controller_->CancelAll(); + } + + private: + void Cleanup() { + if (!root_) + return; + // The ActivationClient may have been destroyed by the time we get here. + aura::client::ActivationClient* client = + aura::client::GetActivationClient(root_); + if (client) + client->RemoveObserver(this); + root_->RemovePreTargetHandler(this); + root_->RemoveObserver(this); + root_ = NULL; + } + + MenuController* controller_; + aura::Window* root_; + + DISALLOW_COPY_AND_ASSIGN(ActivationChangeObserverImpl); +}; + } // namespace // Returns the first descendant of |view| that is hot tracked. @@ -1001,94 +1060,6 @@ void MenuController::StartDrag(SubmenuView* source, } // else case, someone canceled us, don't do anything } -#if defined(OS_WIN) -uint32_t MenuController::Dispatch(const MSG& msg) { - DCHECK(blocking_run_); - - if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) - return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); - - // NOTE: we don't get WM_ACTIVATE or anything else interesting in here. - switch (msg.message) { - case WM_CONTEXTMENU: { - MenuItemView* item = pending_state_.item; - if (item && item->GetRootMenuItem() != item) { - gfx::Point screen_loc(0, item->height()); - View::ConvertPointToScreen(item, &screen_loc); - ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE; - if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1) - source_type = ui::MENU_SOURCE_KEYBOARD; - item->GetDelegate()->ShowContextMenu(item, item->GetCommand(), - screen_loc, source_type); - } - return POST_DISPATCH_NONE; - } - - // NOTE: focus wasn't changed when the menu was shown. As such, don't - // dispatch key events otherwise the focused window will get the events. - case WM_KEYDOWN: { - bool result = OnKeyDown(ui::KeyboardCodeFromNative(msg)); - TranslateMessage(&msg); - return result ? POST_DISPATCH_NONE : POST_DISPATCH_QUIT_LOOP; - } - case WM_CHAR: { - bool should_exit = SelectByChar(static_cast<base::char16>(msg.wParam)); - return should_exit ? POST_DISPATCH_QUIT_LOOP : POST_DISPATCH_NONE; - } - case WM_KEYUP: - return POST_DISPATCH_NONE; - - case WM_SYSKEYUP: - // We may have been shown on a system key, as such don't do anything - // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and - // close the menu. - return POST_DISPATCH_NONE; - - case WM_CANCELMODE: - case WM_SYSKEYDOWN: - // Exit immediately on system keys. - Cancel(EXIT_ALL); - return POST_DISPATCH_QUIT_LOOP; - - default: - break; - } - return POST_DISPATCH_PERFORM_DEFAULT | - (exit_type_ == EXIT_NONE ? POST_DISPATCH_NONE - : POST_DISPATCH_QUIT_LOOP); -} -#else -uint32_t MenuController::Dispatch(const base::NativeEvent& event) { - if (exit_type_ == EXIT_ALL || exit_type_ == EXIT_DESTROYED) - return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); - - switch (ui::EventTypeFromNative(event)) { - case ui::ET_KEY_PRESSED: { - if (!OnKeyDown(ui::KeyboardCodeFromNative(event))) - return POST_DISPATCH_QUIT_LOOP; - - // Do not check mnemonics if the Alt or Ctrl modifiers are pressed. - int flags = ui::EventFlagsFromNative(event); - if ((flags & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) == 0) { - char c = ui::GetCharacterFromKeyCode( - ui::KeyboardCodeFromNative(event), flags); - if (SelectByChar(c)) - return POST_DISPATCH_QUIT_LOOP; - } - return POST_DISPATCH_NONE; - } - case ui::ET_KEY_RELEASED: - return POST_DISPATCH_NONE; - default: - break; - } - - return POST_DISPATCH_PERFORM_DEFAULT | - (exit_type_ == EXIT_NONE ? POST_DISPATCH_NONE - : POST_DISPATCH_QUIT_LOOP); -} -#endif - bool MenuController::OnKeyDown(ui::KeyboardCode key_code) { DCHECK(blocking_run_); @@ -1155,11 +1126,6 @@ bool MenuController::OnKeyDown(ui::KeyboardCode key_code) { CloseSubmenu(); break; -#if defined(OS_WIN) - case VK_APPS: - break; -#endif - default: break; } @@ -1205,6 +1171,25 @@ MenuController::~MenuController() { StopCancelAllTimer(); } +void MenuController::RunMessageLoop(bool nested_menu) { + internal::MenuMessagePumpDispatcher nested_dispatcher(this); + + // |owner_| may be NULL. + aura::Window* root = GetOwnerRootWindow(owner_); + if (root) { + scoped_ptr<ActivationChangeObserverImpl> observer; + if (!nested_menu) + observer.reset(new ActivationChangeObserverImpl(this, root)); + aura::client::GetDispatcherClient(root) + ->RunWithDispatcher(&nested_dispatcher); + } else { + base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); + base::MessageLoop::ScopedNestableTaskAllower allow(loop); + base::RunLoop run_loop(&nested_dispatcher); + run_loop.Run(); + } +} + MenuController::SendAcceleratorResultType MenuController::SendAcceleratorToHotTrackedView() { CustomButton* hot_view = GetFirstHotTrackedView(pending_state_.item); @@ -2321,6 +2306,12 @@ void MenuController::SetExitType(ExitType type) { } } +bool MenuController::ShouldQuitNow() const { + aura::Window* root = GetOwnerRootWindow(owner_); + return !aura::client::GetDragDropClient(root) || + !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); +} + void MenuController::HandleMouseLocation(SubmenuView* source, const gfx::Point& mouse_location) { if (showing_submenu_) @@ -2353,4 +2344,10 @@ void MenuController::HandleMouseLocation(SubmenuView* source, } } +gfx::Screen* MenuController::GetScreen() { + aura::Window* root = GetOwnerRootWindow(owner_); + return root ? gfx::Screen::GetScreenFor(root) + : gfx::Screen::GetNativeScreen(); +} + } // namespace views diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index 3425caf3..cab7bae 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h @@ -13,20 +13,22 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" -#include "base/message_loop/message_pump_dispatcher.h" #include "base/timer/timer.h" #include "ui/events/event_constants.h" #include "ui/views/controls/menu/menu_delegate.h" #include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/widget/widget_observer.h" -namespace ui { -class NativeTheme; -class OSExchangeData; +namespace base { +class MessagePumpDispatcher; } namespace gfx { class Screen; } +namespace ui { +class NativeTheme; +class OSExchangeData; +} namespace views { class MenuButton; @@ -37,6 +39,7 @@ class View; namespace internal { class MenuControllerDelegate; +class MenuMessagePumpDispatcher; class MenuRunnerImpl; } @@ -45,8 +48,7 @@ class MenuRunnerImpl; // MenuController is used internally by the various menu classes to manage // showing, selecting and drag/drop for menus. All relevant events are // forwarded to the MenuController from SubmenuView and MenuHost. -class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher, - public WidgetObserver { +class VIEWS_EXPORT MenuController : public WidgetObserver { public: // Enumeration of how the menu should exit. enum ExitType { @@ -140,6 +142,7 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher, static void TurnOffMenuSelectionHoldForTest(); private: + friend class internal::MenuMessagePumpDispatcher; friend class internal::MenuRunnerImpl; friend class MenuHostRootView; friend class MenuItemView; @@ -251,10 +254,6 @@ class VIEWS_EXPORT MenuController : public base::MessagePumpDispatcher, const ui::LocatedEvent& event); void StartDrag(SubmenuView* source, const gfx::Point& location); - // Dispatcher method. This returns true if the menu was canceled, or - // if the message is such that the menu should be closed. - virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE; - // Key processing. The return value of this is returned from Dispatch. // In other words, if this returns false (which happens if escape was // pressed, or a matching mnemonic was found) the message loop returns. diff --git a/ui/views/controls/menu/menu_controller_aura.cc b/ui/views/controls/menu/menu_controller_aura.cc deleted file mode 100644 index ec402c7..0000000 --- a/ui/views/controls/menu/menu_controller_aura.cc +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2012 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. - -#include "ui/views/controls/menu/menu_controller.h" - -#include "base/run_loop.h" -#include "ui/aura/window.h" -#include "ui/aura/window_observer.h" -#include "ui/gfx/screen.h" -#include "ui/views/widget/widget.h" -#include "ui/wm/public/activation_change_observer.h" -#include "ui/wm/public/activation_client.h" -#include "ui/wm/public/dispatcher_client.h" -#include "ui/wm/public/drag_drop_client.h" - -namespace views { - -namespace { - -// ActivationChangeObserverImpl is used to observe activation changes and close -// the menu. Additionally it listens for the root window to be destroyed and -// cancel the menu as well. -class ActivationChangeObserverImpl - : public aura::client::ActivationChangeObserver, - public aura::WindowObserver, - public ui::EventHandler { - public: - ActivationChangeObserverImpl(MenuController* controller, - aura::Window* root) - : controller_(controller), - root_(root) { - aura::client::GetActivationClient(root_)->AddObserver(this); - root_->AddObserver(this); - root_->AddPreTargetHandler(this); - } - - virtual ~ActivationChangeObserverImpl() { - Cleanup(); - } - - // aura::client::ActivationChangeObserver overrides: - virtual void OnWindowActivated(aura::Window* gained_active, - aura::Window* lost_active) OVERRIDE { - if (!controller_->drag_in_progress()) - controller_->CancelAll(); - } - - // aura::WindowObserver overrides: - virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { - Cleanup(); - } - - // ui::EventHandler overrides: - virtual void OnCancelMode(ui::CancelModeEvent* event) OVERRIDE { - controller_->CancelAll(); - } - - private: - void Cleanup() { - if (!root_) - return; - // The ActivationClient may have been destroyed by the time we get here. - aura::client::ActivationClient* client = - aura::client::GetActivationClient(root_); - if (client) - client->RemoveObserver(this); - root_->RemovePreTargetHandler(this); - root_->RemoveObserver(this); - root_ = NULL; - } - - MenuController* controller_; - aura::Window* root_; - - DISALLOW_COPY_AND_ASSIGN(ActivationChangeObserverImpl); -}; - -aura::Window* GetOwnerRootWindow(views::Widget* owner) { - return owner ? owner->GetNativeWindow()->GetRootWindow() : NULL; -} - -} // namespace - -void MenuController::RunMessageLoop(bool nested_menu) { - // |owner_| may be NULL. - aura::Window* root = GetOwnerRootWindow(owner_); - if (root) { - scoped_ptr<ActivationChangeObserverImpl> observer; - if (!nested_menu) - observer.reset(new ActivationChangeObserverImpl(this, root)); - aura::client::GetDispatcherClient(root)->RunWithDispatcher(this); - } else { - base::MessageLoopForUI* loop = base::MessageLoopForUI::current(); - base::MessageLoop::ScopedNestableTaskAllower allow(loop); - base::RunLoop run_loop(this); - run_loop.Run(); - } -} - -bool MenuController::ShouldQuitNow() const { - aura::Window* root = GetOwnerRootWindow(owner_); - return !aura::client::GetDragDropClient(root) || - !aura::client::GetDragDropClient(root)->IsDragDropInProgress(); -} - -gfx::Screen* MenuController::GetScreen() { - aura::Window* root = GetOwnerRootWindow(owner_); - return root ? - gfx::Screen::GetScreenFor(root) : gfx::Screen::GetNativeScreen(); -} - - -} // namespace views diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher.cc b/ui/views/controls/menu/menu_message_pump_dispatcher.cc new file mode 100644 index 0000000..00d7930 --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher.cc @@ -0,0 +1,16 @@ +// Copyright 2014 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. + +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" + +namespace views { +namespace internal { + +MenuMessagePumpDispatcher::MenuMessagePumpDispatcher(MenuController* controller) + : menu_controller_(controller) {} + +MenuMessagePumpDispatcher::~MenuMessagePumpDispatcher() {} + +} // namespace internal +} // namespace views diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher.h b/ui/views/controls/menu/menu_message_pump_dispatcher.h new file mode 100644 index 0000000..2f5696b --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher.h @@ -0,0 +1,36 @@ +// Copyright 2014 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. + +#ifndef UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_PUMP_DISPATCHER_H_ +#define UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_PUMP_DISPATCHER_H_ + +#include "base/macros.h" +#include "base/message_loop/message_pump_dispatcher.h" + +namespace views { + +class MenuController; + +namespace internal { + +// A message-pump dispatcher object used to dispatch events from the nested +// message-loop initiated by the MenuController. +class MenuMessagePumpDispatcher : public base::MessagePumpDispatcher { + public: + explicit MenuMessagePumpDispatcher(MenuController* menu_controller); + virtual ~MenuMessagePumpDispatcher(); + + private: + // base::MessagePumpDispatcher: + virtual uint32_t Dispatch(const base::NativeEvent& event) OVERRIDE; + + MenuController* menu_controller_; + + DISALLOW_COPY_AND_ASSIGN(MenuMessagePumpDispatcher); +}; + +} // namespace internal +} // namespace views + +#endif // UI_VIEWS_CONTROLS_MENU_MENU_MESSAGE_PUMP_DISPATCHER_H_ diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc b/ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc new file mode 100644 index 0000000..0172f8b --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher_linux.cc @@ -0,0 +1,48 @@ +// Copyright 2014 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. + +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" + +#include "ui/events/event_utils.h" +#include "ui/events/keycodes/keyboard_code_conversion.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/views/controls/menu/menu_controller.h" + +namespace views { +namespace internal { + +uint32_t MenuMessagePumpDispatcher::Dispatch(const base::NativeEvent& event) { + if (menu_controller_->exit_type() == MenuController::EXIT_ALL || + menu_controller_->exit_type() == MenuController::EXIT_DESTROYED) + return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); + + switch (ui::EventTypeFromNative(event)) { + case ui::ET_KEY_PRESSED: { + if (!menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(event))) + return POST_DISPATCH_QUIT_LOOP; + + // Do not check mnemonics if the Alt or Ctrl modifiers are pressed. + int flags = ui::EventFlagsFromNative(event); + if ((flags & (ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) == 0) { + char c = ui::GetCharacterFromKeyCode(ui::KeyboardCodeFromNative(event), + flags); + if (menu_controller_->SelectByChar(c)) + return POST_DISPATCH_QUIT_LOOP; + } + return POST_DISPATCH_NONE; + } + case ui::ET_KEY_RELEASED: + return POST_DISPATCH_NONE; + default: + break; + } + + return POST_DISPATCH_PERFORM_DEFAULT | + (menu_controller_->exit_type() == MenuController::EXIT_NONE + ? POST_DISPATCH_NONE + : POST_DISPATCH_QUIT_LOOP); +} + +} // namespace internal +} // namespace views diff --git a/ui/views/controls/menu/menu_message_pump_dispatcher_win.cc b/ui/views/controls/menu/menu_message_pump_dispatcher_win.cc new file mode 100644 index 0000000..f49b536 --- /dev/null +++ b/ui/views/controls/menu/menu_message_pump_dispatcher_win.cc @@ -0,0 +1,78 @@ +// Copyright 2014 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. + +#include "ui/views/controls/menu/menu_message_pump_dispatcher.h" + +#include <windowsx.h> + +#include "ui/events/event_utils.h" +#include "ui/events/keycodes/keyboard_code_conversion.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/views/controls/menu/menu_controller.h" + +namespace views { +namespace internal { + +uint32_t MenuMessagePumpDispatcher::Dispatch(const MSG& msg) { + DCHECK(menu_controller_->IsBlockingRun()); + + if (menu_controller_->exit_type() == MenuController::EXIT_ALL || + menu_controller_->exit_type() == MenuController::EXIT_DESTROYED) + return (POST_DISPATCH_QUIT_LOOP | POST_DISPATCH_PERFORM_DEFAULT); + + // NOTE: we don't get WM_ACTIVATE or anything else interesting in here. + switch (msg.message) { + case WM_CONTEXTMENU: { + MenuItemView* item = menu_controller_->pending_state_.item; + if (item && item->GetRootMenuItem() != item) { + gfx::Point screen_loc(0, item->height()); + View::ConvertPointToScreen(item, &screen_loc); + ui::MenuSourceType source_type = ui::MENU_SOURCE_MOUSE; + if (GET_X_LPARAM(msg.lParam) == -1 && GET_Y_LPARAM(msg.lParam) == -1) + source_type = ui::MENU_SOURCE_KEYBOARD; + item->GetDelegate()->ShowContextMenu( + item, item->GetCommand(), screen_loc, source_type); + } + return POST_DISPATCH_NONE; + } + + // NOTE: focus wasn't changed when the menu was shown. As such, don't + // dispatch key events otherwise the focused window will get the events. + case WM_KEYDOWN: { + bool result = + menu_controller_->OnKeyDown(ui::KeyboardCodeFromNative(msg)); + TranslateMessage(&msg); + return result ? POST_DISPATCH_NONE : POST_DISPATCH_QUIT_LOOP; + } + case WM_CHAR: { + bool should_exit = + menu_controller_->SelectByChar(static_cast<base::char16>(msg.wParam)); + return should_exit ? POST_DISPATCH_QUIT_LOOP : POST_DISPATCH_NONE; + } + case WM_KEYUP: + return POST_DISPATCH_NONE; + + case WM_SYSKEYUP: + // We may have been shown on a system key, as such don't do anything + // here. If another system key is pushed we'll get a WM_SYSKEYDOWN and + // close the menu. + return POST_DISPATCH_NONE; + + case WM_CANCELMODE: + case WM_SYSKEYDOWN: + // Exit immediately on system keys. + menu_controller_->Cancel(MenuController::EXIT_ALL); + return POST_DISPATCH_QUIT_LOOP; + + default: + break; + } + return POST_DISPATCH_PERFORM_DEFAULT | + (menu_controller_->exit_type() == MenuController::EXIT_NONE + ? POST_DISPATCH_NONE + : POST_DISPATCH_QUIT_LOOP); +} + +} // namespace internal +} // namespace views diff --git a/ui/views/views.gyp b/ui/views/views.gyp index feb92d8..77d3e8b 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -117,10 +117,13 @@ 'controls/menu/menu_config_win.cc', 'controls/menu/menu_controller.cc', 'controls/menu/menu_controller.h', - 'controls/menu/menu_controller_aura.cc', 'controls/menu/menu_controller_delegate.h', 'controls/menu/menu_delegate.cc', 'controls/menu/menu_delegate.h', + 'controls/menu/menu_message_pump_dispatcher.cc', + 'controls/menu/menu_message_pump_dispatcher.h', + 'controls/menu/menu_message_pump_dispatcher_linux.cc', + 'controls/menu/menu_message_pump_dispatcher_win.cc', 'controls/menu/menu_host.cc', 'controls/menu/menu_host.h', 'controls/menu/menu_host_root_view.cc', |