Chromium Code Reviews| Index: ui/views/controls/menu/menu_host.cc |
| diff --git a/ui/views/controls/menu/menu_host.cc b/ui/views/controls/menu/menu_host.cc |
| index 9840abbdf0f650848ddac72fd05b68470f8eb1bf..0707400c3d3e6781d4b6716b1ce08eb77b7d56c1 100644 |
| --- a/ui/views/controls/menu/menu_host.cc |
| +++ b/ui/views/controls/menu/menu_host.cc |
| @@ -5,8 +5,10 @@ |
| #include "ui/views/controls/menu/menu_host.h" |
| #include "base/auto_reset.h" |
| +#include "base/logging.h" |
| #include "base/trace_event/trace_event.h" |
| #include "build/build_config.h" |
| +#include "ui/aura/window_observer.h" |
| #include "ui/events/gestures/gesture_recognizer.h" |
| #include "ui/gfx/path.h" |
| #include "ui/native_theme/native_theme.h" |
| @@ -19,8 +21,67 @@ |
| #include "ui/views/widget/native_widget_private.h" |
| #include "ui/views/widget/widget.h" |
| +#if !defined(OS_MACOSX) |
| +#include "ui/aura/window.h" |
| +#endif |
| + |
| namespace views { |
| +namespace internal { |
| + |
| +#if !defined(OS_MACOSX) |
| +// This class adds itself as the pre target handler for the |window| |
| +// passed in. It currently handles touch events and forwards them to the |
| +// controller. Reason for this approach is views does not get raw touch |
| +// events which we need to determine if a touch happened outside the bounds |
| +// of the menu. |
| +class PreMenuEventDispatchHandler : public ui::EventHandler, |
| + aura::WindowObserver { |
| + public: |
| + explicit PreMenuEventDispatchHandler(const MenuController* controller, |
|
sky
2016/01/13 16:31:13
nit: no explict
ananta
2016/01/13 21:34:47
Done.
|
| + SubmenuView* submenu, |
| + aura::Window* window) |
| + : menu_controller_(const_cast<MenuController*>(controller)), |
| + submenu_(submenu), |
| + window_(window) { |
| + window_->AddPreTargetHandler(this); |
| + window_->AddObserver(this); |
| + } |
| + |
| + ~PreMenuEventDispatchHandler() override { |
| + StopObserving(); |
| + } |
| + |
| + // ui::EventHandler overrides. |
| + void OnTouchEvent(ui::TouchEvent* event) override { |
| + menu_controller_->OnTouchEvent(submenu_, event); |
| + } |
| + |
| + // aura::WindowObserver overrides. |
| + void OnWindowDestroying(aura::Window* window) override { |
| + DCHECK(window_ == window); |
| + StopObserving(); |
| + } |
| + |
| + private: |
| + void StopObserving() { |
| + if (!window_) |
| + return; |
| + window_->RemovePreTargetHandler(this); |
| + window_->RemoveObserver(this); |
| + window_ = nullptr; |
| + } |
| + |
| + MenuController* menu_controller_; |
| + SubmenuView* submenu_; |
| + aura::Window* window_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PreMenuEventDispatchHandler); |
| +}; |
| +#endif // OS_MACOSX |
| + |
| +} // namespace internal |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // MenuHost, public: |
| @@ -61,6 +122,11 @@ void MenuHost::InitMenuHost(Widget* parent, |
| #endif |
| Init(params); |
| +#if !defined(OS_MACOSX) |
| + pre_dispatch_handler_.reset(new internal::PreMenuEventDispatchHandler( |
| + menu_controller, submenu_, GetNativeView())); |
| +#endif |
| + |
| SetContentsView(contents_view); |
| ShowMenuHost(do_capture); |
| } |
| @@ -93,6 +159,9 @@ void MenuHost::DestroyMenuHost() { |
| HideMenuHost(); |
| destroying_ = true; |
| static_cast<MenuHostRootView*>(GetRootView())->ClearSubmenu(); |
| +#if !defined(OS_MACOSX) |
| + pre_dispatch_handler_.reset(); |
| +#endif |
| Close(); |
| } |