From 6c3f864ec00c4e20a05f60032048e9fe2c7e116c Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 15 Jan 2018 08:59:09 +0100 Subject: [PATCH 01/32] examples: Fix notepad example for configurations without printsupport Task-number: QTBUG-65735 Change-Id: I7e0d19de4ac92603f2fd033007343f20a408618a Reviewed-by: Nico Vertriest --- examples/widgets/tutorials/notepad/notepad.cpp | 11 +++++++++++ examples/widgets/tutorials/notepad/notepad.pro | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/widgets/tutorials/notepad/notepad.cpp b/examples/widgets/tutorials/notepad/notepad.cpp index b4f6cf7f8f..44d8597cb7 100644 --- a/examples/widgets/tutorials/notepad/notepad.cpp +++ b/examples/widgets/tutorials/notepad/notepad.cpp @@ -52,8 +52,15 @@ #include #include #include +#if defined(QT_PRINTSUPPORT_LIB) +#include +#if QT_CONFIG(printer) +#if QT_CONFIG(printdialog) #include +#endif // QT_CONFIG(printdialog) #include +#endif // QT_CONFIG(printer) +#endif // QT_PRINTSUPPORT_LIB #include #include @@ -136,11 +143,15 @@ void Notepad::on_actionSave_as_triggered() void Notepad::on_actionPrint_triggered() { +#if QT_CONFIG(printer) QPrinter printDev; +#if QT_CONFIG(printdialog) QPrintDialog dialog(&printDev, this); if (dialog.exec() == QDialog::Rejected) return; +#endif // QT_CONFIG(printdialog) ui->textEdit->print(&printDev); +#endif // QT_CONFIG(printer) } void Notepad::on_actionExit_triggered() diff --git a/examples/widgets/tutorials/notepad/notepad.pro b/examples/widgets/tutorials/notepad/notepad.pro index a552dacf00..6451f22735 100644 --- a/examples/widgets/tutorials/notepad/notepad.pro +++ b/examples/widgets/tutorials/notepad/notepad.pro @@ -1,7 +1,7 @@ TEMPLATE = app TARGET = notepad -QT += printsupport +qtHaveModule(printsupport): QT += printsupport requires(qtConfig(fontdialog)) SOURCES += \ From c561c3b8b473d1b0f3557f8d8d89a7c37f847d5d Mon Sep 17 00:00:00 2001 From: Jeremy LUGAGNE Date: Mon, 22 Jan 2018 14:44:35 +0100 Subject: [PATCH 02/32] Fix -developer-build due to missing Q_DECL_OVERRIDE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie7a2ff0e42131afef1bdec853d09c3b447f9748c Reviewed-by: Sérgio Martins --- src/plugins/platforms/offscreen/qoffscreenintegration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index f72587d11a..154a420e3d 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -69,8 +69,8 @@ public: QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; - QStringList themeNames() const; - QPlatformTheme *createPlatformTheme(const QString &name) const; + QStringList themeNames() const Q_DECL_OVERRIDE; + QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE; static QOffscreenIntegration *createOffscreenIntegration(); From 41cdfbe3a473a4f691c193a58206d860cb9c676d Mon Sep 17 00:00:00 2001 From: Alexander Shevchenko Date: Sun, 21 Jan 2018 10:59:15 +0200 Subject: [PATCH 03/32] unify windows mkspecs: delete redundants in 5.10 mingw-w64 toolchain: - remove 'QMAKE_CFLAGS_AESNI' and 'QMAKE_CFLAGS_SHANI' definitions, which are already set in 'gcc-base.conf' toolchain; this is a continuation of 77347a36 relating variables, introduced in 5.10, - remove 'gcc-base.conf' duplicate inclusion, left after eef2d1af was merged into 5.10. Change-Id: I328def916ccfb93c3f6b8336eb8801defbac37ae Reviewed-by: Kai Koehne Reviewed-by: Oswald Buddenhagen --- mkspecs/win32-g++/qmake.conf | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 12f3567754..0a1cd2dd5a 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -31,8 +31,6 @@ QMAKE_CFLAGS += -fno-keep-inline-dllexport QMAKE_CFLAGS_WARN_ON += -Wextra QMAKE_CFLAGS_SSE2 += -mstackrealign -QMAKE_CFLAGS_AESNI = -maes -QMAKE_CFLAGS_SHANI = -msha QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_CXXFLAGS = $$QMAKE_CFLAGS @@ -88,6 +86,5 @@ QMAKE_NM = $${CROSS_COMPILE}nm -P include(../common/angle.conf) include(../common/windows-vulkan.conf) -include(../common/gcc-base.conf) load(qt_config) From 5c0bd3961fa17d594e2a14d142b75c0002856595 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Jan 2018 13:39:17 +0100 Subject: [PATCH 04/32] Fix resize event flood when moving windows with High DPI scaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correctly scale the requested geometry in the constructor of QWindowSystemInterfacePrivate::GeometryChangeEvent(). Amends 3a31c708790ba2bb3cf3dab32a17a83659a1acde. Task-number: QTBUG-57608 Task-number: QTBUG-65580 Change-Id: I0ef60deda69bb61ab57972e02c342b7773e1da6b Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qwindowsysteminterface.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index c47d940e4a..0a30fb78dc 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -283,9 +283,10 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::Application QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry) : WindowSystemEvent(GeometryChange) , window(window) - , requestedGeometry(window->handle() ? window->handle()->QPlatformWindow::geometry() : QRect()) , newGeometry(newGeometry) { + if (const QPlatformWindow *pw = window->handle()) + requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window); } QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect) From e39a9de3309f84be4101da839a0bacf69090706f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 6 Jan 2018 00:09:14 +0200 Subject: [PATCH 05/32] pcre2: Disable JIT on windows on arm/arm64 sljit, the JIT in pcre2, doesn't quite fully work on windows on arm yet (although the subset of functionality used by pcre2 might mostly work). On arm64, it fails to compile (although working around that failure is pretty easy), when using clang in MinGW mode (where __GNUC__ is defined, making the JIT auto-enabled). Disable it in these configurations until it has been fully tested and fixed upstream first. Change-Id: Ie9681cb7cdd1960586ba194c71e057eb918cb419 Reviewed-by: Giuseppe D'Angelo --- src/3rdparty/pcre2/pcre2.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/3rdparty/pcre2/pcre2.pro b/src/3rdparty/pcre2/pcre2.pro index 3dde2f62f8..296e65cd59 100644 --- a/src/3rdparty/pcre2/pcre2.pro +++ b/src/3rdparty/pcre2/pcre2.pro @@ -16,6 +16,8 @@ DEFINES += HAVE_CONFIG_H # platform/compiler specific definitions uikit|qnx|winrt: DEFINES += PCRE2_DISABLE_JIT +win32:contains(QT_ARCH, "arm"): DEFINES += PCRE2_DISABLE_JIT +win32:contains(QT_ARCH, "arm64"): DEFINES += PCRE2_DISABLE_JIT SOURCES += \ $$PWD/src/pcre2_auto_possess.c \ From f7524d73e33d00c76e55d996cdd4ea841ac6b7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 24 Jan 2018 11:22:42 +0200 Subject: [PATCH 06/32] Don't set no_clang_integrated_as for the disabled pixman asm on clang/mingw There's no external arm assembler to fall back on here. The actual assembly is already disabled since 8072c36eebd064, but passing the empty assembly file to any random external assembler could end up producing an empty object file for the host environment instead of the target, in a cross build. This wasn't an issue as long as the clang compiler only was identified as g++ within mkspecs, making no_clang_integrated_as a no-op. If the mkspec actually identifies it as clang, this config can't be added here. Change-Id: I0f20b9b2a8d13b5e7e1b654e391d88b639c031bf Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/painting.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 1e14498f79..29bef14f0c 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -127,7 +127,7 @@ AVX2_SOURCES += painting/qdrawhelper_avx2.cpp NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp NEON_HEADERS += painting/qdrawhelper_neon_p.h NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S -!uikit:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as +!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as !uikit:!win32:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp From a966991b3af18d57182e5dc5a3ed4985d114b56d Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 19 Jan 2018 10:30:24 +0100 Subject: [PATCH 07/32] Fix a crash when QMovie::speed is set to 0 Setting speed to 0 means the current frame will continue to be shown, the finished signal is not emitted, and state remains QMovie::Running. Task-number: QTBUG-65758 Change-Id: I681d902e3211c5899b21043e5177b7c73d5d3fb5 Reviewed-by: Shawn Rutledge --- src/gui/image/qmovie.cpp | 8 +++++++- tests/auto/gui/image/qmovie/tst_qmovie.cpp | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp index d5e8b1b974..010760de4c 100644 --- a/src/gui/image/qmovie.cpp +++ b/src/gui/image/qmovie.cpp @@ -470,6 +470,10 @@ bool QMoviePrivate::next() currentPixmap = QPixmap::fromImage( info.pixmap.toImage().scaled(scaledSize) ); else currentPixmap = info.pixmap; + + if (!speed) + return true; + nextDelay = speedAdjustedDelay(info.delay); // Adjust delay according to the time it took to read the frame int processingTime = time.elapsed(); @@ -504,7 +508,7 @@ void QMoviePrivate::_q_loadNextFrame(bool starting) emit q->updated(frameRect); emit q->frameChanged(currentFrameNumber); - if (movieState == QMovie::Running) + if (speed && movieState == QMovie::Running) nextImageTimer.start(nextDelay); } else { // Could not read another frame @@ -926,6 +930,8 @@ void QMovie::setPaused(bool paused) void QMovie::setSpeed(int percentSpeed) { Q_D(QMovie); + if (!d->speed && d->movieState == Running) + d->nextImageTimer.start(nextFrameDelay()); d->speed = percentSpeed; } diff --git a/tests/auto/gui/image/qmovie/tst_qmovie.cpp b/tests/auto/gui/image/qmovie/tst_qmovie.cpp index bcaa759faa..4e9e9b8115 100644 --- a/tests/auto/gui/image/qmovie/tst_qmovie.cpp +++ b/tests/auto/gui/image/qmovie/tst_qmovie.cpp @@ -170,6 +170,16 @@ void tst_QMovie::playMovie() QCOMPARE(movie.state(), QMovie::NotRunning); QCOMPARE(movie.frameCount(), frameCount); #endif + + movie.stop(); + QSignalSpy finishedSpy(&movie, &QMovie::finished); + movie.setSpeed(0); + movie.start(); + QCOMPARE(movie.state(), QMovie::Running); + QTestEventLoop::instance().enterLoop(2); + QCOMPARE(finishedSpy.count(), 0); + QCOMPARE(movie.state(), QMovie::Running); + QCOMPARE(movie.currentFrameNumber(), 0); } void tst_QMovie::jumpToFrame_data() From 95a08a711e18c7d994085dff6c1d4df065fb273e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Jan 2018 16:47:01 +0100 Subject: [PATCH 08/32] Windows QPA: Suppress bogus resize events when using native menus Account for the (not yet created) native menu height when handling the initial resize message. Complements 7849aa6e96aa923fca5523afc8cf88edcc0bcf90. Task-number: QTBUG-65917 Task-number: QTBUG-55967 Change-Id: I65c75d796634ecf1a90a72fef8ff3e6e89de11c4 Reviewed-by: Oliver Wolff Reviewed-by: J-P Nurmi --- src/plugins/platforms/windows/qwindowscontext.cpp | 6 ++++-- src/plugins/platforms/windows/qwindowswindow.cpp | 6 ++++-- src/plugins/platforms/windows/qwindowswindow.h | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 9912e03cb9..07efac3117 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -996,8 +996,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::QuerySizeHints: d->m_creationContext->applyToMinMaxInfo(reinterpret_cast(lParam)); return true; - case QtWindows::ResizeEvent: - d->m_creationContext->obtainedGeometry.setSize(QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); + case QtWindows::ResizeEvent: { + const QSize size(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) - d->m_creationContext->menuHeight); + d->m_creationContext->obtainedGeometry.setSize(size); + } return true; case QtWindows::MoveEvent: d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1d81fa9cd5..995b1a2582 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1027,8 +1027,10 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, const QMargins effectiveMargins = margins + customMargins; frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right(); frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom(); - if (QWindowsMenuBar::menuBarOf(w) != nullptr) - frameHeight += GetSystemMetrics(SM_CYMENU); + if (QWindowsMenuBar::menuBarOf(w) != nullptr) { + menuHeight = GetSystemMetrics(SM_CYMENU); + frameHeight += menuHeight; + } const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel(); if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) { frameX -= effectiveMargins.left(); diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 414d4a92f8..4e1f49be3b 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -101,6 +101,7 @@ struct QWindowCreationContext int frameY = CW_USEDEFAULT; int frameWidth = CW_USEDEFAULT; int frameHeight = CW_USEDEFAULT; + int menuHeight = 0; }; struct QWindowsWindowData From b40e0e72333beab192196e8b9cb599e9274d4d56 Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Sun, 29 Oct 2017 18:18:23 +0100 Subject: [PATCH 09/32] Add -DQT_{module}_LIB in pkg-config cflags for each Qt module Build systems such as Meson heavily rely on pkg-config to get build flags. -DQT_{module}_LIB isn't exported in .pc files which makes Meson unable to build some codes out of the box. Change-Id: I806998f19f815e05a47b60129977e52587b38d47 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_module.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index c0a8dcc251..e6a0d97f1a 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -274,7 +274,7 @@ load(qt_targets) else: \ QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS/raw] QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] - QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME + QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ") QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION) for(i, MODULE_DEPENDS): \ From d2b2511f88d3cf0b3db65c1bb5836e08e50636ab Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Wed, 17 Jan 2018 15:22:56 +0300 Subject: [PATCH 10/32] QNAM should prepend Host header to the header list instead of appending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When original QNetworkRequest is missing "Host" header (which is the most common case), it is provided automatically from request URL. However, resulting header is appended to the list, i.e. after all headers specified by user, which may include a big bunch of cookies. To the contrary, RFC 7230 suggests: "However, it is good practice to send header fields that contain control data first, such as Host on requests and Date on responses, so that implementations can decide when not to handle a message as early as possible". Many other user agents are following this suggestion. Task-number: QTBUG-51557 Change-Id: I1448ed3ae124f5ce86a8ca8ff35f5d05476a005d Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/access/qhttpnetworkconnection.cpp | 2 +- src/network/access/qhttpnetworkheader.cpp | 5 +++++ src/network/access/qhttpnetworkheader_p.h | 1 + src/network/access/qhttpnetworkrequest.cpp | 5 +++++ src/network/access/qhttpnetworkrequest_p.h | 1 + 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 8fdcc91efc..5194a2b1c5 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -355,7 +355,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair) host += QByteArray::number(port); } - request.setHeaderField("Host", host); + request.prependHeaderField("Host", host); } reply->d_func()->requestIsPrepared = true; diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp index 7199abbf17..85d68bf88d 100644 --- a/src/network/access/qhttpnetworkheader.cpp +++ b/src/network/access/qhttpnetworkheader.cpp @@ -114,6 +114,11 @@ void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QBy fields.append(qMakePair(name, data)); } +void QHttpNetworkHeaderPrivate::prependHeaderField(const QByteArray &name, const QByteArray &data) +{ + fields.prepend(qMakePair(name, data)); +} + bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const { return (url == other.url); diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h index 46aec1dd8c..506486a52b 100644 --- a/src/network/access/qhttpnetworkheader_p.h +++ b/src/network/access/qhttpnetworkheader_p.h @@ -92,6 +92,7 @@ public: QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; QList headerFieldValues(const QByteArray &name) const; void setHeaderField(const QByteArray &name, const QByteArray &data); + void prependHeaderField(const QByteArray &name, const QByteArray &data); bool operator==(const QHttpNetworkHeaderPrivate &other) const; }; diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp index 60b566299f..ac87a36482 100644 --- a/src/network/access/qhttpnetworkrequest.cpp +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -279,6 +279,11 @@ void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArra d->setHeaderField(name, data); } +void QHttpNetworkRequest::prependHeaderField(const QByteArray &name, const QByteArray &data) +{ + d->prependHeaderField(name, data); +} + QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other) { d = other.d; diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h index ecf8856ded..f9f991977f 100644 --- a/src/network/access/qhttpnetworkrequest_p.h +++ b/src/network/access/qhttpnetworkrequest_p.h @@ -102,6 +102,7 @@ public: QList > header() const Q_DECL_OVERRIDE; QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const Q_DECL_OVERRIDE; void setHeaderField(const QByteArray &name, const QByteArray &data) Q_DECL_OVERRIDE; + void prependHeaderField(const QByteArray &name, const QByteArray &data); Operation operation() const; void setOperation(Operation operation); From 7d6bf37049839ca9a2549aa0f7b120ea574366aa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 23 Jan 2018 22:20:54 -0800 Subject: [PATCH 11/32] MSVC: Don't set a DLL base address for 64-bit The linker complains: LINK : warning LNK4281: undesirable base address 0x67000000 for x64 image; set base address above 4GB for best ASLR optimization And it's not really required anymore, as the recommended /DYNAMICBASE is the default. Change-Id: I56b444f9d6274221a3b7fffd150caab1beecfd43 Reviewed-by: Friedemann Kleint --- src/concurrent/concurrent.pro | 2 +- src/corelib/corelib.pro | 2 +- src/network/network.pro | 2 +- src/opengl/opengl.pro | 2 +- src/sql/sql.pro | 2 +- src/widgets/widgets.pro | 2 +- src/xml/xml.pro | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro index 017153c74d..18510e38a1 100644 --- a/src/concurrent/concurrent.pro +++ b/src/concurrent/concurrent.pro @@ -4,7 +4,7 @@ CONFIG += exceptions DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000 QMAKE_DOCS = $$PWD/doc/qtconcurrent.qdocconf diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 6dc11e1a4d..ce3d4280ab 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -9,7 +9,7 @@ MODULE_CONFIG = moc resources CONFIG += $$MODULE_CONFIG DEFINES += $$MODULE_DEFINES DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x67000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused CONFIG += optimize_full diff --git a/src/network/network.pro b/src/network/network.pro index 98fbf82275..eaf6d599da 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -10,7 +10,7 @@ DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH #DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG #DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG #DEFINES += QSCTPSOCKET_DEBUG QSCTPSERVER_DEBUG -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x64000000 QMAKE_DOCS = $$PWD/doc/qtnetwork.qdocconf diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 016db46405..742be61a50 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -3,7 +3,7 @@ QT = core-private gui-private widgets-private DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x63000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x63000000 solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused diff --git a/src/sql/sql.pro b/src/sql/sql.pro index 133bf831c8..821ae1c9b9 100644 --- a/src/sql/sql.pro +++ b/src/sql/sql.pro @@ -2,7 +2,7 @@ TARGET = QtSql QT = core-private DEFINES += QT_NO_USING_NAMESPACE -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x62000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x62000000 QMAKE_DOCS = $$PWD/doc/qtsql.qdocconf diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index 22bdf08408..8181817787 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -4,7 +4,7 @@ MODULE_CONFIG = uic CONFIG += $$MODULE_CONFIG DEFINES += QT_NO_USING_NAMESPACE -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x65000000 irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf diff --git a/src/xml/xml.pro b/src/xml/xml.pro index cf9feda9bc..31d742d6ea 100644 --- a/src/xml/xml.pro +++ b/src/xml/xml.pro @@ -3,7 +3,7 @@ QT = core-private DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000 +msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x61000000 QMAKE_DOCS = $$PWD/doc/qtxml.qdocconf From 91732818e559c1174283282c17c856e9fc9f78ac Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 24 Jan 2018 08:02:55 +0100 Subject: [PATCH 12/32] Remove dead code from tst_qwineventnotifier.cpp The idx member of EventWithNotifier is unused. Change-Id: I0f5aacaaad4b4e82c57ff7bb020586944014f139 Reviewed-by: Friedemann Kleint --- .../kernel/qwineventnotifier/tst_qwineventnotifier.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp index 15a39b62c0..64e78ec3c3 100644 --- a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp +++ b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp @@ -109,9 +109,6 @@ public: this, &EventWithNotifier::onNotifierActivated); notifier.setHandle(CreateEvent(0, TRUE, FALSE, 0)); notifier.setEnabled(true); - - static int nextIndex = 0; - idx = nextIndex++; } ~EventWithNotifier() @@ -137,7 +134,6 @@ public slots: private: QWinEventNotifier notifier; int activatedCount = 0; - int idx = 0; }; void tst_QWinEventNotifier::manyNotifiers() From f0b8d90402a0ec27b465dbcfa626f5176e167ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 18 Jan 2018 22:49:42 +0100 Subject: [PATCH 13/32] Cocoa: Make dialogs non-resizable again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix regression from commit 8b3a120a where also dialogs got NSResizableWindowMask, making them have a Zoom button. Task-number: QTBUG-65668 Change-Id: I21054b3aa6fc11eab3d93f78ede44ae771522e2c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoawindow.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e86cc2d955..92df6eac49 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -503,9 +503,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) { const Qt::WindowType type = static_cast(int(flags & Qt::WindowType_Mask)); const bool frameless = (flags & Qt::FramelessWindowHint) || windowIsPopupType(type); + const bool resizeable = type != Qt::Dialog; // Dialogs: remove zoom button by disabling resize - // Select base window type. - NSUInteger styleMask = frameless ? NSBorderlessWindowMask : NSResizableWindowMask; + // Select base window type. Note that the value of NSBorderlessWindowMask is 0. + NSUInteger styleMask = (frameless || !resizeable) ? NSBorderlessWindowMask : NSResizableWindowMask; if (frameless) { // No further customizations for frameless since there are no window decorations. From 7b94f1f53b096753a0297c35dd522a3104a28047 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Wed, 24 Jan 2018 22:46:03 -0800 Subject: [PATCH 14/32] Fix build of applications on iOS The PRODUCT_BUNDLE_IDENTIFIER property was not defined in the Xcode project file and therefore the build would fail. This fixes a regression introduced by 0749ba2c5e. Task-number: QTBUG-65673 Change-Id: I8089b36d86588223ec34859af7388c99a3574d8b Reviewed-by: Oswald Buddenhagen --- mkspecs/features/mac/default_pre.prf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf index e3534561a5..f1a4ca77b2 100644 --- a/mkspecs/features/mac/default_pre.prf +++ b/mkspecs/features/mac/default_pre.prf @@ -58,3 +58,10 @@ QMAKE_XCODE_LIBRARY_SUFFIX_SETTING = QT_LIBRARY_SUFFIX xcode_copy_phase_strip_setting.name = COPY_PHASE_STRIP xcode_copy_phase_strip_setting.value = NO QMAKE_MAC_XCODE_SETTINGS += xcode_copy_phase_strip_setting + +xcode_product_bundle_identifier_setting.name = PRODUCT_BUNDLE_IDENTIFIER +xcode_product_bundle_identifier_setting.value = $$QMAKE_TARGET_BUNDLE_PREFIX +isEmpty(xcode_product_bundle_identifier_setting.value): \ + xcode_product_bundle_identifier_setting.value = "com.yourcompany" +xcode_product_bundle_identifier_setting.value = "$${xcode_product_bundle_identifier_setting.value}.${PRODUCT_NAME:rfc1034identifier}" +QMAKE_MAC_XCODE_SETTINGS += xcode_product_bundle_identifier_setting From 7f310be85b0fb2154c2651b792efe11b41bf6b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Thu, 25 Jan 2018 13:46:57 +0100 Subject: [PATCH 15/32] Update bundled libjpeg-turbo to version 1.5.3 [ChangeLog][Third-Party Code] libjpeg-turbo was updated to version 1.5.3 Change-Id: I8c0caec3c92ba199b1a3baac9a523cc399c8001f Reviewed-by: Kai Koehne Reviewed-by: Eirik Aavitsland --- src/3rdparty/libjpeg/qt_attribution.json | 2 +- src/3rdparty/libjpeg/src/ChangeLog.md | 44 ++++++++++++++++++++++++ src/3rdparty/libjpeg/src/jcdctmgr.c | 2 +- src/3rdparty/libjpeg/src/jdapistd.c | 33 +++++++++++++++--- src/3rdparty/libjpeg/src/jdcolor.c | 2 +- src/3rdparty/libjpeg/src/jdmerge.c | 2 +- 6 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json index a1966d43d6..9bfc14f29d 100644 --- a/src/3rdparty/libjpeg/qt_attribution.json +++ b/src/3rdparty/libjpeg/qt_attribution.json @@ -6,7 +6,7 @@ "Description": "The Independent JPEG Group's JPEG software", "Homepage": "http://libjpeg-turbo.virtualgl.org/", - "Version": "1.5.2", + "Version": "1.5.3", "License": "Independent JPEG Group License", "LicenseId": "IJG", "LicenseFile": "LICENSE", diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md index 2aaa50c148..f5fe44bf85 100644 --- a/src/3rdparty/libjpeg/src/ChangeLog.md +++ b/src/3rdparty/libjpeg/src/ChangeLog.md @@ -1,3 +1,47 @@ +1.5.3 +===== + +### Significant changes relative to 1.5.2: + +1. Fixed a NullPointerException in the TurboJPEG Java wrapper that occurred +when using the YUVImage constructor that creates an instance backed by separate +image planes and allocates memory for the image planes. + +2. Fixed an issue whereby the Java version of TJUnitTest would fail when +testing BufferedImage encoding/decoding on big endian systems. + +3. Fixed a segfault in djpeg that would occur if an output format other than +PPM/PGM was selected along with the `-crop` option. The `-crop` option now +works with the GIF and Targa formats as well (unfortunately, it cannot be made +to work with the BMP and RLE formats due to the fact that those output engines +write scanlines in bottom-up order.) djpeg will now exit gracefully if an +output format other than PPM/PGM, GIF, or Targa is selected along with the +`-crop` option. + +4. Fixed an issue whereby `jpeg_skip_scanlines()` would segfault if color +quantization was enabled. + +5. TJBench (both C and Java versions) will now display usage information if any +command-line argument is unrecognized. This prevents the program from silently +ignoring typos. + +6. Fixed an access violation in tjbench.exe (Windows) that occurred when the +program was used to decompress an existing JPEG image. + +7. Fixed an ArrayIndexOutOfBoundsException in the TJExample Java program that +occurred when attempting to decompress a JPEG image that had been compressed +with 4:1:1 chrominance subsampling. + +8. Fixed an issue whereby, when using `jpeg_skip_scanlines()` to skip to the +end of a single-scan (non-progressive) image, subsequent calls to +`jpeg_consume_input()` would return `JPEG_SUSPENDED` rather than +`JPEG_REACHED_EOI`. + +9. `jpeg_crop_scanlines()` now works correctly when decompressing grayscale +JPEG images that were compressed with a sampling factor other than 1 (for +instance, with `cjpeg -grayscale -sample 2x2`). + + 1.5.2 ===== diff --git a/src/3rdparty/libjpeg/src/jcdctmgr.c b/src/3rdparty/libjpeg/src/jcdctmgr.c index aef8517f9c..6e3b19bcb3 100644 --- a/src/3rdparty/libjpeg/src/jcdctmgr.c +++ b/src/3rdparty/libjpeg/src/jcdctmgr.c @@ -216,7 +216,7 @@ compute_reciprocal (UINT16 divisor, DCTELEM *dtbl) #endif dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */ - if(r <= 16) return 0; + if (r <= 16) return 0; else return 1; } diff --git a/src/3rdparty/libjpeg/src/jdapistd.c b/src/3rdparty/libjpeg/src/jdapistd.c index 37afc8448b..105121df2b 100644 --- a/src/3rdparty/libjpeg/src/jdapistd.c +++ b/src/3rdparty/libjpeg/src/jdapistd.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1994-1996, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2015-2016, D. R. Commander. + * Copyright (C) 2010, 2015-2017, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. @@ -190,7 +190,10 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset, * single-pass decompression case, allowing us to use the same MCU column * width for all of the components. */ - align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor; + if (cinfo->comps_in_scan == 1 && cinfo->num_components == 1) + align = cinfo->_min_DCT_scaled_size; + else + align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor; /* Adjust xoffset to the nearest iMCU boundary <= the requested value */ input_xoffset = *xoffset; @@ -215,6 +218,9 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset, for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { + int hsf = (cinfo->comps_in_scan == 1 && cinfo->num_components == 1) ? + 1 : compptr->h_samp_factor; + /* Set downsampled_width to the new output width. */ orig_downsampled_width = compptr->downsampled_width; compptr->downsampled_width = @@ -228,11 +234,10 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset, * values will be used in multi-scan decompressions. */ cinfo->master->first_MCU_col[ci] = - (JDIMENSION) (long) (*xoffset * compptr->h_samp_factor) / - (long) align; + (JDIMENSION) (long) (*xoffset * hsf) / (long) align; cinfo->master->last_MCU_col[ci] = (JDIMENSION) jdiv_round_up((long) ((*xoffset + cinfo->output_width) * - compptr->h_samp_factor), + hsf), (long) align) - 1; } @@ -293,6 +298,14 @@ noop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, } +/* Dummy quantize function used by jpeg_skip_scanlines() */ +LOCAL(void) +noop_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) +{ +} + + /* * In some cases, it is best to call jpeg_read_scanlines() and discard the * output, rather than skipping the scanlines, because this allows us to @@ -308,14 +321,22 @@ read_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines) void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows); + void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf, + JSAMPARRAY output_buf, int num_rows) = NULL; color_convert = cinfo->cconvert->color_convert; cinfo->cconvert->color_convert = noop_convert; + if (cinfo->cquantize && cinfo->cquantize->color_quantize) { + color_quantize = cinfo->cquantize->color_quantize; + cinfo->cquantize->color_quantize = noop_quantize; + } for (n = 0; n < num_lines; n++) jpeg_read_scanlines(cinfo, NULL, 1); cinfo->cconvert->color_convert = color_convert; + if (color_quantize) + cinfo->cquantize->color_quantize = color_quantize; } @@ -370,6 +391,8 @@ jpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines) /* Do not skip past the bottom of the image. */ if (cinfo->output_scanline + num_lines >= cinfo->output_height) { cinfo->output_scanline = cinfo->output_height; + (*cinfo->inputctl->finish_input_pass) (cinfo); + cinfo->inputctl->eoi_reached = TRUE; return cinfo->output_height - cinfo->output_scanline; } diff --git a/src/3rdparty/libjpeg/src/jdcolor.c b/src/3rdparty/libjpeg/src/jdcolor.c index ab8fa24925..05cbf4df1f 100644 --- a/src/3rdparty/libjpeg/src/jdcolor.c +++ b/src/3rdparty/libjpeg/src/jdcolor.c @@ -616,7 +616,7 @@ static const JLONG dither_matrix[4] = { static INLINE boolean is_big_endian(void) { int test_value = 1; - if(*(char *)&test_value != 1) + if (*(char *)&test_value != 1) return TRUE; return FALSE; } diff --git a/src/3rdparty/libjpeg/src/jdmerge.c b/src/3rdparty/libjpeg/src/jdmerge.c index 6276dd0950..ca6f16c252 100644 --- a/src/3rdparty/libjpeg/src/jdmerge.c +++ b/src/3rdparty/libjpeg/src/jdmerge.c @@ -503,7 +503,7 @@ static const JLONG dither_matrix[4] = { static INLINE boolean is_big_endian(void) { int test_value = 1; - if(*(char *)&test_value != 1) + if (*(char *)&test_value != 1) return TRUE; return FALSE; } From ab1e50757454b5afda2f6dec52d2eb16a32d4798 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 19 Jan 2018 23:32:58 -0800 Subject: [PATCH 16/32] QVariant: convert QDateTime and QTime to string with milliseconds This way, it's lossless. Change-Id: I5e421e32396d44e4b39efffd150b744e40fff3a1 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Lars Knoll --- src/corelib/kernel/qvariant.cpp | 4 ++-- tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 29429b5e55..93736ae807 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -440,10 +440,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *str = v_cast(d)->toString(Qt::ISODate); break; case QVariant::Time: - *str = v_cast(d)->toString(Qt::ISODate); + *str = v_cast(d)->toString(Qt::ISODateWithMs); break; case QVariant::DateTime: - *str = v_cast(d)->toString(Qt::ISODate); + *str = v_cast(d)->toString(Qt::ISODateWithMs); break; #endif case QVariant::Bool: diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 0d45159d09..6ec90a66c8 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -1099,8 +1099,9 @@ void tst_QVariant::toString_data() QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); - QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); - QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" ); + QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" ); + QTest::newRow( "qtime-with-ms" ) << QVariant( QTime( 12, 34, 56, 789 ) ) << QString( "12:34:56.789" ); + QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56, 789 ) ) ) << QString( "2002-01-01T12:34:56.789" ); QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) << QString( "123456789012" ); QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello"); @@ -1151,6 +1152,7 @@ void tst_QVariant::toTime_data() QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QTime( 12, 34, 56 ); QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QTime( 12, 34, 56 ); QTest::newRow( "qstring" ) << QVariant( QString( "12:34:56" ) ) << QTime( 12, 34, 56 ); + QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "12:34:56.789" ) ) << QTime( 12, 34, 56, 789 ); } void tst_QVariant::toTime() @@ -1171,6 +1173,10 @@ void tst_QVariant::toDateTime_data() << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) ); QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); + QTest::newRow( "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) ) + << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC ); + QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) ) + << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) ); } void tst_QVariant::toDateTime() From e5c02b2579f53b50120ba19b7d041818e915be28 Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Sun, 21 Jan 2018 21:04:29 +0300 Subject: [PATCH 17/32] Doc: fix wrong link to the example snippet in QApplication class Change-Id: Ib9a1b107dd8d2cd4bf541c3edf19a602fde6356f Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Martin Smith Reviewed-by: Paul Wicking --- src/widgets/kernel/qapplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 943aeaa2d9..0a12d1f6cf 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2868,7 +2868,7 @@ void QApplication::setStartDragDistance(int l) and the current position (e.g. in the mouse move event) is \c currentPos, you can find out if a drag should be started with code like this: - \snippet code/src_gui_kernel_qapplication.cpp 6 + \snippet code/src_gui_kernel_qapplication.cpp 7 Qt uses this value internally, e.g. in QFileDialog. From 6dbf3576093858d981d8321b00f0b19faa7cf217 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 13 Oct 2017 16:27:13 +0200 Subject: [PATCH 18/32] Fix asserts and crashes in QWinEventNotifier activation loop The backwards iteration was done under the assumption that the only valid modification of the winEventNotifierList in a slot connected to activated() would be the removal of the notifier itself. This is wrong. Instead, iterate forwards, like before 85403d0a, and check the index against the current list size in every iteration. This ensures that we do not run out of bounds while the list is modified. Also, retry the activation loop if the list was modified by a slot connected to activated(). This ensures that all notifiers with signaled handles are activated. Task-number: QTBUG-65940 Change-Id: I25f305463b9234f391abc51fe0628d02f49b6931 Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qeventdispatcher_win.cpp | 23 ++++--- src/corelib/kernel/qeventdispatcher_win_p.h | 1 + .../tst_qwineventnotifier.cpp | 60 +++++++++++++++++++ 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index bbd442d570..330870f219 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -905,6 +905,7 @@ bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier) return true; d->winEventNotifierList.append(notifier); + d->winEventNotifierListModified = true; if (!d->winEventNotifierActivatedEvent) d->winEventNotifierActivatedEvent = CreateEvent(0, TRUE, FALSE, nullptr); @@ -928,6 +929,7 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier) if (i == -1) return; d->winEventNotifierList.takeAt(i); + d->winEventNotifierListModified = true; QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); if (nd->waitHandle) nd->unregisterWaitObject(); @@ -938,16 +940,19 @@ void QEventDispatcherWin32::activateEventNotifiers() Q_D(QEventDispatcherWin32); ResetEvent(d->winEventNotifierActivatedEvent); - // Iterate backwards, because the notifier might remove itself on activate(). - for (int i = d->winEventNotifierList.count(); --i >= 0;) { - QWinEventNotifier *notifier = d->winEventNotifierList.at(i); - QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); - if (nd->signaledCount.load() != 0) { - --nd->signaledCount; - nd->unregisterWaitObject(); - d->activateEventNotifier(notifier); + // Activate signaled notifiers. Our winEventNotifierList can be modified in activation slots. + do { + d->winEventNotifierListModified = false; + for (int i = 0; i < d->winEventNotifierList.count(); ++i) { + QWinEventNotifier *notifier = d->winEventNotifierList.at(i); + QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier); + if (nd->signaledCount.load() != 0) { + --nd->signaledCount; + nd->unregisterWaitObject(); + d->activateEventNotifier(notifier); + } } - } + } while (d->winEventNotifierListModified); // Re-register the remaining activated notifiers. for (int i = 0; i < d->winEventNotifierList.count(); ++i) { diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 683c7f8f36..a7ed8dda8a 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -195,6 +195,7 @@ public: HANDLE winEventNotifierActivatedEvent; QList winEventNotifierList; + bool winEventNotifierListModified = false; void activateEventNotifier(QWinEventNotifier * wen); QList queuedUserInputEvents; diff --git a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp index 64e78ec3c3..76efa008f7 100644 --- a/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp +++ b/tests/auto/corelib/kernel/qwineventnotifier/tst_qwineventnotifier.cpp @@ -29,8 +29,11 @@ #include #include #include +#include +#include #include +#include #include class tst_QWinEventNotifier : public QObject @@ -44,6 +47,8 @@ private slots: void simple_data(); void simple(); void manyNotifiers(); + void disableNotifiersInActivatedSlot_data(); + void disableNotifiersInActivatedSlot(); private: HANDLE simpleHEvent; @@ -119,6 +124,7 @@ public: HANDLE eventHandle() const { return notifier.handle(); } int numberOfTimesActivated() const { return activatedCount; } + void setEnabled(bool b) { notifier.setEnabled(b); } signals: void activated(); @@ -180,6 +186,60 @@ void tst_QWinEventNotifier::manyNotifiers() })); } +using Indices = QVector; + +void tst_QWinEventNotifier::disableNotifiersInActivatedSlot_data() +{ + QTest::addColumn("count"); + QTest::addColumn("notifiersToSignal"); + QTest::addColumn("notifiersToDisable"); + QTest::addColumn("deleteNotifiers"); + QTest::newRow("disable_signaled") << 3 << Indices{1} << Indices{1} << false; + QTest::newRow("disable_signaled2") << 3 << Indices{1, 2} << Indices{1} << false; + QTest::newRow("disable_before_signaled") << 3 << Indices{1} << Indices{0, 1} << false; + QTest::newRow("disable_after_signaled") << 3 << Indices{1} << Indices{1, 2} << false; + QTest::newRow("delete_signaled") << 3 << Indices{1} << Indices{1} << true; + QTest::newRow("delete_before_signaled1") << 3 << Indices{1} << Indices{0} << true; + QTest::newRow("delete_before_signaled2") << 3 << Indices{1} << Indices{0, 1} << true; + QTest::newRow("delete_before_signaled3") << 4 << Indices{3, 1} << Indices{0, 1} << true; + QTest::newRow("delete_after_signaled1") << 3 << Indices{1} << Indices{1, 2} << true; + QTest::newRow("delete_after_signaled2") << 4 << Indices{1, 3} << Indices{1, 2} << true; + QTest::newRow("delete_after_signaled3") << 5 << Indices{1} << Indices{1, 4} << true; +} + +void tst_QWinEventNotifier::disableNotifiersInActivatedSlot() +{ + QFETCH(int, count); + QFETCH(Indices, notifiersToSignal); + QFETCH(Indices, notifiersToDisable); + QFETCH(bool, deleteNotifiers); + + QVarLengthArray, 10> events(count); + for (int i = 0; i < count; ++i) + events[i].reset(new EventWithNotifier); + + auto isActivatedOrNull = [&events](int i) { + return !events.at(i) || events.at(i)->numberOfTimesActivated() > 0; + }; + + for (auto &e : events) { + connect(e.get(), &EventWithNotifier::activated, [&]() { + for (int i : notifiersToDisable) { + if (deleteNotifiers) + events[i].reset(); + else + events.at(i)->setEnabled(false); + } + if (std::all_of(notifiersToSignal.begin(), notifiersToSignal.end(), isActivatedOrNull)) + QTimer::singleShot(0, &QTestEventLoop::instance(), SLOT(exitLoop())); + }); + } + for (int i : notifiersToSignal) + SetEvent(events.at(i)->eventHandle()); + QTestEventLoop::instance().enterLoop(30); + QVERIFY(!QTestEventLoop::instance().timeout()); +} + QTEST_MAIN(tst_QWinEventNotifier) #include "tst_qwineventnotifier.moc" From 940fd1734b097cbac681298f13193851bf2bf2b9 Mon Sep 17 00:00:00 2001 From: Alexander Shevchenko Date: Thu, 25 Jan 2018 14:09:46 +0200 Subject: [PATCH 19/32] unify windows mkspecs: move angle/vulkan includes 'win32-icc' toolchain: - remove duplicated angle/vulkan includes. 'win32-g++' toolchain: - place angle/vulkan includes before the unrelated compiler-related variable re-definitions, similarly to the 'win32-clang-msvc', 'win32-icc', and 'win32-msvc' mkspecs. Change-Id: Ie04bc9fb1d51ec0366b42713439f680e51214bbc Reviewed-by: Oliver Wolff Reviewed-by: Oswald Buddenhagen --- mkspecs/win32-g++/qmake.conf | 5 ++--- mkspecs/win32-icc/qmake.conf | 3 --- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 0a1cd2dd5a..9f366e08b8 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -10,6 +10,8 @@ load(device_config) include(../common/gcc-base.conf) include(../common/g++-base.conf) +include(../common/angle.conf) +include(../common/windows-vulkan.conf) # modifications to gcc-base.conf and g++-base.conf @@ -84,7 +86,4 @@ QMAKE_STRIPFLAGS_LIB += --strip-unneeded QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P -include(../common/angle.conf) -include(../common/windows-vulkan.conf) - load(qt_config) diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index cc9c6e7363..6acb07f8aa 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -58,7 +58,4 @@ QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_LIB = xilib /NOLOGO -include(../common/angle.conf) -include(../common/windows-vulkan.conf) - load(qt_config) From 11f6c646967c61e3eac6302a2d4ea8f30a41beff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 24 Jan 2018 12:35:29 +0100 Subject: [PATCH 20/32] rasterwindow: End painting on device before ending on backingstore Change-Id: Ib42de1d7ad0d14e2e2d2ff75606e6cfd7e584c2a Reviewed-by: Simon Hausmann --- examples/gui/rasterwindow/rasterwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/gui/rasterwindow/rasterwindow.cpp b/examples/gui/rasterwindow/rasterwindow.cpp index 68d1d7f524..3eacd20145 100644 --- a/examples/gui/rasterwindow/rasterwindow.cpp +++ b/examples/gui/rasterwindow/rasterwindow.cpp @@ -111,6 +111,7 @@ void RasterWindow::renderNow() painter.fillRect(0, 0, width(), height(), Qt::white); render(&painter); + painter.end(); m_backingStore->endPaint(); m_backingStore->flush(rect); From 7d1962cada48f8c351909d1ccc14b13c3adaa542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Jan 2018 17:28:10 +0100 Subject: [PATCH 21/32] macOS: Handle update requests via setNeedsDisplay more carefully Instead of trying to detect situations where we need to send a real expose event instead of an update request in response to a drawRect call, we keep track of when we've asked the view to display due to a requestUpdate call, and only deliver the corresponding drawRect as an update request if no other code has asked the view to display. This should cover all cases of asking the view to display, issued from our code or from AppKit, such as the view changing its backing scale factor, or otherwise needing a real expose event. Task-number: QTBUG-65663 Change-Id: I1783787823aee889dad8e48f34a1cb0f1b7b06bd Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoawindow.mm | 19 +-------- src/plugins/platforms/cocoa/qnsview.h | 3 ++ src/plugins/platforms/cocoa/qnsview.mm | 44 ++++++++++++++++----- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 92df6eac49..af2931c747 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1157,23 +1157,6 @@ void QCocoaWindow::handleExposeEvent(const QRegion ®ion) m_exposedRect = QRect(); } - QWindowPrivate *windowPrivate = qt_window_private(window()); - if (windowPrivate->updateRequestPending) { - // We can only deliver update request events when the window is exposed, - // and we also have to make sure we deliver any change to the exposed - // rect as a real expose event (including going from non-exposed to - // exposed). FIXME: Should this logic live in QGuiApplication? - if (isExposed() && m_exposedRect == previouslyExposedRect) { - qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "as update request"; - windowPrivate->deliverUpdateRequest(); - return; - } else { - // Since updateRequestPending is still set, we will issue a deferred setNeedsDisplay - // from drawRect and get back into this code on the next display cycle, delivering - // the pending update request. - } - } - qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed(); QWindowSystemInterface::handleExposeEvent(window(), region); } @@ -1348,7 +1331,7 @@ void QCocoaWindow::recreateWindowIfNeeded() void QCocoaWindow::requestUpdate() { qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::requestUpdate" << window(); - [m_view setNeedsDisplay:YES]; + [m_view requestUpdate]; } void QCocoaWindow::requestActivateWindow() diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index f8903725a6..e2ea862cd5 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -81,6 +81,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); NSEvent *m_currentlyInterpretedKeyEvent; bool m_isMenuView; QSet m_acceptedKeyDowns; + bool m_updateRequested; } @property (nonatomic, retain) NSCursor *cursor; @@ -105,6 +106,8 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)resetMouseButtons; +- (void)requestUpdate; + - (void)handleMouseEvent:(NSEvent *)theEvent; - (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber; - (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 61f0012a2d..e3bee95ad9 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -147,6 +147,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") m_isMenuView = false; self.focusRingType = NSFocusRingTypeNone; self.cursor = nil; + m_updateRequested = false; } return self; } @@ -299,6 +300,25 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") return m_platformWindow->isOpaque(); } +- (void)requestUpdate +{ + if (self.needsDisplay) { + // If the view already has needsDisplay set it means that there may be code waiting for + // a real expose event, so we can't issue setNeedsDisplay now as a way to trigger an + // update request. We will re-trigger requestUpdate from drawRect. + return; + } + + [self setNeedsDisplay:YES]; + m_updateRequested = true; +} + +- (void)setNeedsDisplayInRect:(NSRect)rect +{ + [super setNeedsDisplayInRect:rect]; + m_updateRequested = false; +} + - (void)drawRect:(NSRect)dirtyRect { Q_UNUSED(dirtyRect); @@ -322,18 +342,24 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") } #endif - m_platformWindow->handleExposeEvent(exposedRegion); + QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window()); - if (qt_window_private(m_platformWindow->window())->updateRequestPending) { - // A call to QWindow::requestUpdate was issued during the expose event, or we - // had to deliver a real expose event and still need to deliver the update. - // But AppKit will reset the needsDisplay state of the view after completing + if (m_updateRequested) { + Q_ASSERT(windowPrivate->updateRequestPending); + qCDebug(lcQpaCocoaWindow) << "Delivering update request to" << m_platformWindow->window(); + windowPrivate->deliverUpdateRequest(); + m_updateRequested = false; + } else { + m_platformWindow->handleExposeEvent(exposedRegion); + } + + if (windowPrivate->updateRequestPending) { + // A call to QWindow::requestUpdate was issued during event delivery above, + // but AppKit will reset the needsDisplay state of the view after completing // the current display cycle, so we need to defer the request to redisplay. // FIXME: Perhaps this should be a trigger to enable CADisplayLink? - qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request"; - dispatch_async(dispatch_get_main_queue (), ^{ - [self setNeedsDisplay:YES]; - }); + qCDebug(lcQpaCocoaWindow) << "Pending update request, triggering re-display"; + dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; }); } } From 538b1b50764fb3a1898d425a7155319afbcf3b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Feb 2018 12:17:48 +0100 Subject: [PATCH 22/32] Android: Defer initialization of logging rules until qApp construction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Android, we load the application library, and its dependencies (Qt), on Android's main thread (thread 0), and then spin up a secondary thread (thread 1), that we call main() on. If any QObject is constructed during loading of the application library or any of Qt's libraries, via static initializers or constructor functions, we will set QCoreApplicationPrivate::theMainThread to thread 0, which will confuse Qt later on when it's being run on thread 1, and will result in a warning during QCoreApplication construction: QApplication was not created in the main() thread This situation can easily lead to a crash as well. Unfortunately logging via qDebug/qCDebug and friends will trigger this too, as they internally use QObject. Fixing the root cause of this is under investigation, but for now we will partially revert fa2a653b3b934783 for Android. The effect is that any qCDebug with a "qt.*" category before qApp construction will turn into a no-op, like it was before fa2a653b3b934783. This patch does not cover the case of a regular qDebug, or a qCDebug with a non-Qt category. Those will still produce the same symptom, as before fa2a653b3b934783. Task-number: QTBUG-65863 Change-Id: I95675731d233244530d0a2a1c82a9578d5599775 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qloggingregistry.cpp | 10 ++++++++++ src/corelib/kernel/qcoreapplication.cpp | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index b5f8e30b80..cd97268d71 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -44,6 +44,7 @@ #include #include #include +#include // We can't use the default macros because this would lead to recursion. // Instead let's define our own one that unconditionally logs... @@ -255,6 +256,15 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line) QLoggingRegistry::QLoggingRegistry() : categoryFilter(defaultCategoryFilter) { +#if defined(Q_OS_ANDROID) + // Unless QCoreApplication has been constructed we can't be sure that + // we are on Qt's main thread. If we did allow logging here, we would + // potentially set Qt's main thread to Android's thread 0, which would + // confuse Qt later when running main(). + if (!qApp) + return; +#endif + initializeRules(); // Init on first use } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 9ec8262bf9..3814894630 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -802,6 +802,14 @@ void QCoreApplicationPrivate::init() if (!coreappdata()->applicationVersionSet) coreappdata()->applicationVersion = appVersion(); +#if defined(Q_OS_ANDROID) + // We've deferred initializing the logging registry due to not being + // able to guarantee that logging happened on the same thread as the + // Qt main thread, but now that the Qt main thread is set up, we can + // enable categorized logging. + QLoggingRegistry::instance()->initializeRules(); +#endif + #if QT_CONFIG(library) // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0] // into account. If necessary, recompute right away and replay the manual changes on top of the From eadf9e542fcc42597bfe02df065fc4cefa94cd56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 30 Jan 2018 16:40:26 +0100 Subject: [PATCH 23/32] Android: Don't rely on QDir::homePath() to get the application directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the QLoggingRegistry gets called as part of the static initialization phase, it would call into Android's QStandarPaths implementation, which assumed that the HOME env. variable was already set. Since the variable isn't set before main is called, QDir::homePath() returns the root path, which would be cached and always returned. With this fix we now call Android's getFilesDir() directly, which will always return the right path. Since the font locations are also relying on an environment variable being set, we no longer cache that either. Task-number: QTBUG-65820 Change-Id: If45f3d5f0e87b808a62118ae95c31b492885646a Reviewed-by: Tor Arne Vestbø Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/io/qstandardpaths_android.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp index 2a44daf8b5..0667d170c7 100644 --- a/src/corelib/io/qstandardpaths_android.cpp +++ b/src/corelib/io/qstandardpaths_android.cpp @@ -217,7 +217,16 @@ static QString getFilesDir() if (!path.isEmpty()) return path; - return (path = QDir::homePath()); + QJNIObjectPrivate appCtx = applicationContext(); + if (!appCtx.isValid()) + return QString(); + + QJNIObjectPrivate file = appCtx.callObjectMethod("getFilesDir", + "()Ljava/io/File;"); + if (!file.isValid()) + return QString(); + + return (path = getAbsolutePath(file)); } QString QStandardPaths::writableLocation(StandardLocation type) @@ -319,7 +328,9 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) if (!ba.isEmpty()) return QStringList((fontLocation = QDir::cleanPath(QString::fromLocal8Bit(ba)))); - return QStringList((fontLocation = QLatin1String("/system/fonts"))); + // Don't cache the fallback, as we might just have been called before + // QT_ANDROID_FONT_LOCATION has been set. + return QStringList(QLatin1String("/system/fonts")); } return QStringList(writableLocation(type)); From 69d2501ee1900c43a35802eae05a734e479a7776 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 29 Jan 2018 23:56:05 -0800 Subject: [PATCH 24/32] Revert "QVariant: convert QDateTime and QTime to string with milliseconds" This reverts commit ab1e50757454b5afda2f6dec52d2eb16a32d4798. That was supposed to be a minor behavior change, but ends up having visible effects such as QtXmlPatterns xs:dateTime type now reporting sub-second fractions. So we're reverting in 5.10 and re-applying in 5.11. Change-Id: I741e49459c9a688c1c329d6cbd521cd4a0b2aa84 Reviewed-by: Lars Knoll --- src/corelib/kernel/qvariant.cpp | 4 ++-- tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 93736ae807..29429b5e55 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -440,10 +440,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) *str = v_cast(d)->toString(Qt::ISODate); break; case QVariant::Time: - *str = v_cast(d)->toString(Qt::ISODateWithMs); + *str = v_cast(d)->toString(Qt::ISODate); break; case QVariant::DateTime: - *str = v_cast(d)->toString(Qt::ISODateWithMs); + *str = v_cast(d)->toString(Qt::ISODate); break; #endif case QVariant::Bool: diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 6ec90a66c8..0d45159d09 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -1099,9 +1099,8 @@ void tst_QVariant::toString_data() QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); - QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" ); - QTest::newRow( "qtime-with-ms" ) << QVariant( QTime( 12, 34, 56, 789 ) ) << QString( "12:34:56.789" ); - QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56, 789 ) ) ) << QString( "2002-01-01T12:34:56.789" ); + QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); + QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" ); QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) << QString( "123456789012" ); QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello"); @@ -1152,7 +1151,6 @@ void tst_QVariant::toTime_data() QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QTime( 12, 34, 56 ); QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QTime( 12, 34, 56 ); QTest::newRow( "qstring" ) << QVariant( QString( "12:34:56" ) ) << QTime( 12, 34, 56 ); - QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "12:34:56.789" ) ) << QTime( 12, 34, 56, 789 ); } void tst_QVariant::toTime() @@ -1173,10 +1171,6 @@ void tst_QVariant::toDateTime_data() << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) ); QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); - QTest::newRow( "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) ) - << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC ); - QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) ) - << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) ); } void tst_QVariant::toDateTime() From e365993b72d64db441f3940d6c255e3dbb2ad76a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 1 Feb 2018 16:12:49 +0100 Subject: [PATCH 25/32] Fix configure.json for opensslv11 feature Both the test/feature had some errors (incorrect "use" and incomplete "condition") + remove "feature". Task-number: QTBUG-62733 Change-Id: If4b8d2fe080d8fba961231834839afadaed0f0c5 Reviewed-by: Oswald Buddenhagen --- src/network/configure.json | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index 770921f9a6..2f446becf1 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -123,10 +123,10 @@ "use": "network" }, "openssl11": { - "label": "OpenSSL v. 1.1 support", + "label": "OpenSSL 1.1 support", "type": "compile", "test": "unix/openssl11", - "use": "network" + "use": "openssl" } }, @@ -190,9 +190,9 @@ "output": [ "publicFeature", "feature" ] }, "opensslv11": { - "label": "OpenSSL v. 1.1", - "condition": "tests.openssl11", - "output": ["publicFeature", "feature"] + "label": "OpenSSL 1.1", + "condition": "features.openssl && tests.openssl11", + "output": [ "publicFeature" ] }, "sctp": { "label": "SCTP", @@ -307,6 +307,7 @@ For example: }, "openssl", "openssl-linked", + "opensslv11", "sctp", "system-proxies" ] From 9a74cbf47386a861b44900cda2c5a00b4ffd42d8 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Thu, 1 Feb 2018 21:47:42 +0100 Subject: [PATCH 26/32] QString: Wrap extra-long comment line Change-Id: I77c95e99fd23eb914d7e86ee003d7f487c57f0f0 Reviewed-by: Martin Smith --- src/corelib/tools/qstring.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 30f8948eec..9926244497 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6951,7 +6951,10 @@ ushort QString::toUShort(bool *ok, int base) const \snippet qstring/main.cpp 66 - \warning The QString content may only contain valid numerical characters which includes the plus/minus sign, the characters g and e used in scientific notation, and the decimal point. Including the unit or additional characters leads to a conversion error. + \warning The QString content may only contain valid numerical characters + which includes the plus/minus sign, the characters g and e used in scientific + notation, and the decimal point. Including the unit or additional characters + leads to a conversion error. \snippet qstring/main.cpp 67 From 6197df32ec3449ec141bcd9fa4fe47da4cc761e7 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Thu, 1 Feb 2018 21:37:56 +0100 Subject: [PATCH 27/32] QString: Add whitespace handling note to number conversion functions Copied from QLocale::toFloat and companions. Change-Id: Ic3a13a87cfc1ce34de9dd7d7e7b303ef103c384a Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 9926244497..1ef9f5a3c5 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6712,6 +6712,8 @@ QString QString::vasprintf(const char *cformat, va_list ap) \snippet qstring/main.cpp 74 + This function ignores leading and trailing whitespace. + \sa number(), toULongLong(), toInt(), QLocale::toLongLong() */ @@ -6752,6 +6754,8 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b \snippet qstring/main.cpp 79 + This function ignores leading and trailing whitespace. + \sa number(), toLongLong(), QLocale::toULongLong() */ @@ -6794,6 +6798,8 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int \snippet qstring/main.cpp 73 + This function ignores leading and trailing whitespace. + \sa number(), toULong(), toInt(), QLocale::toInt() */ @@ -6823,6 +6829,8 @@ long QString::toLong(bool *ok, int base) const \snippet qstring/main.cpp 78 + This function ignores leading and trailing whitespace. + \sa number(), QLocale::toUInt() */ @@ -6851,6 +6859,8 @@ ulong QString::toULong(bool *ok, int base) const \snippet qstring/main.cpp 72 + This function ignores leading and trailing whitespace. + \sa number(), toUInt(), toDouble(), QLocale::toInt() */ @@ -6878,6 +6888,8 @@ int QString::toInt(bool *ok, int base) const \snippet qstring/main.cpp 77 + This function ignores leading and trailing whitespace. + \sa number(), toInt(), QLocale::toUInt() */ @@ -6905,6 +6917,8 @@ uint QString::toUInt(bool *ok, int base) const \snippet qstring/main.cpp 76 + This function ignores leading and trailing whitespace. + \sa number(), toUShort(), toInt(), QLocale::toShort() */ @@ -6932,6 +6946,8 @@ short QString::toShort(bool *ok, int base) const \snippet qstring/main.cpp 80 + This function ignores leading and trailing whitespace. + \sa number(), toShort(), QLocale::toUShort() */ @@ -6969,6 +6985,8 @@ ushort QString::toUShort(bool *ok, int base) const \snippet qstring/main.cpp 69 + This function ignores leading and trailing whitespace. + \sa number(), QLocale::setDefault(), QLocale::toDouble(), trimmed() */ @@ -6983,6 +7001,8 @@ double QString::toDouble(bool *ok) const If a conversion error occurs, *\a{ok} is set to \c false; otherwise *\a{ok} is set to \c true. Returns 0.0 if the conversion fails. + This function ignores leading and trailing whitespace. + The string conversion will always happen in the 'C' locale. For locale dependent conversion use QLocale::toFloat() @@ -6990,6 +7010,8 @@ double QString::toDouble(bool *ok) const \snippet qstring/main.cpp 71 + This function ignores leading and trailing whitespace. + \sa number(), toDouble(), toInt(), QLocale::toFloat() */ From 35f6f530bfa3877dfdf763ab1cdb1d63cc66c6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 24 Jan 2018 15:42:17 +0100 Subject: [PATCH 28/32] iOS: Simplify logging of QUIView/QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatically printing the relationship between the view, platform window, and window, makes it easier to track each object across events. Change-Id: I9fbfaa5c304849ed99dba3b5cd8e7449105d0307 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 4 +++ src/plugins/platforms/ios/qioswindow.mm | 13 +++++++++ src/plugins/platforms/ios/quiview.mm | 35 ++++++++++++++++--------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 14fa2084c9..8ed5347f66 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -110,6 +110,10 @@ private: friend class QIOSScreen; }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QIOSWindow *window); +#endif + QT_END_NAMESPACE #endif // QIOSWINDOW_H diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 38136c05db..6ee258e363 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -381,6 +381,19 @@ CAEAGLLayer *QIOSWindow::eaglLayer() const return static_cast(m_view.layer); } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QIOSWindow *window) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug << "QIOSWindow(" << (const void *)window; + if (window) + debug << ", window=" << window->window(); + debug << ')'; + return debug; +} +#endif // !QT_NO_DEBUG_STREAM + #include "moc_qioswindow.cpp" QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 4c2184a1f6..bd75ed2384 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -147,6 +147,21 @@ [super dealloc]; } +- (NSString *)description +{ + NSMutableString *description = [NSMutableString stringWithString:[super description]]; + +#ifndef QT_NO_DEBUG_STREAM + QString platformWindowDescription; + QDebug debug(&platformWindowDescription); + debug.nospace() << "; " << m_qioswindow << ">"; + NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1]; + [description replaceCharactersInRange:lastCharacter withString:platformWindowDescription.toNSString()]; +#endif + + return description; +} + - (void)willMoveToWindow:(UIWindow *)newWindow { // UIKIt will normally set the scale factor of a view to match the corresponding @@ -191,13 +206,12 @@ // when the size is also changed. if (!CGAffineTransformIsIdentity(self.transform)) - qWarning() << m_qioswindow->window() - << "is backed by a UIView that has a transform set. This is not supported."; + qWarning() << self << "has a transform set. This is not supported."; QWindow *window = m_qioswindow->window(); QRect lastReportedGeometry = qt_window_private(window)->geometry; QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect(); - qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << currentGeometry; + qCDebug(lcQpaWindow) << m_qioswindow << "new geometry is" << currentGeometry; QWindowSystemInterface::handleGeometryChange(window, currentGeometry); if (currentGeometry.size() != lastReportedGeometry.size()) { @@ -230,7 +244,7 @@ region = QRect(QPoint(), bounds); } - qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed(); + qCDebug(lcQpaWindow) << m_qioswindow << region << "isExposed" << m_qioswindow->isExposed(); QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); } @@ -254,16 +268,14 @@ // blocked by this guard. FirstResponderCandidate firstResponderCandidate(self); - qImDebug() << "win:" << m_qioswindow->window() << "self:" << self - << "first:" << [UIResponder currentFirstResponder]; + qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder]; if (![super becomeFirstResponder]) { - qImDebug() << m_qioswindow->window() - << "was not allowed to become first responder"; + qImDebug() << self << "was not allowed to become first responder"; return NO; } - qImDebug() << m_qioswindow->window() << "became first responder"; + qImDebug() << self << "became first responder"; } if (qGuiApp->focusWindow() != m_qioswindow->window()) @@ -295,13 +307,12 @@ - (BOOL)resignFirstResponder { - qImDebug() << "win:" << m_qioswindow->window() << "self:" << self - << "first:" << [UIResponder currentFirstResponder]; + qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder]; if (![super resignFirstResponder]) return NO; - qImDebug() << m_qioswindow->window() << "resigned first responder"; + qImDebug() << self << "resigned first responder"; UIResponder *newResponder = FirstResponderCandidate::currentCandidate(); if ([self responderShouldTriggerWindowDeactivation:newResponder]) From 28cf5ae000de36cd6ad0df942c2f99bfa7e22129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Jan 2018 17:34:03 +0100 Subject: [PATCH 29/32] macOS: Share view update code between layered and non-layered mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8eaf0607c1ede18ed20180fd43cc93744c99962d Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index e3bee95ad9..3e3e9aac1a 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -334,7 +334,11 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect(); qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion; + [self updateRegion:exposedRegion]; +} +- (void)updateRegion:(QRegion)dirtyRegion +{ #ifndef QT_NO_OPENGL if (m_glContext && m_shouldSetGLContextinDrawRect) { [m_glContext->nsOpenGLContext() setView:self]; @@ -350,7 +354,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") windowPrivate->deliverUpdateRequest(); m_updateRequested = false; } else { - m_platformWindow->handleExposeEvent(exposedRegion); + m_platformWindow->handleExposeEvent(dirtyRegion); } if (windowPrivate->updateRequestPending) { @@ -376,7 +380,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") qCDebug(lcQpaCocoaWindow) << "[QNSView updateLayer]" << m_platformWindow->window(); // FIXME: Find out if there's a way to resolve the dirty rect like in drawRect: - m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect()); + [self updateRegion:QRectF::fromCGRect(self.bounds).toRect()]; } - (void)viewDidChangeBackingProperties From 83b0abf928af6cd9f301e3367c439eca22aab323 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 30 Jan 2018 00:32:36 +0100 Subject: [PATCH 30/32] Use the right attribute when checking if shortcuts are shown Change-Id: I784965dda64551e6093af817881aa6472d2cc226 Reviewed-by: Jake Petroules Reviewed-by: Gabriel de Dietrich --- src/widgets/kernel/qaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index 853e27cd6e..a48eb90048 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -1332,7 +1332,7 @@ bool QAction::isShortcutVisibleInContextMenu() const { Q_D(const QAction); if (d->shortcutVisibleInContextMenu == -1) { - if (QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus)) + if (QApplication::instance()->testAttribute(Qt::AA_DontShowShortcutsInContextMenus)) return false; return qApp->styleHints()->showShortcutsInContextMenus(); } From c48f4bde0044bd5b23af231f3639d0779ecbdb03 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 1 Feb 2018 20:59:58 +0100 Subject: [PATCH 31/32] Set the ellipseDiameters back to the original size in QGraphicsView When calling setSceneRect() on a QTouchPoint it will cause the ellipseDiameters to be changed, whereas this should not be affected by the scene rectangle as it should be in logical pixels. Also add a manual test for visually checking the ellipse diameters on various devices. Change-Id: I1ee9207cb1a63cfef33fe904594c73aba221af5c Reviewed-by: Shawn Rutledge --- src/widgets/graphicsview/qgraphicsview.cpp | 6 +- .../qgraphicsscene/tst_qgraphicsscene.cpp | 76 ++++++++ tests/manual/touchGraphicsItem/main.cpp | 163 ++++++++++++++++++ .../touchGraphicsItem/touchGraphicsItem.pro | 5 + 4 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 tests/manual/touchGraphicsItem/main.cpp create mode 100644 tests/manual/touchGraphicsItem/touchGraphicsItem.pro diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 1cc8543fdd..0c847b899e 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -313,13 +313,15 @@ void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEv QList touchPoints = touchEvent->touchPoints(); for (int i = 0; i < touchPoints.count(); ++i) { QTouchEvent::TouchPoint &touchPoint = touchPoints[i]; + const QSizeF ellipseDiameters = touchPoint.ellipseDiameters(); // the scene will set the item local pos, startPos, lastPos, and rect before delivering to // an item, but for now those functions are returning the view's local coordinates - touchPoint.setSceneRect(d->mapToScene(touchPoint.rect())); + touchPoint.setScenePos(d->mapToScene(touchPoint.pos())); touchPoint.setStartScenePos(d->mapToScene(touchPoint.startPos())); touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos())); + touchPoint.setEllipseDiameters(ellipseDiameters); - // screenPos, startScreenPos, lastScreenPos, and screenRect are already set + // screenPos, startScreenPos, and lastScreenPos are already set } touchEvent->setTouchPoints(touchPoints); diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index bfdb540c2b..e7cf8f17a2 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -254,6 +254,7 @@ private slots: void zeroScale(); void focusItemChangedSignal(); void minimumRenderSize(); + void checkTouchPointsEllipseDiameters(); // task specific tests below me void task139710_bspTreeCrash(); @@ -4764,6 +4765,81 @@ void tst_QGraphicsScene::minimumRenderSize() QVERIFY(smallChild->repaints > smallerGrandChild->repaints); } +class TouchItem : public QGraphicsRectItem +{ +public: + TouchItem() : QGraphicsRectItem(QRectF(-10, -10, 20, 20)), + seenTouch(false) + { + setAcceptTouchEvents(true); + setFlag(QGraphicsItem::ItemIgnoresTransformations); + } + bool seenTouch; + QList touchPoints; +protected: + bool sceneEvent(QEvent *event) override + { + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + seenTouch = true; + touchPoints = static_cast(event)->touchPoints(); + event->accept(); + return true; + default: + break; + } + return QGraphicsRectItem::sceneEvent(event); + } +}; + +void tst_QGraphicsScene::checkTouchPointsEllipseDiameters() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + scene.setSceneRect(1, 1, 198, 198); + view.scale(1.5, 1.5); + view.setFocus(); + TouchItem *rect = new TouchItem; + scene.addItem(rect); + view.show(); + QApplication::setActiveWindow(&view); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + const QSizeF ellipseDiameters(10.0, 10.0); + QTouchEvent::TouchPoint touchPoint(0); + touchPoint.setState(Qt::TouchPointPressed); + touchPoint.setPos(view.mapFromScene(rect->mapToScene(rect->boundingRect().center()))); + touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); + touchPoint.setEllipseDiameters(ellipseDiameters); + + QList touchPoints = { touchPoint }; + + QTouchDevice *testDevice = QTest::createTouchDevice(QTouchDevice::TouchPad); + QTouchEvent touchEvent(QEvent::TouchBegin, + testDevice, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + QApplication::sendEvent(view.viewport(), &touchEvent); + QVERIFY(rect->seenTouch); + QVERIFY(rect->touchPoints.size() == 1); + QCOMPARE(ellipseDiameters, rect->touchPoints.first().ellipseDiameters()); + + rect->seenTouch = false; + rect->touchPoints.clear(); + QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, + testDevice, + Qt::NoModifier, + Qt::TouchPointMoved, + touchPoints); + QApplication::sendEvent(view.viewport(), &touchEvent); + QVERIFY(rect->seenTouch); + QVERIFY(rect->touchPoints.size() == 1); + QCOMPARE(ellipseDiameters, rect->touchPoints.first().ellipseDiameters()); +} + void tst_QGraphicsScene::taskQTBUG_15977_renderWithDeviceCoordinateCache() { QGraphicsScene scene; diff --git a/tests/manual/touchGraphicsItem/main.cpp b/tests/manual/touchGraphicsItem/main.cpp new file mode 100644 index 0000000000..7afadc7edd --- /dev/null +++ b/tests/manual/touchGraphicsItem/main.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +class TouchableItem : public QGraphicsRectItem +{ +public: + TouchableItem() : QGraphicsRectItem(50, 50, 400, 400) + { + setBrush(Qt::yellow); + setAcceptTouchEvents(true); + } +protected: + bool sceneEvent(QEvent *e) + { + const bool ret = QGraphicsRectItem::sceneEvent(e); + switch (e->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + { + QTouchEvent *te = static_cast(e); + for (const QTouchEvent::TouchPoint &tp : te->touchPoints()) { + QGraphicsEllipseItem *diameterItem = nullptr; + QSizeF ellipse = tp.ellipseDiameters(); + if (ellipse.isNull()) { + ellipse = QSizeF(5, 5); + } else { + diameterItem = new QGraphicsEllipseItem(QRectF(tp.pos().x() - ellipse.width() / 2, tp.pos().y() - ellipse.height() / 2, + ellipse.width(), ellipse.height()), this); + diameterItem->setPen(QPen(Qt::red)); + diameterItem->setBrush(QBrush(Qt::red)); + if (ellipse.width() > qreal(2) && ellipse.height() > qreal(2)) + ellipse.scale(ellipse.width() - 2, ellipse.height() - 2, Qt::IgnoreAspectRatio); + } + QGraphicsItem *parent = diameterItem ? static_cast(diameterItem) : static_cast(this); + QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem(QRectF(tp.pos().x() - ellipse.width() / 2, + tp.pos().y() - ellipse.height() / 2, + ellipse.width(), ellipse.height()), parent); + ellipseItem->setPen(QPen(Qt::blue)); + ellipseItem->setBrush(QBrush(Qt::blue)); + } + te->accept(); + return true; + } + default: + break; + } + return ret; + } +}; + +int main(int argc, char **argv) +{ + QApplication a(argc, argv); + QMainWindow mw; + QWidget *w = new QWidget; + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(new QLabel("The blue ellipses should indicate touch point contact patches")); + qDebug() << "Touch devices:"; + for (const QTouchDevice *device : QTouchDevice::devices()) { + QString result; + QTextStream str(&result); + str << (device->type() == QTouchDevice::TouchScreen ? "TouchScreen" : "TouchPad") + << " \"" << device->name() << "\", max " << device->maximumTouchPoints() + << " touch points, capabilities:"; + const QTouchDevice::Capabilities capabilities = device->capabilities(); + if (capabilities & QTouchDevice::Position) + str << " Position"; + if (capabilities & QTouchDevice::Area) + str << " Area"; + if (capabilities & QTouchDevice::Pressure) + str << " Pressure"; + if (capabilities & QTouchDevice::Velocity) + str << " Velocity"; + if (capabilities & QTouchDevice::RawPositions) + str << " RawPositions"; + if (capabilities & QTouchDevice::NormalizedPosition) + str << " NormalizedPosition"; + if (capabilities & QTouchDevice::MouseEmulation) + str << " MouseEmulation"; + vbox->addWidget(new QLabel(result)); + qDebug() << " " << result; + } + QGraphicsView *view = new QGraphicsView; + view->viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + QGraphicsScene *scene = new QGraphicsScene(0, 0, 500, 500); + TouchableItem *touchableItem = new TouchableItem; + scene->addItem(touchableItem); + view->setScene(scene); + vbox->addWidget(view); + w->setLayout(vbox); + mw.setCentralWidget(w); + QMenu *menu = mw.menuBar()->addMenu("Menu"); + QAction *clear = new QAction("Clear"); + QObject::connect(clear, &QAction::triggered, [=]() { + qDeleteAll(touchableItem->childItems()); + }); + menu->addAction(clear); + QAction *ignoreTransform = new QAction("Ignore transformations"); + QObject::connect(ignoreTransform, &QAction::triggered, [=]() { + view->scale(1.5, 1.5); + touchableItem->setFlag(QGraphicsItem::ItemIgnoresTransformations); + }); + menu->addAction(ignoreTransform); + QAction *quit = new QAction("Quit"); + quit->setShortcut(QKeySequence::Quit); + QObject::connect(quit, &QAction::triggered, &QApplication::quit); + menu->addAction(quit); + mw.show(); + + return a.exec(); +} + + diff --git a/tests/manual/touchGraphicsItem/touchGraphicsItem.pro b/tests/manual/touchGraphicsItem/touchGraphicsItem.pro new file mode 100644 index 0000000000..67799ce9c4 --- /dev/null +++ b/tests/manual/touchGraphicsItem/touchGraphicsItem.pro @@ -0,0 +1,5 @@ +QT+=widgets +TEMPLATE = app +TARGET = touchGraphicsItem +INCLUDEPATH += . +SOURCES += main.cpp From 4ba535616b8d3dfda7fbe162c6513f3008c1077a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 7 Feb 2018 23:25:06 -0800 Subject: [PATCH 32/32] QSaveFile: Check for EINTR in fsync()/fdatasync() [ChangeLog][QtCore][QSaveFile] Fixed an issue that would cause QSaveFile::commit() to fail if Unix signals were delivered at the same time. Task-number: QTBUG-66268 Change-Id: I3debfc11127e4516b505fffd151148e70662cd5e Reviewed-by: Oswald Buddenhagen Reviewed-by: David Faure --- src/corelib/io/qfsfileengine_unix.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index c040d67862..e406fb4447 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -180,10 +180,11 @@ bool QFSFileEnginePrivate::nativeFlush() bool QFSFileEnginePrivate::nativeSyncToDisk() { Q_Q(QFSFileEngine); + int ret; #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 - const int ret = fdatasync(nativeHandle()); + EINTR_LOOP(ret, fdatasync(nativeHandle())); #else - const int ret = fsync(nativeHandle()); + EINTR_LOOP(ret, fsync(nativeHandle())); #endif if (ret != 0) q->setError(QFile::WriteError, qt_error_string(errno));