19 #include "MouseTouchAdaptor.h"
21 #include <qpa/qwindowsysteminterface.h>
23 #include <QCoreApplication>
24 #include <QMouseEvent>
27 using QTest::QTouchEventSequence;
30 MouseTouchAdaptor *g_instance =
nullptr;
32 Qt::MouseButton translateMouseButton(xcb_button_t detail)
35 case 1:
return Qt::LeftButton;
36 case 2:
return Qt::MidButton;
37 case 3:
return Qt::RightButton;
39 default:
return Qt::NoButton;
44 MouseTouchAdaptor::MouseTouchAdaptor()
45 : QObject(nullptr), m_leftButtonIsPressed(false), m_enabled(true)
47 QCoreApplication::instance()->installNativeEventFilter(
this);
49 m_touchDevice =
new QTouchDevice;
50 m_touchDevice->setType(QTouchDevice::TouchScreen);
51 QWindowSystemInterface::registerTouchDevice(m_touchDevice);
54 MouseTouchAdaptor::~MouseTouchAdaptor()
59 MouseTouchAdaptor* MouseTouchAdaptor::instance()
62 g_instance =
new MouseTouchAdaptor;
68 bool MouseTouchAdaptor::nativeEventFilter(
const QByteArray & eventType,
69 void * message,
long * )
75 if (eventType !=
"xcb_generic_event_t") {
77 qWarning(
"MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!");
81 xcb_generic_event_t *xcbEvent =
static_cast<xcb_generic_event_t *
>(message);
83 switch (xcbEvent->response_type & ~0x80) {
84 case XCB_BUTTON_PRESS:
85 return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent));
87 case XCB_BUTTON_RELEASE:
88 return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent));
90 case XCB_MOTION_NOTIFY:
91 return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent));
99 bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
101 Qt::MouseButton button = translateMouseButton(pressEvent->detail);
104 if (button != Qt::LeftButton)
107 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
109 QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
111 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
113 touchEvent.press(0 , windowPos);
114 touchEvent.commit(
false );
116 m_leftButtonIsPressed =
true;
120 bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent)
122 Qt::MouseButton button = translateMouseButton(releaseEvent->detail);
125 if (button != Qt::LeftButton)
128 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
130 QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
132 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
134 touchEvent.release(0 , windowPos);
135 touchEvent.commit(
false );
137 m_leftButtonIsPressed =
false;
141 bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
143 if (!m_leftButtonIsPressed) {
147 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
149 QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(),
event->event_y / targetWindow->devicePixelRatio());
151 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
153 touchEvent.move(0 , windowPos);
154 touchEvent.commit(
false );
159 QWindow *MouseTouchAdaptor::findQWindowWithXWindowID(WId windowId)
161 QWindowList windowList = QGuiApplication::topLevelWindows();
162 QWindow *foundWindow =
nullptr;
165 while (!foundWindow && i < windowList.count()) {
166 QWindow *window = windowList[i];
167 if (window->winId() == windowId) {
168 foundWindow = window;
174 Q_ASSERT(foundWindow);
178 bool MouseTouchAdaptor::enabled()
const
183 void MouseTouchAdaptor::setEnabled(
bool value)
185 if (value != m_enabled) {
187 Q_EMIT enabledChanged(value);