diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 3 | ||||
-rw-r--r-- | src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp | 39 |
2 files changed, 41 insertions, 1 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 313f1bcb54..d6ffb020d0 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2789,6 +2789,9 @@ void QGuiApplicationPrivate::processContextMenuEvent(QWindowSystemInterfacePriva void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e) { + if (!QInputDevicePrivate::isRegistered(e->device)) + return; + modifier_buttons = e->modifiers; QPointingDevice *device = const_cast<QPointingDevice *>(static_cast<const QPointingDevice *>(e->device)); QPointingDevicePrivate *devPriv = QPointingDevicePrivate::get(device); diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp index 95265b3378..a3f6a470be 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp @@ -474,9 +474,46 @@ void QEvdevTouchScreenHandler::registerPointingDevice() QWindowSystemInterface::registerInputDevice(m_device); } +/*! \internal + + QEvdevTouchScreenHandler::unregisterPointingDevice can be called by several cases. + + First of all, the case that an application is terminated, and destroy all input devices + immediately to unregister in this case. + + Secondly, the case that removing a device without touch events for the device while the + application is still running. In this case, the destructor of QEvdevTouchScreenHandler from + the connection with QDeviceDiscovery::deviceRemoved in QEvdevTouchManager calls this method. + And this method moves a device into the main thread and then deletes it later but there is no + touch events for the device so that the device would be deleted in appropriate time. + + Finally, this case is similar as the second one but with touch events, that is, a device is + removed while touch events are given to the device and the application is still running. + In this case, this method is called by readData with ENODEV error and the destructor of + QEvdevTouchScreenHandler. So in order to prevent accessing the device which is already nullptr, + check the nullity of a device first. And as same as the second case, move the device into the + main thread and then delete it later. But in this case, cannot guarantee which event is + handled first since the list or queue where posting QDeferredDeleteEvent and appending touch + events are different. + If touch events are handled first, there is no problem because the device which is used for + these events is registered. However if QDeferredDeleteEvent for deleting the device is + handled first, this may cause a crash due to using unregistered device when processing touch + events later. In order to prevent processing such touch events, check a device which is used + for touch events is registered when processing touch events. + + see QGuiApplicationPrivate::processTouchEvent(). + */ void QEvdevTouchScreenHandler::unregisterPointingDevice() { - delete m_device; + if (!m_device) + return; + + if (QGuiApplication::instance()) { + m_device->moveToThread(QGuiApplication::instance()->thread()); + m_device->deleteLater(); + } else { + delete m_device; + } m_device = nullptr; } |