summaryrefslogtreecommitdiffstats
path: root/src/compositor
diff options
context:
space:
mode:
authorMikko Levonmaa <mikko.levonmaa@lge.com>2014-03-31 11:31:18 -0700
committerMikko Levonmaa <mikko.levonmaa@lge.com>2014-10-20 09:58:56 +0200
commit155aee0c513e88f83364ee932b344cfbee1f4986 (patch)
tree40da8e773c2f62d6dbbb676570392912677c6940 /src/compositor
parent0febf7c52f5cc4bc5c7767f7572ff87a5aa8a7af (diff)
Support for multiple input devices
Allows the registration of multiple input devices for the compositor via private APIs. Since the Qt stack does not support separate input devices via the QPA, the identification of each device (wl_seat) is left up to the implementor. The compositor will identify input event via the QWaylandInputDevice::isOwner method. Usually this will happen when an item on the UI has received an event and would like to send it to the client surface. See QWaylandSurfaceItem for more details. Includes basic unit tests Change-Id: I7ee1db49388713bf3076c23cf8f8a165aefc2fe0 Reviewed-by: Mikko Levonmaa <mikko.levonmaa@lge.com> Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp5
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.h4
-rw-r--r--src/compositor/compositor_api/qwaylandinput.cpp6
-rw-r--r--src/compositor/compositor_api/qwaylandinput.h3
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.cpp29
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.h3
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp43
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h14
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp6
9 files changed, 89 insertions, 24 deletions
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index 0891e8a9f..25ceb6e85 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -297,4 +297,9 @@ QWaylandSurfaceView *QWaylandCompositor::createView(QWaylandSurface *surface)
return new QWaylandSurfaceView(surface);
}
+QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent)
+{
+ return m_compositor->inputDeviceFor(inputEvent);
+}
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h
index 751fc420b..2c73a1d3e 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.h
+++ b/src/compositor/compositor_api/qwaylandcompositor.h
@@ -51,6 +51,8 @@ struct wl_display;
QT_BEGIN_NAMESPACE
+class QInputEvent;
+
class QMimeData;
class QUrl;
class QOpenGLContext;
@@ -149,6 +151,8 @@ public:
virtual QWaylandSurfaceView *createView(QWaylandSurface *surface);
+ QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent);
+
protected:
QWaylandCompositor(QWindow *window, const char *socketName, QtWayland::Compositor *dptr);
virtual void retainedSelectionReceived(QMimeData *mimeData);
diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp
index 97bbb23b3..76e365fb5 100644
--- a/src/compositor/compositor_api/qwaylandinput.cpp
+++ b/src/compositor/compositor_api/qwaylandinput.cpp
@@ -183,4 +183,10 @@ QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities()
return d->capabilities();
}
+bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent)
+{
+ Q_UNUSED(inputEvent);
+ return true;
+}
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandinput.h
index 2c0b9ee7c..209228b97 100644
--- a/src/compositor/compositor_api/qwaylandinput.h
+++ b/src/compositor/compositor_api/qwaylandinput.h
@@ -54,6 +54,7 @@ class QWaylandSurface;
class QKeyEvent;
class QTouchEvent;
class QWaylandSurfaceView;
+class QInputEvent;
namespace QtWayland {
class InputDevice;
@@ -125,6 +126,8 @@ public:
QWaylandInputDevice::CapabilityFlags capabilities();
+ virtual bool isOwner(QInputEvent *inputEvent);
+
private:
QtWayland::InputDevice *d;
Q_DISABLE_COPY(QWaylandInputDevice)
diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
index 254d45bbd..79afa3786 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
@@ -149,7 +149,7 @@ void QWaylandSurfaceItem::mousePressEvent(QMouseEvent *event)
return;
}
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
if (inputDevice->mouseFocus() != this)
inputDevice->setMouseFocus(this, event->localPos(), event->windowPos());
inputDevice->sendMousePressEvent(event->button(), event->localPos(), event->windowPos());
@@ -158,7 +158,7 @@ void QWaylandSurfaceItem::mousePressEvent(QMouseEvent *event)
void QWaylandSurfaceItem::mouseMoveEvent(QMouseEvent *event)
{
if (surface()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendMouseMoveEvent(this, event->localPos(), event->windowPos());
}
}
@@ -166,7 +166,7 @@ void QWaylandSurfaceItem::mouseMoveEvent(QMouseEvent *event)
void QWaylandSurfaceItem::mouseReleaseEvent(QMouseEvent *event)
{
if (surface()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendMouseReleaseEvent(event->button(), event->localPos(), event->windowPos());
}
}
@@ -174,7 +174,7 @@ void QWaylandSurfaceItem::mouseReleaseEvent(QMouseEvent *event)
void QWaylandSurfaceItem::hoverEnterEvent(QHoverEvent *event)
{
if (surface()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendMouseMoveEvent(this, event->pos());
}
}
@@ -182,7 +182,7 @@ void QWaylandSurfaceItem::hoverEnterEvent(QHoverEvent *event)
void QWaylandSurfaceItem::hoverMoveEvent(QHoverEvent *event)
{
if (surface()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendMouseMoveEvent(this, event->pos());
}
}
@@ -190,7 +190,7 @@ void QWaylandSurfaceItem::hoverMoveEvent(QHoverEvent *event)
void QWaylandSurfaceItem::hoverLeaveEvent(QHoverEvent *event)
{
if (surface()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendMouseMoveEvent(this, event->pos());
}
}
@@ -203,7 +203,7 @@ void QWaylandSurfaceItem::wheelEvent(QWheelEvent *event)
return;
}
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendMouseWheelEvent(event->orientation(), event->delta());
}
}
@@ -211,7 +211,7 @@ void QWaylandSurfaceItem::wheelEvent(QWheelEvent *event)
void QWaylandSurfaceItem::keyPressEvent(QKeyEvent *event)
{
if (surface()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendFullKeyEvent(event);
}
}
@@ -219,7 +219,7 @@ void QWaylandSurfaceItem::keyPressEvent(QKeyEvent *event)
void QWaylandSurfaceItem::keyReleaseEvent(QKeyEvent *event)
{
if (surface() && hasFocus()) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
inputDevice->sendFullKeyEvent(event);
}
}
@@ -227,7 +227,7 @@ void QWaylandSurfaceItem::keyReleaseEvent(QKeyEvent *event)
void QWaylandSurfaceItem::touchEvent(QTouchEvent *event)
{
if (m_touchEventsEnabled) {
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
+ QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
QPoint pointPos;
const QList<QTouchEvent::TouchPoint> &points = event->touchPoints();
@@ -249,15 +249,18 @@ void QWaylandSurfaceItem::touchEvent(QTouchEvent *event)
}
}
-void QWaylandSurfaceItem::takeFocus()
+void QWaylandSurfaceItem::takeFocus(QWaylandInputDevice *device)
{
setFocus(true);
if (!surface())
return;
- QWaylandInputDevice *inputDevice = compositor()->defaultInputDevice();
- inputDevice->setKeyboardFocus(surface());
+ QWaylandInputDevice *target = device;
+ if (!target) {
+ target = compositor()->defaultInputDevice();
+ }
+ target->setKeyboardFocus(surface());
}
void QWaylandSurfaceItem::surfaceMapped()
diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h
index 58dc4d871..fb70705b2 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceitem.h
+++ b/src/compositor/compositor_api/qwaylandsurfaceitem.h
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
class QWaylandSurfaceTextureProvider;
class QMutex;
+class QWaylandInputDevice;
class Q_COMPOSITOR_EXPORT QWaylandSurfaceItem : public QQuickItem, public QWaylandSurfaceView
{
@@ -101,7 +102,7 @@ protected:
void touchEvent(QTouchEvent *event);
public slots:
- void takeFocus();
+ virtual void takeFocus(QWaylandInputDevice *device = 0);
void setPaintEnabled(bool paintEnabled);
private slots:
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index ada82a2e1..a792d5531 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -109,7 +109,6 @@ Compositor *Compositor::instance()
Compositor::Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::ExtensionFlags extensions)
: m_extensions(extensions)
, m_display(new Display)
- , m_default_input_device(0)
, m_current_frame(0)
, m_last_queued_buf(-1)
, m_qt_compositor(qt_compositor)
@@ -188,6 +187,7 @@ Compositor::~Compositor()
delete m_touchExtension;
delete m_qtkeyExtension;
+ removeInputDevice(m_default_wayland_input_device);
delete m_default_wayland_input_device;
delete m_data_device_manager;
@@ -226,6 +226,16 @@ void Compositor::destroySurface(Surface *surface)
m_destroyed_surfaces << surface->waylandSurface();
}
+void Compositor::resetInputDevice(Surface *surface)
+{
+ foreach (QWaylandInputDevice *dev, m_inputDevices) {
+ if (dev->keyboardFocus() == surface->waylandSurface())
+ dev->setKeyboardFocus(0);
+ if (dev->mouseFocus() && dev->mouseFocus()->surface() == surface->waylandSurface())
+ dev->setMouseFocus(0, QPointF(), QPointF());
+ }
+}
+
void Compositor::cleanupGraphicsResources()
{
qDeleteAll(m_destroyed_surfaces);
@@ -323,7 +333,7 @@ void Compositor::initializeExtensions()
void Compositor::initializeDefaultInputDevice()
{
m_default_wayland_input_device = new QWaylandInputDevice(m_qt_compositor);
- m_default_input_device = m_default_wayland_input_device->handle();
+ registerInputDevice(m_default_wayland_input_device);
}
QList<QWaylandClient *> Compositor::clients() const
@@ -381,7 +391,8 @@ QWaylandCompositor::ExtensionFlags Compositor::extensions() const
InputDevice* Compositor::defaultInputDevice()
{
- return m_default_input_device;
+ // The list gets prepended so that default is the last element
+ return m_inputDevices.last()->handle();
}
QList<QtWayland::Surface *> Compositor::surfacesForClient(wl_client *client)
@@ -499,6 +510,32 @@ void Compositor::loadServerBufferIntegration()
}
}
+void Compositor::registerInputDevice(QWaylandInputDevice *device)
+{
+ // The devices get prepended as the first input device that gets added
+ // is assumed to be the default and it will claim to accept all the input
+ // events if asked
+ m_inputDevices.prepend(device);
+}
+
+void Compositor::removeInputDevice(QWaylandInputDevice *device)
+{
+ m_inputDevices.removeOne(device);
+}
+
+QWaylandInputDevice *Compositor::inputDeviceFor(QInputEvent *inputEvent)
+{
+ QWaylandInputDevice *dev = NULL;
+ for (int i = 0; i < m_inputDevices.size(); i++) {
+ QWaylandInputDevice *candidate = m_inputDevices.at(i);
+ if (candidate->isOwner(inputEvent)) {
+ dev = candidate;
+ break;
+ }
+ }
+ return dev;
+}
+
} // namespace Wayland
QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h
index 9c6192fae..9c3a0f9de 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor_p.h
+++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h
@@ -59,6 +59,8 @@ QT_BEGIN_NAMESPACE
class QWaylandClient;
class QWaylandClientPrivate;
+class QInputEvent;
+
class QWaylandCompositor;
class QWaylandInputDevice;
class WindowManagerServerIntegration;
@@ -96,7 +98,12 @@ public:
void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces);
void frameFinished(Surface *surface = 0);
- InputDevice *defaultInputDevice(); //we just have 1 default device for now (since QPA doesn't give us anything else)
+ InputDevice *defaultInputDevice();
+
+ void registerInputDevice(QWaylandInputDevice *device);
+ QList<QWaylandInputDevice *> inputDevices() const { return m_inputDevices; }
+ QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent);
+ void removeInputDevice(QWaylandInputDevice *device);
void destroySurface(Surface *surface);
@@ -156,6 +163,8 @@ public:
void feedRetainedSelectionData(QMimeData *data);
static void bindGlobal(wl_client *client, void *data, uint32_t version, uint32_t id);
+ void resetInputDevice(Surface *surface);
+
public slots:
void cleanupGraphicsResources();
@@ -176,7 +185,8 @@ protected:
/* Input */
QWaylandInputDevice *m_default_wayland_input_device;
- InputDevice *m_default_input_device;
+
+ QList<QWaylandInputDevice *> m_inputDevices;
/* Output */
//make this a list of the available screens
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index 143002845..b494b3e01 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -294,11 +294,7 @@ void Surface::setBackBuffer(SurfaceBuffer *buffer)
m_damage = m_damage.intersected(QRect(QPoint(), m_size));
emit m_waylandSurface->damaged(m_damage);
} else {
- InputDevice *inputDevice = m_compositor->defaultInputDevice();
- if (inputDevice->keyboardFocus() == this)
- inputDevice->setKeyboardFocus(0);
- if (inputDevice->mouseFocus() && inputDevice->mouseFocus()->surface() == waylandSurface())
- inputDevice->setMouseFocus(0, QPointF(), QPointF());
+ m_compositor->resetInputDevice(this);
}
m_damage = QRegion();
}