xcb: cleanup updating of scrolling device valuators
This includes: - Better sharing of common code. - Less argument passing. - Improved code readability: It is somewhat confusing to read when QXcbWindow::handleEnterNotifyEvent calls connection()->handleEnterEvent(). - Better organizing of ifdefs. Change-Id: I4405390cada13b51db78f9fd30e26bb1793395ff Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
7499d4404f
commit
f69d30804d
@ -500,7 +500,7 @@ public:
|
||||
static bool xEmbedSystemTrayVisualHasAlphaChannel();
|
||||
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
void handleEnterEvent();
|
||||
void xi2UpdateScrollingDevices();
|
||||
#endif
|
||||
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
@ -616,9 +616,12 @@ private:
|
||||
Qt::Orientations legacyOrientations = 0;
|
||||
QPointF lastScrollPosition;
|
||||
};
|
||||
void updateScrollingDevice(ScrollingDevice& scrollingDevice, int num_classes, void *classes);
|
||||
void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
|
||||
QHash<int, ScrollingDevice> m_scrollingDevices;
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
|
||||
void xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice);
|
||||
ScrollingDevice *scrollingDeviceForId(int id);
|
||||
#endif
|
||||
|
||||
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
|
||||
static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event);
|
||||
|
@ -526,9 +526,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
#endif // QT_CONFIG(tabletevent)
|
||||
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(sourceDeviceId);
|
||||
if (device != m_scrollingDevices.end())
|
||||
xi2HandleScrollEvent(xiEvent, device.value());
|
||||
if (ScrollingDevice *device = scrollingDeviceForId(sourceDeviceId))
|
||||
xi2HandleScrollEvent(xiEvent, *device);
|
||||
#endif // XCB_USE_XINPUT21
|
||||
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
@ -828,42 +827,39 @@ void QXcbConnection::xi2HandleHierachyEvent(void *event)
|
||||
void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
|
||||
{
|
||||
xXIDeviceChangedEvent *xiEvent = reinterpret_cast<xXIDeviceChangedEvent *>(event);
|
||||
|
||||
// ### If a slave device changes (XIDeviceChange), we should probably run setup on it again.
|
||||
if (xiEvent->reason != XISlaveSwitch)
|
||||
return;
|
||||
|
||||
switch (xiEvent->reason) {
|
||||
case XIDeviceChange:
|
||||
break;
|
||||
case XISlaveSwitch: {
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
// This code handles broken scrolling device drivers that reset absolute positions
|
||||
// when they are made active. Whenever a new slave device is made active the
|
||||
// primary pointer sends a DeviceChanged event with XISlaveSwitch, and the new
|
||||
// active slave in sourceid.
|
||||
|
||||
QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(xiEvent->sourceid);
|
||||
if (device == m_scrollingDevices.end())
|
||||
return;
|
||||
|
||||
int nrDevices = 0;
|
||||
XIDeviceInfo* xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), xiEvent->sourceid, &nrDevices);
|
||||
if (nrDevices <= 0) {
|
||||
qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", xiEvent->sourceid);
|
||||
return;
|
||||
}
|
||||
updateScrollingDevice(*device, xiDeviceInfo->num_classes, xiDeviceInfo->classes);
|
||||
XIFreeDeviceInfo(xiDeviceInfo);
|
||||
if (ScrollingDevice *scrollingDevice = scrollingDeviceForId(xiEvent->sourceid))
|
||||
xi2UpdateScrollingDevice(*scrollingDevice);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qCDebug(lcQpaXInputEvents, "unknown device-changed-event (device %d)", xiEvent->sourceid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int num_classes, void *classInfo)
|
||||
{
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
XIAnyClassInfo **classes = reinterpret_cast<XIAnyClassInfo**>(classInfo);
|
||||
void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice)
|
||||
{
|
||||
int nrDevices = 0;
|
||||
Display *dpy = static_cast<Display *>(m_xlib_display);
|
||||
XIDeviceInfo* deviceInfo = XIQueryDevice(dpy, scrollingDevice.deviceId, &nrDevices);
|
||||
if (nrDevices <= 0) {
|
||||
qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", scrollingDevice.deviceId);
|
||||
return;
|
||||
}
|
||||
QPointF lastScrollPosition;
|
||||
if (lcQpaXInput().isDebugEnabled())
|
||||
lastScrollPosition = scrollingDevice.lastScrollPosition;
|
||||
for (int c = 0; c < num_classes; ++c) {
|
||||
if (classes[c]->type == XIValuatorClass) {
|
||||
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classes[c]);
|
||||
for (int c = 0; c < deviceInfo->num_classes; ++c) {
|
||||
XIAnyClassInfo *classInfo = deviceInfo->classes[c];
|
||||
if (classInfo->type == XIValuatorClass) {
|
||||
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classInfo);
|
||||
const int valuatorAtom = qatom(vci->label);
|
||||
if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
|
||||
scrollingDevice.lastScrollPosition.setX(vci->value);
|
||||
@ -876,37 +872,30 @@ void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int
|
||||
lastScrollPosition.x(), lastScrollPosition.y(),
|
||||
scrollingDevice.lastScrollPosition.x(),
|
||||
scrollingDevice.lastScrollPosition.y());
|
||||
#else
|
||||
Q_UNUSED(scrollingDevice);
|
||||
Q_UNUSED(num_classes);
|
||||
Q_UNUSED(classInfo);
|
||||
#endif
|
||||
|
||||
XIFreeDeviceInfo(deviceInfo);
|
||||
}
|
||||
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
void QXcbConnection::handleEnterEvent()
|
||||
void QXcbConnection::xi2UpdateScrollingDevices()
|
||||
{
|
||||
QHash<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin();
|
||||
const QHash<int, ScrollingDevice>::iterator end = m_scrollingDevices.end();
|
||||
while (it != end) {
|
||||
ScrollingDevice& scrollingDevice = it.value();
|
||||
int nrDevices = 0;
|
||||
XIDeviceInfo* xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), scrollingDevice.deviceId, &nrDevices);
|
||||
if (nrDevices <= 0) {
|
||||
qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", scrollingDevice.deviceId);
|
||||
it = m_scrollingDevices.erase(it);
|
||||
continue;
|
||||
}
|
||||
updateScrollingDevice(scrollingDevice, xiDeviceInfo->num_classes, xiDeviceInfo->classes);
|
||||
XIFreeDeviceInfo(xiDeviceInfo);
|
||||
xi2UpdateScrollingDevice(it.value());
|
||||
++it;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QXcbConnection::ScrollingDevice *QXcbConnection::scrollingDeviceForId(int id)
|
||||
{
|
||||
ScrollingDevice *dev = nullptr;
|
||||
if (m_scrollingDevices.contains(id))
|
||||
dev = &m_scrollingDevices[id];
|
||||
return dev;
|
||||
}
|
||||
|
||||
void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
|
||||
{
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
|
||||
|
||||
if (xiEvent->evtype == XI_Motion && scrollingDevice.orientations) {
|
||||
@ -976,11 +965,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(event);
|
||||
Q_UNUSED(scrollingDevice);
|
||||
#endif // XCB_USE_XINPUT21
|
||||
}
|
||||
#endif // XCB_USE_XINPUT21
|
||||
|
||||
static int xi2ValuatorOffset(const unsigned char *maskPtr, int maskLen, int number)
|
||||
{
|
||||
|
@ -2288,7 +2288,8 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in
|
||||
{
|
||||
connection()->setTime(timestamp);
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
connection()->handleEnterEvent();
|
||||
// Updates scroll valuators, as user might have done some scrolling outside our X client.
|
||||
connection()->xi2UpdateScrollingDevices();
|
||||
#endif
|
||||
|
||||
const QPoint global = QPoint(root_x, root_y);
|
||||
|
Loading…
Reference in New Issue
Block a user