14
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
* Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
17
* Zsombor Egri <zsomboir.egri@canonical.com>
19
#include "ucmousetouchadaptor.h"
20
#include "uctestextras.h"
20
#include "mousetouchadaptor_p.h"
22
#include <qpa/qplatformnativeinterface.h>
22
23
#include <qpa/qwindowsysteminterface.h>
24
25
#include <QCoreApplication>
25
26
#include <QMouseEvent>
28
using QTest::QTouchEventSequence;
32
Qt::MouseButton translateMouseButton(xcb_button_t detail)
29
#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
30
#define ENABLE_TOUCH_EMULATION
33
namespace UbuntuToolkit {
35
QTouchDevice *MouseTouchAdaptor::m_touchDevice = nullptr;
37
MouseTouchAdaptorPrivate::~MouseTouchAdaptorPrivate()
35
case 1: return Qt::LeftButton;
36
case 2: return Qt::MidButton;
37
case 3: return Qt::RightButton;
38
// Button values 4-7 are Wheel events
39
default: return Qt::NoButton;
39
QCoreApplication::instance()->removeNativeEventFilter(this);
42
} // end of anonymous namespace
45
43
* \qmltype MouseTouchAdaptor
46
* \instantiates UCMouseTouchAdaptor
44
* \instantiates MouseTouchAdaptor
47
45
* \inqmlmodule Ubuntu.Test 1.0
48
46
* \ingroup ubuntu-test
49
47
* \brief Singleton type turning mouse events into single finger touch events.
63
UCMouseTouchAdaptor::UCMouseTouchAdaptor()
65
, m_leftButtonIsPressed(false)
68
QCoreApplication::instance()->installNativeEventFilter(this);
70
UCTestExtras::registerTouchDevice();
71
m_touchDevice = UCTestExtras::m_touchDevice;
74
bool UCMouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType,
75
void * message, long * /*result*/)
81
if (eventType != "xcb_generic_event_t") {
83
qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
87
xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message);
89
switch (xcbEvent->response_type & ~0x80) {
90
case XCB_BUTTON_PRESS:
91
return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
93
case XCB_BUTTON_RELEASE:
94
return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
96
case XCB_MOTION_NOTIFY:
97
return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
105
bool UCMouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
107
Qt::MouseButton button = translateMouseButton(pressEvent->detail);
109
// Just eat the event if it wasn't a left mouse press
110
if (button != Qt::LeftButton)
113
QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
115
QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
117
QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
118
false /* autoCommit */);
119
touchEvent.press(0 /* touchId */, windowPos);
120
touchEvent.commit(false /* processEvents */);
122
m_leftButtonIsPressed = true;
126
bool UCMouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
128
Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
130
// Just eat the event if it wasn't a left mouse release
131
if (button != Qt::LeftButton)
134
QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
136
QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
138
QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
139
false /* autoCommit */);
140
touchEvent.release(0 /* touchId */, windowPos);
141
touchEvent.commit(false /* processEvents */);
143
m_leftButtonIsPressed = false;
147
bool UCMouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
149
if (!m_leftButtonIsPressed) {
153
QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
155
QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(), event->event_y / targetWindow->devicePixelRatio());
157
QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
158
false /* autoCommit */);
159
touchEvent.move(0 /* touchId */, windowPos);
160
touchEvent.commit(false /* processEvents */);
165
QWindow *UCMouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
61
MouseTouchAdaptor::MouseTouchAdaptor(QObject *parent)
63
#ifdef UBUNTUTOOLKIT_ENABLE_X11_TOUCH_EMULATION
64
QObject(*(new X11MouseTouchAdaptorPrivate), parent)
66
QObject(*(new MouseTouchAdaptorPrivate), parent)
69
#ifdef ENABLE_TOUCH_EMULATION
70
registerTouchDevice();
72
qWarning() << "MouseTouchAdaptor not available on this architecture.";
74
Q_D(MouseTouchAdaptor);
78
// registers a test touch device, returns true if a device was found/registered
79
bool MouseTouchAdaptor::registerTouchDevice()
81
// check if there is any touch device registered in the system
83
QList<const QTouchDevice*> touchDevices = QTouchDevice::devices();
84
Q_FOREACH(const QTouchDevice *device, touchDevices) {
85
if (device->type() == QTouchDevice::TouchScreen) {
86
m_touchDevice = const_cast<QTouchDevice*>(device);
91
// if none, register one
92
#ifdef ENABLE_TOUCH_EMULATION
94
m_touchDevice = new QTouchDevice;
95
m_touchDevice->setType(QTouchDevice::TouchScreen);
96
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
103
QWindow *MouseTouchAdaptorPrivate::findQWindowWithXWindowID(WId windowId)
167
105
QWindowList windowList = QGuiApplication::topLevelWindows();
168
106
QWindow *foundWindow = nullptr;
185
123
* \qmlproperty bool MouseTouchAdaptor::enabled
186
124
* Enables the mouse to touch conversion functionality. Defaults to true.
188
bool UCMouseTouchAdaptor::enabled() const
192
void UCMouseTouchAdaptor::setEnabled(bool value)
194
if (value != m_enabled) {
196
Q_EMIT enabledChanged(value);
126
bool MouseTouchAdaptorPrivate::isEnabled() const
130
void MouseTouchAdaptorPrivate::setEnabled(bool value)
133
qWarning() << "MouseTouchAdaptor not available on this architecture, thus cannot be enabled.";
136
} // namespace UbuntuToolkit
138
#include "moc_mousetouchadaptor.cpp"