diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-08 15:00:00 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-08 15:00:00 +0000 |
commit | 978a0d53f38c292a21843d3902d25b90c00bd376 (patch) | |
tree | f5cd0ea3e236002203da113332920eab41955aa3 | |
parent | 993076036efa8bd7b5436556f8a7d0c3fedf8738 (diff) | |
download | chromium_src-978a0d53f38c292a21843d3902d25b90c00bd376.zip chromium_src-978a0d53f38c292a21843d3902d25b90c00bd376.tar.gz chromium_src-978a0d53f38c292a21843d3902d25b90c00bd376.tar.bz2 |
views: Target the synthetic wheel events to the view under the mouse cursor.
BUG=137591
Review URL: https://codereview.chromium.org/11761005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175526 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ui/views/controls/menu/menu_host_root_view.cc | 3 | ||||
-rw-r--r-- | ui/views/widget/native_widget_aura.cc | 12 | ||||
-rw-r--r-- | ui/views/widget/root_view.cc | 24 | ||||
-rw-r--r-- | ui/views/widget/widget_unittest.cc | 117 |
4 files changed, 142 insertions, 14 deletions
diff --git a/ui/views/controls/menu/menu_host_root_view.cc b/ui/views/controls/menu/menu_host_root_view.cc index ad8bf0a..fd165a8 100644 --- a/ui/views/controls/menu/menu_host_root_view.cc +++ b/ui/views/controls/menu/menu_host_root_view.cc @@ -62,8 +62,7 @@ bool MenuHostRootView::OnMouseWheel(const ui::MouseWheelEvent& event) { #endif } -void MenuHostRootView::DispatchGestureEvent( - ui::GestureEvent* event) { +void MenuHostRootView::DispatchGestureEvent(ui::GestureEvent* event) { RootView::DispatchGestureEvent(event); if (event->handled()) return; diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 3eff315..1bc65ba 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -799,18 +799,6 @@ void NativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) { } void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) { - if (event->type() == ui::ET_SCROLL) { - delegate_->OnScrollEvent(event); - if (event->handled()) - return; - - // Convert unprocessed scroll events into wheel events. - ui::MouseWheelEvent mwe(*static_cast<ui::ScrollEvent*>(event)); - delegate_->OnMouseEvent(&mwe); - if (mwe.handled()) - event->SetHandled(); - return; - } delegate_->OnScrollEvent(event); } diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc index 5b0de0b..12c2d12 100644 --- a/ui/views/widget/root_view.cc +++ b/ui/views/widget/root_view.cc @@ -139,6 +139,30 @@ void RootView::DispatchScrollEvent(ui::ScrollEvent* event) { v && v != this && !event->stopped_propagation(); v = v->parent()) { v->OnScrollEvent(event); } + + if (event->handled() || event->type() != ui::ET_SCROLL) + return; + + // Convert unprocessed scroll events into mouse-wheel events. Note that + // wheel events are normally sent to the focused view. However, if the focused + // view does not process these wheel events, then dispatch them to the view + // under the cursor. + ui::MouseWheelEvent wheel(*event); + if (OnMouseWheel(wheel)) { + event->SetHandled(); + } else { + View* focused_view = + GetFocusManager() ? GetFocusManager()->GetFocusedView() : NULL; + View* v = GetEventHandlerForPoint(wheel.location()); + if (v != focused_view) { + for (; v && v != this; v = v->parent()) { + if (v->OnMouseWheel(wheel)) { + event->SetHandled(); + break; + } + } + } + } } void RootView::DispatchTouchEvent(ui::TouchEvent* event) { diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index b8bb6c6..dc11612 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc @@ -122,6 +122,81 @@ class MouseView : public View { DISALLOW_COPY_AND_ASSIGN(MouseView); }; +// A view that keeps track of the events it receives, but consumes no events. +class EventCountView : public View { + public: + EventCountView() {} + virtual ~EventCountView() {} + + int GetEventCount(ui::EventType type) { + return event_count_[type]; + } + + void ResetCounts() { + event_count_.clear(); + } + + private: + void RecordEvent(const ui::Event& event) { + ++event_count_[event.type()]; + } + + // Overridden from View: + virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE { + RecordEvent(event); + return false; + } + virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE { + RecordEvent(event); + return false; + } + virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE { + RecordEvent(event); + } + virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE { + RecordEvent(event); + } + virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE { + RecordEvent(event); + } + virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE { + RecordEvent(event); + } + virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE { + RecordEvent(event); + return false; + } + virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE { + RecordEvent(event); + return false; + } + virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE { + RecordEvent(event); + return false; + } + + // Overridden from ui::EventHandler: + virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { + RecordEvent(*event); + } + virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE { + RecordEvent(*event); + } + virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { + RecordEvent(*event); + } + virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE { + RecordEvent(*event); + } + virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { + RecordEvent(*event); + } + + std::map<ui::EventType, int> event_count_; + + DISALLOW_COPY_AND_ASSIGN(EventCountView); +}; + // A view that does a capture on gesture-begin events. class GestureCaptureView : public View { public: @@ -1167,6 +1242,48 @@ TEST_F(WidgetTest, DesktopNativeWidgetAuraNoPaintAfterHideTest) { #endif // !defined(OS_CHROMEOS) +// Tests that wheel events generted from scroll events are targetted to the +// views under the cursor when the focused view does not processed them. +TEST_F(WidgetTest, WheelEventsFromScrollEventTarget) { + EventCountView* focused_view = new EventCountView; + focused_view->set_focusable(true); + + EventCountView* cursor_view = new EventCountView; + + focused_view->SetBounds(0, 0, 50, 40); + cursor_view->SetBounds(60, 0, 50, 40); + + Widget* widget = CreateTopLevelPlatformWidget(); + widget->GetRootView()->AddChildView(focused_view); + widget->GetRootView()->AddChildView(cursor_view); + + focused_view->RequestFocus(); + EXPECT_TRUE(focused_view->HasFocus()); + + // Generate a scroll event on the cursor view. The focused view will receive a + // wheel event, but since it doesn't process the event, the view under the + // cursor will receive the wheel event. + ui::ScrollEvent scroll(ui::ET_SCROLL, gfx::Point(65, 5), 0, 0, 20); + widget->OnScrollEvent(&scroll); + + EXPECT_EQ(0, focused_view->GetEventCount(ui::ET_SCROLL)); + EXPECT_EQ(1, focused_view->GetEventCount(ui::ET_MOUSEWHEEL)); + + EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_SCROLL)); + EXPECT_EQ(1, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL)); + + focused_view->ResetCounts(); + cursor_view->ResetCounts(); + + ui::ScrollEvent scroll2(ui::ET_SCROLL, gfx::Point(5, 5), 0, 0, 20); + widget->OnScrollEvent(&scroll2); + EXPECT_EQ(1, focused_view->GetEventCount(ui::ET_SCROLL)); + EXPECT_EQ(1, focused_view->GetEventCount(ui::ET_MOUSEWHEEL)); + + EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_SCROLL)); + EXPECT_EQ(0, cursor_view->GetEventCount(ui::ET_MOUSEWHEEL)); +} + #endif // defined(USE_AURA) } // namespace |