From 76922a706f0584ce2aa1a0ca758cf0c6196ea729 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 9 Dec 2014 18:52:24 +0300 Subject: Decide whether to synthesize mouse events on a per device basis Currently Qt uses the QPlatformIntegration::StyleHint SynthesizeMouseFromTouchEvents to check whether to synthesize mouse events from touch events. But not only platform plugins can produce touch events, they can be created by e.g. QTest::touchEvent() and in this case we almost definitely need synthesizing regardless of the platform. This commit introduces a QTouchDevice::MouseEmulation capability which replaces use of the QPlatformIntegration::SynthesizeMouseFromTouchEvents. So it's possible to pass QTouchDevice without this capability to QTest::touchEvent() and be sure that mouse events will be synthesized. Notice that touch pads always emulate mouse events. As a result we can activate some tests which were disabled for specific platform configurations by commits 6c1670d8c273819435867c42725c0db0eee597dc and e9760f1559361c39f269fb89f1ebd01f6ee8378d. Change-Id: Idc82fa4007a095fc1cb5934979361b0023d2b793 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 2 -- src/plugins/platforms/cocoa/qnsview.mm | 2 +- src/plugins/platforms/windows/qwindowscontext.cpp | 5 +++++ src/plugins/platforms/windows/qwindowscontext.h | 3 +++ src/plugins/platforms/windows/qwindowsintegration.cpp | 19 ++++++++++++------- .../platforms/windows/qwindowsmousehandler.cpp | 7 ++++--- src/plugins/platforms/winrt/qwinrttheme.cpp | 2 -- src/plugins/platforms/xcb/qxcbconnection.cpp | 1 - src/plugins/platforms/xcb/qxcbconnection.h | 2 -- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 11 +++++++---- src/plugins/platforms/xcb/qxcbintegration.cpp | 3 --- 11 files changed, 32 insertions(+), 25 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index d3071be636..d95908f23b 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -505,8 +505,6 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const { if (hint == QPlatformIntegration::FontSmoothingGamma) return 2.0; - if (hint == QPlatformIntegration::SynthesizeMouseFromTouchEvents) - return false; return QPlatformIntegration::styleHint(hint); } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 5625d19ed7..cfd2eeb837 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -157,7 +157,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; if (!touchDevice) { touchDevice = new QTouchDevice; touchDevice->setType(QTouchDevice::TouchPad); - touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation); QWindowSystemInterface::registerTouchDevice(touchDevice); } } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index b397b12311..ebd41d482b 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1235,6 +1235,11 @@ void QWindowsContext::setAsyncExpose(bool value) d->m_asyncExpose = value; } +QTouchDevice *QWindowsContext::touchDevice() const +{ + return d->m_mouseHandler.touchDevice(); +} + /*! \brief Windows functions for actual windows. diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 7c88ee14ba..870a42946d 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -67,6 +67,7 @@ struct QWindowCreationContext; struct QWindowsContextPrivate; class QPoint; class QKeyEvent; +class QTouchDevice; #ifndef Q_OS_WINCE struct QWindowsUser32DLL @@ -219,6 +220,8 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + QTouchDevice *touchDevice() const; + private: void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w); #ifndef QT_NO_CONTEXTMENU diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 63dcb6abf8..af7ecd5834 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -227,6 +227,18 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL qCDebug(lcQpaWindows) << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling=" << QWindowsScaling::factor(); + + QTouchDevice *touchDevice = m_context.touchDevice(); + if (touchDevice) { +#ifdef Q_OS_WINCE + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); +#else + if (!(m_options & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) { + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); + } +#endif + QWindowSystemInterface::registerTouchDevice(touchDevice); + } } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() @@ -496,13 +508,6 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co break; case QPlatformIntegration::UseRtlExtensions: return QVariant(d->m_context.useRTLExtensions()); - case QPlatformIntegration::SynthesizeMouseFromTouchEvents: -#ifdef Q_OS_WINCE - // We do not want Qt to synthesize mouse events as Windows also does that. - return false; -#else // Q_OS_WINCE - return QVariant(bool(d->m_options & DontPassOsMouseEventsSynthesizedFromTouch)); -#endif // !Q_OS_WINCE default: break; } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index b940dcd62c..b1ced95a71 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -128,7 +128,10 @@ static inline QTouchDevice *createTouchDevice() QTouchDevice *result = new QTouchDevice; result->setType(digitizers & QT_NID_INTEGRATED_TOUCH ? QTouchDevice::TouchScreen : QTouchDevice::TouchPad); - result->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition); + QTouchDevice::Capabilities capabilities = QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition; + if (result->type() == QTouchDevice::TouchPad) + capabilities |= QTouchDevice::MouseEmulation; + result->setCapabilities(capabilities); result->setMaximumTouchPoints(maxTouchPoints); return result; } @@ -150,8 +153,6 @@ QWindowsMouseHandler::QWindowsMouseHandler() : m_leftButtonDown(false), m_previousCaptureWindow(0) { - if (m_touchDevice) - QWindowSystemInterface::registerTouchDevice(m_touchDevice); } Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index f33e07901a..c42368cc87 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -224,8 +224,6 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) return defaultThemeHint(StartDragVelocity); case QPlatformIntegration::UseRtlExtensions: return false; - case QPlatformIntegration::SynthesizeMouseFromTouchEvents: - return true; case QPlatformIntegration::PasswordMaskCharacter: return defaultThemeHint(PasswordMaskCharacter); case QPlatformIntegration::SetFocusOnTouchRelease: diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 43c73671a9..d5cf708ed2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -299,7 +299,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , has_shape_extension(false) , has_randr_extension(false) , has_input_shape(false) - , has_touch_without_mouse_emulation(false) , has_xkb(false) , m_buttons(0) , m_focusWindow(0) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 391d4c10cc..a3c8c0b95e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -442,7 +442,6 @@ public: bool hasXShape() const { return has_shape_extension; } bool hasXRandr() const { return has_randr_extension; } bool hasInputShape() const { return has_input_shape; } - bool hasTouchWithoutMouseEmulation() const { return has_touch_without_mouse_emulation; } bool hasXKB() const { return has_xkb; } bool supportsThreadedRendering() const { return m_reader->isRunning(); } @@ -609,7 +608,6 @@ private: bool has_shape_extension; bool has_randr_extension; bool has_input_shape; - bool has_touch_without_mouse_emulation; bool has_xkb; Qt::MouseButtons m_buttons; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index e9fb47dabd..d1b3ead11c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -282,14 +282,14 @@ void QXcbConnection::xi2Select(xcb_window_t window) mask.mask_len = sizeof(bitMask); mask.mask = xiBitMask; if (!m_touchDevices.isEmpty()) { - mask.deviceid = XIAllMasterDevices; - Status result = XISelectEvents(xDisplay, window, &mask, 1); // If we select for touch events on the master pointer, XInput2 // will not synthesize mouse events. This means Qt must do it, // which is also preferable, since Qt can control better when // to do so. - if (result == Success) - has_touch_without_mouse_emulation = true; + mask.deviceid = XIAllMasterDevices; + Status result = XISelectEvents(xDisplay, window, &mask, 1); + if (result != Success) + qCDebug(lcQpaXInput, "XInput 2.2: failed to select touch events, window %x, result %d", window, result); } } #endif // XCB_USE_XINPUT22 @@ -424,6 +424,9 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) dev->size.width() > 10000 || dev->size.height() > 10000) dev->size = QSizeF(130, 110); } + if (!isUsingXInput22() || type == QTouchDevice::TouchPad) + caps |= QTouchDevice::MouseEmulation; + if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) { dev->qtTouchDevice = new QTouchDevice; dev->qtTouchDevice->setName(QString::fromUtf8(dev->xiDeviceInfo->name)); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 1676035f6b..258359d20f 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -374,9 +374,6 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const // X11 always has support for windows, but the // window manager could prevent it (e.g. matchbox) return false; - case QPlatformIntegration::SynthesizeMouseFromTouchEvents: - // We do not want Qt to synthesize mouse events if X11 already does it. - return m_connections.at(0)->hasTouchWithoutMouseEmulation(); default: break; } -- cgit v1.2.3