From 621ab8ab59901cc3f9bd98be709929c9eac997a8 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 4 Sep 2018 11:08:06 +0200 Subject: bmp image handler: check for out of range image size Make the decoder fail early to avoid spending time and memory on attempting to decode a corrupt image file. Change-Id: I874e04f3b43122d73f8e58c7a5bcc4a741b68264 Reviewed-by: Lars Knoll --- src/gui/image/qbmphandler.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 587f375ce7..5dff4ab0ac 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -188,6 +188,8 @@ static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi) if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) || (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS))) return false; // weird compression type + if (bi.biWidth < 0 || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384) + return false; return true; } -- cgit v1.2.3 From bff307ab93bd6963f84e08e8050efa6a838dba6e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Aug 2018 14:58:43 +0200 Subject: Fix XCB on endian mismatched client and server with SHM off If SHM is disabled, that code path already does its own bswaping. Change-Id: I6c17f6c5c5502c8f89098d38d931b6b8f50b2640 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 9966e06c7b..c9dde35558 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -412,6 +412,8 @@ public: bool imageNeedsEndianSwap() const { + if (!hasShm()) + return false; // The non-Shm path does its own swapping #if Q_BYTE_ORDER == Q_BIG_ENDIAN return m_setup->image_byte_order != XCB_IMAGE_ORDER_MSB_FIRST; #else -- cgit v1.2.3 From 45c1473847ad65c4d43f9a605a86439867442883 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 13 Sep 2018 01:59:26 +0200 Subject: Detect when we are at the sentence boundary On Samsung devices this would cause it to always to captalize each word even if it was not a new sentence. Therefore we use QTextBoundaryFinder to determine if it is a new sentence or not. Task-number: QTBUG-69398 Task-number: QTBUG-66531 Change-Id: I24bf36f09a2570acfefd4343551cb1720ddc6279 Reviewed-by: BogDan Vatra Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidinputcontext.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index f548a1fa96..c46a435db1 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -58,6 +58,7 @@ #include #include +#include #include @@ -892,8 +893,19 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/) return res; const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt(); - - if (!(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase)) + const int localPos = query->value(Qt::ImCursorPosition).toInt(); + + bool atWordBoundary = (localPos == 0); + if (!atWordBoundary) { + QString surroundingText = query->value(Qt::ImSurroundingText).toString(); + surroundingText.truncate(localPos); + // Add a character to see if it is at the end of the sentence or not + QTextBoundaryFinder finder(QTextBoundaryFinder::Sentence, surroundingText + QLatin1Char('A')); + finder.setPosition(localPos); + if (finder.isAtBoundary()) + atWordBoundary = finder.isAtBoundary(); + } + if (atWordBoundary && !(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase)) res |= CAP_MODE_SENTENCES; if (qtInputMethodHints & Qt::ImhUppercaseOnly) -- cgit v1.2.3 From 2c649856d5c27a55f04f572f88bebaa142f7b1c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Sep 2018 13:33:29 +0200 Subject: macOS: Clarify what static mutex in QCocoaGLContext is used for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I4af0b78dbecad40b2a73cdbdb09a8eb60efdb013 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index f11016679a..069429796e 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -393,8 +393,10 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) return true; } -// NSOpenGLContext is not re-entrant (https://openradar.appspot.com/37064579) -static QMutex s_contextMutex; +// NSOpenGLContext is not re-entrant. Even when using separate contexts per thread, +// view, and window, calls into the API will still deadlock. For more information +// see https://openradar.appspot.com/37064579 +static QMutex s_reentrancyMutex; void QCocoaGLContext::update() { @@ -403,7 +405,7 @@ void QCocoaGLContext::update() // render-loop that doesn't return to one of the outer pools. QMacAutoReleasePool pool; - QMutexLocker locker(&s_contextMutex); + QMutexLocker locker(&s_reentrancyMutex); qCInfo(lcQpaOpenGLContext) << "Updating" << m_context << "for" << m_context.view; [m_context update]; } @@ -422,7 +424,7 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface) return; } - QMutexLocker locker(&s_contextMutex); + QMutexLocker locker(&s_reentrancyMutex); [m_context flushBuffer]; } -- cgit v1.2.3 From 704a3989d15f3a59106a00655534b12a1d7a2aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 12 Sep 2018 12:42:44 +0200 Subject: Fix spelling mistake in qimage.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2138318894587cc0b5f03af14a57b2a39509f0da Reviewed-by: Eirik Aavitsland Reviewed-by: Tor Arne Vestbø --- src/gui/image/qimage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 7764c19452..4b7a3b1ead 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -334,7 +334,7 @@ public: static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW; static QImage::Format toImageFormat(QPixelFormat format) Q_DECL_NOTHROW; - // Platform spesific conversion functions + // Platform specific conversion functions #if defined(Q_OS_DARWIN) || defined(Q_QDOC) CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED; #endif -- cgit v1.2.3 From c9f316c8b90ce8bb11b6e9e0bf898c269cd35bfb Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 11 Sep 2018 19:18:35 +0200 Subject: ODBC: Correctly check if the field is within the fieldCache range This was found while running the ODBC tests. tst_QSqlQuery::isNull() accounts for this already. Change-Id: Idf99a85396d7aa4e69b89467f873b105ef946f7f Reviewed-by: Christian Ehrlicher Reviewed-by: Edward Welbourne --- src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index daf9686b5e..1fbbcd0ef1 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -1307,7 +1307,7 @@ QVariant QODBCResult::data(int field) bool QODBCResult::isNull(int field) { Q_D(const QODBCResult); - if (field < 0 || field > d->fieldCache.size()) + if (field < 0 || field >= d->fieldCache.size()) return true; if (field <= d->fieldCacheIdx) { // since there is no good way to find out whether the value is NULL -- cgit v1.2.3 From 49efea26a5fae8c2275999c36c7c8d24cf4125de Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 12 Sep 2018 10:04:39 +0200 Subject: sqlite: Fix QSqlError handling when opening/closing database Both sqlite3_open_v2 and sqlite3_close are documented to return an error code: https://www.sqlite.org/c3ref/open.html https://sqlite.org/c3ref/close.html However, those were ignored (other than checking whether the operation succeeded), causing QSqlError::nativeErrorCode() to always be "-1" when there was an error while opening/closing the database. Additionally, the error string needs to be read (via sqlite3_errmsg16) in qMakeError *before* d->access is set to 0, or the databaseText() will always be "out of memory" no matter what error actually happened. Task-number: QTBUG-70506 Change-Id: I75cbf178c9711442e640afd26c4502214d20c598 Reviewed-by: Andy Shaw Reviewed-by: Simon Hausmann Reviewed-by: Edward Welbourne --- src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index 2a770d0245..491d903137 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -109,7 +109,7 @@ static QVariant::Type qGetColumnType(const QString &tpName) } static QSqlError qMakeError(sqlite3 *access, const QString &descr, QSqlError::ErrorType type, - int errorCode = -1) + int errorCode) { return QSqlError(descr, QString(reinterpret_cast(sqlite3_errmsg16(access))), @@ -803,7 +803,9 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c openMode |= SQLITE_OPEN_NOMUTEX; - if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) { + const int res = sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL); + + if (res == SQLITE_OK) { sqlite3_busy_timeout(d->access, timeOut); setOpen(true); setOpenError(false); @@ -816,14 +818,15 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c #endif return true; } else { + setLastError(qMakeError(d->access, tr("Error opening database"), + QSqlError::ConnectionError, res)); + setOpenError(true); + if (d->access) { sqlite3_close(d->access); d->access = 0; } - setLastError(qMakeError(d->access, tr("Error opening database"), - QSqlError::ConnectionError)); - setOpenError(true); return false; } } @@ -840,8 +843,10 @@ void QSQLiteDriver::close() sqlite3_update_hook(d->access, NULL, NULL); } - if (sqlite3_close(d->access) != SQLITE_OK) - setLastError(qMakeError(d->access, tr("Error closing database"), QSqlError::ConnectionError)); + const int res = sqlite3_close(d->access); + + if (res != SQLITE_OK) + setLastError(qMakeError(d->access, tr("Error closing database"), QSqlError::ConnectionError, res)); d->access = 0; setOpen(false); setOpenError(false); -- cgit v1.2.3 From 74700493c33bf8acc2973a6d151be209fd606655 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Thu, 13 Sep 2018 16:32:13 +0200 Subject: Doc: Remove extra \a command causing QDoc macro expansion error Change-Id: I453a68a579e4fd519616cd1a9f934501b01ef44c Reviewed-by: Martin Smith --- src/corelib/kernel/qmetatype.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 82952919dd..eb67544f21 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1058,7 +1058,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter, \internal \since 5.12 - Registers a user type for marshalling, with \a typeName, a \a + Registers a user type for marshalling, with \a typeName, a \a destructor, a \a constructor, and a \a size. Returns the type's handle, or -1 if the type could not be registered. */ -- cgit v1.2.3 From 5728a9d8a7f8b64099cf369d9d307a00b5fce29c Mon Sep 17 00:00:00 2001 From: Romain Pokrzywka Date: Wed, 22 Aug 2018 22:43:29 -0500 Subject: Windows QPA: Dispatch skipped touch/pen events if compression is off If the hardware produces events faster than the app can consume between two updates, Windows automatically coalesces them into a single message with the latest touch/pen pointer state and coordinates, effectively compressing those events. But the pointer API also supports querying and retrieving the skipped individual touch and pen frames. There are cases where keeping all the events generated by the hardware is desired, especially for pen events where having the most sampled points available is critical to precisely rendering curves. Qt already defines application attributes to control event compression for general high frequency events and for tablet events in particular. Use them on Windows also to control whether to retrieve skipped frames. [ChangeLog][Windows] The application attributes AA_CompressTabletEvents and AA_CompressHighFrequencyEvents are now supported on Windows 8 and above for touch/pen input, with the same defaults as on X11 (compress touch events, don't compress tablet events) Task-number: QTBUG-44964 Task-number: QTBUG-60437 Change-Id: I1b11a043e2d71ee502895971fafb3a46306a89d8 Reviewed-by: Andre de la Rocha Reviewed-by: Friedemann Kleint --- src/corelib/global/qnamespace.qdoc | 10 +++-- src/plugins/platforms/windows/qwindowscontext.cpp | 6 ++- src/plugins/platforms/windows/qwindowscontext.h | 4 ++ .../platforms/windows/qwindowsintegration.cpp | 4 +- .../platforms/windows/qwindowspointerhandler.cpp | 49 ++++++++++++++++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 37144dcf17..42009e0b5e 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -245,7 +245,10 @@ QEvent::MouseMove, QEvent::TouchUpdate, and changes in window size and position will be combined whenever they occur more frequently than the application handles them, so that they don't accumulate and overwhelm the - application later. On other platforms, the default is false. + application later. + On Windows 8 and above the default value is also true, but it only applies + to touch events. Mouse and window events remain unaffected by this flag. + On other platforms, the default is false. (In the future, the compression feature may be implemented across platforms.) You can test the attribute to see whether compression is enabled. If your application needs to handle all events with no compression, @@ -256,8 +259,9 @@ \value AA_CompressTabletEvents Enables compression of input events from tablet devices. Notice that AA_CompressHighFrequencyEvents must be true for events compression - to be enabled, and that this flag extends the former to tablet events. Its default - value is false. + to be enabled, and that this flag extends the former to tablet events. + Currently supported on the X11 windowing system, Windows 8 and above. + The default value is false. This value was added in Qt 5.10. \value AA_DontCheckOpenGLContextThreadAffinity When making a context diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 03bb1bee48..373758b49e 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -201,7 +201,9 @@ void QWindowsUser32DLL::init() getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects"); getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo"); getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo"); + getPointerFrameTouchInfoHistory = (GetPointerFrameTouchInfoHistory)library.resolve("GetPointerFrameTouchInfoHistory"); getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo"); + getPointerPenInfoHistory = (GetPointerPenInfoHistory)library.resolve("GetPointerPenInfoHistory"); skipPointerFrameMessages = (SkipPointerFrameMessages)library.resolve("SkipPointerFrameMessages"); } @@ -216,8 +218,8 @@ void QWindowsUser32DLL::init() bool QWindowsUser32DLL::supportsPointerApi() { return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects - && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo - && skipPointerFrameMessages; + && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerFrameTouchInfoHistory + && getPointerPenInfo && getPointerPenInfoHistory && skipPointerFrameMessages; } void QWindowsShcoreDLL::init() diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 8102e0bf19..622c729a10 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -92,7 +92,9 @@ struct QWindowsUser32DLL typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *); typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID); + typedef BOOL (WINAPI *GetPointerFrameTouchInfoHistory)(UINT32, UINT32 *, UINT32 *, PVOID); typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID); + typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID); typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32); typedef BOOL (WINAPI *SetProcessDPIAware)(); typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND); @@ -110,7 +112,9 @@ struct QWindowsUser32DLL GetPointerDeviceRects getPointerDeviceRects = nullptr; GetPointerTouchInfo getPointerTouchInfo = nullptr; GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr; + GetPointerFrameTouchInfoHistory getPointerFrameTouchInfoHistory = nullptr; GetPointerPenInfo getPointerPenInfo = nullptr; + GetPointerPenInfoHistory getPointerPenInfoHistory = nullptr; SkipPointerFrameMessages skipPointerFrameMessages = nullptr; // Windows Vista onwards diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 0694435427..7d621126b9 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -236,7 +236,9 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness); QWindowsFontDatabase::setFontOptions(m_options); - if (!m_context.initPointer(m_options)) { + if (m_context.initPointer(m_options)) { + QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents); + } else { m_context.initTablet(m_options); if (tabletAbsoluteRange >= 0) m_context.setTabletAbsoluteRange(tabletAbsoluteRange); diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index d8918d1b3d..7ead14822a 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -106,6 +106,32 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string(); return false; } + + if (!pointerCount) + return false; + + // The history count is the same for all the touchpoints in touchInfo + quint32 historyCount = touchInfo[0].pointerInfo.historyCount; + // dispatch any skipped frames if event compression is disabled by the app + if (historyCount > 1 && !QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) { + touchInfo.resize(pointerCount * historyCount); + if (!QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId, + &historyCount, + &pointerCount, + touchInfo.data())) { + qWarning() << "GetPointerFrameTouchInfoHistory() failed:" << qt_error_string(); + return false; + } + + // history frames are returned with the most recent frame first so we iterate backwards + bool result = true; + for (auto it = touchInfo.rbegin(), end = touchInfo.rend(); it != end; it += pointerCount) { + result &= translateTouchEvent(window, hwnd, et, msg, + &(*(it + (pointerCount - 1))), pointerCount); + } + return result; + } + return translateTouchEvent(window, hwnd, et, msg, touchInfo.data(), pointerCount); } case QT_PT_PEN: { @@ -114,6 +140,29 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q qWarning() << "GetPointerPenInfo() failed:" << qt_error_string(); return false; } + + quint32 historyCount = penInfo.pointerInfo.historyCount; + // dispatch any skipped frames if generic or tablet event compression is disabled by the app + if (historyCount > 1 + && (!QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents) + || !QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents))) { + QVarLengthArray penInfoHistory(historyCount); + + if (!QWindowsContext::user32dll.getPointerPenInfoHistory(pointerId, + &historyCount, + penInfoHistory.data())) { + qWarning() << "GetPointerPenInfoHistory() failed:" << qt_error_string(); + return false; + } + + // history frames are returned with the most recent frame first so we iterate backwards + bool result = true; + for (auto it = penInfoHistory.rbegin(), end = penInfoHistory.rend(); it != end; ++it) { + result &= translatePenEvent(window, hwnd, et, msg, &(*(it))); + } + return result; + } + return translatePenEvent(window, hwnd, et, msg, &penInfo); } } -- cgit v1.2.3 From 6ff862a6821112ede25a7a2da646ca279812ed50 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 12 Sep 2018 21:01:04 +0200 Subject: Fix binary compatibility with old generated moc files Commit 1c623bc6d1c0a7ca52d81ca72c64f36898b3e12c introduced a new QMetaObject revision, which change the size of the QMetaEnum data. When looking up QMetaEnum in a QMetaObject, this size need to be checked for every different QMEtaObject from the hierarchy, not just the first one. Change-Id: I6f0d3982329822e15e284aef9b141d4c9ab351b9 Reviewed-by: David Faure Reviewed-by: Thiago Macieira Reviewed-by: Allan Sandfeld Jensen --- src/corelib/kernel/qmetaobject.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 6c17535f07..a6ee12ede1 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -970,9 +970,9 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co int QMetaObject::indexOfEnumerator(const char *name) const { const QMetaObject *m = this; - const int intsPerEnum = priv(m->d.data)->revision >= 8 ? 5 : 4; while (m) { const QMetaObjectPrivate *d = priv(m->d.data); + const int intsPerEnum = d->revision >= 8 ? 5 : 4; for (int i = d->enumeratorCount - 1; i >= 0; --i) { const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i]); if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { @@ -986,6 +986,7 @@ int QMetaObject::indexOfEnumerator(const char *name) const m = this; while (m) { const QMetaObjectPrivate *d = priv(m->d.data); + const int intsPerEnum = d->revision >= 8 ? 5 : 4; for (int i = d->enumeratorCount - 1; i >= 0; --i) { const char *prop = rawStringData(m, m->d.data[d->enumeratorData + intsPerEnum * i + 1]); if (name[0] == prop[0] && strcmp(name + 1, prop + 1) == 0) { -- cgit v1.2.3