diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index d1fc7d17114e229ad1653f2bb99233b469c1ef18..a45383946f22ecf06a46c1e06f8cd1d0b7c5d4da 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -282,6 +282,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget , m_cursorPositionWithinSelection(-1) , m_cursorPosition(0) , m_emptyPreviousSelection(true) + , m_wheelAckPending(false) { m_host->SetView(this); #ifndef QT_NO_ACCESSIBILITY @@ -1350,7 +1351,28 @@ void RenderWidgetHostViewQt::accessibilityActiveChanged(bool active) void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev) { - m_host->ForwardWheelEvent(WebEventFactory::toWebWheelEvent(ev, dpiScale())); + if (!m_wheelAckPending) { + Q_ASSERT(m_pendingWheelEvents.isEmpty()); + m_wheelAckPending = true; + m_host->ForwardWheelEvent(WebEventFactory::toWebWheelEvent(ev, dpiScale())); + return; + } + if (!m_pendingWheelEvents.isEmpty()) { + // Try to combine with this wheel event with the last pending one. + if (WebEventFactory::coalesceWebWheelEvent(m_pendingWheelEvents.last(), ev, dpiScale())) + return; + } + m_pendingWheelEvents.append(WebEventFactory::toWebWheelEvent(ev, dpiScale())); +} + +void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &/*event*/, content::InputEventAckState /*ack_result*/) +{ + m_wheelAckPending = false; + if (!m_pendingWheelEvents.isEmpty()) { + m_wheelAckPending = true; + m_host->ForwardWheelEvent(m_pendingWheelEvents.takeFirst()); + } + // TODO: We could forward unhandled wheelevents to our parent. } void RenderWidgetHostViewQt::clearPreviousTouchMotionState() diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 59e21b853932d372c97a90d4170e9ea4ee6de3a6..4b7f9094e44b14417890fcd2a3f830b29fbc3f7d 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -152,6 +152,7 @@ public: bool HasAcceleratedSurface(const gfx::Size&) override; void DidCreateNewRendererCompositorFrameSink(cc::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) override; void SubmitCompositorFrame(const viz::LocalSurfaceId&, cc::CompositorFrame) override; + void WheelEventAck(const blink::WebMouseWheelEvent &event, content::InputEventAckState ack_result) override; void GetScreenInfo(content::ScreenInfo* results); gfx::Rect GetBoundsInRootWindow() override; @@ -270,6 +271,9 @@ private: QString m_surroundingText; bool m_imeHasHiddenTextCapability; + + bool m_wheelAckPending; + QList<blink::WebMouseWheelEvent> m_pendingWheelEvents; }; } // namespace QtWebEngineCore diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 18f8d393f0d76d057f65ce3610fdd8898b28558d..c31de19a287cbd686c93251480349f35a4b008c5 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -1247,38 +1247,56 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, doub } #endif -blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, double dpiScale) +static void setBlinkWheelEventDelta(blink::WebMouseWheelEvent &webEvent) { - WebMouseWheelEvent webEvent; - webEvent.delta_x = 0; - webEvent.delta_y = 0; - webEvent.wheel_ticks_x = 0; - webEvent.wheel_ticks_y = 0; - webEvent.SetType(webEventTypeForEvent(ev)); - webEvent.SetModifiers(modifiersForEvent(ev)); - webEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); - - webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; - webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; - // We can't use the device specific QWheelEvent::pixelDelta(), so we calculate // a pixel delta based on ticks and scroll per line. static const float cDefaultQtScrollStep = 20.f; #if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) - const int wheelScrollLines = QGuiApplication::styleHints()->wheelScrollLines(); + static const int wheelScrollLines = QGuiApplication::styleHints()->wheelScrollLines(); #else - const int wheelScrollLines = 3; + static const int wheelScrollLines = 3; #endif webEvent.delta_x = webEvent.wheel_ticks_x * wheelScrollLines * cDefaultQtScrollStep; webEvent.delta_y = webEvent.wheel_ticks_y * wheelScrollLines * cDefaultQtScrollStep; +} + +blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, double dpiScale) +{ + WebMouseWheelEvent webEvent; + webEvent.SetType(webEventTypeForEvent(ev)); + webEvent.SetModifiers(modifiersForEvent(ev)); + webEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale); webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); + webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; + setBlinkWheelEventDelta(webEvent); + return webEvent; } +bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent, QWheelEvent *ev, double dpiScale) +{ + if (webEventTypeForEvent(ev) != webEvent.GetType()) + return false; + if (modifiersForEvent(ev) != webEvent.GetModifiers()) + return false; + + webEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale); + webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); + + webEvent.wheel_ticks_x += static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_y += static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; + setBlinkWheelEventDelta(webEvent); + + return true; +} + content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *ev) { content::NativeWebKeyboardEvent webKitEvent(reinterpret_cast<gfx::NativeEvent>(ev)); diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h index 259795c1f5d4abb8aea847a61f9c6f826fe1c1b1..5758af848109469bd6ed1400bfa26fec91b79da5 100644 --- a/src/core/web_event_factory.h +++ b/src/core/web_event_factory.h @@ -68,6 +68,7 @@ public: static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *, double dpiScale); #endif static blink::WebMouseWheelEvent toWebWheelEvent(QWheelEvent*, double dpiScale); + static bool coalesceWebWheelEvent(blink::WebMouseWheelEvent &, QWheelEvent*, double dpiScale); static content::NativeWebKeyboardEvent toWebKeyboardEvent(QKeyEvent*); };