summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-08 15:00:00 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-08 15:00:00 +0000
commit978a0d53f38c292a21843d3902d25b90c00bd376 (patch)
treef5cd0ea3e236002203da113332920eab41955aa3
parent993076036efa8bd7b5436556f8a7d0c3fedf8738 (diff)
downloadchromium_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.cc3
-rw-r--r--ui/views/widget/native_widget_aura.cc12
-rw-r--r--ui/views/widget/root_view.cc24
-rw-r--r--ui/views/widget/widget_unittest.cc117
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