summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-10-24 16:30:31 +0200
committerLiang Qi <liang.qi@qt.io>2017-10-27 06:52:08 +0000
commit4267567f5366b237c763d1b93cd09501a483a070 (patch)
tree06ac8607b5bcfabf94d7270209596b7120563110 /src
parent684cfe05641ba9f3abc7e128d9dab5b331ef0689 (diff)
Coalesce wheel events when possible
Combine wheel events if we are getting more than Chromium can handle. This improves latency and perceived performance when scrolling with touchpads or fine-grained mouse, on a slow machine or with a debug build. Change-Id: Id847c8e7782e155c28067b6051ce92896b68ca7a Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/core/render_widget_host_view_qt.cpp24
-rw-r--r--src/core/render_widget_host_view_qt.h4
-rw-r--r--src/core/web_event_factory.cpp48
-rw-r--r--src/core/web_event_factory.h1
4 files changed, 61 insertions, 16 deletions
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index d1fc7d171..a45383946 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 59e21b853..4b7f9094e 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 18f8d393f..c31de19a2 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 259795c1f..5758af848 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*);
};