From 621ab8ab59901cc3f9bd98be709929c9eac997a8 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 4 Sep 2018 11:08:06 +0200 Subject: [PATCH 01/16] 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(+) 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; } From e04b85b026f59120e69a4acb3f3e4469abccc325 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 10 Sep 2018 10:51:33 +0200 Subject: [PATCH 02/16] Doc: improve Mandelbrot example Change-Id: Iac6c3e681f3d5b195d08513ac5fe4b661c3d0f59 Reviewed-by: Andy Nichols --- examples/corelib/threads/doc/src/mandelbrot.qdoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/corelib/threads/doc/src/mandelbrot.qdoc b/examples/corelib/threads/doc/src/mandelbrot.qdoc index dd0e4e5ef2..274874632e 100644 --- a/examples/corelib/threads/doc/src/mandelbrot.qdoc +++ b/examples/corelib/threads/doc/src/mandelbrot.qdoc @@ -39,7 +39,7 @@ The heavy computation here is the Mandelbrot set, probably the world's most famous fractal. These days, while sophisticated - programs such as \l{http://xaos.sourceforge.net/}{XaoS} that provide real-time zooming in the + programs such as \l{http://matek.hu/xaos/doku.php}{XaoS} that provide real-time zooming in the Mandelbrot set, the standard Mandelbrot algorithm is just slow enough for our purposes. @@ -201,7 +201,7 @@ \snippet threads/mandelbrot/renderthread.cpp 9 Once we're done with all the iterations, we call - QWaitCondition::wait() to put the thread to sleep by calling, + QWaitCondition::wait() to put the thread to sleep, unless \c restart is \c true. There's no use in keeping a worker thread looping indefinitely while there's nothing to do. @@ -232,7 +232,7 @@ \snippet threads/mandelbrot/mandelbrotwidget.cpp 0 - The implementation starts with a few contants that we'll need + The implementation starts with a few constants that we'll need later on. \snippet threads/mandelbrot/mandelbrotwidget.cpp 1 @@ -256,15 +256,15 @@ slot later on. Qt knows how to take of copy of many C++ and Qt types, but QImage isn't one of them. We must therefore call the template function qRegisterMetaType() before we can use QImage - as parameter in queued connections. + as a parameter in queued connections. \snippet threads/mandelbrot/mandelbrotwidget.cpp 2 \snippet threads/mandelbrot/mandelbrotwidget.cpp 3 \snippet threads/mandelbrot/mandelbrotwidget.cpp 4 In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling - the background with black. If we have nothing yet to paint (\c - pixmap is null), we print a message on the widget asking the user + the background with black. If we have nothing to paint yet (\c + pixmap is null), we display a message on the widget asking the user to be patient and return from the function immediately. \snippet threads/mandelbrot/mandelbrotwidget.cpp 5 @@ -293,7 +293,7 @@ Notice that we rely on \c resizeEvent() being automatically called by Qt when the widget is shown the first time to generate - the image the very first time. + the initial image. \snippet threads/mandelbrot/mandelbrotwidget.cpp 11 @@ -307,7 +307,7 @@ control the zoom level. QWheelEvent::delta() returns the angle of the wheel mouse movement, in eights of a degree. For most mice, one wheel step corresponds to 15 degrees. We find out how many - mouse steps we have and determine the zoom factor in consequence. + mouse steps we have and determine the resulting zoom factor. For example, if we have two wheel steps in the positive direction (i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor to the second power, i.e. 0.8 * 0.8 = 0.64. From bff307ab93bd6963f84e08e8050efa6a838dba6e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Aug 2018 14:58:43 +0200 Subject: [PATCH 03/16] 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(+) 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 From 45c1473847ad65c4d43f9a605a86439867442883 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 13 Sep 2018 01:59:26 +0200 Subject: [PATCH 04/16] 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 --- .../platforms/android/qandroidinputcontext.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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(); + const int localPos = query->value(Qt::ImCursorPosition).toInt(); - if (!(qtInputMethodHints & Qt::ImhLowercaseOnly) && !(qtInputMethodHints & Qt::ImhNoAutoUppercase)) + 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) 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: [PATCH 05/16] 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(-) 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]; } 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: [PATCH 06/16] 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(-) 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 From 14bae62bd2e965a25e61564eb2f7e61ad7b1e9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 11 Sep 2018 13:03:56 +0200 Subject: [PATCH 07/16] Blacklist flaky tst_QGL::graphicsViewClipping on RHEL 7.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic771b263c988525d4b887cb2a1de9f9c7343e49b Reviewed-by: Liang Qi Reviewed-by: Tor Arne Vestbø --- tests/auto/opengl/qgl/BLACKLIST | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST index 71be4bf19d..1eb0197484 100644 --- a/tests/auto/opengl/qgl/BLACKLIST +++ b/tests/auto/opengl/qgl/BLACKLIST @@ -19,6 +19,7 @@ winrt [graphicsViewClipping] windows winrt +rhel-7.4 ci [glFBOUseInGLWidget] windows winrt From c9f316c8b90ce8bb11b6e9e0bf898c269cd35bfb Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 11 Sep 2018 19:18:35 +0200 Subject: [PATCH 08/16] 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(-) 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 From 49efea26a5fae8c2275999c36c7c8d24cf4125de Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 12 Sep 2018 10:04:39 +0200 Subject: [PATCH 09/16] 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 ++++++++++++------- .../kernel/qsqldatabase/tst_qsqldatabase.cpp | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) 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); diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 1f055e9c33..8cf43e243b 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -197,6 +197,8 @@ private slots: void sqlite_enableRegexp_data() { generic_data("QSQLITE"); } void sqlite_enableRegexp(); + void sqlite_openError(); + private: void createTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db); @@ -2332,6 +2334,22 @@ void tst_QSqlDatabase::sqlite_enableRegexp() QFAIL_SQL(q, next()); } +void tst_QSqlDatabase::sqlite_openError() +{ + // see QTBUG-70506 + if (!QSqlDatabase::drivers().contains("QSQLITE")) + QSKIP("Database driver QSQLITE not available"); + + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite_openError"); + db.setDatabaseName("/doesnotexist/foo.sqlite"); + QVERIFY(db.isValid()); + + QVERIFY(!db.open()); + QSqlError error = db.lastError(); + QCOMPARE(error.nativeErrorCode(), "14"); // SQLITE_CANTOPEN + QCOMPARE(error.databaseText(), "unable to open database file"); +} + void tst_QSqlDatabase::cloneDatabase() { QFETCH(QString, dbName); From 74700493c33bf8acc2973a6d151be209fd606655 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Thu, 13 Sep 2018 16:32:13 +0200 Subject: [PATCH 10/16] 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(-) 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. */ From a62bab95d3adfcd6aab1f32d41750f0c1a5adfe3 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Wed, 12 Sep 2018 12:57:33 +0200 Subject: [PATCH 11/16] Doc: Move touch examples around so they get included in docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-59249 Change-Id: I71f1d2e28f0cadbad1d6bcf117198018eaf8e012 Reviewed-by: Topi Reiniö --- examples/examples.pro | 3 +-- examples/{ => widgets}/touch/dials/dials.pro | 2 +- examples/{ => widgets}/touch/dials/dials.ui | 0 .../dials/doc/images/touch-dials-example.png | Bin .../touch/dials/doc/src/touch-dials.qdoc | 2 +- examples/{ => widgets}/touch/dials/main.cpp | 0 .../touch/fingerpaint/doc/src}/fingerpaint.qdoc | 2 +- .../touch/fingerpaint/fingerpaint.pro | 2 +- .../{ => widgets}/touch/fingerpaint/main.cpp | 0 .../touch/fingerpaint/mainwindow.cpp | 0 .../touch/fingerpaint/mainwindow.h | 0 .../touch/fingerpaint/scribblearea.cpp | 0 .../touch/fingerpaint/scribblearea.h | 0 .../knobs/doc/images/touch-knobs-example.png | Bin .../touch/knobs/doc/src/touch-knobs.qdoc | 2 +- examples/{ => widgets}/touch/knobs/knob.cpp | 0 examples/{ => widgets}/touch/knobs/knob.h | 0 examples/{ => widgets}/touch/knobs/knobs.pro | 2 +- examples/{ => widgets}/touch/knobs/main.cpp | 0 .../pinchzoom/doc/images/pinch-zoom-example.png | Bin 0 -> 42493 bytes .../touch/pinchzoom/doc/src}/pinchzoom.qdoc | 2 +- .../touch/pinchzoom/graphicsview.cpp | 0 .../touch/pinchzoom/graphicsview.h | 0 .../touch/pinchzoom/images/cheese.jpg | Bin examples/{ => widgets}/touch/pinchzoom/main.cpp | 0 examples/{ => widgets}/touch/pinchzoom/mice.qrc | 0 .../{ => widgets}/touch/pinchzoom/mouse.cpp | 0 examples/{ => widgets}/touch/pinchzoom/mouse.h | 0 .../{ => widgets}/touch/pinchzoom/pinchzoom.pro | 2 +- examples/{ => widgets}/touch/touch.pro | 0 examples/widgets/widgets.pro | 1 + 31 files changed, 10 insertions(+), 10 deletions(-) rename examples/{ => widgets}/touch/dials/dials.pro (58%) rename examples/{ => widgets}/touch/dials/dials.ui (100%) rename examples/{ => widgets}/touch/dials/doc/images/touch-dials-example.png (100%) rename examples/{ => widgets}/touch/dials/doc/src/touch-dials.qdoc (99%) rename examples/{ => widgets}/touch/dials/main.cpp (100%) rename {doc/src/examples => examples/widgets/touch/fingerpaint/doc/src}/fingerpaint.qdoc (99%) rename examples/{ => widgets}/touch/fingerpaint/fingerpaint.pro (81%) rename examples/{ => widgets}/touch/fingerpaint/main.cpp (100%) rename examples/{ => widgets}/touch/fingerpaint/mainwindow.cpp (100%) rename examples/{ => widgets}/touch/fingerpaint/mainwindow.h (100%) rename examples/{ => widgets}/touch/fingerpaint/scribblearea.cpp (100%) rename examples/{ => widgets}/touch/fingerpaint/scribblearea.h (100%) rename examples/{ => widgets}/touch/knobs/doc/images/touch-knobs-example.png (100%) rename examples/{ => widgets}/touch/knobs/doc/src/touch-knobs.qdoc (99%) rename examples/{ => widgets}/touch/knobs/knob.cpp (100%) rename examples/{ => widgets}/touch/knobs/knob.h (100%) rename examples/{ => widgets}/touch/knobs/knobs.pro (60%) rename examples/{ => widgets}/touch/knobs/main.cpp (100%) create mode 100644 examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png rename {doc/src/examples => examples/widgets/touch/pinchzoom/doc/src}/pinchzoom.qdoc (97%) rename examples/{ => widgets}/touch/pinchzoom/graphicsview.cpp (100%) rename examples/{ => widgets}/touch/pinchzoom/graphicsview.h (100%) rename examples/{ => widgets}/touch/pinchzoom/images/cheese.jpg (100%) rename examples/{ => widgets}/touch/pinchzoom/main.cpp (100%) rename examples/{ => widgets}/touch/pinchzoom/mice.qrc (100%) rename examples/{ => widgets}/touch/pinchzoom/mouse.cpp (100%) rename examples/{ => widgets}/touch/pinchzoom/mouse.h (100%) rename examples/{ => widgets}/touch/pinchzoom/pinchzoom.pro (75%) rename examples/{ => widgets}/touch/touch.pro (100%) diff --git a/examples/examples.pro b/examples/examples.pro index 4ec5ca60e2..077e5828a9 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -4,8 +4,7 @@ CONFIG += no_docs_target SUBDIRS = \ corelib \ embedded \ - qpa \ - touch + qpa qtHaveModule(dbus): SUBDIRS += dbus qtHaveModule(network): SUBDIRS += network diff --git a/examples/touch/dials/dials.pro b/examples/widgets/touch/dials/dials.pro similarity index 58% rename from examples/touch/dials/dials.pro rename to examples/widgets/touch/dials/dials.pro index 2c522a46f0..0e823551cc 100644 --- a/examples/touch/dials/dials.pro +++ b/examples/widgets/touch/dials/dials.pro @@ -4,5 +4,5 @@ SOURCES += main.cpp FORMS += dials.ui # install -target.path = $$[QT_INSTALL_EXAMPLES]/touch/dials +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/dials INSTALLS += target diff --git a/examples/touch/dials/dials.ui b/examples/widgets/touch/dials/dials.ui similarity index 100% rename from examples/touch/dials/dials.ui rename to examples/widgets/touch/dials/dials.ui diff --git a/examples/touch/dials/doc/images/touch-dials-example.png b/examples/widgets/touch/dials/doc/images/touch-dials-example.png similarity index 100% rename from examples/touch/dials/doc/images/touch-dials-example.png rename to examples/widgets/touch/dials/doc/images/touch-dials-example.png diff --git a/examples/touch/dials/doc/src/touch-dials.qdoc b/examples/widgets/touch/dials/doc/src/touch-dials.qdoc similarity index 99% rename from examples/touch/dials/doc/src/touch-dials.qdoc rename to examples/widgets/touch/dials/doc/src/touch-dials.qdoc index 10784c8c0d..dec8248efb 100644 --- a/examples/touch/dials/doc/src/touch-dials.qdoc +++ b/examples/widgets/touch/dials/doc/src/touch-dials.qdoc @@ -29,7 +29,7 @@ \example touch/dials \title Touch Dials Example \ingroup touchinputexamples - \brief Shows how to apply touch to a set of standard Qt widgets + \brief Shows how to apply touch to a set of standard Qt widgets. The Touch Dials example shows how to apply touch to a set of standard Qt widgets. diff --git a/examples/touch/dials/main.cpp b/examples/widgets/touch/dials/main.cpp similarity index 100% rename from examples/touch/dials/main.cpp rename to examples/widgets/touch/dials/main.cpp diff --git a/doc/src/examples/fingerpaint.qdoc b/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc similarity index 99% rename from doc/src/examples/fingerpaint.qdoc rename to examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc index 79001ddc7d..6f8f636f86 100644 --- a/doc/src/examples/fingerpaint.qdoc +++ b/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc @@ -29,7 +29,7 @@ \example touch/fingerpaint \title Finger Paint Example \ingroup touchinputexamples - \brief Shows the use of a touchscreen to make a simple painting application + \brief Shows the use of a touchscreen to make a simple painting application. The Finger Paint example shows the use of a touchscreen with a custom widget to create a simple painting application. diff --git a/examples/touch/fingerpaint/fingerpaint.pro b/examples/widgets/touch/fingerpaint/fingerpaint.pro similarity index 81% rename from examples/touch/fingerpaint/fingerpaint.pro rename to examples/widgets/touch/fingerpaint/fingerpaint.pro index f196f7eed4..6370da6607 100644 --- a/examples/touch/fingerpaint/fingerpaint.pro +++ b/examples/widgets/touch/fingerpaint/fingerpaint.pro @@ -9,5 +9,5 @@ SOURCES = main.cpp \ scribblearea.cpp # install -target.path = $$[QT_INSTALL_EXAMPLES]/touch/fingerpaint +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/fingerpaint INSTALLS += target diff --git a/examples/touch/fingerpaint/main.cpp b/examples/widgets/touch/fingerpaint/main.cpp similarity index 100% rename from examples/touch/fingerpaint/main.cpp rename to examples/widgets/touch/fingerpaint/main.cpp diff --git a/examples/touch/fingerpaint/mainwindow.cpp b/examples/widgets/touch/fingerpaint/mainwindow.cpp similarity index 100% rename from examples/touch/fingerpaint/mainwindow.cpp rename to examples/widgets/touch/fingerpaint/mainwindow.cpp diff --git a/examples/touch/fingerpaint/mainwindow.h b/examples/widgets/touch/fingerpaint/mainwindow.h similarity index 100% rename from examples/touch/fingerpaint/mainwindow.h rename to examples/widgets/touch/fingerpaint/mainwindow.h diff --git a/examples/touch/fingerpaint/scribblearea.cpp b/examples/widgets/touch/fingerpaint/scribblearea.cpp similarity index 100% rename from examples/touch/fingerpaint/scribblearea.cpp rename to examples/widgets/touch/fingerpaint/scribblearea.cpp diff --git a/examples/touch/fingerpaint/scribblearea.h b/examples/widgets/touch/fingerpaint/scribblearea.h similarity index 100% rename from examples/touch/fingerpaint/scribblearea.h rename to examples/widgets/touch/fingerpaint/scribblearea.h diff --git a/examples/touch/knobs/doc/images/touch-knobs-example.png b/examples/widgets/touch/knobs/doc/images/touch-knobs-example.png similarity index 100% rename from examples/touch/knobs/doc/images/touch-knobs-example.png rename to examples/widgets/touch/knobs/doc/images/touch-knobs-example.png diff --git a/examples/touch/knobs/doc/src/touch-knobs.qdoc b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc similarity index 99% rename from examples/touch/knobs/doc/src/touch-knobs.qdoc rename to examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc index d39dd564b2..6da5992195 100644 --- a/examples/touch/knobs/doc/src/touch-knobs.qdoc +++ b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc @@ -29,7 +29,7 @@ \example touch/knobs \title Touch Knobs Example \ingroup touchinputexamples - \brief Shows how to create custom controls that accept touch input + \brief Shows how to create custom controls that accept touch input. The Touch Knobs example shows how to create custom controls that accept touch input. diff --git a/examples/touch/knobs/knob.cpp b/examples/widgets/touch/knobs/knob.cpp similarity index 100% rename from examples/touch/knobs/knob.cpp rename to examples/widgets/touch/knobs/knob.cpp diff --git a/examples/touch/knobs/knob.h b/examples/widgets/touch/knobs/knob.h similarity index 100% rename from examples/touch/knobs/knob.h rename to examples/widgets/touch/knobs/knob.h diff --git a/examples/touch/knobs/knobs.pro b/examples/widgets/touch/knobs/knobs.pro similarity index 60% rename from examples/touch/knobs/knobs.pro rename to examples/widgets/touch/knobs/knobs.pro index 267ba26167..0915b0665a 100644 --- a/examples/touch/knobs/knobs.pro +++ b/examples/widgets/touch/knobs/knobs.pro @@ -4,5 +4,5 @@ HEADERS = knob.h SOURCES = main.cpp knob.cpp # install -target.path = $$[QT_INSTALL_EXAMPLES]/touch/knobs +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/knobs INSTALLS += target diff --git a/examples/touch/knobs/main.cpp b/examples/widgets/touch/knobs/main.cpp similarity index 100% rename from examples/touch/knobs/main.cpp rename to examples/widgets/touch/knobs/main.cpp diff --git a/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png b/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png new file mode 100644 index 0000000000000000000000000000000000000000..7db51fbf55d6e6ed9314d73c4de8f05fd3f417e2 GIT binary patch literal 42493 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 Date: Wed, 22 Aug 2018 22:43:29 -0500 Subject: [PATCH 12/16] 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 ++-- .../platforms/windows/qwindowscontext.cpp | 6 ++- .../platforms/windows/qwindowscontext.h | 4 ++ .../platforms/windows/qwindowsintegration.cpp | 4 +- .../windows/qwindowspointerhandler.cpp | 49 +++++++++++++++++++ 5 files changed, 67 insertions(+), 6 deletions(-) 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); } } From 6ff862a6821112ede25a7a2da646ca279812ed50 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 12 Sep 2018 21:01:04 +0200 Subject: [PATCH 13/16] 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(-) 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) { From 004b3742a20c7643ae0db5f4e6a7841055eb6fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 13 Sep 2018 08:34:42 +0300 Subject: [PATCH 14/16] Blacklist a tst_QFileDialog2 test due to extreme flakiness in macOS Task-number: QTBUG-70087 Change-Id: Icc2467177209fef8aad59c5424e936ef96aa6289 Reviewed-by: Liang Qi --- tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST diff --git a/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST b/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST new file mode 100644 index 0000000000..e0887d8ad1 --- /dev/null +++ b/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST @@ -0,0 +1,2 @@ +[QTBUG4419_lineEditSelectAll] +osx From f4dd670fe93b094aade3eac26adc81cf71b197b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 13 Sep 2018 09:13:08 +0300 Subject: [PATCH 15/16] Blacklist an extremely flaky tst_QDoubleSpinBox::editingFinished test Task-number: QTBUG-70088 Change-Id: I9239f379121f6167dd665ae3137a449d0ac5b6c7 Reviewed-by: Liang Qi --- tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST diff --git a/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST b/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST new file mode 100644 index 0000000000..c1b6c9693e --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST @@ -0,0 +1,2 @@ +[editingFinished] +* From 6bb0cbc6865911c31f5edee7c24f270d265bd46d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 15 Sep 2018 14:35:24 +0200 Subject: [PATCH 16/16] tst_QMdiSubWindow: fix flaky setOpaqueResizeAndMove test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tst_QMdiSubWindow::setOpaqueResizeAndMove checks if a resize of the mdi subwindow works as expected by simulating mouse events. Those events are sent to fast and therefore the operationMap of QMdiSubWindowPrivate is not yet updated which let the test fail. There was already a call to qWait(250) to wait for the 200ms timer but sometimes (esp. in virtual environments) the timer was not triggered after this period. Fix it by checking if resizeTimerId is set back to -1 which means that updateDirtyRegions() was called. Change-Id: I961ba80589d2f725a6858ba70b84fb35750a6964 Reviewed-by: Tony Sarajärvi --- tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro | 2 +- .../auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro b/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro index 4299f7711e..e33271428f 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro +++ b/tests/auto/widgets/widgets/qmdisubwindow/qmdisubwindow.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qmdisubwindow -QT += widgets testlib +QT += widgets widgets-private testlib INCLUDEPATH += . SOURCES += tst_qmdisubwindow.cpp DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp index 4908f1b9f7..8b2f032172 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp +++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp @@ -30,6 +30,7 @@ #include #include "qmdisubwindow.h" +#include "private/qmdisubwindow_p.h" #include "qmdiarea.h" #include @@ -723,7 +724,9 @@ void tst_QMdiSubWindow::setOpaqueResizeAndMove() resizeSpy.clear(); QCOMPARE(resizeSpy.count(), 0); - QTest::qWait(250); // delayed update of dirty regions + // we need to wait for the resizeTimer to make sure updateDirtyRegions is called + auto priv = static_cast(qt_widget_private(window)); + QTRY_COMPARE(priv->resizeTimerId, -1); // Enter resize mode. int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2;