input: Synchronize multiple mice handled through evdevmouse plugin

EvdevMouseManager now receives relative pointer coordinates from each
connected mouse and is then responsible for clamping and forwarding them
to the QWindowSystemInterface. This avoids jumping cursors when multiple
pointer devices are connected. This does not change behavior together
with devices handled through the evdevtouch plugin.

Change-Id: I7feb358f68c3b3ebd138116224b4747c88c6761f
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
bb10
Johannes Zellner 2012-05-17 15:16:55 -07:00 committed by Qt by Nokia
parent 33fb856a6d
commit 39c5bad574
4 changed files with 54 additions and 32 deletions

View File

@ -73,8 +73,6 @@ QEvdevMouseHandler *QEvdevMouseHandler::createLinuxInputMouseHandler(const QStri
QString device = "/dev/input/event0";
bool compression = true;
int jitterLimit = 0;
int xoffset = 0;
int yoffset = 0;
QStringList args = specification.split(QLatin1Char(':'));
foreach (const QString &arg, args) {
@ -82,10 +80,6 @@ QEvdevMouseHandler *QEvdevMouseHandler::createLinuxInputMouseHandler(const QStri
compression = false;
else if (arg.startsWith("dejitter="))
jitterLimit = arg.mid(9).toInt();
else if (arg.startsWith("xoffset="))
xoffset = arg.mid(8).toInt();
else if (arg.startsWith("yoffset="))
yoffset = arg.mid(8).toInt();
else if (arg.startsWith(QLatin1String("/dev/")))
device = arg;
}
@ -97,17 +91,17 @@ QEvdevMouseHandler *QEvdevMouseHandler::createLinuxInputMouseHandler(const QStri
int fd;
fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if (fd >= 0) {
return new QEvdevMouseHandler(fd, compression, jitterLimit, xoffset, yoffset);
return new QEvdevMouseHandler(fd, compression, jitterLimit);
} else {
qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno));
return 0;
}
}
QEvdevMouseHandler::QEvdevMouseHandler(int deviceDescriptor, bool compression, int jitterLimit, int xoffset, int yoffset)
QEvdevMouseHandler::QEvdevMouseHandler(int deviceDescriptor, bool compression, int jitterLimit)
: m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0),
m_fd(deviceDescriptor), m_compression(compression),
m_xoffset(xoffset), m_yoffset(yoffset), m_buttons(0)
m_buttons(0)
{
setObjectName(QLatin1String("Evdev Mouse Handler"));
@ -127,24 +121,8 @@ QEvdevMouseHandler::~QEvdevMouseHandler()
void QEvdevMouseHandler::sendMouseEvent()
{
QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
if (m_x + m_xoffset < g.left())
m_x = g.left() - m_xoffset;
else if (m_x + m_xoffset > g.right())
m_x = g.right() - m_xoffset;
emit handleMouseEvent(m_x - m_prevx, m_y - m_prevy, m_buttons);
if (m_y + m_yoffset < g.top())
m_y = g.top() - m_yoffset;
else if (m_y + m_yoffset > g.bottom())
m_y = g.bottom() - m_yoffset;
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
#ifdef QT_QPA_MOUSE_HANDLER_DEBUG
qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons));
#endif
QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons);
m_prevx = m_x;
m_prevy = m_y;
}

View File

@ -58,11 +58,14 @@ public:
static QEvdevMouseHandler *createLinuxInputMouseHandler(const QString &key, const QString &specification);
~QEvdevMouseHandler();
signals:
void handleMouseEvent(int x, int y, Qt::MouseButtons buttons);
private slots:
void readMouseData();
private:
QEvdevMouseHandler(int deviceDescriptor, bool compression, int jitterLimit, int xoffset, int yoffset);
QEvdevMouseHandler(int deviceDescriptor, bool compression, int jitterLimit);
void sendMouseEvent();
@ -71,7 +74,6 @@ private:
int m_prevx, m_prevy;
int m_fd;
bool m_compression;
int m_xoffset, m_yoffset;
Qt::MouseButtons m_buttons;
int m_jitterLimitSquared;
};

View File

@ -42,9 +42,11 @@
#include "qevdevmousemanager.h"
#include <QStringList>
#include <QCoreApplication>
#include <QGuiApplication>
#include <QScreen>
#include <QWindowSystemInterface>
//#define QT_QPA_MOUSEMANAGER_DEBUG
#define QT_QPA_MOUSEMANAGER_DEBUG
#ifdef QT_QPA_MOUSEMANAGER_DEBUG
#include <QDebug>
@ -53,6 +55,7 @@
QT_BEGIN_NAMESPACE
QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specification)
: m_x(0), m_y(0), m_xoffset(0), m_yoffset(0)
{
Q_UNUSED(key);
@ -70,6 +73,10 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif
devices.append(arg);
args.removeAll(arg);
useUDev = false;
} else if (arg.startsWith("xoffset=")) {
m_xoffset = arg.mid(8).toInt();
} else if (arg.startsWith("yoffset=")) {
m_yoffset = arg.mid(8).toInt();
}
}
@ -109,6 +116,32 @@ QEvdevMouseManager::~QEvdevMouseManager()
m_mice.clear();
}
void QEvdevMouseManager::handleMouseEvent(int x, int y, Qt::MouseButtons buttons)
{
// update current absolute coordinates
m_x += x;
m_y += y;
// clamp to screen geometry
QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
if (m_x + m_xoffset < g.left())
m_x = g.left() - m_xoffset;
else if (m_x + m_xoffset > g.right())
m_x = g.right() - m_xoffset;
if (m_y + m_yoffset < g.top())
m_y = g.top() - m_yoffset;
else if (m_y + m_yoffset > g.bottom())
m_y = g.bottom() - m_yoffset;
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, buttons);
#ifdef QT_QPA_MOUSEMANAGER_DEBUG
qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(buttons));
#endif
}
void QEvdevMouseManager::addMouse(const QString &deviceNode)
{
#ifdef QT_QPA_MOUSEMANAGER_DEBUG
@ -124,10 +157,12 @@ void QEvdevMouseManager::addMouse(const QString &deviceNode)
QEvdevMouseHandler *handler;
handler = QEvdevMouseHandler::createLinuxInputMouseHandler("EvdevMouse", specification);
if (handler)
if (handler) {
connect(handler, SIGNAL(handleMouseEvent(int, int, Qt::MouseButtons)), this, SLOT(handleMouseEvent(int, int, Qt::MouseButtons)));
m_mice.insert(deviceNode, handler);
else
} else {
qWarning("Failed to open mouse");
}
}
void QEvdevMouseManager::removeMouse(const QString &deviceNode)

View File

@ -63,6 +63,9 @@ public:
explicit QEvdevMouseManager(const QString &key, const QString &specification);
~QEvdevMouseManager();
public slots:
void handleMouseEvent(int x, int y, Qt::MouseButtons buttons);
private slots:
void addMouse(const QString &deviceNode = QString());
void removeMouse(const QString &deviceNode);
@ -73,6 +76,10 @@ private:
#ifndef QT_NO_LIBUDEV
QUDeviceHelper *m_udeviceHelper;
#endif // QT_NO_LIBUDEV
int m_x;
int m_y;
int m_xoffset;
int m_yoffset;
};
QT_END_HEADER