summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Klokkahmmer Helsing <johan.helsing@qt.io>2016-09-29 14:59:56 +0200
committerJohan Helsing <johan.helsing@qt.io>2016-10-03 13:49:53 +0000
commit7e5af3d2903e25404422b705837408ccd89c74b9 (patch)
treee453dac6b2265778f836026d202778e08195806e
parentdb9f2fc90ad1ae302846fa23d4955a8c07c444b7 (diff)
Compositor: Send touch events to the surface pressed
This changes the API so that QWaylandTouch does not make assumptions about touch focus, and consequently enables writing compositors where multiple clients can receive touch input at the same time. Task-number: QTBUG-56237 Change-Id: I21fe6d9b5ac65e9f910f64cc4a02824119571c52 Reviewed-by: Nedim Hadzic <nedim.hadzic@pelagicore.com> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp25
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.h1
-rw-r--r--src/compositor/compositor_api/qwaylandseat.cpp31
-rw-r--r--src/compositor/compositor_api/qwaylandseat.h8
-rw-r--r--src/compositor/compositor_api/qwaylandtouch.cpp100
-rw-r--r--src/compositor/compositor_api/qwaylandtouch.h13
-rw-r--r--src/compositor/compositor_api/qwaylandtouch_p.h23
-rw-r--r--src/compositor/extensions/qwlqttouch.cpp4
-rw-r--r--src/compositor/extensions/qwlqttouch_p.h2
9 files changed, 57 insertions, 150 deletions
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
index f41a4c3ee..3e8d4b136 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
@@ -638,18 +638,6 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event)
if (d->shouldSendInputEvents() && d->touchEventsEnabled) {
QWaylandSeat *seat = compositor()->seatFor(event);
- if (event->type() == QEvent::TouchBegin) {
- QQuickItem *grabber = window()->mouseGrabberItem();
- if (grabber != this)
- grabMouse();
- }
-
- if (event->type() == QEvent::TouchEnd) {
- QQuickItem *grabber = window()->mouseGrabberItem();
- if (grabber == this)
- ungrabMouse();
- }
-
QPoint pointPos;
const QList<QTouchEvent::TouchPoint> &points = event->touchPoints();
if (!points.isEmpty())
@@ -664,23 +652,12 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event)
if (seat->mouseFocus() != d->view.data()) {
seat->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos));
}
- seat->sendFullTouchEvent(event);
+ seat->sendFullTouchEvent(surface(), event);
} else {
event->ignore();
}
}
-/*!
- * \internal
- */
-void QWaylandQuickItem::mouseUngrabEvent()
-{
- if (surface()) {
- QTouchEvent e(QEvent::TouchCancel);
- touchEvent(&e);
- }
-}
-
#ifndef QT_NO_IM
/*!
* \internal
diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h
index 5c89d58b4..2a226f5d4 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.h
+++ b/src/compositor/compositor_api/qwaylandquickitem.h
@@ -132,7 +132,6 @@ protected:
void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE;
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
#ifndef QT_NO_IM
void inputMethodEvent(QInputMethodEvent *event) Q_DECL_OVERRIDE;
diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp
index 017cc89cc..d096dff79 100644
--- a/src/compositor/compositor_api/qwaylandseat.cpp
+++ b/src/compositor/compositor_api/qwaylandseat.cpp
@@ -262,52 +262,47 @@ void QWaylandSeat::sendKeyReleaseEvent(uint code)
*
* Returns the serial for the touch up or touch down event.
*/
-uint QWaylandSeat::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state)
+uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &point, Qt::TouchPointState state)
{
Q_D(QWaylandSeat);
- if (d->touch.isNull()) {
+
+ if (d->touch.isNull())
return 0;
- }
- return d->touch->sendTouchPointEvent(id, point,state);
+
+ return d->touch->sendTouchPointEvent(surface, id, point,state);
}
/*!
* Sends a frame event to the touch device.
*/
-void QWaylandSeat::sendTouchFrameEvent()
+void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
{
Q_D(QWaylandSeat);
- if (!d->touch.isNull()) {
- d->touch->sendFrameEvent();
- }
+ if (!d->touch.isNull())
+ d->touch->sendFrameEvent(client);
}
/*!
* Sends a cancel event to the touch device.
*/
-void QWaylandSeat::sendTouchCancelEvent()
+void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
{
Q_D(QWaylandSeat);
- if (!d->touch.isNull()) {
- d->touch->sendCancelEvent();
- }
+ if (!d->touch.isNull())
+ d->touch->sendCancelEvent(client);
}
/*!
* Sends the \a event to the touch device.
*/
-void QWaylandSeat::sendFullTouchEvent(QTouchEvent *event)
+void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
{
Q_D(QWaylandSeat);
- if (!mouseFocus()) {
- qWarning("Cannot send touch event, no pointer focus, fix the compositor");
- return;
- }
if (!d->touch)
return;
- d->touch->sendFullTouchEvent(event);
+ d->touch->sendFullTouchEvent(surface, event);
}
/*!
diff --git a/src/compositor/compositor_api/qwaylandseat.h b/src/compositor/compositor_api/qwaylandseat.h
index d6ea276f4..3e90342c7 100644
--- a/src/compositor/compositor_api/qwaylandseat.h
+++ b/src/compositor/compositor_api/qwaylandseat.h
@@ -94,11 +94,11 @@ public:
void sendFullKeyEvent(QKeyEvent *event);
void sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event);
- uint sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state);
- void sendTouchFrameEvent();
- void sendTouchCancelEvent();
+ uint sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &point, Qt::TouchPointState state);
+ void sendTouchFrameEvent(QWaylandClient *client);
+ void sendTouchCancelEvent(QWaylandClient *client);
- void sendFullTouchEvent(QTouchEvent *event);
+ void sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event);
QWaylandPointer *pointer() const;
//Normally set by the mouse device,
diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp
index 2caa06bee..9e354605b 100644
--- a/src/compositor/compositor_api/qwaylandtouch.cpp
+++ b/src/compositor/compositor_api/qwaylandtouch.cpp
@@ -49,49 +49,33 @@ QT_BEGIN_NAMESPACE
QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandSeat *seat)
: wl_touch()
, seat(seat)
- , focusResource()
{
Q_UNUSED(touch);
}
-void QWaylandTouchPrivate::resetFocusState()
-{
- focusDestroyListener.reset();
- focusResource = 0;
-}
-
-void QWaylandTouchPrivate::touch_bind_resource(Resource *resource)
-{
- focusResource = resource;
-}
-
-void QWaylandTouchPrivate::touch_destroy_resource(Resource *resource)
-{
- if (focusResource == resource) {
- resetFocusState();
- }
-}
-
void QWaylandTouchPrivate::touch_release(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
-uint QWaylandTouchPrivate::sendDown(uint32_t time, int touch_id, const QPointF &position)
+uint QWaylandTouchPrivate::sendDown(QWaylandSurface *surface, uint32_t time, int touch_id, const QPointF &position)
{
Q_Q(QWaylandTouch);
- if (!focusResource || !seat->mouseFocus())
+ auto focusResource = resourceMap().value(surface->client()->client());
+ if (!focusResource)
return 0;
uint32_t serial = q->compositor()->nextSerial();
- wl_touch_send_down(focusResource->handle, serial, time, seat->mouseFocus()->surfaceResource(), touch_id,
+ wl_touch_send_down(focusResource->handle, serial, time, surface->resource(), touch_id,
wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
return serial;
}
-uint QWaylandTouchPrivate::sendUp(uint32_t time, int touch_id)
+uint QWaylandTouchPrivate::sendUp(QWaylandClient *client, uint32_t time, int touch_id)
{
+ auto focusResource = resourceMap().value(client->client());
+
if (!focusResource)
return 0;
@@ -100,8 +84,11 @@ uint QWaylandTouchPrivate::sendUp(uint32_t time, int touch_id)
wl_touch_send_up(focusResource->handle, serial, time, touch_id);
return serial;
}
-void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF &position)
+
+void QWaylandTouchPrivate::sendMotion(QWaylandClient *client, uint32_t time, int touch_id, const QPointF &position)
{
+ auto focusResource = resourceMap().value(client->client());
+
if (!focusResource)
return;
@@ -125,7 +112,6 @@ void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF
QWaylandTouch::QWaylandTouch(QWaylandSeat *seat, QObject *parent)
: QWaylandObject(*new QWaylandTouchPrivate(this, seat), parent)
{
- connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandTouch::focusDestroyed);
}
/*!
@@ -152,20 +138,20 @@ QWaylandCompositor *QWaylandTouch::compositor() const
*
* Returns the serial of the down or up event if sent, otherwise 0.
*/
-uint QWaylandTouch::sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state)
+uint QWaylandTouch::sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &position, Qt::TouchPointState state)
{
Q_D(QWaylandTouch);
uint32_t time = compositor()->currentTimeMsecs();
uint serial = 0;
switch (state) {
case Qt::TouchPointPressed:
- serial = d->sendDown(time, id, position);
+ serial = d->sendDown(surface, time, id, position);
break;
case Qt::TouchPointMoved:
- d->sendMotion(time, id, position);
+ d->sendMotion(surface->client(), time, id, position);
break;
case Qt::TouchPointReleased:
- serial = d->sendUp(time, id);
+ serial = d->sendUp(surface->client(), time, id);
break;
case Qt::TouchPointStationary:
// stationary points are not sent through wayland, the client must cache them
@@ -179,21 +165,23 @@ uint QWaylandTouch::sendTouchPointEvent(int id, const QPointF &position, Qt::Tou
* Sends a touch frame event for the touch device. This indicates the end of a
* contact point list.
*/
-void QWaylandTouch::sendFrameEvent()
+void QWaylandTouch::sendFrameEvent(QWaylandClient *client)
{
Q_D(QWaylandTouch);
- if (d->focusResource)
- d->send_frame(d->focusResource->handle);
+ auto focusResource = d->resourceMap().value(client->client());
+ if (focusResource)
+ d->send_frame(focusResource->handle);
}
/*!
* Sends a touch cancel event for the touch device.
*/
-void QWaylandTouch::sendCancelEvent()
+void QWaylandTouch::sendCancelEvent(QWaylandClient *client)
{
Q_D(QWaylandTouch);
- if (d->focusResource)
- d->send_cancel(d->focusResource->handle);
+ auto focusResource = d->resourceMap().value(client->client());
+ if (focusResource)
+ d->send_cancel(focusResource->handle);
}
/*!
@@ -202,16 +190,16 @@ void QWaylandTouch::sendCancelEvent()
*
* \sa sendTouchPointEvent(), sendFrameEvent()
*/
-void QWaylandTouch::sendFullTouchEvent(QTouchEvent *event)
+void QWaylandTouch::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
{
Q_D(QWaylandTouch);
if (event->type() == QEvent::TouchCancel) {
- sendCancelEvent();
+ sendCancelEvent(surface->client());
return;
}
QtWayland::TouchExtensionGlobal *ext = QtWayland::TouchExtensionGlobal::findIn(d->compositor());
- if (ext && ext->postTouchEvent(event, d->seat->mouseFocus()))
+ if (ext && ext->postTouchEvent(event, surface))
return;
const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
@@ -222,9 +210,9 @@ void QWaylandTouch::sendFullTouchEvent(QTouchEvent *event)
for (int i = 0; i < pointCount; ++i) {
const QTouchEvent::TouchPoint &tp(points.at(i));
// Convert the local pos in the compositor window to surface-relative.
- sendTouchPointEvent(tp.id(), tp.pos(), tp.state());
+ sendTouchPointEvent(surface, tp.id(), tp.pos(), tp.state());
}
- sendFrameEvent();
+ sendFrameEvent(surface->client());
}
/*!
@@ -236,36 +224,4 @@ void QWaylandTouch::addClient(QWaylandClient *client, uint32_t id, uint32_t vers
d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_touch::interfaceVersion(), version));
}
-/*!
- * Returns the Wayland resource for this QWaylandTouch.
- */
-struct wl_resource *QWaylandTouch::focusResource() const
-{
- Q_D(const QWaylandTouch);
- if (!d->focusResource)
- return Q_NULLPTR;
- return d->focusResource->handle;
-}
-
-/*!
- * \internal
- */
-void QWaylandTouch::focusDestroyed(void *data)
-{
- Q_UNUSED(data)
- Q_D(QWaylandTouch);
- d->resetFocusState();
-}
-
-/*!
- * \internal
- */
-void QWaylandTouch::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
-{
- Q_UNUSED(newFocus);
- Q_UNUSED(oldFocus);
- Q_D(QWaylandTouch);
- d->resetFocusState();
-}
-
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandtouch.h b/src/compositor/compositor_api/qwaylandtouch.h
index f539ce2cd..05ee5ad40 100644
--- a/src/compositor/compositor_api/qwaylandtouch.h
+++ b/src/compositor/compositor_api/qwaylandtouch.h
@@ -51,6 +51,7 @@ class QWaylandTouchPrivate;
class QWaylandSeat;
class QWaylandView;
class QWaylandClient;
+class QWaylandSurface;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouch : public QWaylandObject
{
@@ -62,19 +63,15 @@ public:
QWaylandSeat *seat() const;
QWaylandCompositor *compositor() const;
- virtual uint sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state);
- virtual void sendFrameEvent();
- virtual void sendCancelEvent();
-
- virtual void sendFullTouchEvent(QTouchEvent *event);
+ virtual uint sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &position, Qt::TouchPointState state);
+ virtual void sendFrameEvent(QWaylandClient *client);
+ virtual void sendCancelEvent(QWaylandClient *client);
+ virtual void sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event);
virtual void addClient(QWaylandClient *client, uint32_t id, uint32_t version);
- wl_resource *focusResource() const;
-
private:
void focusDestroyed(void *data);
- void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus);
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandtouch_p.h b/src/compositor/compositor_api/qwaylandtouch_p.h
index 35cd30502..75529134b 100644
--- a/src/compositor/compositor_api/qwaylandtouch_p.h
+++ b/src/compositor/compositor_api/qwaylandtouch_p.h
@@ -71,31 +71,14 @@ public:
QWaylandCompositor *compositor() const { return seat->compositor(); }
- uint sendDown(uint32_t time, int touch_id, const QPointF &position);
- void sendMotion(uint32_t time, int touch_id, const QPointF &position);
- uint sendUp(uint32_t time, int touch_id);
+ uint sendDown(QWaylandSurface *surface, uint32_t time, int touch_id, const QPointF &position);
+ void sendMotion(QWaylandClient *client, uint32_t time, int touch_id, const QPointF &position);
+ uint sendUp(QWaylandClient *client, uint32_t time, int touch_id);
- void setFocusResource()
- {
- if (focusResource)
- return;
-
- QWaylandView *mouseFocus = seat->mouseFocus();
- if (!mouseFocus || !mouseFocus->surface())
- return;
-
- focusResource = resourceMap().value(mouseFocus->surface()->waylandClient());
- }
private:
- void resetFocusState();
- void touch_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
- void touch_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
void touch_release(Resource *resource) Q_DECL_OVERRIDE;
QWaylandSeat *seat;
-
- Resource *focusResource;
- QWaylandDestroyListener focusDestroyListener;
};
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwlqttouch.cpp b/src/compositor/extensions/qwlqttouch.cpp
index 17246b397..0d1120a4e 100644
--- a/src/compositor/extensions/qwlqttouch.cpp
+++ b/src/compositor/extensions/qwlqttouch.cpp
@@ -64,14 +64,14 @@ static inline int toFixed(qreal f)
return int(f * 10000);
}
-bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandView *view)
+bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurface *surface)
{
const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
const int pointCount = points.count();
if (!pointCount)
return false;
- wl_client *surfaceClient = view->surface()->client()->client();
+ wl_client *surfaceClient = surface->client()->client();
uint32_t time = m_compositor->currentTimeMsecs();
const int rescount = m_resources.count();
diff --git a/src/compositor/extensions/qwlqttouch_p.h b/src/compositor/extensions/qwlqttouch_p.h
index 0b3f3acca..f3697aa83 100644
--- a/src/compositor/extensions/qwlqttouch_p.h
+++ b/src/compositor/extensions/qwlqttouch_p.h
@@ -77,7 +77,7 @@ public:
TouchExtensionGlobal(QWaylandCompositor *compositor);
~TouchExtensionGlobal();
- bool postTouchEvent(QTouchEvent *event, QWaylandView *view);
+ bool postTouchEvent(QTouchEvent *event, QWaylandSurface *surface);
void setBehviorFlags(BehaviorFlags flags);
BehaviorFlags behaviorFlags() const { return m_flags; }