summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/render_widget_host_view_qt.cpp103
-rw-r--r--src/core/render_widget_host_view_qt.h3
-rw-r--r--src/core/web_event_factory.cpp48
-rw-r--r--src/core/web_event_factory.h2
-rw-r--r--tests/manual/html/pointer-events.html69
5 files changed, 179 insertions, 46 deletions
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 9be5bd498..7ce71a81d 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -957,6 +957,12 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
case QEvent::TouchCancel:
handleTouchEvent(static_cast<QTouchEvent*>(event));
break;
+ case QEvent::TabletPress:
+ Focus(); // Fall through.
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ handleTabletEvent(static_cast<QTabletEvent*>(event));
+ break;
#ifndef QT_NO_GESTURES
case QEvent::NativeGesture:
handleGestureEvent(static_cast<QNativeGestureEvent *>(event));
@@ -1089,49 +1095,7 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event)
// transformation done by Chromium.
if (event->source() == Qt::MouseEventSynthesizedBySystem)
return;
-
- blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event, dpiScale());
- if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown || webEvent.GetType() == blink::WebInputEvent::kMouseUp)
- && webEvent.button == blink::WebMouseEvent::Button::kNoButton) {
- // Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down for no button.
- return;
- }
-
-
- if (event->type() == QMouseEvent::MouseButtonPress) {
- if (event->button() != m_clickHelper.lastPressButton
- || (event->timestamp() - m_clickHelper.lastPressTimestamp > static_cast<ulong>(qGuiApp->styleHints()->mouseDoubleClickInterval()))
- || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance())
- m_clickHelper.clickCounter = 0;
-
- m_clickHelper.lastPressTimestamp = event->timestamp();
- webEvent.click_count = ++m_clickHelper.clickCounter;
- m_clickHelper.lastPressButton = event->button();
- m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint();
- }
-
- webEvent.movement_x = event->globalX() - m_previousMousePosition.x();
- webEvent.movement_y = event->globalY() - m_previousMousePosition.y();
-
- if (IsMouseLocked())
- QCursor::setPos(m_previousMousePosition);
- else
- m_previousMousePosition = event->globalPos();
-
- if (m_imeInProgress && event->type() == QMouseEvent::MouseButtonPress) {
- m_imeInProgress = false;
- // Tell input method to commit the pre-edit string entered so far, and finish the
- // composition operation.
-#ifdef Q_OS_WIN
- // Yes the function name is counter-intuitive, but commit isn't actually implemented
- // by the Windows QPA, and reset does exactly what is necessary in this case.
- qApp->inputMethod()->reset();
-#else
- qApp->inputMethod()->commit();
-#endif
- }
-
- m_host->ForwardMouseEvent(webEvent);
+ handlePointerEvent<QMouseEvent>(event);
}
void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
@@ -1483,6 +1447,59 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
}
}
+void RenderWidgetHostViewQt::handleTabletEvent(QTabletEvent *event)
+{
+ handlePointerEvent<QTabletEvent>(event);
+}
+
+template<class T>
+void RenderWidgetHostViewQt::handlePointerEvent(T *event)
+{
+ // Currently WebMouseEvent is a subclass of WebPointerProperties, so basically
+ // tablet events are mouse events with extra properties.
+ blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event, dpiScale());
+ if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown || webEvent.GetType() == blink::WebInputEvent::kMouseUp)
+ && webEvent.button == blink::WebMouseEvent::Button::kNoButton) {
+ // Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down for no button.
+ return;
+ }
+
+ if (webEvent.GetType() == blink::WebInputEvent::kMouseDown) {
+ if (event->button() != m_clickHelper.lastPressButton
+ || (event->timestamp() - m_clickHelper.lastPressTimestamp > static_cast<ulong>(qGuiApp->styleHints()->mouseDoubleClickInterval()))
+ || (event->pos() - m_clickHelper.lastPressPosition).manhattanLength() > qGuiApp->styleHints()->startDragDistance())
+ m_clickHelper.clickCounter = 0;
+
+ m_clickHelper.lastPressTimestamp = event->timestamp();
+ webEvent.click_count = ++m_clickHelper.clickCounter;
+ m_clickHelper.lastPressButton = event->button();
+ m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint();
+ }
+
+ webEvent.movement_x = event->globalX() - m_previousMousePosition.x();
+ webEvent.movement_y = event->globalY() - m_previousMousePosition.y();
+
+ if (IsMouseLocked())
+ QCursor::setPos(m_previousMousePosition);
+ else
+ m_previousMousePosition = event->globalPos();
+
+ if (m_imeInProgress && webEvent.GetType() == blink::WebInputEvent::kMouseDown) {
+ m_imeInProgress = false;
+ // Tell input method to commit the pre-edit string entered so far, and finish the
+ // composition operation.
+#ifdef Q_OS_WIN
+ // Yes the function name is counter-intuitive, but commit isn't actually implemented
+ // by the Windows QPA, and reset does exactly what is necessary in this case.
+ qApp->inputMethod()->reset();
+#else
+ qApp->inputMethod()->commit();
+#endif
+ }
+
+ m_host->ForwardMouseEvent(webEvent);
+}
+
void RenderWidgetHostViewQt::handleHoverEvent(QHoverEvent *ev)
{
m_host->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(ev, dpiScale()));
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 7d32cc645..74f14d0d4 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -186,6 +186,7 @@ public:
void handleKeyEvent(QKeyEvent*);
void handleWheelEvent(QWheelEvent*);
void handleTouchEvent(QTouchEvent*);
+ void handleTabletEvent(QTabletEvent *ev);
#ifndef QT_NO_GESTURES
void handleGestureEvent(QNativeGestureEvent *);
#endif
@@ -194,6 +195,8 @@ public:
void handleInputMethodEvent(QInputMethodEvent*);
void handleInputMethodQueryEvent(QInputMethodQueryEvent*);
+ template<class T> void handlePointerEvent(T*);
+
#if defined(OS_MACOSX)
void SetActive(bool active) override { QT_NOT_YET_IMPLEMENTED }
bool IsSpeaking() const override { QT_NOT_YET_IMPLEMENTED; return false; }
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 18f8d393f..b785adec0 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -76,6 +76,7 @@
#include <QKeyEvent>
#include <QMouseEvent>
#include <QStyleHints>
+#include <QTabletEvent>
#include <QWheelEvent>
using namespace blink;
@@ -1032,7 +1033,8 @@ static inline double currentTimeForEvent(const QInputEvent* event)
return static_cast<double>(timer.elapsed()) / 1000;
}
-static WebMouseEvent::Button mouseButtonForEvent(QMouseEvent *event)
+template<class T>
+static WebMouseEvent::Button mouseButtonForEvent(T *event)
{
if (event->button() == Qt::LeftButton)
return WebMouseEvent::Button::kLeft;
@@ -1041,7 +1043,7 @@ static WebMouseEvent::Button mouseButtonForEvent(QMouseEvent *event)
else if (event->button() == Qt::MidButton)
return WebMouseEvent::Button::kMiddle;
- if (event->type() != QEvent::MouseMove)
+ if (event->type() != QEvent::MouseMove && event->type() != QEvent::TabletMove)
return WebMouseEvent::Button::kNoButton;
// This is technically wrong, mouse move should always have ButtonNone,
@@ -1147,14 +1149,17 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event)
{
switch (event->type()) {
case QEvent::MouseButtonPress:
+ case QEvent::TabletPress:
return WebInputEvent::kMouseDown;
case QEvent::MouseButtonRelease:
+ case QEvent::TabletRelease:
return WebInputEvent::kMouseUp;
case QEvent::Enter:
return WebInputEvent::kMouseEnter;
case QEvent::Leave:
return WebInputEvent::kMouseLeave;
case QEvent::MouseMove:
+ case QEvent::TabletMove:
return WebInputEvent::kMouseMove;
case QEvent::Wheel:
return WebInputEvent::kMouseWheel;
@@ -1178,6 +1183,20 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event)
}
}
+static WebPointerProperties::PointerType pointerTypeForTabletEvent(const QTabletEvent *ev)
+{
+ switch (ev->pointerType()) {
+ case QTabletEvent::UnknownPointer:
+ return WebPointerProperties::PointerType::kUnknown;
+ case QTabletEvent::Pen:
+ return WebPointerProperties::PointerType::kPen;
+ case QTabletEvent::Eraser:
+ return WebPointerProperties::PointerType::kEraser;
+ default:
+ return WebPointerProperties::PointerType::kMouse;
+ }
+}
+
WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
{
WebMouseEvent webKitEvent(webEventTypeForEvent(ev),
@@ -1188,7 +1207,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
modifiersForEvent(ev),
currentTimeForEvent(ev));
- webKitEvent.button = mouseButtonForEvent(ev);
+ webKitEvent.button = mouseButtonForEvent<QMouseEvent>(ev);
webKitEvent.click_count = 0;
return webKitEvent;
@@ -1208,6 +1227,29 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale)
return webKitEvent;
}
+WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev, double dpiScale)
+{
+ WebMouseEvent webKitEvent(webEventTypeForEvent(ev),
+ ev->x() / dpiScale,
+ ev->y() / dpiScale,
+ ev->globalX(),
+ ev->globalY(),
+ modifiersForEvent(ev),
+ currentTimeForEvent(ev));
+
+ webKitEvent.force = ev->pressure();
+ webKitEvent.tilt_x = ev->xTilt();
+ webKitEvent.tilt_y = ev->yTilt();
+ webKitEvent.tangential_pressure = ev->tangentialPressure();
+ webKitEvent.twist = ev->rotation();
+ webKitEvent.pointer_type = pointerTypeForTabletEvent(ev);
+
+ webKitEvent.button = mouseButtonForEvent<QTabletEvent>(ev);
+ webKitEvent.click_count = 0;
+
+ return webKitEvent;
+}
+
#ifndef QT_NO_GESTURES
WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, double dpiScale)
{
diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h
index 259795c1f..c9ae86a73 100644
--- a/src/core/web_event_factory.h
+++ b/src/core/web_event_factory.h
@@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE
class QHoverEvent;
class QKeyEvent;
class QMouseEvent;
+class QTabletEvent;
class QWheelEvent;
#ifndef QT_NO_GESTURES
class QNativeGestureEvent;
@@ -64,6 +65,7 @@ class WebEventFactory {
public:
static blink::WebMouseEvent toWebMouseEvent(QMouseEvent*, double dpiScale);
static blink::WebMouseEvent toWebMouseEvent(QHoverEvent*, double dpiScale);
+ static blink::WebMouseEvent toWebMouseEvent(QTabletEvent*, double dpiScale);
#ifndef QT_NO_GESTURES
static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *, double dpiScale);
#endif
diff --git a/tests/manual/html/pointer-events.html b/tests/manual/html/pointer-events.html
new file mode 100644
index 000000000..c6e728662
--- /dev/null
+++ b/tests/manual/html/pointer-events.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Pointer event test</title>
+ </head>
+ <body>
+
+<p>
+ <canvas id="listener" width="500" height="500" style="border: silver 1px dotted;"></canvas>
+</p>
+<p>
+ Touch this circle with a stylus. Its size indicates your pressure; its position is the angle between your stylus and your tablet device; and the radius is the rotation - if your tablet supports it.
+</p>
+
+ </body>
+ <script>
+
+var canvas = document.getElementById("listener");
+var context = canvas.getContext('2d');
+
+var eventName = [
+ "pointerover",
+ "pointerenter",
+ "pointerdown",
+ "pointermove",
+ "pointerup",
+ "pointercancel",
+ "pointerout",
+ "pointerleave",
+ "gotpointercapture",
+ "lostpointercapture"
+];
+
+for (var i = 0; i < eventName.length; i++) {
+ canvas.addEventListener(eventName[i], function(ev) {
+ drawCircle(ev.pressure, ev.tiltX, ev.tiltY, ev.twist);
+ }, false);
+}
+
+drawCircle(0, 0, 0, 0);
+
+function drawCircle(pressure, tiltX, tiltY, twist) {
+ var centerX = canvas.width / 2 + tiltX;
+ var centerY = canvas.height / 2 + tiltY;
+ var radius = 100 + 100 * pressure;
+
+ context.clearRect(0, 0, canvas.width, canvas.height);
+ context.beginPath();
+ context.arc(centerX,
+ centerY,
+ radius,
+ 0,
+ 2 * Math.PI,
+ false);
+ context.fillStyle = 'lightblue';
+ context.fill();
+ context.lineWidth = 3;
+ context.strokeStyle = '#008B8B';
+ context.stroke();
+
+ context.beginPath();
+ context.moveTo(centerX, centerY);
+ context.lineTo(centerX + radius * Math.cos(twist), centerY + radius * Math.sin(twist));
+ context.stroke();
+}
+
+</script>
+</html>