diff options
| author | dtapuska <dtapuska@chromium.org> | 2016-03-23 12:34:51 -0700 |
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2016-03-23 19:36:11 +0000 |
| commit | c1d91e8f7cd46f1cb68ec09e49d4de5c90175d6c (patch) | |
| tree | 705633382bf9cee0ec1d3c9648f36fd877f26348 | |
| parent | 7578772922ea18a0d5b25f7b9c571845ca344789 (diff) | |
| download | chromium_src-c1d91e8f7cd46f1cb68ec09e49d4de5c90175d6c.zip chromium_src-c1d91e8f7cd46f1cb68ec09e49d4de5c90175d6c.tar.gz chromium_src-c1d91e8f7cd46f1cb68ec09e49d4de5c90175d6c.tar.bz2 | |
Fix missing fields in GestureScrollBegin/Update/End event conversions.
Some of the fields were missing from the event conversion path that
occurs when a plugin is used. This caused fields to be populated
with the default value. As a result the default values enabled
overscroll scrolling when using a low precision delta
mouse wheel with an MacOSX machine.
The bug did not indicate which precision of mouse was being
used but overscrolling for PDF files with a touchpad or a magic
mouse (which have high precision deltas) still enable
elastic overscroll; but that is consistent with MacOSX.
This is a behavioural change for MacOSX but is consistent
with Safari when using a high precision mouse.
BUG=596778
Review URL: https://codereview.chromium.org/1829743003
Cr-Commit-Position: refs/heads/master@{#382901}
5 files changed, 162 insertions, 27 deletions
diff --git a/third_party/WebKit/Source/core/events/GestureEvent.cpp b/third_party/WebKit/Source/core/events/GestureEvent.cpp index f758af2..97575e9 100644 --- a/third_party/WebKit/Source/core/events/GestureEvent.cpp +++ b/third_party/WebKit/Source/core/events/GestureEvent.cpp @@ -38,6 +38,8 @@ PassRefPtrWillBeRawPtr<GestureEvent> GestureEvent::create(PassRefPtrWillBeRawPtr float velocityX = 0; float velocityY = 0; bool inertial = false; + bool synthetic = false; + ScrollGranularity deltaUnits = ScrollGranularity::ScrollByPrecisePixel; GestureSource source = GestureSourceUninitialized; switch (event.source()) { @@ -53,9 +55,17 @@ PassRefPtrWillBeRawPtr<GestureEvent> GestureEvent::create(PassRefPtrWillBeRawPtr switch (event.type()) { case PlatformEvent::GestureScrollBegin: - eventType = EventTypeNames::gesturescrollstart; break; + eventType = EventTypeNames::gesturescrollstart; + synthetic = event.synthetic(); + deltaUnits = event.deltaUnits(); + inertial = event.inertial(); + break; case PlatformEvent::GestureScrollEnd: - eventType = EventTypeNames::gesturescrollend; break; + eventType = EventTypeNames::gesturescrollend; + synthetic = event.synthetic(); + deltaUnits = event.deltaUnits(); + inertial = event.inertial(); + break; case PlatformEvent::GestureScrollUpdate: // Only deltaX/Y are used when converting this // back to a PlatformGestureEvent. @@ -63,6 +73,7 @@ PassRefPtrWillBeRawPtr<GestureEvent> GestureEvent::create(PassRefPtrWillBeRawPtr deltaX = event.deltaX(); deltaY = event.deltaY(); inertial = event.inertial(); + deltaUnits = event.deltaUnits(); break; case PlatformEvent::GestureTap: eventType = EventTypeNames::gesturetap; break; @@ -87,7 +98,7 @@ PassRefPtrWillBeRawPtr<GestureEvent> GestureEvent::create(PassRefPtrWillBeRawPtr default: return nullptr; } - return adoptRefWillBeNoop(new GestureEvent(eventType, view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.getModifiers(), deltaX, deltaY, velocityX, velocityY, inertial, event.timestamp(), event.resendingPluginId(), source)); + return adoptRefWillBeNoop(new GestureEvent(eventType, view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.getModifiers(), deltaX, deltaY, velocityX, velocityY, inertial, synthetic, deltaUnits, event.timestamp(), event.resendingPluginId(), source)); } const AtomicString& GestureEvent::interfaceName() const @@ -109,18 +120,22 @@ GestureEvent::GestureEvent() , m_velocityX(0) , m_velocityY(0) , m_inertial(false) + , m_synthetic(false) + , m_deltaUnits(ScrollGranularity::ScrollByPrecisePixel) , m_source(GestureSourceUninitialized) , m_resendingPluginId(-1) { } -GestureEvent::GestureEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, PlatformEvent::Modifiers modifiers, float deltaX, float deltaY, float velocityX, float velocityY, bool inertial, double platformTimeStamp, int resendingPluginId, GestureSource source) +GestureEvent::GestureEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, PlatformEvent::Modifiers modifiers, float deltaX, float deltaY, float velocityX, float velocityY, bool inertial, bool synthetic, ScrollGranularity deltaUnits, double platformTimeStamp, int resendingPluginId, GestureSource source) : MouseRelatedEvent(type, true, true, nullptr, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY), IntPoint(0, 0), modifiers, platformTimeStamp, PositionType::Position) , m_deltaX(deltaX) , m_deltaY(deltaY) , m_velocityX(velocityX) , m_velocityY(velocityY) , m_inertial(inertial) + , m_synthetic(synthetic) + , m_deltaUnits(deltaUnits) , m_source(source) , m_resendingPluginId(resendingPluginId) { diff --git a/third_party/WebKit/Source/core/events/GestureEvent.h b/third_party/WebKit/Source/core/events/GestureEvent.h index 0f8c06c..46ea208 100644 --- a/third_party/WebKit/Source/core/events/GestureEvent.h +++ b/third_party/WebKit/Source/core/events/GestureEvent.h @@ -57,19 +57,22 @@ public: GestureSource source() const { return m_source; } int resendingPluginId() const { return m_resendingPluginId; } + bool synthetic() const { return m_synthetic; } + ScrollGranularity deltaUnits() const { return m_deltaUnits; } DECLARE_VIRTUAL_TRACE(); private: GestureEvent(); - GestureEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, PlatformEvent::Modifiers, float deltaX, float deltaY, float velocityX, float velocityY, bool inertial, double platformTimeStamp, int resendingPluginId, GestureSource); + GestureEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, PlatformEvent::Modifiers, float deltaX, float deltaY, float velocityX, float velocityY, bool inertial, bool synthetic, ScrollGranularity deltaUnits, double platformTimeStamp, int resendingPluginId, GestureSource); float m_deltaX; float m_deltaY; float m_velocityX; float m_velocityY; bool m_inertial; - + bool m_synthetic; + ScrollGranularity m_deltaUnits; GestureSource m_source; int m_resendingPluginId; }; diff --git a/third_party/WebKit/Source/platform/PlatformGestureEvent.h b/third_party/WebKit/Source/platform/PlatformGestureEvent.h index 350fe9e..86ec241 100644 --- a/third_party/WebKit/Source/platform/PlatformGestureEvent.h +++ b/third_party/WebKit/Source/platform/PlatformGestureEvent.h @@ -99,19 +99,19 @@ public: float deltaX() const { - ASSERT(m_type == PlatformEvent::GestureScrollUpdate); + ASSERT(m_type == PlatformEvent::GestureScrollBegin || m_type == PlatformEvent::GestureScrollUpdate); return m_data.m_scroll.m_deltaX; } float deltaY() const { - ASSERT(m_type == PlatformEvent::GestureScrollUpdate); + ASSERT(m_type == PlatformEvent::GestureScrollBegin || m_type == PlatformEvent::GestureScrollUpdate); return m_data.m_scroll.m_deltaY; } ScrollGranularity deltaUnits() const { - ASSERT(m_type == PlatformEvent::GestureScrollUpdate); + ASSERT(m_type == PlatformEvent::GestureScrollBegin || m_type == PlatformEvent::GestureScrollUpdate || m_type == PlatformEvent::GestureScrollEnd); return m_data.m_scroll.m_deltaUnits; } @@ -135,10 +135,16 @@ public: bool inertial() const { - ASSERT(m_type == PlatformEvent::GestureScrollUpdate || m_type == PlatformEvent::GestureScrollEnd); + ASSERT(m_type == PlatformEvent::GestureScrollBegin || m_type == PlatformEvent::GestureScrollUpdate || m_type == PlatformEvent::GestureScrollEnd); return m_data.m_scroll.m_inertial; } + bool synthetic() const + { + ASSERT(m_type == PlatformEvent::GestureScrollBegin || m_type == PlatformEvent::GestureScrollEnd); + return m_data.m_scroll.m_synthetic; + } + int resendingPluginId() const { if (m_type == PlatformEvent::GestureScrollUpdate @@ -214,6 +220,8 @@ protected: } m_tap; struct { + // |m_deltaX| and |m_deltaY| represent deltas in GSU but + // are only hints in GSB. float m_deltaX; float m_deltaY; float m_velocityX; @@ -222,6 +230,7 @@ protected: bool m_inertial; ScrollGranularity m_deltaUnits; int m_resendingPluginId; + bool m_synthetic; } m_scroll; struct { diff --git a/third_party/WebKit/Source/web/WebInputEventConversion.cpp b/third_party/WebKit/Source/web/WebInputEventConversion.cpp index 946fd9d..58d1c02 100644 --- a/third_party/WebKit/Source/web/WebInputEventConversion.cpp +++ b/third_party/WebKit/Source/web/WebInputEventConversion.cpp @@ -49,7 +49,8 @@ namespace blink { -static float scaleDeltaToWindow(const Widget* widget, float delta) +namespace { +float scaleDeltaToWindow(const Widget* widget, float delta) { float scale = 1; if (widget) { @@ -60,7 +61,7 @@ static float scaleDeltaToWindow(const Widget* widget, float delta) return delta / scale; } -static FloatSize scaleSizeToWindow(const Widget* widget, FloatSize size) +FloatSize scaleSizeToWindow(const Widget* widget, FloatSize size) { return FloatSize(scaleDeltaToWindow(widget, size.width()), scaleDeltaToWindow(widget, size.height())); } @@ -70,7 +71,7 @@ static FloatSize scaleSizeToWindow(const Widget* widget, FloatSize size) // in the root layer (see updateRootLayerTransform in WebViewImpl) as well as the overscroll effect on OSX. // This is in addition to the visual viewport "pinch-zoom" transformation and is one of the few cases where // the visual viewport is not equal to the renderer's coordinate-space. -static FloatPoint convertHitPointToRootFrame(const Widget* widget, FloatPoint pointInRendererViewport) +FloatPoint convertHitPointToRootFrame(const Widget* widget, FloatPoint pointInRendererViewport) { float scale = 1; IntSize offset; @@ -90,7 +91,7 @@ static FloatPoint convertHitPointToRootFrame(const Widget* widget, FloatPoint po (pointInRendererViewport.y() - offset.height()) / scale + visualViewport.y() + overscrollOffset.height()); } -static unsigned toPlatformModifierFrom(WebMouseEvent::Button button) +unsigned toPlatformModifierFrom(WebMouseEvent::Button button) { if (button == WebMouseEvent::ButtonNone) return 0; @@ -104,6 +105,38 @@ static unsigned toPlatformModifierFrom(WebMouseEvent::Button button) return webMouseButtonToPlatformModifier[button]; } +ScrollGranularity toPlatformScrollGranularity(WebGestureEvent::ScrollUnits units) +{ + switch (units) { + case WebGestureEvent::ScrollUnits::PrecisePixels: + return ScrollGranularity::ScrollByPrecisePixel; + case WebGestureEvent::ScrollUnits::Pixels: + return ScrollGranularity::ScrollByPixel; + case WebGestureEvent::ScrollUnits::Page: + return ScrollGranularity::ScrollByPage; + default: + ASSERT_NOT_REACHED(); + return ScrollGranularity::ScrollByPrecisePixel; + } +} + +WebGestureEvent::ScrollUnits toWebGestureScrollUnits(ScrollGranularity granularity) +{ + switch (granularity) { + case ScrollGranularity::ScrollByPrecisePixel: + return WebGestureEvent::ScrollUnits::PrecisePixels; + case ScrollGranularity::ScrollByPixel: + return WebGestureEvent::ScrollUnits::Pixels; + case ScrollGranularity::ScrollByPage: + return WebGestureEvent::ScrollUnits::Page; + default: + ASSERT_NOT_REACHED(); + return WebGestureEvent::ScrollUnits::PrecisePixels; + } +} + +} // namespace + // MakePlatformMouseEvent ----------------------------------------------------- // TODO(mustaq): Add tests for this. @@ -185,10 +218,18 @@ PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const W case WebInputEvent::GestureScrollBegin: m_type = PlatformEvent::GestureScrollBegin; m_data.m_scroll.m_resendingPluginId = e.resendingPluginId; + m_data.m_scroll.m_deltaX = e.data.scrollBegin.deltaXHint; + m_data.m_scroll.m_deltaY = e.data.scrollBegin.deltaYHint; + m_data.m_scroll.m_deltaUnits = toPlatformScrollGranularity(e.data.scrollBegin.deltaHintUnits); + m_data.m_scroll.m_inertial = e.data.scrollBegin.inertial; + m_data.m_scroll.m_synthetic = e.data.scrollBegin.synthetic; break; case WebInputEvent::GestureScrollEnd: m_type = PlatformEvent::GestureScrollEnd; m_data.m_scroll.m_resendingPluginId = e.resendingPluginId; + m_data.m_scroll.m_deltaUnits = toPlatformScrollGranularity(e.data.scrollEnd.deltaUnits); + m_data.m_scroll.m_inertial = e.data.scrollEnd.inertial; + m_data.m_scroll.m_synthetic = e.data.scrollEnd.synthetic; break; case WebInputEvent::GestureFlingStart: m_type = PlatformEvent::GestureFlingStart; @@ -204,19 +245,7 @@ PlatformGestureEventBuilder::PlatformGestureEventBuilder(Widget* widget, const W m_data.m_scroll.m_velocityY = e.data.scrollUpdate.velocityY; m_data.m_scroll.m_preventPropagation = e.data.scrollUpdate.preventPropagation; m_data.m_scroll.m_inertial = e.data.scrollUpdate.inertial; - switch (e.data.scrollUpdate.deltaUnits) { - case WebGestureEvent::ScrollUnits::PrecisePixels: - m_data.m_scroll.m_deltaUnits = ScrollGranularity::ScrollByPrecisePixel; - break; - case WebGestureEvent::ScrollUnits::Pixels: - m_data.m_scroll.m_deltaUnits = ScrollGranularity::ScrollByPixel; - break; - case WebGestureEvent::ScrollUnits::Page: - m_data.m_scroll.m_deltaUnits = ScrollGranularity::ScrollByPage; - break; - default: - ASSERT_NOT_REACHED(); - } + m_data.m_scroll.m_deltaUnits = toPlatformScrollGranularity(e.data.scrollUpdate.deltaUnits); break; case WebInputEvent::GestureTap: m_type = PlatformEvent::GestureTap; @@ -712,11 +741,20 @@ WebGestureEventBuilder::WebGestureEventBuilder(const LayoutObject* layoutObject, } else if (event.type() == EventTypeNames::gesturescrollstart) { type = GestureScrollBegin; resendingPluginId = event.resendingPluginId(); + data.scrollBegin.deltaXHint = event.deltaX(); + data.scrollBegin.deltaYHint = event.deltaY(); + data.scrollBegin.deltaHintUnits = toWebGestureScrollUnits(event.deltaUnits()); + data.scrollBegin.inertial = event.inertial(); + data.scrollBegin.synthetic = event.synthetic(); } else if (event.type() == EventTypeNames::gesturescrollend) { type = GestureScrollEnd; resendingPluginId = event.resendingPluginId(); + data.scrollEnd.deltaUnits = toWebGestureScrollUnits(event.deltaUnits()); + data.scrollEnd.inertial = event.inertial(); + data.scrollEnd.synthetic = event.synthetic(); } else if (event.type() == EventTypeNames::gesturescrollupdate) { type = GestureScrollUpdate; + data.scrollUpdate.deltaUnits = toWebGestureScrollUnits(event.deltaUnits()); data.scrollUpdate.deltaX = event.deltaX(); data.scrollUpdate.deltaY = event.deltaY(); data.scrollUpdate.inertial = event.inertial(); diff --git a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp index b852d84..5c38d5b 100644 --- a/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebInputEventConversionTest.cpp @@ -993,4 +993,74 @@ TEST(WebInputEventConversionTest, PlatformWheelEventBuilder) } } +TEST(WebInputEventConversionTest, PlatformGestureEventBuilder) +{ + const std::string baseURL("http://www.test8.com/"); + const std::string fileName("fixed_layout.html"); + + URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("fixed_layout.html")); + FrameTestHelpers::WebViewHelper webViewHelper; + WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(baseURL + fileName, true); + int pageWidth = 640; + int pageHeight = 480; + webViewImpl->resize(WebSize(pageWidth, pageHeight)); + webViewImpl->updateAllLifecyclePhases(); + + FrameView* view = toLocalFrame(webViewImpl->page()->mainFrame())->view(); + + { + WebGestureEvent webGestureEvent; + webGestureEvent.type = WebInputEvent::GestureScrollBegin; + webGestureEvent.x = 0; + webGestureEvent.y = 5; + webGestureEvent.globalX = 10; + webGestureEvent.globalY = 15; + webGestureEvent.sourceDevice = WebGestureDeviceTouchpad; + webGestureEvent.resendingPluginId = 2; + webGestureEvent.data.scrollBegin.inertial = true; + webGestureEvent.data.scrollBegin.synthetic = true; + webGestureEvent.data.scrollBegin.deltaXHint = 100; + webGestureEvent.data.scrollBegin.deltaYHint = 10; + webGestureEvent.data.scrollBegin.deltaHintUnits = WebGestureEvent::Pixels; + + PlatformGestureEventBuilder platformGestureBuilder(view, webGestureEvent); + EXPECT_EQ(PlatformGestureSourceTouchpad, platformGestureBuilder.source()); + EXPECT_EQ(2, platformGestureBuilder.resendingPluginId()); + EXPECT_EQ(0, platformGestureBuilder.position().x()); + EXPECT_EQ(5, platformGestureBuilder.position().y()); + EXPECT_EQ(10, platformGestureBuilder.globalPosition().x()); + EXPECT_EQ(15, platformGestureBuilder.globalPosition().y()); + EXPECT_TRUE(platformGestureBuilder.inertial()); + EXPECT_TRUE(platformGestureBuilder.synthetic()); + EXPECT_EQ(100, platformGestureBuilder.deltaX()); + EXPECT_EQ(10, platformGestureBuilder.deltaY()); + EXPECT_EQ(ScrollGranularity::ScrollByPixel, platformGestureBuilder.deltaUnits()); + } + + { + WebGestureEvent webGestureEvent; + webGestureEvent.type = WebInputEvent::GestureScrollEnd; + webGestureEvent.x = 0; + webGestureEvent.y = 5; + webGestureEvent.globalX = 10; + webGestureEvent.globalY = 15; + webGestureEvent.sourceDevice = WebGestureDeviceTouchpad; + webGestureEvent.resendingPluginId = 2; + webGestureEvent.data.scrollEnd.inertial = false; + webGestureEvent.data.scrollEnd.synthetic = true; + webGestureEvent.data.scrollEnd.deltaUnits = WebGestureEvent::Page; + + PlatformGestureEventBuilder platformGestureBuilder(view, webGestureEvent); + EXPECT_EQ(PlatformGestureSourceTouchpad, platformGestureBuilder.source()); + EXPECT_EQ(2, platformGestureBuilder.resendingPluginId()); + EXPECT_EQ(0, platformGestureBuilder.position().x()); + EXPECT_EQ(5, platformGestureBuilder.position().y()); + EXPECT_EQ(10, platformGestureBuilder.globalPosition().x()); + EXPECT_EQ(15, platformGestureBuilder.globalPosition().y()); + EXPECT_FALSE(platformGestureBuilder.inertial()); + EXPECT_TRUE(platformGestureBuilder.synthetic()); + EXPECT_EQ(ScrollGranularity::ScrollByPage, platformGestureBuilder.deltaUnits()); + } +} + } // namespace blink |
