summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.3.070
-rw-r--r--doc/global/manifest-meta.qdocconf13
-rw-r--r--src/network/ssl/qsslcontext.cpp23
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp24
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp5
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp81
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h9
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp13
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp12
10 files changed, 129 insertions, 122 deletions
diff --git a/dist/changes-5.3.0 b/dist/changes-5.3.0
index f97e8699d2..62021b7b07 100644
--- a/dist/changes-5.3.0
+++ b/dist/changes-5.3.0
@@ -91,6 +91,10 @@ QtCore
- QLibraryInfo provides information on how Qt was built.
- Added class QMarginsF to support handling margins with floating-point
values.
+ - The setSharable() and isSharable() functions in Qt containers has
+ been deprecated and will be removed in Qt 6. New applications should
+ not use this feature, while old applications that may be using this
+ (undocumented) feature should port away from it.
- Atomic support:
* Added more operations to the atomic classes, including operator T(),
@@ -222,6 +226,9 @@ QtGui
EGL
- [QTBUG-36993] Native (that is, not distance field based) text
rendering is now functional on OpenGL 3.2+ core profiles too.
+ - The function QOpenGLShaderProgram::create() has been added. It is can
+ be used to force immediate allocation of the program's id.
+ - QFont::setRawName() and QFont::rawName() were deprecated.
- Accessibility:
* [QTBUG-37204] Implemented text attributes to enable VoiceOver to read
@@ -285,8 +292,6 @@ QtNetwork
QtPrintSupport
--------------
- - [QTBUG-29663] Made the Qt buildsystem automatically include the
- necessary plugins so that static applications can print.
- CUPS 1.4 is now required for print support on Linux and other *nix
platforms.
@@ -309,19 +314,29 @@ QtPrintSupport
QtSql
-----
- - QSqlQuery::isNull(field) now correctly returns true for "no such field".
- - QSqlQuery::isNull(fieldname) is a new overload.
- - [QTBUG-12186] Fixed the order of values with positional binding in a
- QSqlQuery
+ - QSqlError:
+ * Now handles alphanumeric error codes. Used by QPSQL. Old numeric
+ code is deprecated.
+
+ - QSqlQuery:
+ * isNull(field) now correctly returns true for "no such field".
+ * isNull(fieldname) is a new overload.
+ * [QTBUG-12186] Fixed order of values with positional binding.
+
+ - QSqlTableModel:
+ * [QTBUG-38509] Fix failure to refresh in selectRow()
+
+ - QIBASE:
+ * [QTBUG-37508] Fix QByteArray memory corruption in QIBaseDriver::open().
+ * Support for prepared queries in numRowsAffected().
+
+ - QODBC:
+ * [QTBUG-37831] Fix access of tmpStorage in QODBCResult::exec().
- QSQLITE:
* Creating temporary databases is now possible
* Empty database name now opens in-memory database.
- - QSqlError
- * Now handles alphanumeric error codes. Used by QPSQL. Old numeric
- code is deprecated.
-
QtTest
------
@@ -430,8 +445,6 @@ QtWidgets
Android
-------
- - [QTBUG-34781] Fixed regression in "make install" on library projects on
- Android so they can be used inside subdirs projects again.
- [QTBUG-36074] Fixed crash on populating large combo boxes or menus.
- [QTBUG-36528] Fixed QDir::entryList() for assets scheme to no longer
skip the first file in the directory.
@@ -513,3 +526,36 @@ qdbus
trying to display remote interfaces that had complex types without a
matching base Qt type.
+configure & build system
+------------------------
+
+ - Configure's -separate-debug-info option is now checked more strictly.
+ - Added configure [-no]-imf options for QNX.
+ - Added unsupported linux-libc++-clang and freebsd-clang mkspecs.
+ - Numerous configuration-specific build fixes.
+
+qmake
+-----
+
+ - QTPLUGIN will now be automatically populated with the plugins that are
+ typically needed by the used Qt modules.
+ - qmake will not create dependencies on system headers any more, provided it
+ detects the system include paths.
+ - Added DISTCLEAN_DEPS variable analogous to CLEAN_DEPS.
+ - Added function $$getenv() which is equivalent to using the $$() expansion,
+ but permits various qmake meta characters in the name.
+ - [MacOS] QMAKE_BUNDLEID_PREFIX is now recognized by the Makefile generator.
+ - [QTBUG-29939][MSVC2012+] Added Windows XP target support.
+ - [QTBUG-35570][VS2012+] Fixed bad ProgramDataBaseFileName.
+ - [QTBUG-38066][VS2010+] Fixed version suffix being appended to applications.
+ - [QTBUG-31185][VS] The PlatformToolset environment variable is now honored.
+ - [QTBUG-34781][Android] Fixed regression in "make install" on library projects
+ so they can be used inside subdirs projects again.
+ - [QTBUG-37113] Fixed creation of excessively long relative paths, which
+ would lead to errors with MSVC. Note that this does not fix all such cases.
+
+qlalr
+-----
+
+ - (Re-)added to Qt base. Added corresponding qmake feature file.
+ Caveat: the generated files are not scanned for dependencies.
diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf
index 516e810c21..f5a4422601 100644
--- a/doc/global/manifest-meta.qdocconf
+++ b/doc/global/manifest-meta.qdocconf
@@ -39,15 +39,18 @@ manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \
"QtQuick/Qt Quick Demo - Tweet Search" \
"QtQuick/Qt Quick Demo - Maroon*" \
"QtQuick/Qt Quick Demo - Calqlatr" \
- "QtQuick/Qt Quick Particles Examples - Emitters" \
+ "QtQuick/Qt Quick Demo - StocQt" \
+ "QtQuick/Qt Quick Demo - Clocks" \
"QtQuick/Qt Quick Examples - Shader Effects" \
- "QtWebKitExamples/Fancy Browser" \
- "QtWebKitExamples/Flickr View Example" \
- "QtWebKitExamples/YouTube View Example" \
+ "QtQuick/Qt Quick Examples - Text" \
+ "QtQuick/Qt Quick Examples - Window and Screen" \
"QtQuickControls/Qt Quick Controls - Gallery" \
"QtQuickControls/Qt Quick Controls - Text Editor Example" \
"QtQuickControls/Qt Quick Controls - Table View Example" \
- "QtWidgets/Application Example"
+ "QtQuickControls/Qt Quick Controls - Calendar Example" \
+ "QtQuickDialogs/Qt Quick System Dialog Examples" \
+ "QtWidgets/Application Example" \
+ "QtWinExtras/Quick Player"
manifestmeta.highlighted.attributes = isHighlighted:true
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index 9c68218062..f5e5352d5e 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -214,22 +214,23 @@ init_context:
}
// Add all our CAs to this store.
- QList<QSslCertificate> expiredCerts;
foreach (const QSslCertificate &caCertificate, sslContext->sslConfiguration.caCertificates()) {
- // add expired certs later, so that the
- // valid ones are used before the expired ones
- if (caCertificate.expiryDate() < QDateTime::currentDateTime()) {
- expiredCerts.append(caCertificate);
- } else {
+ // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
+ //
+ // If several CA certificates matching the name, key identifier, and
+ // serial number condition are available, only the first one will be
+ // examined. This may lead to unexpected results if the same CA
+ // certificate is available with different expiration dates. If a
+ // ``certificate expired'' verification error occurs, no other
+ // certificate will be searched. Make sure to not have expired
+ // certificates mixed with valid ones.
+ //
+ // See also: QSslSocketBackendPrivate::verify()
+ if (caCertificate.expiryDate() >= QDateTime::currentDateTime()) {
q_X509_STORE_add_cert(sslContext->ctx->cert_store, (X509 *)caCertificate.handle());
}
}
- // now add the expired certs
- foreach (const QSslCertificate &caCertificate, expiredCerts) {
- q_X509_STORE_add_cert(sslContext->ctx->cert_store, reinterpret_cast<X509 *>(caCertificate.handle()));
- }
-
if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
// tell OpenSSL the directories where to look up the root certs on demand
QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index f9f7d0b35d..2ee69d35da 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1600,23 +1600,23 @@ QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certifi
setDefaultCaCertificates(defaultCaCertificates() + systemCaCertificates());
}
- QList<QSslCertificate> expiredCerts;
-
foreach (const QSslCertificate &caCertificate, QSslSocket::defaultCaCertificates()) {
- // add expired certs later, so that the
- // valid ones are used before the expired ones
- if (caCertificate.expiryDate() < QDateTime::currentDateTime()) {
- expiredCerts.append(caCertificate);
- } else {
+ // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
+ //
+ // If several CA certificates matching the name, key identifier, and
+ // serial number condition are available, only the first one will be
+ // examined. This may lead to unexpected results if the same CA
+ // certificate is available with different expiration dates. If a
+ // ``certificate expired'' verification error occurs, no other
+ // certificate will be searched. Make sure to not have expired
+ // certificates mixed with valid ones.
+ //
+ // See also: QSslContext::fromConfiguration()
+ if (caCertificate.expiryDate() >= QDateTime::currentDateTime()) {
q_X509_STORE_add_cert(certStore, reinterpret_cast<X509 *>(caCertificate.handle()));
}
}
- // now add the expired certs
- foreach (const QSslCertificate &caCertificate, expiredCerts) {
- q_X509_STORE_add_cert(certStore, reinterpret_cast<X509 *>(caCertificate.handle()));
- }
-
QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
// Register a custom callback to get all verification errors.
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
index 24e9ccd39f..ab92bac37d 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
@@ -100,9 +100,8 @@ void QEGLPlatformBackingStore::updateTexture()
glBindTexture(GL_TEXTURE_2D, m_bsTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- // QOpenGLTextureBlitter requires GL_REPEAT for the time being
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
} else {
glBindTexture(GL_TEXTURE_2D, m_bsTexture);
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 773220660a..e2ff7197aa 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -425,17 +425,8 @@ QWinRTScreen::QWinRTScreen(ICoreWindow *window)
#endif
, m_cursor(new QWinRTCursor(window))
, m_orientation(Qt::PrimaryOrientation)
+ , m_touchDevice(Q_NULLPTR)
{
-#ifdef Q_OS_WINPHONE // On phone, there can be only one touch device
- QTouchDevice *touchDevice = new QTouchDevice;
- touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
- touchDevice->setType(QTouchDevice::TouchScreen);
- touchDevice->setName(QStringLiteral("WinPhoneTouchScreen"));
- Pointer pointer = { Pointer::TouchScreen, touchDevice };
- m_pointers.insert(0, pointer);
- QWindowSystemInterface::registerTouchDevice(touchDevice);
-#endif
-
Rect rect;
window->get_Bounds(&rect);
m_geometry = QRect(0, 0, rect.Width, rect.Height);
@@ -763,47 +754,25 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
if (FAILED(pointerPoint->get_Properties(&properties)))
return E_INVALIDARG;
-#ifdef Q_OS_WINPHONE
- quint32 pointerId = 0;
- Pointer pointer = m_pointers.value(pointerId);
+ PointerDeviceType pointerDeviceType;
+#if defined(Q_OS_WINPHONE) && _MSC_VER <= 1700
+ pointerDeviceType = PointerDeviceType_Touch;
#else
- Pointer pointer = { Pointer::Unknown, 0 };
- quint32 pointerId;
- pointerPoint->get_PointerId(&pointerId);
- if (m_pointers.contains(pointerId)) {
- pointer = m_pointers.value(pointerId);
- } else { // We have not yet enumerated this device. Do so now...
- IPointerDevice *device;
- if (SUCCEEDED(pointerPoint->get_PointerDevice(&device))) {
- PointerDeviceType type;
- device->get_PointerDeviceType(&type);
- switch (type) {
- case PointerDeviceType_Touch:
- pointer.type = Pointer::TouchScreen;
- pointer.device = new QTouchDevice;
- pointer.device->setName(QStringLiteral("WinRT TouchScreen ") + QString::number(pointerId));
- // TODO: We may want to probe the device usage flags for more accurate values for these next two
- pointer.device->setType(QTouchDevice::TouchScreen);
- pointer.device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
- QWindowSystemInterface::registerTouchDevice(pointer.device);
- break;
-
- case PointerDeviceType_Pen:
- pointer.type = Pointer::Tablet;
- break;
-
- case PointerDeviceType_Mouse:
- pointer.type = Pointer::Mouse;
- break;
- }
-
- m_pointers.insert(pointerId, pointer);
- device->Release();
- }
+ ComPtr<IPointerDevice> pointerDevice;
+ HRESULT hr = pointerPoint->get_PointerDevice(&pointerDevice);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get pointer device.");
+ return S_OK;
+ }
+
+ hr = pointerDevice->get_PointerDeviceType(&pointerDeviceType);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get pointer device type.");
+ return S_OK;
}
#endif
- switch (pointer.type) {
- case Pointer::Mouse: {
+ switch (pointerDeviceType) {
+ case PointerDeviceType_Mouse: {
qint32 delta;
properties->get_MouseWheelDelta(&delta);
if (delta) {
@@ -840,7 +809,15 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
break;
}
- case Pointer::TouchScreen: {
+ case PointerDeviceType_Touch: {
+ if (!m_touchDevice) {
+ m_touchDevice = new QTouchDevice;
+ m_touchDevice->setName(QStringLiteral("WinRTTouchScreen"));
+ m_touchDevice->setType(QTouchDevice::TouchScreen);
+ m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition);
+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
+ }
+
quint32 id;
pointerPoint->get_PointerId(&id);
@@ -868,7 +845,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
it.value().normalPosition = QPointF(pos.x()/m_geometry.width(), pos.y()/m_geometry.height());
it.value().pressure = pressure;
- QWindowSystemInterface::handleTouchEvent(topWindow(), pointer.device, m_touchPoints.values(), mods);
+ QWindowSystemInterface::handleTouchEvent(topWindow(), m_touchDevice, m_touchPoints.values(), mods);
// Remove released points, station others
for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = m_touchPoints.begin(); i != m_touchPoints.end();) {
@@ -880,7 +857,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
break;
}
- case Pointer::Tablet: {
+ case PointerDeviceType_Pen: {
quint32 id;
pointerPoint->get_PointerId(&id);
@@ -903,7 +880,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *a
float rotation;
properties->get_Twist(&rotation);
- QWindowSystemInterface::handleTabletEvent(topWindow(), isPressed, pos, pos, pointerId,
+ QWindowSystemInterface::handleTabletEvent(topWindow(), isPressed, pos, pos, 0,
pointerType, pressure, xTilt, yTilt,
0, rotation, 0, id, mods);
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index c6511e9446..753d89541c 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -101,12 +101,6 @@ class QWinRTPageFlipper;
class QWinRTCursor;
class QWinRTInputContext;
-struct Pointer {
- enum Type { Unknown, Mouse, TouchScreen, Tablet };
- Type type;
- QTouchDevice *device;
-};
-
class QWinRTScreen : public QPlatformScreen
{
public:
@@ -165,6 +159,7 @@ private:
ABI::Windows::UI::Core::ICoreWindow *m_coreWindow;
ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView;
ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application;
+
QRect m_geometry;
QImage::Format m_format;
QSurfaceFormat m_surfaceFormat;
@@ -183,7 +178,7 @@ private:
#ifndef Q_OS_WINPHONE
QHash<quint32, QPair<Qt::Key, QString> > m_activeKeys;
#endif
- QHash<quint32, Pointer> m_pointers;
+ QTouchDevice *m_touchDevice;
QHash<quint32, QWindowSystemInterface::TouchPoint> m_touchPoints;
};
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index e3b81c2b40..f5f6c712c5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1791,19 +1791,6 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
return true;
}
-bool QXcbConnection::xi2GetButtonState(void *event, int buttonNum)
-{
- xXIDeviceEvent *xideviceevent = static_cast<xXIDeviceEvent *>(event);
- unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1];
-
- for (int i = 0; i < (xideviceevent->buttons_len * 4); i++) {
- if (buttonNum < 8)
- return (buttonsMaskAddr[i] & (1 << buttonNum));
- buttonNum -= 8;
- }
- return false;
-}
-
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
// - "pad1" and "pad" became "pad0"
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 1933b89a19..6e511356c4 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -532,7 +532,6 @@ private:
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
- static bool xi2GetButtonState(void *event, int buttonNum);
#endif
xcb_connection_t *m_connection;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 831ccba6f6..efa1691780 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -575,7 +575,7 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
#ifdef XCB_USE_XINPUT21
xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
- if (xiEvent->evtype == XI_Motion) {
+ if (xiEvent->evtype == XI_Motion && scrollingDevice.orientations) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint rawDelta;
@@ -612,20 +612,20 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
}
}
- } else if (xiEvent->evtype == XI_ButtonRelease) {
+ } else if (xiEvent->evtype == XI_ButtonRelease && scrollingDevice.legacyOrientations) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint angleDelta;
if (scrollingDevice.legacyOrientations & Qt::Vertical) {
- if (xi2GetButtonState(xiDeviceEvent, 4))
+ if (xiDeviceEvent->detail == 4)
angleDelta.setY(120);
- else if (xi2GetButtonState(xiDeviceEvent, 5))
+ else if (xiDeviceEvent->detail == 5)
angleDelta.setY(-120);
}
if (scrollingDevice.legacyOrientations & Qt::Horizontal) {
- if (xi2GetButtonState(xiDeviceEvent, 6))
+ if (xiDeviceEvent->detail == 6)
angleDelta.setX(120);
- if (xi2GetButtonState(xiDeviceEvent, 7))
+ else if (xiDeviceEvent->detail == 7)
angleDelta.setX(-120);
}
if (!angleDelta.isNull()) {