Commit 71f09952 authored by sahel's avatar sahel Committed by Commit Bot

Autoscroll has priority over wheel scrolling.

On autoscroll start the mouse_wheel_phase_handler_ ends the current
scrolling sequence(if such exists). While Autoscrolling wheel events
in the mouse wheel event queue are ignored and once autoscrolling ends
the mouse_wheel_event_queue resumes processing wheel events normally.

This change is identical to giving priority to touchscreen scrolling
over wheel scrolling and it is done to make sure that attempting to
wheel scroll during a middle click autoscroll doesn't cause unwanted GSB
/GSE generation.

Bug: 835314
Test: *.TimerBasedLatchingBreaksWithAutoscrollStart
Change-Id: Id568ee2676a6dafc2705c144ea4d92d46311b788
Reviewed-on: https://chromium-review.googlesource.com/1011457
Commit-Queue: Sahel Sharifymoghaddam <sahel@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554496}
parent 24196fa1
...@@ -266,12 +266,13 @@ void MouseWheelEventQueue::OnGestureScrollEvent( ...@@ -266,12 +266,13 @@ void MouseWheelEventQueue::OnGestureScrollEvent(
blink::WebInputEvent::kGestureScrollBegin) { blink::WebInputEvent::kGestureScrollBegin) {
scrolling_device_ = gesture_event.event.SourceDevice(); scrolling_device_ = gesture_event.event.SourceDevice();
} else if (scrolling_device_ == gesture_event.event.SourceDevice() && } else if (scrolling_device_ == gesture_event.event.SourceDevice() &&
(gesture_event.event.GetType() == gesture_event.event.GetType() ==
blink::WebInputEvent::kGestureScrollEnd || blink::WebInputEvent::kGestureScrollEnd) {
(gesture_event.event.GetType() ==
blink::WebInputEvent::kGestureFlingStart &&
scrolling_device_ != blink::kWebGestureDeviceTouchpad))) {
scrolling_device_ = blink::kWebGestureDeviceUninitialized; scrolling_device_ = blink::kWebGestureDeviceUninitialized;
} else if (gesture_event.event.GetType() ==
blink::WebInputEvent::kGestureFlingStart) {
// With browser side fling we shouldn't reset scrolling_device_ on GFS since
// the fling_controller processes the GFS to generate and send GSU events.
} }
} }
......
...@@ -2228,6 +2228,7 @@ void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) { ...@@ -2228,6 +2228,7 @@ void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) {
} }
void RenderWidgetHostImpl::OnAutoscrollStart(const gfx::PointF& position) { void RenderWidgetHostImpl::OnAutoscrollStart(const gfx::PointF& position) {
GetView()->OnAutoscrollStart();
WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build( WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureScrollBegin, WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceSyntheticAutoscroll); blink::kWebGestureDeviceSyntheticAutoscroll);
......
...@@ -1915,6 +1915,11 @@ void RenderWidgetHostViewAndroid::UpdateNativeViewTree( ...@@ -1915,6 +1915,11 @@ void RenderWidgetHostViewAndroid::UpdateNativeViewTree(
CreateOverscrollControllerIfPossible(); CreateOverscrollControllerIfPossible();
} }
MouseWheelPhaseHandler*
RenderWidgetHostViewAndroid::GetMouseWheelPhaseHandler() {
return &mouse_wheel_phase_handler_;
}
void RenderWidgetHostViewAndroid::RunAckCallbacks() { void RenderWidgetHostViewAndroid::RunAckCallbacks() {
while (!ack_callbacks_.empty()) { while (!ack_callbacks_.empty()) {
ack_callbacks_.front().Run(); ack_callbacks_.front().Run();
......
...@@ -335,6 +335,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid ...@@ -335,6 +335,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void LostFocus(); void LostFocus();
private: private:
MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() override;
void RunAckCallbacks(); void RunAckCallbacks();
bool ShouldRouteEvents() const; bool ShouldRouteEvents() const;
......
...@@ -2466,6 +2466,10 @@ RenderWidgetHostViewAura::AllocateFrameSinkIdForGuestViewHack() { ...@@ -2466,6 +2466,10 @@ RenderWidgetHostViewAura::AllocateFrameSinkIdForGuestViewHack() {
->AllocateFrameSinkId(); ->AllocateFrameSinkId();
} }
MouseWheelPhaseHandler* RenderWidgetHostViewAura::GetMouseWheelPhaseHandler() {
return &event_handler_->mouse_wheel_phase_handler();
}
void RenderWidgetHostViewAura::TakeFallbackContentFrom( void RenderWidgetHostViewAura::TakeFallbackContentFrom(
RenderWidgetHostView* view) { RenderWidgetHostView* view) {
DCHECK(!static_cast<RenderWidgetHostViewBase*>(view) DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)
......
...@@ -73,6 +73,7 @@ class DirectManipulationBrowserTest; ...@@ -73,6 +73,7 @@ class DirectManipulationBrowserTest;
class CursorManager; class CursorManager;
class DelegatedFrameHost; class DelegatedFrameHost;
class DelegatedFrameHostClient; class DelegatedFrameHostClient;
class MouseWheelPhaseHandler;
class RenderFrameHostImpl; class RenderFrameHostImpl;
class RenderWidgetHostView; class RenderWidgetHostView;
class TouchSelectionControllerClientAura; class TouchSelectionControllerClientAura;
...@@ -436,6 +437,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -436,6 +437,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// collide with FrameSinkIds used by RenderWidgetHostImpls. // collide with FrameSinkIds used by RenderWidgetHostImpls.
static viz::FrameSinkId AllocateFrameSinkIdForGuestViewHack(); static viz::FrameSinkId AllocateFrameSinkIdForGuestViewHack();
MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() override;
void CreateAuraWindow(aura::client::WindowType type); void CreateAuraWindow(aura::client::WindowType type);
void CreateDelegatedFrameHostClient(); void CreateDelegatedFrameHostClient();
......
...@@ -684,6 +684,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test { ...@@ -684,6 +684,7 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
void TimerBasedLatchingBreaksWithMouseMove(); void TimerBasedLatchingBreaksWithMouseMove();
void TimerBasedLatchingBreaksWithModifiersChange(); void TimerBasedLatchingBreaksWithModifiersChange();
void TimerBasedLatchingBreaksWithDirectionChange(); void TimerBasedLatchingBreaksWithDirectionChange();
void TimerBasedLatchingBreaksWithAutoscrollStart();
void TouchpadFlingStartResetsWheelPhaseState(); void TouchpadFlingStartResetsWheelPhaseState();
void GSBWithTouchSourceStopsWheelScrollSequence(); void GSBWithTouchSourceStopsWheelScrollSequence();
...@@ -2370,6 +2371,63 @@ TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest, ...@@ -2370,6 +2371,63 @@ TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
TimerBasedLatchingBreaksWithDirectionChange(); TimerBasedLatchingBreaksWithDirectionChange();
} }
void RenderWidgetHostViewAuraTest::
TimerBasedLatchingBreaksWithAutoscrollStart() {
// The test is valid only when wheel scroll latching is enabled.
if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
return;
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the Autoscroll starts.
view_->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout(
TestTimeouts::action_max_timeout());
view_->InitAsChild(nullptr);
view_->Show();
sink_->ClearMessages();
ui::MouseWheelEvent event(gfx::Vector2d(0, 5), gfx::Point(2, 2),
gfx::Point(2, 2), ui::EventTimeForNow(), 0, 0);
view_->OnMouseEvent(&event);
base::RunLoop().RunUntilIdle();
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
EXPECT_TRUE(events[0]->ToEvent());
const WebMouseWheelEvent* wheel_event =
static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_TRUE(view_->GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
events = GetAndResetDispatchedMessages();
// Autoscroll start breaks wheel scroll latching sequence by sending the
// pending wheel end event, the non-blocking wheel end event will be acked
// immediately and a GSE will be sent. The next wheel event will start a new
// scrolling sequence.
view_->OnAutoscrollStart();
EXPECT_FALSE(view_->GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
ui::MouseWheelEvent event2(gfx::Vector2d(0, 5), gfx::Point(2, 2),
gfx::Point(2, 2), ui::EventTimeForNow(), 0, 0);
view_->OnMouseEvent(&event2);
base::RunLoop().RunUntilIdle();
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel GestureScrollEnd MouseWheel", GetMessageNames(events));
EXPECT_TRUE(events[0]->ToEvent());
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase);
EXPECT_TRUE(events[2]->ToEvent());
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
}
TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
TimerBasedLatchingBreaksWithAutoscrollStart) {
TimerBasedLatchingBreaksWithAutoscrollStart();
}
// Tests that a gesture fling start with touchpad source resets wheel phase // Tests that a gesture fling start with touchpad source resets wheel phase
// state. // state.
void RenderWidgetHostViewAuraTest::TouchpadFlingStartResetsWheelPhaseState() { void RenderWidgetHostViewAuraTest::TouchpadFlingStartResetsWheelPhaseState() {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "content/browser/compositor/surface_utils.h" #include "content/browser/compositor/surface_utils.h"
#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/display_util.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h" #include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
#include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_delegate.h"
...@@ -93,6 +94,10 @@ void RenderWidgetHostViewBase::NotifyObserversAboutShutdown() { ...@@ -93,6 +94,10 @@ void RenderWidgetHostViewBase::NotifyObserversAboutShutdown() {
DCHECK(!observers_.might_have_observers()); DCHECK(!observers_.might_have_observers());
} }
MouseWheelPhaseHandler* RenderWidgetHostViewBase::GetMouseWheelPhaseHandler() {
return nullptr;
}
bool RenderWidgetHostViewBase::OnMessageReceived(const IPC::Message& msg){ bool RenderWidgetHostViewBase::OnMessageReceived(const IPC::Message& msg){
return false; return false;
} }
...@@ -385,6 +390,14 @@ void RenderWidgetHostViewBase::ShowDisambiguationPopup( ...@@ -385,6 +390,14 @@ void RenderWidgetHostViewBase::ShowDisambiguationPopup(
NOTIMPLEMENTED_LOG_ONCE(); NOTIMPLEMENTED_LOG_ONCE();
} }
void RenderWidgetHostViewBase::OnAutoscrollStart() {
if (!GetMouseWheelPhaseHandler())
return;
// End the current scrolling seqeunce when autoscrolling starts.
GetMouseWheelPhaseHandler()->DispatchPendingWheelEndEvent();
}
gfx::Size RenderWidgetHostViewBase::GetVisibleViewportSize() const { gfx::Size RenderWidgetHostViewBase::GetVisibleViewportSize() const {
return GetViewBounds().size(); return GetViewBounds().size();
} }
......
...@@ -78,6 +78,7 @@ namespace content { ...@@ -78,6 +78,7 @@ namespace content {
class BrowserAccessibilityDelegate; class BrowserAccessibilityDelegate;
class BrowserAccessibilityManager; class BrowserAccessibilityManager;
class CursorManager; class CursorManager;
class MouseWheelPhaseHandler;
class RenderWidgetHostImpl; class RenderWidgetHostImpl;
class RenderWidgetHostViewBaseObserver; class RenderWidgetHostViewBaseObserver;
class SyntheticGestureTarget; class SyntheticGestureTarget;
...@@ -475,6 +476,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase ...@@ -475,6 +476,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// changes. // changes.
virtual void SetShowingContextMenu(bool showing) {} virtual void SetShowingContextMenu(bool showing) {}
virtual void OnAutoscrollStart();
// Returns the associated RenderWidgetHostImpl. // Returns the associated RenderWidgetHostImpl.
RenderWidgetHostImpl* host() const { return host_; } RenderWidgetHostImpl* host() const { return host_; }
...@@ -541,6 +544,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase ...@@ -541,6 +544,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
void NotifyObserversAboutShutdown(); void NotifyObserversAboutShutdown();
virtual MouseWheelPhaseHandler* GetMouseWheelPhaseHandler();
#if defined(USE_AURA) #if defined(USE_AURA)
virtual void ScheduleEmbed( virtual void ScheduleEmbed(
ui::mojom::WindowTreeClientPtr client, ui::mojom::WindowTreeClientPtr client,
......
...@@ -419,6 +419,8 @@ class CONTENT_EXPORT RenderWidgetHostViewMac ...@@ -419,6 +419,8 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// collide with FrameSinkIds used by RenderWidgetHostImpls. // collide with FrameSinkIds used by RenderWidgetHostImpls.
static viz::FrameSinkId AllocateFrameSinkIdForGuestViewHack(); static viz::FrameSinkId AllocateFrameSinkIdForGuestViewHack();
MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() override;
// Shuts down the render_widget_host_. This is a separate function so we can // Shuts down the render_widget_host_. This is a separate function so we can
// invoke it from the message loop. // invoke it from the message loop.
void ShutdownHost(); void ShutdownHost();
......
...@@ -1198,6 +1198,10 @@ RenderWidgetHostViewMac::AllocateFrameSinkIdForGuestViewHack() { ...@@ -1198,6 +1198,10 @@ RenderWidgetHostViewMac::AllocateFrameSinkIdForGuestViewHack() {
->AllocateFrameSinkId(); ->AllocateFrameSinkId();
} }
MouseWheelPhaseHandler* RenderWidgetHostViewMac::GetMouseWheelPhaseHandler() {
return &mouse_wheel_phase_handler_;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostNSViewClient implementation: // RenderWidgetHostNSViewClient implementation:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment