From b4e9cb4c29ef797fe535a84717bebf81fbdc61e4 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 24 Sep 2017 08:26:30 +0300 Subject: Qmake: Introduce and use QMAKE_NULL_DEVICE variable Task-number: QTBUG-62985 Change-Id: If1a4cabd54df7d69be1a580dc120f75d6c6b2092 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/ctest_testcase_common.prf | 14 ++------------ mkspecs/features/qt_functions.prf | 5 +---- mkspecs/features/spec_post.prf | 2 ++ mkspecs/features/toolchain.prf | 18 ++++++------------ qmake/generators/win32/mingw_make.cpp | 8 +------- 5 files changed, 12 insertions(+), 35 deletions(-) diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf index cdc5cca1d7..15701b6a41 100644 --- a/mkspecs/features/ctest_testcase_common.prf +++ b/mkspecs/features/ctest_testcase_common.prf @@ -1,10 +1,5 @@ -win32 { - CMAKE_VERSION = $$system(cmake --version 2>NUL, lines) -} else { - CMAKE_VERSION = $$system(cmake --version 2>/dev/null, lines) -} - +CMAKE_VERSION = $$system(cmake --version 2>$$QMAKE_NULL_DEVICE, lines) CMAKE_VERSION = $$member(CMAKE_VERSION, 0, 0) check.commands = @@ -15,12 +10,7 @@ isEmpty(CMAKE_VERSION) { return() } -win32 { - CTEST_VERSION = $$system(ctest --version 2>NUL) -} else { - CTEST_VERSION = $$system(ctest --version 2>/dev/null) -} - +CTEST_VERSION = $$system(ctest --version 2>$$QMAKE_NULL_DEVICE) isEmpty(CTEST_VERSION) { message("ctest executable not found. Not running CMake unit tests") return() diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index c00fdb73f8..1f44650227 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -291,10 +291,7 @@ defineReplace(pkgConfigExecutable) { } } - equals(QMAKE_HOST.os, Windows): \ - PKG_CONFIG += 2> NUL - else: \ - PKG_CONFIG += 2> /dev/null + PKG_CONFIG += 2> $$QMAKE_NULL_DEVICE return($$PKG_CONFIG) } diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf index f87bf3c037..62be69ffda 100644 --- a/mkspecs/features/spec_post.prf +++ b/mkspecs/features/spec_post.prf @@ -82,6 +82,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_MKDIR = mkdir # legacy QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1 QMAKE_STREAM_EDITOR = $(QMAKE) -install sed + QMAKE_NULL_DEVICE = NUL QMAKE_INSTALL_FILE = copy /y QMAKE_INSTALL_PROGRAM = copy /y } else { @@ -101,6 +102,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_MKDIR = mkdir -p # legacy QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1 QMAKE_STREAM_EDITOR = sed + QMAKE_NULL_DEVICE = /dev/null equals(QMAKE_HOST.os, Windows) { MINGW_IN_SHELL = 1 # legacy diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 35175f1744..e7ada377d7 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -32,15 +32,11 @@ isEmpty($${target_prefix}.INCDIRS) { # Get default include and library paths from compiler # gcc { - !equals(QMAKE_HOST.os, Windows) { - cmd_prefix = "LC_ALL=C" - cmd_suffix = "/dev/null" - null_file = /dev/null - } else { + cmd_suffix = "<$$QMAKE_NULL_DEVICE >$$QMAKE_NULL_DEVICE" + equals(QMAKE_HOST.os, Windows): \ cmd_prefix = "set LC_ALL=C&" - cmd_suffix = "NUL" - null_file = NUL - } + else: \ + cmd_prefix = "LC_ALL=C" cxx_flags = $$QMAKE_CXXFLAGS @@ -59,7 +55,7 @@ isEmpty($${target_prefix}.INCDIRS) { rim_qcc: \ # Need the cc1plus and ld command lines to pick up the paths - cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$null_file -v + cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$QMAKE_NULL_DEVICE -v else: darwin:clang: \ # Need to link to pick up library paths cxx_flags += $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v @@ -175,9 +171,7 @@ defineReplace(qtVariablesFromMSVC) { } defineReplace(qtVariablesFromGCC) { - null_device = /dev/null - equals(QMAKE_HOST.os, Windows): null_device = NUL - ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines, ec) + ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$QMAKE_NULL_DEVICE 2>$$QMAKE_NULL_DEVICE", lines, ec) !equals(ec, 0): qtCompilerErrror($$1) return($$ret) } diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index bad53dc5b7..2d69f708fb 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -36,12 +36,6 @@ #include #include -#ifdef Q_OS_WIN -#define NULL_DEVICE "NUL" -#else -#define NULL_DEVICE "/dev/null" -#endif - QT_BEGIN_NAMESPACE MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator() @@ -329,7 +323,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { - t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" NULL_DEVICE; + t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>$$QMAKE_NULL_DEVICE"; if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) { t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ; } else { -- cgit v1.2.3 From 2b51ad471270c01858369f10c7645d863d89160c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 25 Sep 2017 11:28:20 +0200 Subject: Cups: Check the created QPrintDevice is valid before using it Task-number: QTBUG-63293 Change-Id: Ibde0e8db955f6f3647b31cef8561d0744754cec1 Reviewed-by: Friedemann Kleint --- src/plugins/printsupport/cups/qcupsprintengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp index e7949d3a0b..6a4eecb06d 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine.cpp +++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp @@ -293,7 +293,7 @@ void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter) // Try create the printer, only use it if it returns valid QPrintDevice printDevice = ps->createPrintDevice(newPrinter); - if (!m_printDevice.isValid()) + if (!printDevice.isValid()) return; m_printDevice.swap(printDevice); printerName = m_printDevice.id(); -- cgit v1.2.3 From 807fa90b32466fd936704459884c12214d8a254f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 26 Sep 2017 10:57:04 +0200 Subject: Fix crash with clips entirely outside glyph map When the range to work on is empty just continue to next span. Task-number: QTBUG-63412 Change-Id: Ic5cb77ed438eb9c218f482095aa0cd4e3c2fc6e6 Reviewed-by: Oliver Wolff --- src/gui/painting/qdrawhelper.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c78fdfe62e..6c25710271 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5627,6 +5627,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, int start = qMax(x, clip.x); int end = qMin(x + mapWidth, clip.x + clip.len); + if (end <= start) + continue; Q_ASSERT(end - start <= buffer_size); QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start); @@ -5900,6 +5902,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, int start = qMax(x, clip.x); int end = qMin(x + mapWidth, clip.x + clip.len); + if (end <= start) + continue; Q_ASSERT(end - start <= buffer_size); QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start); -- cgit v1.2.3 From 267b1a140aed9ba3c2c4cda0bb6f838cebfbd0d1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 Sep 2017 14:45:52 +0200 Subject: regularexpression example: Fix compilation with clipboard disabled Use the new configure system consistently. Task-number: QTBUG-63429 Change-Id: I6668ba9fde09492f3e60e614103e18e88783d0c4 Reviewed-by: Giuseppe D'Angelo --- .../tools/regularexpression/regularexpressiondialog.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp index 7fdce3b674..67d0db4bed 100644 --- a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp +++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp @@ -129,6 +129,10 @@ PatternLineEdit::PatternLineEdit(QWidget *parent) : connect(escapeSelectionAction, &QAction::triggered, this, &PatternLineEdit::escapeSelection); connect(copyToCodeAction, &QAction::triggered, this, &PatternLineEdit::copyToCode); connect(pasteFromCodeAction, &QAction::triggered, this, &PatternLineEdit::pasteFromCode); +#if !QT_CONFIG(clipboard) + copyToCodeAction->setEnabled(false); + pasteFromCodeAction->setEnabled(false); +#endif } void PatternLineEdit::escapeSelection() @@ -144,12 +148,16 @@ void PatternLineEdit::escapeSelection() void PatternLineEdit::copyToCode() { +#if QT_CONFIG(clipboard) QGuiApplication::clipboard()->setText(patternToCode(text())); +#endif } void PatternLineEdit::pasteFromCode() { +#if QT_CONFIG(clipboard) setText(codeToPattern(QGuiApplication::clipboard()->text())); +#endif } void PatternLineEdit::contextMenuEvent(QContextMenuEvent *event) @@ -316,7 +324,7 @@ void RegularExpressionDialog::refresh() void RegularExpressionDialog::copyEscapedPatternToClipboard() { -#ifndef QT_NO_CLIPBOARD +#if QT_CONFIG(clipboard) QClipboard *clipboard = QGuiApplication::clipboard(); if (clipboard) clipboard->setText(escapedPatternLineEdit->text()); @@ -361,7 +369,7 @@ QWidget *RegularExpressionDialog::setupLeftUi() palette.setBrush(QPalette::Base, palette.brush(QPalette::Disabled, QPalette::Base)); escapedPatternLineEdit->setPalette(palette); -#ifndef QT_NO_CLIPBOARD +#if QT_CONFIG(clipboard) QAction *copyEscapedPatternAction = new QAction(this); copyEscapedPatternAction->setText(tr("Copy to clipboard")); copyEscapedPatternAction->setIcon(QIcon(QStringLiteral(":/images/copy.png"))); -- cgit v1.2.3 From 8883e44eca057dce04e94bce50d41c472e4e8f00 Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Fri, 22 Sep 2017 09:02:39 +0300 Subject: Add changes file for Qt 5.9.2 Task-number: QTBUG-62760 Done-with: Oswald Buddenhagen Change-Id: Ic3f724dd4f85f7a0494e1cf7612277e4bf02d1c3 Reviewed-by: Oliver Wolff Reviewed-by: Thiago Macieira Reviewed-by: Timur Pocheptsov Reviewed-by: Kai Koehne --- dist/changes-5.9.2 | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 dist/changes-5.9.2 diff --git a/dist/changes-5.9.2 b/dist/changes-5.9.2 new file mode 100644 index 0000000000..0ed88849ed --- /dev/null +++ b/dist/changes-5.9.2 @@ -0,0 +1,259 @@ +Qt 5.9.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Building examples inside the Qt source tree while not building Qt itself + is rejected now, because this can cause hard to debug configuration + issues. If building isolated examples is needed, you may still use shadow + builds. + + - This version of Qt restores compatibility with pre-5.9.0 calculation of + QCryptographicHash algorithms that were labelled "Sha3_nnn": that is, + applications compiled with old versions of Qt will continue using the + Keccak algorithm. Applications recompiled with this version will use + SHA-3, unless QT_SHA3_KECCAK_COMPAT is #define'd prior to #include + . + +**************************************************************************** +* General Notes * +**************************************************************************** + +Binary Compatibility Note +------------------------- + + - The variable QOperatingSystemVersion::AndroidOreo was added in this + release. Code that uses this variable will not run under Qt 5.9.1. If + backwards compatibility is desired, use instead + QOperatingSystemVersion(QOperatingSystemVersion::Android, 8) + [This is similar to QOperatingSystemVersion::MacOSHighSierra added in + 5.9.1] + + - This version of Qt changes the values assigned to enumerations + QCryptographicHash::Sha3_nnn. Applications compiled with this version and + using those enumerations will not work with Qt 5.9.0 and 5.9.1, unless + QT_SHA3_KECCAK_COMPAT is defined. + +Deprecation Notice +------------------ + + - Starting with Qt 5.10, IPv6 support will be mandatory for all platforms. + Systems without proper IPv6 support, such as the getaddrinfo() function + or the proper socket address structures, will not be able to build + QtNetwork anymore. + +Third-Party Code +---------------- + + - [QTBUG-31020] zlib was updated to version 1.2.11. + - libpng was updated to version 1.6.32 + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - [QTBUG-61350] Fixed the conversion from string to double of the strings + "0E+1" and "0E-1" (with capital E), which QString::toDouble(), + QByteArray::toDouble() and similar functions reported as invalid. + + - QFile: + * [QTBUG-57023] Reverted an incorrect change from Qt 5.9.0 that forbade + the creation and access to Alternate Data Streams on NTFS on Windows. + This means that file names containing a colon (':') are allowed again, + but note that they are not regular files. + + - QFileInfo: + * [QTBUG-62802] Relative symbolic links on Windows are now resolved to + their absolute path by symLinkTarget(). + + - QFileSystemWatcher: + * [QTBUG-62242] Fixed a crash on Windows if this class was instantiated + before QCoreApplication was created. + * [QTBUG-61792] Fixed an issue on Windows that would cause this class not + to monitor files properly if the directory containing the monitored + files was added to the list of watched paths after the files. + + - QLocale: + * [QTBUG-53565] Fixed the conversion of QTime to string form and parsing + from string form to always treat the value as the decimal fraction of + the seconds component. That is, the string format ".z" produces/parses + ".2" for 200 milliseconds and ".002" for 2 milliseconds. Use of "z" or + "zzz" is discouraged outside decimal fractions to avoid surprises. + * [QTBUG-61949] Fixed bcp57Name() to return "en" for the QLocale::c() + locale. Previously, it returned "C", which is not a valid BCP47 + language tag. + + - QProcess: + * [QTBUG-61634] Added a workaround for a rare race-condition bug in + some C libraries that caused the child process started by QProcess to + hang after trying to launch a non-existent executable or change to a + non-existent directory. + * [QTBUG-62584] Fixed a race-condition bug that could cause + waitForXxx() functions to hang forever if a slot triggered by that + function futher started a nested event loop. + + - QTimeZone: + * [QTBUG-63205] Fixed a bug that would cause QTimeZone to mis-parse + timezone files on Unix systems if they contained leap second + information. + + - QVariant: + * [QTBUG-61471] Fixed QVariant to actually perform the conversions + between QVariantHash and QVariantMap in the respective .toHash() and + .toMap() functions. QVariant already reported true in .canConvert() + between those two types. + +QtDBus +------ + + - [QTBUG-62284] Fixed a race condition in QDBusAbstractInterface that + could cause the class to never see the notification that the remote + service became available and cause isValid() to change to true. + +QtGui +----- + + - Text: + * [QTBUG-61520] Fixed matching of non-regular font weights for + application fonts on macOS. + +QtNetwork +--------- + + - [QTBUG-61692] Fixed the handling of application-wide proxy settings (set + with QNetworkProxy): previously, QTcpSocket would directly fall back to + the system settings if the object-specific setting was + QNetworkProxy::DefaultProxy. + + - QLocalSocket: + * [QTBUG-61643] Fixed an issue with Qt pipe-handling code that could + cause deadlocks on Windows, most often if the QLocalSocket object tried + to wait for more data during application shutdown. + +QtTest +------ + + - Added flowId to messages when logging in TeamCity format. FlowId is used + to distinguish logging from multiple processes running in parallel. + +QtWidgets +--------- + + - Android: + * [QTBUG-48639] Fixed label duplication for buttons when using style + sheets with the Android style. + + - QLineEdit: + * [QTBUG-60319] Fixed behavior of the ImSurroundingText query. + Previously, it returned a masked text whose length may be less than + the cursor position. Now it returns unmasked text, so the text length + is always greater than or equal to the cursor position. + + - QMenu: + * [QTBUG-59794] Fixed menu size issue when using high DPI on + multi-screen system. + +**************************************************************************** +* Compiler-specific Changes * +**************************************************************************** + +clang +----- + + - [QTBUG-61840][QTBUG-62085] Fixed an issue that caused recent Clang + versions to print a warning about [[nodiscard]. + +Visual Studio +------------- + + - [QTBUG-61902] Changed Qt uses of certain C++ Standard Library functions + that Visual Studio warns about. Now Qt public headers call + Microsoft-specific versions that do not produce warnings. + +**************************************************************************** +* Platform-specific Changes * +**************************************************************************** + +macOS +----- + + - [QTBUG-59222] Switching focus objects inside a top level window while + composing text using dead keys or input method events would leave the + application in an inconsistent state. The composition now automatically + cancels when the focus object changes. + +Windows +------- + + - [QTBUG-57916] Fixed build with ANGLE and newer MinGW versions. + - [QTBUG-62083] Fixed Qt trying to steal certain events from user windows if + the event ID was WM_USER. + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - [QTBUG-35928][QTBUG-41908][Apple] Qt can now be built using just the + Xcode Command Line Tools, without needing to install the full Xcode IDE. + - [QTBUG-55755][Windows] All Qt .exe files now include meta information, + like .dll files already did. + - [QTBUG-58012] (Re-)added a way to specify alternative ICU libraries. + - [QTBUG-62150] Fixed detection of ICU in static builds. + - [QTBUG-53537][X11] Added missing detection of Xinerama. + - [QTBUG-61731][X11] Fixed detection of AT-SPI, allowing accessibility + support to be built again. + - [X11] Fixed detection of x11-xcb with pkg-config. + - [CMake] All Qt module defines are now propagated to the config files. + +qmake +----- + + - [QTBUG-31034] Added qmake feature and configure option to use ccache. + - [QTBUG-48342] Fixed generation of extraneous slashes in -project mode. + - [QTBUG-55633] Fixed misparsing of some string literal concatenations + as C++11 raw strings. This affects dependency scanning. + - [QTBUG-59301][Xcode] Fixed duplicate references in project files. + - [QTBUG-59827][nmake] The 'clean' target now deletes backup files of + MSVC manifests. + - [QTBUG-60455][Android] libc++ is now used instead of libstdc++ when + building with the android-clang mkspec. + - [QTBUG-60430][iOS] Fixed handling of the deprecated variable + QMAKE_IOS_TARGETED_DEVICE_FAMILY. + - [QTBUG-60899][WinRT] Fixed capability handling for Win10 targets. + - [WinRT] Added support for new Win10 capabilities. + - [QTBUG-61335][MinGW] Worked around LTO+MRI linker issue when cross- + building from Linux. + - [QTBUG-61411][Windows] _UNICODE is now defined, consistently with VS. + - [QTBUG-61688][MSVC] Fixed compilation of precompiled headers with + CONFIG+=silent. Done by removing redundant progress messages. + - [QTBUG-61690][QTBUG-61735] Fixed detection of compiler default search + paths for various compilers and platforms. + - [QTBUG-63197][Windows] Fixed moc'ing in a build directory with spaces + when INCLUDEPATH contains 40+ entries. + - [Android] Fixed building with ndkr16+ by using unified headers. + - [Windows] Fixed repeated installation of read-only files. + - [VS] Fixed deployment rules in created solution files. -- cgit v1.2.3 From ec16ba393baf504d4b192cc349775c62d3c96aa0 Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Mon, 2 Oct 2017 09:23:31 +0300 Subject: Revert "Qmake: Introduce and use QMAKE_NULL_DEVICE variable" With that change QNX7 builds in windows will fail. This reverts commit b4e9cb4c29ef797fe535a84717bebf81fbdc61e4. Task-number: QTBUG-63535 Change-Id: Ia91d173803af62d41d1a7e5832bab911920f590d Reviewed-by: Frederik Gladhorn --- mkspecs/features/ctest_testcase_common.prf | 14 ++++++++++++-- mkspecs/features/qt_functions.prf | 5 ++++- mkspecs/features/spec_post.prf | 2 -- mkspecs/features/toolchain.prf | 18 ++++++++++++------ qmake/generators/win32/mingw_make.cpp | 8 +++++++- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf index 15701b6a41..cdc5cca1d7 100644 --- a/mkspecs/features/ctest_testcase_common.prf +++ b/mkspecs/features/ctest_testcase_common.prf @@ -1,5 +1,10 @@ -CMAKE_VERSION = $$system(cmake --version 2>$$QMAKE_NULL_DEVICE, lines) +win32 { + CMAKE_VERSION = $$system(cmake --version 2>NUL, lines) +} else { + CMAKE_VERSION = $$system(cmake --version 2>/dev/null, lines) +} + CMAKE_VERSION = $$member(CMAKE_VERSION, 0, 0) check.commands = @@ -10,7 +15,12 @@ isEmpty(CMAKE_VERSION) { return() } -CTEST_VERSION = $$system(ctest --version 2>$$QMAKE_NULL_DEVICE) +win32 { + CTEST_VERSION = $$system(ctest --version 2>NUL) +} else { + CTEST_VERSION = $$system(ctest --version 2>/dev/null) +} + isEmpty(CTEST_VERSION) { message("ctest executable not found. Not running CMake unit tests") return() diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 1f44650227..c00fdb73f8 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -291,7 +291,10 @@ defineReplace(pkgConfigExecutable) { } } - PKG_CONFIG += 2> $$QMAKE_NULL_DEVICE + equals(QMAKE_HOST.os, Windows): \ + PKG_CONFIG += 2> NUL + else: \ + PKG_CONFIG += 2> /dev/null return($$PKG_CONFIG) } diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf index 62be69ffda..f87bf3c037 100644 --- a/mkspecs/features/spec_post.prf +++ b/mkspecs/features/spec_post.prf @@ -82,7 +82,6 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_MKDIR = mkdir # legacy QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1 QMAKE_STREAM_EDITOR = $(QMAKE) -install sed - QMAKE_NULL_DEVICE = NUL QMAKE_INSTALL_FILE = copy /y QMAKE_INSTALL_PROGRAM = copy /y } else { @@ -102,7 +101,6 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_MKDIR = mkdir -p # legacy QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1 QMAKE_STREAM_EDITOR = sed - QMAKE_NULL_DEVICE = /dev/null equals(QMAKE_HOST.os, Windows) { MINGW_IN_SHELL = 1 # legacy diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index e7ada377d7..35175f1744 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -32,11 +32,15 @@ isEmpty($${target_prefix}.INCDIRS) { # Get default include and library paths from compiler # gcc { - cmd_suffix = "<$$QMAKE_NULL_DEVICE >$$QMAKE_NULL_DEVICE" - equals(QMAKE_HOST.os, Windows): \ - cmd_prefix = "set LC_ALL=C&" - else: \ + !equals(QMAKE_HOST.os, Windows) { cmd_prefix = "LC_ALL=C" + cmd_suffix = "/dev/null" + null_file = /dev/null + } else { + cmd_prefix = "set LC_ALL=C&" + cmd_suffix = "NUL" + null_file = NUL + } cxx_flags = $$QMAKE_CXXFLAGS @@ -55,7 +59,7 @@ isEmpty($${target_prefix}.INCDIRS) { rim_qcc: \ # Need the cc1plus and ld command lines to pick up the paths - cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$QMAKE_NULL_DEVICE -v + cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$null_file -v else: darwin:clang: \ # Need to link to pick up library paths cxx_flags += $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v @@ -171,7 +175,9 @@ defineReplace(qtVariablesFromMSVC) { } defineReplace(qtVariablesFromGCC) { - ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$QMAKE_NULL_DEVICE 2>$$QMAKE_NULL_DEVICE", lines, ec) + null_device = /dev/null + equals(QMAKE_HOST.os, Windows): null_device = NUL + ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines, ec) !equals(ec, 0): qtCompilerErrror($$1) return($$ret) } diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 2d69f708fb..bad53dc5b7 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -36,6 +36,12 @@ #include #include +#ifdef Q_OS_WIN +#define NULL_DEVICE "NUL" +#else +#define NULL_DEVICE "/dev/null" +#endif + QT_BEGIN_NAMESPACE MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator() @@ -323,7 +329,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { - t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>$$QMAKE_NULL_DEVICE"; + t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" NULL_DEVICE; if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) { t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ; } else { -- cgit v1.2.3 From c5ef7bd5e1f7c586d3a1b5566428dde1ffcb8d25 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 8 Sep 2017 13:10:34 +0200 Subject: Remove // from license text Change-Id: I252b296713e03b749c6e99391a6928c942474378 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/LICENSE | 64 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/3rdparty/angle/LICENSE b/src/3rdparty/angle/LICENSE index bdacb32e36..dc322e998d 100644 --- a/src/3rdparty/angle/LICENSE +++ b/src/3rdparty/angle/LICENSE @@ -1,32 +1,32 @@ -// Copyright (C) 2002-2013 The ANGLE Project Authors. -// All rights reserved. -// -// 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 TransGaming Inc., Google Inc., 3DLabs Inc. -// Ltd., nor the names of their 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. +Copyright (C) 2002-2013 The ANGLE Project Authors. +All rights reserved. + +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 TransGaming Inc., Google Inc., 3DLabs Inc. + Ltd., nor the names of their 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. -- cgit v1.2.3 From d7c57fa68e7bfa1fcb1bca3bcc1ea3e3668167a9 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 3 Oct 2017 13:32:11 +0200 Subject: tests: un-blacklist tst_QMenuBar::taskQTBUG4965_escapeEaten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't qWaitForWindowExposed on native menu bars. Other test functions in this file are already disabling the native manu bar. Task-number: QTBUG-24326 Change-Id: Iecf907ca84589159417d0d942c911485a41af164 Reviewed-by: Tony Sarajärvi --- tests/auto/widgets/widgets/qmenubar/BLACKLIST | 4 ---- tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/auto/widgets/widgets/qmenubar/BLACKLIST b/tests/auto/widgets/widgets/qmenubar/BLACKLIST index 06776d961d..ee08086e83 100644 --- a/tests/auto/widgets/widgets/qmenubar/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenubar/BLACKLIST @@ -1,9 +1,5 @@ [check_menuPosition] ubuntu-14.04 ubuntu-16.04 -[taskQTBUG4965_escapeEaten] -ubuntu-14.04 -ubuntu-16.04 -redhatenterpriselinuxworkstation-6.6 [task256322_highlight] osx diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 251a351cc1..9a70208b94 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -1374,6 +1374,7 @@ void tst_QMenuBar::menubarSizeHint() void tst_QMenuBar::taskQTBUG4965_escapeEaten() { QMenuBar menubar; + menubar.setNativeMenuBar(false); QMenu menu("menu1"); QAction *first = menubar.addMenu(&menu); menu.addAction("quit", &menubar, SLOT(close()), QKeySequence("ESC")); -- cgit v1.2.3 From ba423261cd9abedda8b732c82371515003d385ce Mon Sep 17 00:00:00 2001 From: Svenn-Arne Dragly Date: Tue, 5 Sep 2017 15:02:20 +0200 Subject: Improve performance in QThreadPool When many runnables are executed, this improves the performance by not resizing the queue for each runnable, which was the case in the previous version, because of many calls to QVector::takeFirst(). Also add a test that makes sure tryTake() is safe to call and does not leave the queue in a bad state that tries to use nullptr entries. Change-Id: I608134ecfa9cfc03db4878dcbd6f9c1107e13e90 Reviewed-by: Lars Knoll --- src/corelib/thread/qthreadpool.cpp | 87 ++++++++++++++-------- src/corelib/thread/qthreadpool_p.h | 84 ++++++++++++++++++++- .../corelib/thread/qthreadpool/tst_qthreadpool.cpp | 64 ++++++++++++++++ 3 files changed, 204 insertions(+), 31 deletions(-) diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index f3ce1f258f..ccd8194b35 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -73,7 +73,7 @@ public: \internal */ QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager) - :manager(manager), runnable(0) + :manager(manager), runnable(nullptr) { } /* @@ -84,7 +84,7 @@ void QThreadPoolThread::run() QMutexLocker locker(&manager->mutex); for(;;) { QRunnable *r = runnable; - runnable = 0; + runnable = nullptr; do { if (r) { @@ -116,8 +116,19 @@ void QThreadPoolThread::run() if (manager->tooManyThreadsActive()) break; - r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : 0; - } while (r != 0); + if (manager->queue.isEmpty()) { + r = nullptr; + break; + } + + QueuePage *page = manager->queue.first(); + r = page->pop(); + + if (page->isFinished()) { + manager->queue.removeFirst(); + delete page; + } + } while (true); if (manager->isExiting) { registerThreadInactive(); @@ -163,6 +174,7 @@ QThreadPoolPrivate:: QThreadPoolPrivate() bool QThreadPoolPrivate::tryStart(QRunnable *task) { + Q_ASSERT(task != nullptr); if (allThreads.isEmpty()) { // always create at least one thread startThread(task); @@ -183,7 +195,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task) if (!expiredThreads.isEmpty()) { // restart an expired thread QThreadPoolThread *thread = expiredThreads.dequeue(); - Q_ASSERT(thread->runnable == 0); + Q_ASSERT(thread->runnable == nullptr); ++activeThreads; @@ -199,22 +211,25 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task) return true; } -inline bool operator<(int priority, const QPair &p) -{ return p.second < priority; } -inline bool operator<(const QPair &p, int priority) -{ return priority < p.second; } +inline bool comparePriority(int priority, const QueuePage *p) +{ + return p->priority() < priority; +} void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) { + Q_ASSERT(runnable != nullptr); if (runnable->autoDelete()) ++runnable->ref; - // put it on the queue - QVector >::const_iterator begin = queue.constBegin(); - QVector >::const_iterator it = queue.constEnd(); - if (it != begin && priority > (*(it - 1)).second) - it = std::upper_bound(begin, --it, priority); - queue.insert(it - begin, qMakePair(runnable, priority)); + for (QueuePage *page : qAsConst(queue)) { + if (page->priority() == priority && !page->isFull()) { + page->push(runnable); + return; + } + } + auto it = std::upper_bound(queue.constBegin(), queue.constEnd(), priority, comparePriority); + queue.insert(std::distance(queue.constBegin(), it), new QueuePage(runnable, priority)); } int QThreadPoolPrivate::activeThreadCount() const @@ -228,8 +243,18 @@ int QThreadPoolPrivate::activeThreadCount() const void QThreadPoolPrivate::tryToStartMoreThreads() { // try to push tasks on the queue to any available threads - while (!queue.isEmpty() && tryStart(queue.constFirst().first)) - queue.removeFirst(); + while (!queue.isEmpty()) { + QueuePage *page = queue.first(); + if (!tryStart(page->first())) + break; + + page->pop(); + + if (page->isFinished()) { + queue.removeFirst(); + delete page; + } + } } bool QThreadPoolPrivate::tooManyThreadsActive() const @@ -243,6 +268,7 @@ bool QThreadPoolPrivate::tooManyThreadsActive() const */ void QThreadPoolPrivate::startThread(QRunnable *runnable) { + Q_ASSERT(runnable != nullptr); QScopedPointer thread(new QThreadPoolThread(this)); thread->setObjectName(QLatin1String("Thread (pooled)")); Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here) @@ -306,12 +332,14 @@ bool QThreadPoolPrivate::waitForDone(int msecs) void QThreadPoolPrivate::clear() { QMutexLocker locker(&mutex); - for (QVector >::const_iterator it = queue.constBegin(); - it != queue.constEnd(); ++it) { - QRunnable* r = it->first; - if (r->autoDelete() && !--r->ref) - delete r; + for (QueuePage *page : qAsConst(queue)) { + while (!page->isFinished()) { + QRunnable *r = page->pop(); + if (r && r->autoDelete() && !--r->ref) + delete r; + } } + qDeleteAll(queue); queue.clear(); } @@ -336,22 +364,21 @@ bool QThreadPool::tryTake(QRunnable *runnable) { Q_D(QThreadPool); - if (runnable == 0) + if (runnable == nullptr) return false; { QMutexLocker locker(&d->mutex); - auto it = d->queue.begin(); - auto end = d->queue.end(); - - while (it != end) { - if (it->first == runnable) { - d->queue.erase(it); + for (QueuePage *page : qAsConst(d->queue)) { + if (page->tryTake(runnable)) { + if (page->isFinished()) { + d->queue.removeOne(page); + delete page; + } if (runnable->autoDelete()) --runnable->ref; // undo ++ref in start() return true; } - ++it; } } diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 4a9f9e5cfa..18b89bbba9 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -62,6 +62,87 @@ QT_BEGIN_NAMESPACE +class QueuePage { +public: + enum { + MaxPageSize = 256 + }; + + QueuePage(QRunnable *runnable, int pri) + : m_priority(pri) + { + push(runnable); + } + + bool isFull() { + return m_lastIndex >= MaxPageSize - 1; + } + + bool isFinished() { + return m_firstIndex > m_lastIndex; + } + + void push(QRunnable *runnable) { + Q_ASSERT(runnable != nullptr); + Q_ASSERT(!isFull()); + m_lastIndex += 1; + m_entries[m_lastIndex] = runnable; + } + + void skipToNextOrEnd() { + while (!isFinished() && m_entries[m_firstIndex] == nullptr) { + m_firstIndex += 1; + } + } + + QRunnable *first() { + Q_ASSERT(!isFinished()); + QRunnable *runnable = m_entries[m_firstIndex]; + Q_ASSERT(runnable); + return runnable; + } + + QRunnable *pop() { + Q_ASSERT(!isFinished()); + QRunnable *runnable = first(); + Q_ASSERT(runnable); + + // clear the entry although this should not be necessary + m_entries[m_firstIndex] = nullptr; + m_firstIndex += 1; + + // make sure the next runnable returned by first() is not a nullptr + skipToNextOrEnd(); + + return runnable; + } + + bool tryTake(QRunnable *runnable) { + Q_ASSERT(!isFinished()); + for (int i = m_firstIndex; i <= m_lastIndex; i++) { + if (m_entries[i] == runnable) { + m_entries[i] = nullptr; + if (i == m_firstIndex) { + // make sure first() does not return a nullptr + skipToNextOrEnd(); + } + return true; + } + } + return false; + } + + int priority() const { + return m_priority; + } + +private: + int m_priority = 0; + int m_firstIndex = 0; + int m_lastIndex = -1; + QRunnable *m_entries[MaxPageSize]; +}; + class QThreadPoolThread; class Q_CORE_EXPORT QThreadPoolPrivate : public QObjectPrivate { @@ -83,12 +164,13 @@ public: bool waitForDone(int msecs); void clear(); void stealAndRunRunnable(QRunnable *runnable); + void deletePageIfFinished(QueuePage *page); mutable QMutex mutex; QList allThreads; QQueue waitingThreads; QQueue expiredThreads; - QVector > queue; + QVector queue; QWaitCondition noActiveThreads; bool isExiting; diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index fdc4ecb5c8..66853a88d8 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -93,6 +93,7 @@ private slots: void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); + void takeAllAndIncreaseMaxThreadCount(); private: QMutex m_functionTestMutex; @@ -1199,5 +1200,68 @@ void tst_QThreadPool::stressTest() } } +void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() { + class Task : public QRunnable + { + public: + Task(QSemaphore *mainBarrier, QSemaphore *threadBarrier) + : m_mainBarrier(mainBarrier) + , m_threadBarrier(threadBarrier) + { + setAutoDelete(false); + } + + void run() { + m_mainBarrier->release(); + m_threadBarrier->acquire(); + } + private: + QSemaphore *m_mainBarrier; + QSemaphore *m_threadBarrier; + }; + + QSemaphore mainBarrier; + QSemaphore taskBarrier; + + QThreadPool threadPool; + threadPool.setMaxThreadCount(1); + + Task *task1 = new Task(&mainBarrier, &taskBarrier); + Task *task2 = new Task(&mainBarrier, &taskBarrier); + Task *task3 = new Task(&mainBarrier, &taskBarrier); + + threadPool.start(task1); + threadPool.start(task2); + threadPool.start(task3); + + mainBarrier.acquire(1); + + QCOMPARE(threadPool.activeThreadCount(), 1); + + QVERIFY(!threadPool.tryTake(task1)); + QVERIFY(threadPool.tryTake(task2)); + QVERIFY(threadPool.tryTake(task3)); + + // A bad queue implementation can segfault here because two consecutive items in the queue + // have been taken + threadPool.setMaxThreadCount(4); + + // Even though we increase the max thread count, there should only be one job to run + QCOMPARE(threadPool.activeThreadCount(), 1); + + // Make sure jobs 2 and 3 never started + QCOMPARE(mainBarrier.available(), 0); + + taskBarrier.release(1); + + threadPool.waitForDone(); + + QCOMPARE(threadPool.activeThreadCount(), 0); + + delete task1; + delete task2; + delete task3; +} + QTEST_MAIN(tst_QThreadPool); #include "tst_qthreadpool.moc" -- cgit v1.2.3 From 2755e02f071d1dc18c763517447f4870a4493510 Mon Sep 17 00:00:00 2001 From: Milla Pohjanheimo Date: Mon, 2 Oct 2017 15:14:11 +0300 Subject: Increase timeout for tst_QXmlSimpleReader::inputFromSocket() test The test tst_QXmlSimpleReader::inputFromSocket() is failing with "QTestLib: This test case check ("(((server->listening)))") failed because the requested timeout (5000 ms) was too short, 11700 ms would have been sufficient this time". Increased the timeout, since it's better to wait than to fail. Task-number: QTBUG-63539 Change-Id: I804549648ea834e41d3c87871f5bab90f209385c Reviewed-by: Thiago Macieira --- tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp index 8a5c8ec1df..f77fd2ebab 100644 --- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp +++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp @@ -562,7 +562,7 @@ void tst_QXmlSimpleReader::inputFromSocket() QSKIP("WinRT does not support connecting to localhost"); #endif - QTRY_VERIFY(server->listening); + QTRY_VERIFY_WITH_TIMEOUT(server->listening, 15000); QTcpSocket sock; sock.connectToHost(QHostAddress::LocalHost, TEST_PORT); -- cgit v1.2.3 From 70ee08951a7ff225b47829d9d2a0ee25a68725f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 4 Oct 2017 21:44:19 -0700 Subject: Doc: Remove unsupported systems out of QNetworkDatagram's list We don't support Windows versions prior to 7 nor Windows CE anymore. Change-Id: I638cf58bfa7b4e5fb386fffd14ea930155d67689 Reviewed-by: Jesus Fernandez Reviewed-by: Edward Welbourne --- src/network/kernel/qnetworkdatagram.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/network/kernel/qnetworkdatagram.cpp b/src/network/kernel/qnetworkdatagram.cpp index dd412b69d1..d167190684 100644 --- a/src/network/kernel/qnetworkdatagram.cpp +++ b/src/network/kernel/qnetworkdatagram.cpp @@ -124,9 +124,7 @@ QT_BEGIN_NAMESPACE \row \li Linux \li Supported \li Supported \li Supported \row \li OS X \li Supported \li Supported \li Only for IPv6 \row \li Other Unix supporting RFC 3542 \li Only for IPv6 \li Only for IPv6 \li Only for IPv6 - \row \li Windows XP and older \li Not supported \li Not supported \li Not supported - \row \li Windows Vista & up \li Supported \li Supported \li Supported - \row \li Windows CE \li Not supported \li Not supported \li Not supported + \row \li Windows (desktop) \li Supported \li Supported \li Supported \row \li Windows RT \li Not supported \li Not supported \li Not supported \endtable -- cgit v1.2.3 From f62768d046528636789f901ac79e2cfa1843a7b7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 21 Sep 2017 13:27:51 -0700 Subject: QUrl: re-fix the setPath("//path") case leading to scheme://path Commits aba336c2b4ad8926dc8a000718bbb7f8a6d5a72d (in Qt 5.2) and aba336c2b4ad8926dc8a000718bbb7f8a6d5a72d (in 5.6) both tried to deal with this problem, with different levels of success. This is the third attempt (and hopefully the charm). Instead of modifying the path that the user provides, go straight ahead and declare it invalid. This is supported by RFC 3986, which declares this expansion impossible: relative-part = "//" authority path-abempty / path-absolute / path-noscheme / path-empty path-abempty = *( "/" segment ) path-absolute = "/" [ segment-nz *( "/" segment ) ] path-noscheme = segment-nz-nc *( "/" segment ) The "path-abempty" and "path-noscheme" cases are the two issues we already handle. This commit adds the third one: path-absolute, which requires that the first segment of the path be of non-zero length. That is, it is now possible again to have http://example.com//path constructed piece-wise, without it producing http://example.com/path. Additionally, it catches the case of http://example.com//path parsed from full URL then followed by setAuthority(""). Change-Id: I69f37f9304f24709a823fffd14e67a5e7212ddcd Reviewed-by: David Faure --- src/corelib/io/qurl.cpp | 31 ++++++++++++++++++++++--------- tests/auto/corelib/io/qurl/tst_qurl.cpp | 17 ++++++++++++++--- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index ac694a464a..a499dc2d30 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -499,9 +499,10 @@ public: InvalidFragmentError = Fragment << 8, - // the following two cases are only possible in combination - // with presence/absence of the authority and scheme. See validityError(). + // the following three cases are only possible in combination with + // presence/absence of the path, authority and scheme. See validityError(). AuthorityPresentAndPathIsRelative = Authority << 8 | Path << 8 | 0x10000, + AuthorityAbsentAndPathIsDoubleSlash, RelativeUrlPathContainsColonBeforeSlash = Scheme << 8 | Authority << 8 | Path << 8 | 0x10000, NoError = 0 @@ -1627,19 +1628,32 @@ inline QUrlPrivate::ErrorCode QUrlPrivate::validityError(QString *source, int *p return error->code; } - // There are two more cases of invalid URLs that QUrl recognizes and they + // There are three more cases of invalid URLs that QUrl recognizes and they // are only possible with constructed URLs (setXXX methods), not with // parsing. Therefore, they are tested here. // - // The two cases are a non-empty path that doesn't start with a slash and: + // Two cases are a non-empty path that doesn't start with a slash and: // - with an authority // - without an authority, without scheme but the path with a colon before // the first slash + // The third case is an empty authority and a non-empty path that starts + // with "//". // Those cases are considered invalid because toString() would produce a URL // that wouldn't be parsed back to the same QUrl. - if (path.isEmpty() || path.at(0) == QLatin1Char('/')) + if (path.isEmpty()) return NoError; + if (path.at(0) == QLatin1Char('/')) { + if (sectionIsPresent & QUrlPrivate::Authority || port != -1 || + path.length() == 1 || path.at(1) != QLatin1Char('/')) + return NoError; + if (source) { + *source = path; + *position = 0; + } + return AuthorityAbsentAndPathIsDoubleSlash; + } + if (sectionIsPresent & QUrlPrivate::Host) { if (source) { *source = path; @@ -2514,10 +2528,7 @@ void QUrl::setPath(const QString &path, ParsingMode mode) mode = TolerantMode; } - int from = 0; - while (from < data.length() - 2 && data.midRef(from, 2) == QLatin1String("//")) - ++from; - d->setPath(data, from, data.length()); + d->setPath(data, 0, data.length()); // optimized out, since there is no path delimiter // if (path.isNull()) @@ -3989,6 +4000,8 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err case QUrlPrivate::AuthorityPresentAndPathIsRelative: return QStringLiteral("Path component is relative and authority is present"); + case QUrlPrivate::AuthorityAbsentAndPathIsDoubleSlash: + return QStringLiteral("Path component starts with '//' and authority is absent"); case QUrlPrivate::RelativeUrlPathContainsColonBeforeSlash: return QStringLiteral("Relative URL's path component contains ':' before any '/'"); } diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index c5647752fd..1ff85fc6dc 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -2074,6 +2074,14 @@ void tst_QUrl::isValid() QVERIFY(url.errorString().contains("Path component is relative and authority is present")); } + { + QUrl url("http:"); + url.setPath("//example.com"); + QVERIFY(!url.isValid()); + QVERIFY(url.toString().isEmpty()); + QVERIFY(url.errorString().contains("Path component starts with '//' and authority is absent")); + } + { QUrl url; url.setPath("http://example.com"); @@ -3649,12 +3657,12 @@ void tst_QUrl::setComponents_data() QTest::newRow("path-%3A-before-slash") << QUrl() << int(Path) << "c%3A/" << Tolerant << true << PrettyDecoded << "c%3A/" << "c%3A/"; - QTest::newRow("path-doubleslash") << QUrl("trash:/") + QTest::newRow("path-doubleslash") << QUrl("http://example.com") << int(Path) << "//path" << Tolerant << true - << PrettyDecoded << "/path" << "trash:/path"; + << PrettyDecoded << "//path" << "http://example.com//path"; QTest::newRow("path-withdotdot") << QUrl("file:///tmp") << int(Path) << "//tmp/..///root/." << Tolerant << true - << PrettyDecoded << "/tmp/..///root/." << "file:///tmp/..///root/."; + << PrettyDecoded << "//tmp/..///root/." << "file:////tmp/..///root/."; // the other fields can be present and be empty // that is, their delimiters would be present, but there would be nothing to one side @@ -3777,6 +3785,9 @@ void tst_QUrl::setComponents_data() QTest::newRow("invalid-path-2") << QUrl("http://example.com") << int(Path) << "relative" << Strict << false << PrettyDecoded << "relative" << ""; + QTest::newRow("invalid-path-3") << QUrl("trash:/") + << int(Path) << "//path" << Tolerant << false + << PrettyDecoded << "//path" << ""; // -- test bad percent encoding -- // unnecessary to test the scheme, since percent-decoding is not performed in it; -- cgit v1.2.3 From 7f7d9393809f64b37f161f64312d0704d23a11b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 3 Oct 2017 10:25:22 +0200 Subject: Windows: Let topmost and bottom windows use raise and lower respectively 329a029c361bcbaf70f3aa919693f0bef48a152f made ::raise and ::lower do nothing for topmost and bottommost windows. This made it impossible to e.g. raise one topmost window above another topmost window using QWindow::raise. Task-number: QTBUG-62021 Change-Id: I5f60816cbc48d69c0411e3bd68852d8bd8e300bb Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index bea849383d..16c2e16d64 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -875,7 +875,7 @@ void QWindowsBaseWindow::raise_sys() const Qt::WindowType type = window()->type(); if (type == Qt::Popup || type == Qt::SubWindow // Special case for QTBUG-63121: MDI subwindows with WindowStaysOnTopHint - || (window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0) { + || !(window()->flags() & Qt::WindowStaysOnBottomHint)) { SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } @@ -883,7 +883,7 @@ void QWindowsBaseWindow::raise_sys() void QWindowsBaseWindow::lower_sys() { qCDebug(lcQpaWindows) << __FUNCTION__ << this << window(); - if ((window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0) + if (!(window()->flags() & Qt::WindowStaysOnTopHint)) SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } -- cgit v1.2.3 From 248beda08f831d04e6b59df202921152b106bbfa Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 5 Oct 2017 16:35:11 +0200 Subject: XCB platform: Fix crash on X servers with BGR888 display If the native visual was BGR888, the XCB plugin would assert as soon as it needed to find the corresponding QImage format. Fix by adding the required mapping in qt_xcb_imageFormatForVisual(). Task-number: QTBUG-62840 Change-Id: Idd9eb01a60f605ad004d5b0c3025ded63ed64271 Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbimage.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index c0403d589d..c419bd913d 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -78,6 +78,16 @@ QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t d && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) return QImage::Format_RGB32; + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { + if (depth == 24 && format->bits_per_pixel == 32 && visual->blue_mask == 0xff0000 + && visual->green_mask == 0xff00 && visual->red_mask == 0xff) + return QImage::Format_RGBX8888; + } else { + if (depth == 24 && format->bits_per_pixel == 32 && visual->blue_mask == 0xff00 + && visual->green_mask == 0xff0000 && visual->red_mask == 0xff000000) + return QImage::Format_RGBX8888; + } + if (depth == 16 && format->bits_per_pixel == 16 && visual->red_mask == 0xf800 && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f) return QImage::Format_RGB16; @@ -128,8 +138,9 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap } break; } - case QImage::Format_RGB32: // fall-through - case QImage::Format_ARGB32_Premultiplied: { + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_RGBX8888: { uint *p = (uint*)image.scanLine(i); uint *end = p + image.width(); while (p < end) { @@ -146,7 +157,7 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap } // fix-up alpha channel - if (format == QImage::Format_RGB32) { + if (format == QImage::Format_RGB32 || format == QImage::Format_RGBX8888) { QRgb *p = (QRgb *)image.bits(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) -- cgit v1.2.3 From 0366f68b6d63efb2544ccd75dce5157e9c8d6313 Mon Sep 17 00:00:00 2001 From: Mika Salmela Date: Fri, 15 Sep 2017 08:52:23 +0300 Subject: Prevent changing the width for layout item's rect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For gridlayout items the x position is rounded, but the QRectF changes the width to keep the right edge. The width is yet calculated exactly for the text so we need to preserve it. Task-number: QTBUG-61244 Change-Id: I823ba742c9ab299740232b5d9b4ad5713e1782c4 Reviewed-by: Jan Arve Sæther --- src/gui/util/qgridlayoutengine.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp index 8ff2a3eeec..33adac40b2 100644 --- a/src/gui/util/qgridlayoutengine.cpp +++ b/src/gui/util/qgridlayoutengine.cpp @@ -1051,10 +1051,12 @@ void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbs if (m_snapToPixelGrid) { // x and y should already be rounded, but the call to geometryWithin() above might // result in a geom with x,y at half-pixels (due to centering within the cell) - geom.setX(qround(geom.x())); + // QRectF may change the width as it wants to maintain the right edge. In this + // case the width need to be preserved. + geom.moveLeft(qround(geom.x())); // Do not snap baseline aligned items, since that might cause the baselines to not be aligned. if (align != Qt::AlignBaseline) - geom.setY(qround(geom.y())); + geom.moveTop(qround(geom.y())); } visualRect(&geom, visualDirection(), contentsGeometry); item->setGeometry(geom); -- cgit v1.2.3 From c071413ecca3599d27aab21b7efab0193af5f1d9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 5 Oct 2017 16:54:35 +0200 Subject: Fix zero-length lines with scaling We should calculate the pen width based on the scaling similar to how it is done for normal lines, otherwise we get the scaling applied twice. Task-number: QTBUG-61777 Change-Id: Iba71d55971a1d29537d2c9ff33749223a06160de Reviewed-by: Eirik Aavitsland --- src/gui/painting/qpaintengine_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index ef58f96fbc..92ab6e8375 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1638,7 +1638,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) QPointF p = lines[i].p1(); QLineF line = s->matrix.map(QLineF(QPointF(p.x() - width*0.5, p.y()), QPointF(p.x() + width*0.5, p.y()))); - d->rasterizer->rasterizeLine(line.p1(), line.p2(), 1); + d->rasterizer->rasterizeLine(line.p1(), line.p2(), width / line.length()); } continue; } -- cgit v1.2.3 From 7724e4f378f8d97a3b2a3ad6c01e2db057d638aa Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 6 Oct 2017 18:00:03 +0200 Subject: Bump version Change-Id: Iee20a3f956409e4859a5490ad320162f46fac10b --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 9f7fc2fa1f..ace04b0970 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.9.2 +MODULE_VERSION = 5.9.3 -- cgit v1.2.3 From e470348d87eff920e9549b683f80a09144fb3e54 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 6 Oct 2017 00:05:05 -0700 Subject: Fix deprecated API usage Amends c1cece8e54 For some reason, this was missed in the original change. This is now outright prohibited in the watchOS 4 SDK and will cause a compilation error on that platform. Change-Id: Iaa2edf6256a54ca11dec9f1efd8a4d18ba7dc046 Reviewed-by: Timur Pocheptsov --- src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 7694bfd6bb..6347d4d231 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -666,7 +666,7 @@ static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f) return kCTFontUIFontSystem; case QPlatformTheme::TipLabelFont: - return kCTFontToolTipFontType; + return kCTFontUIFontToolTip; case QPlatformTheme::StatusBarFont: return kCTFontUIFontSystem; -- cgit v1.2.3 From 10f2b5aa66c95563702b02770df39c7cf1b2ef61 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 4 Oct 2017 21:20:01 -0700 Subject: QUdpSocket: make sure receiveDatagram() returns empty on error If the datagram reception failed, we forgot to set the buffer back to empty. The returned QNetworkDatagram did report isValid() == false, but it was possible to get the .data() and check its size, getting nonsense. Tests in the next commit. Change-Id: I638cf58bfa7b4e5fb386fffd14ea91adf2133d47 Reviewed-by: Jesus Fernandez Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/socket/qudpsocket.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp index 37b385dfb5..79629a07f2 100644 --- a/src/network/socket/qudpsocket.cpp +++ b/src/network/socket/qudpsocket.cpp @@ -454,10 +454,12 @@ QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize) QAbstractSocketEngine::WantAll); d->hasPendingData = false; d->socketEngine->setReadNotificationEnabled(true); - if (readBytes < 0) + if (readBytes < 0) { d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString()); - else if (readBytes != result.d->data.size()) - result.d->data.truncate(readBytes); + readBytes = 0; + } + + result.d->data.truncate(readBytes); return result; } -- cgit v1.2.3 From 6dea9bfa1086043bf6fdc373f19c66b1e29b8f00 Mon Sep 17 00:00:00 2001 From: Krzysztof Kawa Date: Sun, 4 Jun 2017 14:27:06 +0200 Subject: Documentation: Add missing event type for non-client mouse events Documentation is missing the specialized event type names in the non-client mouse event enum description. Task-number: QTBUG-55018 Change-Id: Ica35994e13fc9a637a52eeca361898f8669fdbd1 Reviewed-by: Thiago Macieira Reviewed-by: Leena Miettinen --- src/corelib/kernel/qcoreevent.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index e90cd842ab..1e6b328c75 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -170,10 +170,10 @@ QT_BEGIN_NAMESPACE \value LeaveEditFocus An editor widget loses focus for editing. QT_KEYPAD_NAVIGATION must be defined. \value LeaveWhatsThisMode Send to toplevel widgets when the application leaves "What's This?" mode. \value LocaleChange The system locale has changed. - \value NonClientAreaMouseButtonDblClick A mouse double click occurred outside the client area. - \value NonClientAreaMouseButtonPress A mouse button press occurred outside the client area. - \value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area. - \value NonClientAreaMouseMove A mouse move occurred outside the client area. + \value NonClientAreaMouseButtonDblClick A mouse double click occurred outside the client area (QMouseEvent). + \value NonClientAreaMouseButtonPress A mouse button press occurred outside the client area (QMouseEvent). + \value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area (QMouseEvent). + \value NonClientAreaMouseMove A mouse move occurred outside the client area (QMouseEvent). \value MacSizeChange The user changed his widget sizes (\macos only). \value MetaCall An asynchronous method invocation via QMetaObject::invokeMethod(). \value ModifiedChange Widgets modification state has been changed. -- cgit v1.2.3 From a24597d93d7f1f30b7656af0af97f9a18797c2a5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 9 Oct 2017 11:49:03 +0200 Subject: Windows font database: Remove clamping of default font size Partially revert a72513cab7cdfac638ef572838277aa062f1d296. The value is too small for Chinese fonts. Task-number: QTBUG-63654 Change-Id: If020bfc3044258b7abfd9d463bc9b292a9cc0839 Reviewed-by: Alessandro Portale --- src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index 58b700b93f..a0adcd6e2e 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1980,12 +1980,6 @@ QFont QWindowsFontDatabase::systemDefaultFont() // long deprecated; the message font of the NONCLIENTMETRICS structure obtained by // SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see // QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger. - // In single monitor setups, the point sizes revolve around 8 (depending on UI - // scale factor, but not proportional to it). However, in multi monitor setups, - // where the DPI of the primary monitor are smaller than those of the secondary, - // large bogus values are returned. Limit to 8.25 in that case. - if (GetSystemMetrics(SM_CMONITORS) > 1 && systemFont.pointSizeF() > 8.25) - systemFont.setPointSizeF(8.25); #endif // Qt 5 qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont; return systemFont; -- cgit v1.2.3 From d20aa0d50d6dfc2dc1b88cc912425a28df6437de Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 9 Oct 2017 19:39:11 +0200 Subject: Fix typo in QKeyEvent docs Change-Id: I926fc94ae039f03c507149a6d3fc66f4584201e2 Reviewed-by: Jake Petroules --- src/gui/kernel/qevent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 680acb16e7..a7848b5485 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -1123,7 +1123,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, The event is propagated up the parent widget chain until a widget accepts it or an event filter consumes it. - The QWidget::setEnable() function can be used to enable or disable + The QWidget::setEnabled() function can be used to enable or disable mouse and keyboard events for a widget. The event handlers QWidget::keyPressEvent(), QWidget::keyReleaseEvent(), -- cgit v1.2.3 From a402b3a02e129702b1606a445affdba67ab9f805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 4 Oct 2017 12:31:38 +0200 Subject: Add support for HTTP status 308 Permanent Redirect 308 Permanent Redirect was introduced after redirection support was initially added to Qt. [ChangeLog][QtNetwork][QNetworkAccessManager] Added support for HTTP status 308. Task-number: QTBUG-63075 Change-Id: I1c6cda331d776237113ef8854de9abfe7e41ed3e Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../access/qhttpnetworkconnectionchannel.cpp | 3 +- src/network/access/qhttpnetworkreply.cpp | 2 +- src/network/access/qnetworkreply.cpp | 2 +- src/network/access/qnetworkreplyhttpimpl.cpp | 1 + .../access/qnetworkreply/tst_qnetworkreply.cpp | 40 ++++++++++++++++++++++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index e1084e0870..e7bb8e6619 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -553,7 +553,8 @@ void QHttpNetworkConnectionChannel::handleStatus() case 302: case 303: case 305: - case 307: { + case 307: + case 308: { // Parse the response headers and get the "location" url QUrl redirectUrl = connection->d_func()->parseRedirectResponse(socket, reply); if (redirectUrl.isValid()) diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 612abb9044..778ba821e8 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -96,7 +96,7 @@ void QHttpNetworkReply::setRedirectUrl(const QUrl &url) bool QHttpNetworkReply::isHttpRedirect(int statusCode) { return (statusCode == 301 || statusCode == 302 || statusCode == 303 - || statusCode == 305 || statusCode == 307); + || statusCode == 305 || statusCode == 307 || statusCode == 308); } qint64 QHttpNetworkReply::contentLength() const diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 8e7059de0f..abe952cd08 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -297,7 +297,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() This signal is emitted if the QNetworkRequest::FollowRedirectsAttribute was set in the request and the server responded with a 3xx status (specifically - 301, 302, 303, 305 or 307 status code) with a valid url in the location + 301, 302, 303, 305, 307 or 308 status code) with a valid url in the location header, indicating a HTTP redirect. The \a url parameter contains the new redirect url as returned by the server in the location header. diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 9f1b37c4e9..8ba2b12a46 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1200,6 +1200,7 @@ void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode) case 302: // Found case 303: // See Other case 307: // Temporary Redirect + case 308: // Permanent Redirect // What do we do about the caching of the HTML note? // The response to a 303 MUST NOT be cached, while the response to // all of the others is cacheable if the headers indicate it to be diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 542246ff2d..16f06b2d15 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -488,6 +488,8 @@ private Q_SLOTS: void ioHttpUserVerifiedRedirect_data(); void ioHttpUserVerifiedRedirect(); void ioHttpCookiesDuringRedirect(); + void ioHttpRedirect_data(); + void ioHttpRedirect(); #ifndef QT_NO_SSL void putWithServerClosingConnectionImmediately(); #endif @@ -8438,6 +8440,44 @@ void tst_QNetworkReply::ioHttpCookiesDuringRedirect() QVERIFY(target.receivedData.contains("\r\nCookie: hello=world\r\n")); } +void tst_QNetworkReply::ioHttpRedirect_data() +{ + QTest::addColumn("status"); + + QTest::addRow("301") << "301 Moved Permanently"; + QTest::addRow("302") << "302 Found"; + QTest::addRow("303") << "303 See Other"; + QTest::addRow("305") << "305 Use Proxy"; + QTest::addRow("307") << "307 Temporary Redirect"; + QTest::addRow("308") << "308 Permanent Redirect"; +} + +void tst_QNetworkReply::ioHttpRedirect() +{ + QFETCH(QString, status); + + MiniHttpServer target(httpEmpty200Response, false); + QUrl targetUrl("http://localhost/"); + targetUrl.setPort(target.serverPort()); + + QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n" + "Content-Type: text/plain\r\n" + "location: %2\r\n" + "\r\n").arg(status, targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1(), false); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + QNetworkRequest request(url); + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + QNetworkReplyPtr reply(manager.get(request)); + // Set policy back to what it was + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); +} + #ifndef QT_NO_SSL class PutWithServerClosingConnectionImmediatelyHandler: public QObject -- cgit v1.2.3 From e28fd642a9acb120191906bdbc0d133036947e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Fri, 6 Oct 2017 13:20:39 +0300 Subject: Extend blacklisting of tst_gestures in RHEL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This autotest has been blacklisted already in RHEL 7.1 and RHEL 7.2. This one extends it to 7.3 and 7.4. Task-number: QTBUG-52523 Change-Id: I3e2d8cd882d9f7dc58a65bde88e3aa16438b13c3 Reviewed-by: Simo Fält --- tests/auto/other/gestures/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST index e33d36e201..bd43b99d39 100644 --- a/tests/auto/other/gestures/BLACKLIST +++ b/tests/auto/other/gestures/BLACKLIST @@ -1,5 +1,7 @@ [] rhel-7.1 rhel-7.2 +rhel-7.3 +rhel-7.4 [customGesture] opensuse-13.1 -- cgit v1.2.3 From 9909ff108e942ea0cd233d2cd3715f830c2ad89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Mon, 9 Oct 2017 12:57:55 +0300 Subject: Fix blacklisting of tst_QOpenGL in Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit ba1b73175b5b47ff0565c58f0d6c51d515c21831 tried blacklisting this autotest in Windows 7 only. This however does not work. We can't pin point blacklisting to a specific Windows version. Task-number: QTBUG-63122 Change-Id: I5edb5b56fd86ad194214818a838db9cfd6be2ad1 Reviewed-by: Simo Fält --- tests/auto/gui/qopengl/BLACKLIST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/gui/qopengl/BLACKLIST b/tests/auto/gui/qopengl/BLACKLIST index a16327d411..a036106c57 100644 --- a/tests/auto/gui/qopengl/BLACKLIST +++ b/tests/auto/gui/qopengl/BLACKLIST @@ -7,4 +7,4 @@ windows [openGLPaintDevice] windows [wglContextWrap] -windows-7 +windows -- cgit v1.2.3 From f1033567aa4295d5e0122f01c7781a8b23d0d781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Mon, 9 Oct 2017 14:08:23 +0200 Subject: QDockWidget - improve resize On high DPI (e.g Apple Retina) user resizes of QDockWidgets (with custom titlebars) could fail. There was a cursor position check in mouse move event bailing out if the cursor pos was not within the widget. The problem was that we could be on the edge (or maybe even cross it?). Furthermore there is (/was) no similar check when setting the cursor to be a resize cursor, so users will obviously expect the resize to occur. This solves a part of QTBUG-63526 [ChangeLog][QtWidgets][QDockWidget] Fixed an issue in QDockWidgets where the widget would not resize despite showing a resize cursor. Task-number: QTBUG-63526 Change-Id: Ifa842a109071552506da3a82822d903dc252c8cd Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Andy Shaw --- src/widgets/widgets/qwidgetresizehandler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp index 5bd87ac91c..09c5e52219 100644 --- a/src/widgets/widgets/qwidgetresizehandler.cpp +++ b/src/widgets/widgets/qwidgetresizehandler.cpp @@ -118,7 +118,9 @@ bool QWidgetResizeHandler::eventFilter(QObject *o, QEvent *ee) QMouseEvent *e = static_cast(ee); if (w->isMaximized()) break; - if (!widget->rect().contains(widget->mapFromGlobal(e->globalPos()))) + const QRect widgetRect = widget->rect().marginsAdded(QMargins(range, range, range, range)); + const QPoint cursorPoint = widget->mapFromGlobal(e->globalPos()); + if (!widgetRect.contains(cursorPoint) || mode == Center || mode == Nowhere) return false; if (e->button() == Qt::LeftButton) { #if 0 // Used to be included in Qt4 for Q_WS_X11 -- cgit v1.2.3 From 7f6f1d7e300498ab7a0e7bb0c472305099cdf714 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 10 Oct 2017 14:19:37 +0000 Subject: Revert "Do not include qfloat16 tables in arm64 builds" They are needed for older compilers that doesn't support the __fp16 extension. Reverts under the assumptions other compilers will optimize it away. This reverts commit 6dc7e468dfd052dc4cf6187843bcb1a5b82ec6ff. Task-number: QTBUG-63693 Change-Id: If780de001d8c12df0db12caaf62505f16e01b663 Reviewed-by: Thiago Macieira --- src/corelib/global/global.pri | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index b76d1ef43c..a3c1c4d65e 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -79,16 +79,13 @@ gcc:ltcg { SOURCES += $$VERSIONTAGGING_SOURCES } -# On AARCH64 the fp16 extension is mandatory, so we don't need the conversion tables. -!contains(QT_ARCH, "arm64") { - QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h - - qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables) - - qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT} - qfloat16_tables.output = global/qfloat16tables.cpp - qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES - qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE - qfloat16_tables.variable_out = SOURCES - QMAKE_EXTRA_COMPILERS += qfloat16_tables -} +QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h + +qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables) + +qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT} +qfloat16_tables.output = global/qfloat16tables.cpp +qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES +qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE +qfloat16_tables.variable_out = SOURCES +QMAKE_EXTRA_COMPILERS += qfloat16_tables -- cgit v1.2.3 From e6fe342abbbe6cb9d659742f11ebb54b6117095d Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 9 Oct 2017 11:27:24 +0200 Subject: Fix CVE-2017-10989 in sqlite Change-Id: I556a453f386e887abee77a4dc147eae45970a61c Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- .../patches/0001-Fix-CVE-2017-10989-in-sqlite.patch | 15 +++++++++++++++ src/3rdparty/sqlite/sqlite3.c | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 src/3rdparty/sqlite/patches/0001-Fix-CVE-2017-10989-in-sqlite.patch diff --git a/src/3rdparty/sqlite/patches/0001-Fix-CVE-2017-10989-in-sqlite.patch b/src/3rdparty/sqlite/patches/0001-Fix-CVE-2017-10989-in-sqlite.patch new file mode 100644 index 0000000000..26d022f6c6 --- /dev/null +++ b/src/3rdparty/sqlite/patches/0001-Fix-CVE-2017-10989-in-sqlite.patch @@ -0,0 +1,15 @@ +diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c +index 7f5e75921f..f5c6180a03 100644 +--- a/src/3rdparty/sqlite/sqlite3.c ++++ b/src/3rdparty/sqlite/sqlite3.c +@@ -165733,6 +165733,10 @@ static int getNodeSize( + rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); ++ }else if( pRtree->iNodeSize<(512-64) ){ ++ rc = SQLITE_CORRUPT; ++ *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", ++ pRtree->zName); + } + } + diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 7f5e75921f..f5c6180a03 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -165733,6 +165733,10 @@ static int getNodeSize( rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + }else if( pRtree->iNodeSize<(512-64) ){ + rc = SQLITE_CORRUPT; + *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", + pRtree->zName); } } -- cgit v1.2.3 From e03b64c5b1eeebfbbb94d67eb9a9c1d35eaba0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Wed, 11 Oct 2017 09:48:35 +0300 Subject: Extend blacklisting of tst_qwidget tests to cover RHEL 7.3 & 7.4 The autotest has been blacklisted for RHEL 7.1 and RHEL 7.2 earlier already and it is still failing in 7.4. Task-number: QTBUG-46116 Change-Id: I0f33be849513a2debaf8c093dcd413fa09b5c681 Reviewed-by: Heikki Halmet --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 010e96467c..a04a67e4be 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -14,6 +14,8 @@ ubuntu-14.04 ubuntu-16.04 rhel-7.1 rhel-7.2 +rhel-7.3 +rhel-7.4 osx [focusProxyAndInputMethods] linux -- cgit v1.2.3 From 8ac9addd946637401e4685c6e91d1a3cd5b2d768 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 10 Oct 2017 10:54:08 -0700 Subject: QCocoaWindow: Toggle titlebar transparency to support unified toolbar This is need from macOS 10.13 onwards. See NSWindow related notes on https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKit/ Change-Id: I4b4653d7342de985d22b128d73940e7163bdb1e8 Task-number: QTBUG-63444 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 6ef459566a..c6fa6795c1 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -2161,6 +2161,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window) if (!m_drawContentBorderGradient) { [window setStyleMask:[window styleMask] & ~NSTexturedBackgroundWindowMask]; [[[window contentView] superview] setNeedsDisplay:YES]; + window.titlebarAppearsTransparent = NO; return; } @@ -2185,6 +2186,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window) int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness; [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask]; + window.titlebarAppearsTransparent = YES; [window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge]; [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; -- cgit v1.2.3 From f6cca6ab8a6055a0bc3a32d4c7943679972fb9ea Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 5 Oct 2017 09:04:36 +0200 Subject: Replace 'an unique' with 'a unique' Unique begins with a "y" sound, hence a unique is correct. Change-Id: I9eb6b4d4c9ddab45af931e97c041c24edf163eca Reviewed-by: Jake Petroules --- src/dbus/qdbusintrospection.cpp | 2 +- src/gui/util/qhexstring_p.h | 2 +- src/network/ssl/qsslsocket_mac.cpp | 2 +- tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dbus/qdbusintrospection.cpp b/src/dbus/qdbusintrospection.cpp index a700a2a215..6e406f7616 100644 --- a/src/dbus/qdbusintrospection.cpp +++ b/src/dbus/qdbusintrospection.cpp @@ -195,7 +195,7 @@ QT_BEGIN_NAMESPACE \inmodule QtDBus \brief Information about one interface on the bus. - Each interface on D-Bus has an unique \a name, identifying where that interface was defined. + Each interface on D-Bus has a unique \a name, identifying where that interface was defined. Interfaces may have annotations, methods, signals and properties, but none are mandatory. */ diff --git a/src/gui/util/qhexstring_p.h b/src/gui/util/qhexstring_p.h index 511eec0f1b..d30a8eeee8 100644 --- a/src/gui/util/qhexstring_p.h +++ b/src/gui/util/qhexstring_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -// internal helper. Converts an integer value to an unique string token +// internal helper. Converts an integer value to a unique string token template struct HexString { diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 2aecf3407f..0aef6a2a99 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -92,7 +92,7 @@ EphemeralSecKeychain::EphemeralSecKeychain() { const auto uuid = QUuid::createUuid(); if (uuid.isNull()) { - qCWarning(lcSsl) << "Failed to create an unique keychain name"; + qCWarning(lcSsl) << "Failed to create a unique keychain name"; return; } diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index d48ee03a22..b950bf3957 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -689,7 +689,7 @@ void tst_QFileDialog2::completionOnLevelAfterRoot() } } if (testDir.isEmpty()) - QSKIP("This test requires to have an unique directory of at least six ascii characters under c:/"); + QSKIP("This test requires to have a unique directory of at least six ascii characters under c:/"); #else fd.setFilter(QDir::Hidden | QDir::AllDirs | QDir::Files | QDir::System); fd.setDirectory("/"); -- cgit v1.2.3 From bc74273143dfb5de8e2255649c7fd037d3d4075a Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 6 Oct 2017 11:07:14 +0200 Subject: QPainter: fix invalid pen style when drawing misspelled words This code asks the platform theme to resolve SpellCheckUnderline to an actual pen style (wave, solid, dash, etc.) but if there's no theme, or if the default implementation in QPlatformTheme is used, the value is still SpellCheckUnderline, which then casted to a PenStyle below in qpainter.cpp: pen.setStyle((Qt::PenStyle)(underlineStyle)); The value 7 is an invalid PenStyle, which leads to random behavior when drawing the underline. Make it WaveUnderline if the platform theme had no opinion on how to draw it. Change-Id: I4f02f9b58f10582cee5aefce7a4d5cd300133140 Reviewed-by: Frederik Gladhorn --- src/gui/painting/qpainter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index b186182c34..49d8fd2846 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6259,6 +6259,8 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); if (theme) underlineStyle = QTextCharFormat::UnderlineStyle(theme->themeHint(QPlatformTheme::SpellCheckUnderlineStyle).toInt()); + if (underlineStyle == QTextCharFormat::SpellCheckUnderline) // still not resolved + underlineStyle = QTextCharFormat::WaveUnderline; } if (underlineStyle == QTextCharFormat::WaveUnderline) { -- cgit v1.2.3 From 5fa64386336b3072a12054726483e4850fc53dea Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 24 Sep 2017 08:26:30 +0300 Subject: Qmake: Introduce and use QMAKE_{SYSTEM,SHELL}_NULL_DEVICE variable, take 2 SYSTEM is used for system() calls, while SHELL is used in the target Makefiles. Task-number: QTBUG-62985 Change-Id: Ia75d3939c59c98699359421166433e8b4a6ee35e Reviewed-by: Frederik Gladhorn Reviewed-by: Oswald Buddenhagen --- mkspecs/features/ctest_testcase_common.prf | 14 ++------------ mkspecs/features/qt_functions.prf | 5 +---- mkspecs/features/spec_post.prf | 12 ++++++++---- mkspecs/features/toolchain.prf | 19 +++++++------------ qmake/generators/win32/mingw_make.cpp | 8 +------- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf index cdc5cca1d7..adb9da1b6f 100644 --- a/mkspecs/features/ctest_testcase_common.prf +++ b/mkspecs/features/ctest_testcase_common.prf @@ -1,10 +1,5 @@ -win32 { - CMAKE_VERSION = $$system(cmake --version 2>NUL, lines) -} else { - CMAKE_VERSION = $$system(cmake --version 2>/dev/null, lines) -} - +CMAKE_VERSION = $$system(cmake --version 2>$$QMAKE_SYSTEM_NULL_DEVICE, lines) CMAKE_VERSION = $$member(CMAKE_VERSION, 0, 0) check.commands = @@ -15,12 +10,7 @@ isEmpty(CMAKE_VERSION) { return() } -win32 { - CTEST_VERSION = $$system(ctest --version 2>NUL) -} else { - CTEST_VERSION = $$system(ctest --version 2>/dev/null) -} - +CTEST_VERSION = $$system(ctest --version 2>$$QMAKE_SYSTEM_NULL_DEVICE) isEmpty(CTEST_VERSION) { message("ctest executable not found. Not running CMake unit tests") return() diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index c00fdb73f8..1903e509c8 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -291,10 +291,7 @@ defineReplace(pkgConfigExecutable) { } } - equals(QMAKE_HOST.os, Windows): \ - PKG_CONFIG += 2> NUL - else: \ - PKG_CONFIG += 2> /dev/null + PKG_CONFIG += 2> $$QMAKE_SYSTEM_NULL_DEVICE return($$PKG_CONFIG) } diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf index f87bf3c037..432bb51516 100644 --- a/mkspecs/features/spec_post.prf +++ b/mkspecs/features/spec_post.prf @@ -82,6 +82,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_MKDIR = mkdir # legacy QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1 QMAKE_STREAM_EDITOR = $(QMAKE) -install sed + QMAKE_SHELL_NULL_DEVICE = NUL QMAKE_INSTALL_FILE = copy /y QMAKE_INSTALL_PROGRAM = copy /y } else { @@ -101,6 +102,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_MKDIR = mkdir -p # legacy QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1 QMAKE_STREAM_EDITOR = sed + QMAKE_SHELL_NULL_DEVICE = /dev/null equals(QMAKE_HOST.os, Windows) { MINGW_IN_SHELL = 1 # legacy @@ -118,9 +120,11 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ } QMAKE_INSTALL_DIR = $$QMAKE_COPY_DIR equals(QMAKE_HOST.os, Windows) { - QMAKE_SYMBOLIC_LINK = $(QMAKE) -install ln -f -s - QMAKE_LN_SHLIB = $(QMAKE) -install ln -s + QMAKE_SYMBOLIC_LINK = $(QMAKE) -install ln -f -s + QMAKE_LN_SHLIB = $(QMAKE) -install ln -s + QMAKE_SYSTEM_NULL_DEVICE = NUL } else { - QMAKE_SYMBOLIC_LINK = ln -f -s - QMAKE_LN_SHLIB = ln -s + QMAKE_SYMBOLIC_LINK = ln -f -s + QMAKE_LN_SHLIB = ln -s + QMAKE_SYSTEM_NULL_DEVICE = /dev/null } diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 7b6f48de72..ba41598be1 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -32,15 +32,11 @@ isEmpty($${target_prefix}.INCDIRS) { # Get default include and library paths from compiler # gcc { - !equals(QMAKE_HOST.os, Windows) { - cmd_prefix = "LC_ALL=C" - cmd_suffix = "/dev/null" - null_file = /dev/null - } else { + cmd_suffix = "<$$QMAKE_SYSTEM_NULL_DEVICE >$$QMAKE_SYSTEM_NULL_DEVICE" + equals(QMAKE_HOST.os, Windows): \ cmd_prefix = "set LC_ALL=C&" - cmd_suffix = "NUL" - null_file = NUL - } + else: \ + cmd_prefix = "LC_ALL=C" cxx_flags = $$QMAKE_CXXFLAGS @@ -59,7 +55,7 @@ isEmpty($${target_prefix}.INCDIRS) { rim_qcc: \ # Need the cc1plus and ld command lines to pick up the paths - cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$null_file -v + cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$QMAKE_SYSTEM_NULL_DEVICE -v else: darwin:clang: \ # Need to link to pick up library paths cxx_flags += $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v @@ -175,9 +171,8 @@ defineReplace(qtVariablesFromMSVC) { } defineReplace(qtVariablesFromGCC) { - null_device = /dev/null - equals(QMAKE_HOST.os, Windows): null_device = NUL - ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines, ec) + ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ + <$$QMAKE_SYSTEM_NULL_DEVICE 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) !equals(ec, 0): qtCompilerErrror($$1) return($$ret) } diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index bad53dc5b7..f9c3870192 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -36,12 +36,6 @@ #include #include -#ifdef Q_OS_WIN -#define NULL_DEVICE "NUL" -#else -#define NULL_DEVICE "/dev/null" -#endif - QT_BEGIN_NAMESPACE MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator() @@ -329,7 +323,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { - t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" NULL_DEVICE; + t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>$$QMAKE_SHELL_NULL_DEVICE"; if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) { t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ; } else { -- cgit v1.2.3 From 7809bba68f65ad9e95691d52e6584314d4909bd0 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 13 Oct 2017 13:25:33 +0200 Subject: QHostAddress::setAddress - fix an overload taking SpecialAddress It must detach, otherwise it overwrites all QHostAddresses that were sharing a given QHostAddressPrivate. This overload was introduced in 5.8 and probably as a result broke some pre-existing code, that previously was using a conversion and the correctly working setAddress. Conveniently, QHostAddress::clear() does: d.detach(); d->clear();, exactly the first thing we do in other overloads of setAddress. Task-number: QTBUG-63764 Change-Id: I63c36e877c9358d3ff26ba1f2e4adf35b771f426 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/network/kernel/qhostaddress.cpp | 86 ++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 1b7061d050..a8d3a0bf98 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -518,49 +518,6 @@ QHostAddress::QHostAddress(SpecialAddress address) setAddress(address); } -/*! - \overload - \since 5.8 - - Sets the special address specified by \a address. -*/ -void QHostAddress::setAddress(SpecialAddress address) -{ - d->clear(); - - Q_IPV6ADDR ip6; - memset(&ip6, 0, sizeof ip6); - quint32 ip4 = INADDR_ANY; - - switch (address) { - case Null: - return; - - case Broadcast: - ip4 = INADDR_BROADCAST; - break; - case LocalHost: - ip4 = INADDR_LOOPBACK; - break; - case AnyIPv4: - break; - - case LocalHostIPv6: - ip6[15] = 1; - Q_FALLTHROUGH(); - case AnyIPv6: - d->setAddress(ip6); - return; - - case Any: - d->protocol = QAbstractSocket::AnyIPProtocol; - return; - } - - // common IPv4 part - d->setAddress(ip4); -} - /*! Destroys the host address object. */ @@ -724,6 +681,49 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr) #endif } +/*! + \overload + \since 5.8 + + Sets the special address specified by \a address. +*/ +void QHostAddress::setAddress(SpecialAddress address) +{ + clear(); + + Q_IPV6ADDR ip6; + memset(&ip6, 0, sizeof ip6); + quint32 ip4 = INADDR_ANY; + + switch (address) { + case Null: + return; + + case Broadcast: + ip4 = INADDR_BROADCAST; + break; + case LocalHost: + ip4 = INADDR_LOOPBACK; + break; + case AnyIPv4: + break; + + case LocalHostIPv6: + ip6[15] = 1; + Q_FALLTHROUGH(); + case AnyIPv6: + d->setAddress(ip6); + return; + + case Any: + d->protocol = QAbstractSocket::AnyIPProtocol; + return; + } + + // common IPv4 part + d->setAddress(ip4); +} + /*! Returns the IPv4 address as a number. -- cgit v1.2.3 From 2d4fe257cad8b10f284de7a0b10a1a297026e86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 12 Oct 2017 16:32:07 +0200 Subject: Remove some unused, local variables Change-Id: I453162d2d396bb3427064d3b1593bb6c71376605 Reviewed-by: Friedemann Kleint --- src/dbus/qdbusmetatype.cpp | 1 - src/gui/painting/qstroker.cpp | 2 -- src/gui/text/qtextodfwriter.cpp | 1 - src/tools/uic/cpp/cppwritedeclaration.cpp | 2 +- src/widgets/effects/qpixmapfilter.cpp | 1 - src/widgets/styles/qstylehelper.cpp | 1 - 6 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/dbus/qdbusmetatype.cpp b/src/dbus/qdbusmetatype.cpp index fb2b407997..6ed6c43e9d 100644 --- a/src/dbus/qdbusmetatype.cpp +++ b/src/dbus/qdbusmetatype.cpp @@ -216,7 +216,6 @@ Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock) void QDBusMetaType::registerMarshallOperators(int id, MarshallFunction mf, DemarshallFunction df) { - QByteArray var; QVector *ct = customTypes(); if (id < 0 || !mf || !df || !ct) return; // error! diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index c52792c2d3..4776545be6 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -1147,8 +1147,6 @@ void QDashStroker::processCurrentSubpath() QLineF cline; - QPainterPath dashPath; - QSubpathFlatIterator it(&m_elements, m_dashThreshold); qfixed2d prev = it.next(); diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index e228b3c840..3dd19a6eda 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -381,7 +381,6 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF } if (image.isNull()) { - QString context; if (image.isNull()) { // try direct loading name = imageFormat.name(); // remove qrc:/ prefix again image.load(name); diff --git a/src/tools/uic/cpp/cppwritedeclaration.cpp b/src/tools/uic/cpp/cppwritedeclaration.cpp index 3aadc878e3..6ebef1cc41 100644 --- a/src/tools/uic/cpp/cppwritedeclaration.cpp +++ b/src/tools/uic/cpp/cppwritedeclaration.cpp @@ -105,7 +105,7 @@ void WriteDeclaration::acceptUI(DomUI *node) QString qualifiedClassName = node->elementClass() + m_option.postfix; QString className = qualifiedClassName; - QString varName = m_driver->findOrInsertWidget(node->elementWidget()); + m_driver->findOrInsertWidget(node->elementWidget()); QString widgetClassName = node->elementWidget()->attributeClass(); QString exportMacro = node->elementExportMacro(); diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp index 9d70825b0e..211c09ee71 100644 --- a/src/widgets/effects/qpixmapfilter.cpp +++ b/src/widgets/effects/qpixmapfilter.cpp @@ -925,7 +925,6 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap scaledRadius /= scale; QImage srcImage; - QImage destImage; if (srcRect == src.rect()) { srcImage = src.toImage(); diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index 24d90fc0ba..141b731b65 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -278,7 +278,6 @@ void drawDial(const QStyleOptionSlider *option, QPainter *painter) buttonColor.setHsv(buttonColor .hue(), qMin(140, buttonColor .saturation()), qMax(180, buttonColor.value())); - QColor shadowColor(0, 0, 0, 20); if (enabled) { // Drop shadow -- cgit v1.2.3 From e00b295344e23bf2110c744b057225a24d589757 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Oct 2017 10:29:01 +0200 Subject: QSystemTrayIcon/Windows: Fix position of context menu with High DPI scaling Apply scale factor of screen. Task-number: QTBUG-63781 Change-Id: I1b5630edbdf6bb356955a7d70458a885af441953 Reviewed-by: Joerg Bornemann --- src/widgets/util/qsystemtrayicon_win.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/widgets/util/qsystemtrayicon_win.cpp b/src/widgets/util/qsystemtrayicon_win.cpp index d110cb8be4..3f007f24c1 100644 --- a/src/widgets/util/qsystemtrayicon_win.cpp +++ b/src/widgets/util/qsystemtrayicon_win.cpp @@ -49,7 +49,9 @@ #include #include +#include #include +#include #include #include #include @@ -335,6 +337,13 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) Q_ASSERT(q_uNOTIFYICONID == HIWORD(m->lParam)); message = LOWORD(m->lParam); gpos = QPoint(GET_X_LPARAM(m->wParam), GET_Y_LPARAM(m->wParam)); + // Drop this chunk when merging to 5.10; code has been moved to Windows QPA. + if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) { + if (const QPlatformScreen *screen = primaryScreen->handle()->screenForPosition(gpos)) { + gpos = QHighDpi::fromNative(gpos, QHighDpiScaling::factor(screen), + screen->geometry().topLeft()); + } + } } else { Q_ASSERT(q_uNOTIFYICONID == m->wParam); message = m->lParam; -- cgit v1.2.3 From 10da5fb55b0db3c5351fa9c6b3966becf89bf014 Mon Sep 17 00:00:00 2001 From: Vyacheslav Koscheev Date: Fri, 6 Oct 2017 15:22:47 +0700 Subject: Attach Qt main c++ thread to jvm at the early beginning We need it 1. to be sure, that thread is already attached to jvm when we attach debugger to the process 2. to have a human-friendly name for main native thread Change-Id: I1e572a0f09ec8af24a910835aaa6d302f6f2cb43 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/androidjnimain.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index ad2fef7070..594fcbadad 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -450,6 +450,17 @@ static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobj static void *startMainMethod(void */*data*/) { + { + JNIEnv* env = nullptr; + JavaVMAttachArgs args; + args.version = JNI_VERSION_1_6; + args.name = "QtMainThread"; + args.group = NULL; + JavaVM *vm = QtAndroidPrivate::javaVM(); + if (vm != 0) + vm->AttachCurrentThread(&env, &args); + } + QVarLengthArray params(m_applicationParams.size()); for (int i = 0; i < m_applicationParams.size(); i++) params[i] = static_cast(m_applicationParams[i].constData()); -- cgit v1.2.3 From f1838fd69274a37bd65fed112fa0eef868556535 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 15 Oct 2017 10:37:22 +0300 Subject: qmake: Actually resolve QMAKE_SHELL_NULL_DEVICE when writing to Makefile This is C++, not qmake code. Amends 5fa6438633. Change-Id: Ie5b88c3a06dbe089948488ea3b4b297a08164113 Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/mingw_make.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index f9c3870192..792ffb1997 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -323,7 +323,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" <isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { - t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>$$QMAKE_SHELL_NULL_DEVICE"; + t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" << var("QMAKE_SHELL_NULL_DEVICE"); if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) { t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ; } else { -- cgit v1.2.3 From 49da5ce10034161017b261e000d4e9063d962401 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 16 Oct 2017 18:36:33 +0300 Subject: ANGLE: Fix compilation with MinGW /X is transformed into X:. Pass arguments with dash instead. Change-Id: Ib69ce73d9b8e54f4ea4b17fdb0ca43c85977717d Reviewed-by: Thiago Macieira --- src/angle/src/common/gles_common.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/angle/src/common/gles_common.pri b/src/angle/src/common/gles_common.pri index ea4fb03aae..5d5682a1df 100644 --- a/src/angle/src/common/gles_common.pri +++ b/src/angle/src/common/gles_common.pri @@ -585,7 +585,7 @@ angle_d3d11: SHADERS = VS_Passthrough2D \ for (SHADER, SHADERS) { INPUT = $$eval($${SHADER}.input) OUT_DIR = $$OUT_PWD/libANGLE/$$relative_path($$dirname($$INPUT), $$ANGLE_DIR/src/libANGLE)/compiled - fxc_$${SHADER}.commands = $$FXC /nologo /E $${SHADER} /T $$eval($${SHADER}.type) /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} + fxc_$${SHADER}.commands = $$FXC -nologo -E $${SHADER} -T $$eval($${SHADER}.type) -Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} fxc_$${SHADER}.output = $$OUT_DIR/$$eval($${SHADER}.output) fxc_$${SHADER}.input = $$INPUT fxc_$${SHADER}.dependency_type = TYPE_C -- cgit v1.2.3 From 198225983df9f402bb368b449f1abeea95ff0dce Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 11 Oct 2017 18:42:32 -0700 Subject: QShortcut: Fall back to cross platform code in absence of QPA menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS, absence of a QPA menu means that we should be using our own internal logic since there's no entity on the QCocoaMenuDelegate to take care of the shortcuts. Change-Id: I35ed8f0b55445f61d0528709d4debb636a502002 Task-number: QTBUG-61039 Reviewed-by: Tor Arne Vestbø Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qshortcut.cpp | 4 +++- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 28 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index 0585a59e89..f944a7097b 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -289,8 +289,10 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge // not the QMenu.) Since we can also reach this code by climbing the menu // hierarchy (see below), or when the shortcut is not a key-equivalent, we // need to check whether the QPA menu is actually disabled. + // When there is no QPA menu, there will be no QCocoaMenuDelegate checking + // for the actual shortcuts. We can then fallback to our own logic. QPlatformMenu *pm = menu->platformMenu(); - if (!pm || !pm->isEnabled()) + if (pm && !pm->isEnabled()) continue; #endif QAction *a = menu->menuAction(); diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index f0fb7bc367..ad30db501a 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -133,6 +133,7 @@ private slots: void menuSize_Scrolling_data(); void menuSize_Scrolling(); void tearOffMenuNotDisplayed(); + void QTBUG_61039_menu_shortcuts(); protected slots: void onActivated(QAction*); @@ -1609,5 +1610,32 @@ void tst_QMenu::tearOffMenuNotDisplayed() QVERIFY(!torn->isVisible()); } +void tst_QMenu::QTBUG_61039_menu_shortcuts() +{ + QAction *actionKamen = new QAction("Action Kamen"); + actionKamen->setShortcut(QKeySequence(QLatin1String("K"))); + + QAction *actionJoe = new QAction("Action Joe"); + actionJoe->setShortcut(QKeySequence(QLatin1String("Ctrl+J"))); + + QMenu menu; + menu.addAction(actionKamen); + menu.addAction(actionJoe); + QVERIFY(!menu.platformMenu()); + + QWidget widget; + widget.addAction(menu.menuAction()); + widget.show(); + QVERIFY(QTest::qWaitForWindowActive(&widget)); + + QSignalSpy actionKamenSpy(actionKamen, &QAction::triggered); + QTest::keyClick(&widget, Qt::Key_K); + QTRY_COMPARE(actionKamenSpy.count(), 1); + + QSignalSpy actionJoeSpy(actionJoe, &QAction::triggered); + QTest::keyClick(&widget, Qt::Key_J, Qt::ControlModifier); + QTRY_COMPARE(actionJoeSpy.count(), 1); +} + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v1.2.3 From 127483b5e30de6c1905ea3280dd45a0b7d6a3813 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Oct 2017 15:34:35 +0200 Subject: Windows QPA: Fix reporting of TabletLeaveProximity events Move the check for totalPacks below; it prevents leave notifications from being handled. Task-number: QTBUG-53628 Change-Id: I2436c51308803337e6d48ef958e03123283d4a1d Reviewed-by: Shawn Rutledge --- .../platforms/windows/qwindowstabletsupport.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 7e1017426f..5fe58fbfa5 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -352,16 +352,26 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L { PACKET proximityBuffer[1]; // we are only interested in the first packet in this case const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer); - if (!totalPacks) - return false; + if (!LOWORD(lParam)) { qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice; - QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime, - m_devices.at(m_currentDevice).currentDevice, - m_devices.at(m_currentDevice).currentPointerType, - m_devices.at(m_currentDevice).uniqueId); + if (totalPacks > 0) { + QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime, + m_devices.at(m_currentDevice).currentDevice, + m_devices.at(m_currentDevice).currentPointerType, + m_devices.at(m_currentDevice).uniqueId); + } else { + QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice, + m_devices.at(m_currentDevice).currentPointerType, + m_devices.at(m_currentDevice).uniqueId); + + } return true; } + + if (!totalPacks) + return false; + const UINT currentCursor = proximityBuffer[0].pkCursor; UINT physicalCursorId; QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId); -- cgit v1.2.3 From b16add0dc6db16b20f730b763ffa080f953b52e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 13 Oct 2017 14:38:49 +0200 Subject: QNetworkReply: Reduce noise and a fail when building with no-ssl A few tests would QSKIP depending on the inclusion of SSL, producing multiple lines of noise in the output. And one test used https in one of its configurations without checking to see if it could, causing an UnknownProtocolError. Change-Id: I5f54bf1005f962cc027c099b816fbe245dc43d3f Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 39 ++++++++++------------ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 16f06b2d15..439f1cd618 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -8167,7 +8167,9 @@ void tst_QNetworkReply::ioHttpRedirectErrors_data() "location: http://localhost:%1\r\n\r\n"); QTest::newRow("too-many-redirects") << "http://localhost" << tempRedirectReply << QNetworkReply::TooManyRedirectsError; +#if QT_CONFIG(ssl) QTest::newRow("insecure-redirect") << "https://localhost" << tempRedirectReply << QNetworkReply::InsecureRedirectError; +#endif QTest::newRow("unknown-redirect") << "http://localhost"<< tempRedirectReply.replace("http", "bad_protocol") << QNetworkReply::ProtocolUnknownError; } @@ -8178,7 +8180,7 @@ void tst_QNetworkReply::ioHttpRedirectErrors() QFETCH(QNetworkReply::NetworkError, error); QUrl localhost(url); - MiniHttpServer server("", localhost.scheme() == "https"); + MiniHttpServer server("", localhost.scheme() == QLatin1String("https")); localhost.setPort(server.serverPort()); @@ -8228,11 +8230,13 @@ void tst_QNetworkReply::ioHttpRedirectPolicy_data() QTest::addColumn("statusCode"); QTest::newRow("manual-nossl") << QNetworkRequest::ManualRedirectPolicy << false << 0 << 307; - QTest::newRow("manual-ssl") << QNetworkRequest::ManualRedirectPolicy << true << 0 << 307; QTest::newRow("nolesssafe-nossl") << QNetworkRequest::NoLessSafeRedirectPolicy << false << 1 << 200; - QTest::newRow("nolesssafe-ssl") << QNetworkRequest::NoLessSafeRedirectPolicy << true << 1 << 200; QTest::newRow("same-origin-nossl") << QNetworkRequest::SameOriginRedirectPolicy << false << 1 << 200; +#if QT_CONFIG(ssl) + QTest::newRow("manual-ssl") << QNetworkRequest::ManualRedirectPolicy << true << 0 << 307; + QTest::newRow("nolesssafe-ssl") << QNetworkRequest::NoLessSafeRedirectPolicy << true << 1 << 200; QTest::newRow("same-origin-ssl") << QNetworkRequest::SameOriginRedirectPolicy << true << 1 << 200; +#endif } void tst_QNetworkReply::ioHttpRedirectPolicy() @@ -8240,10 +8244,6 @@ void tst_QNetworkReply::ioHttpRedirectPolicy() QFETCH(const QNetworkRequest::RedirectPolicy, policy); QFETCH(const bool, ssl); -#ifdef QT_NO_SSL - if (ssl) - QSKIP("SSL is not supported"); -#endif QFETCH(const int, redirectCount); QFETCH(const int, statusCode); @@ -8251,11 +8251,7 @@ void tst_QNetworkReply::ioHttpRedirectPolicy() // Setup HTTP server. SameOriginRedirector redirectServer("", ssl); - QUrl url(QLatin1String( -#ifndef QT_NO_SSL - ssl ? "https://localhost" : -#endif - "http://localhost")); + QUrl url(QLatin1String(ssl ? "https://localhost" : "http://localhost")); url.setPort(redirectServer.serverPort()); redirectServer.responses.push_back(httpEmpty200Response); @@ -8291,27 +8287,35 @@ void tst_QNetworkReply::ioHttpRedirectPolicyErrors_data() // 1. NoLessSafeRedirectsPolicy QTest::newRow("nolesssafe-nossl-nossl-too-many") << QNetworkRequest::NoLessSafeRedirectPolicy << false << QString("http://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; +#if QT_CONFIG(ssl) QTest::newRow("nolesssafe-ssl-ssl-too-many") << QNetworkRequest::NoLessSafeRedirectPolicy << true << QString("https:/localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; QTest::newRow("nolesssafe-ssl-nossl-insecure-redirect") << QNetworkRequest::NoLessSafeRedirectPolicy << true << QString("http://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif // 2. SameOriginRedirectsPolicy QTest::newRow("same-origin-nossl-nossl-too-many") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("http://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; +#if QT_CONFIG(ssl) QTest::newRow("same-origin-ssl-ssl-too-many") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("https://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError; QTest::newRow("same-origin-https-http-wrong-protocol") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("http://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif QTest::newRow("same-origin-http-https-wrong-protocol") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("https://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; QTest::newRow("same-origin-http-http-wrong-host") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("http://not-so-localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#if QT_CONFIG(ssl) QTest::newRow("same-origin-https-https-wrong-host") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("https://not-so-localhost:%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif QTest::newRow("same-origin-http-http-wrong-port") << QNetworkRequest::SameOriginRedirectPolicy << false << QString("http://localhost/%1") << 50 << QNetworkReply::InsecureRedirectError; +#if QT_CONFIG(ssl) QTest::newRow("same-origin-https-https-wrong-port") << QNetworkRequest::SameOriginRedirectPolicy << true << QString("https://localhost/%1") << 50 << QNetworkReply::InsecureRedirectError; +#endif } void tst_QNetworkReply::ioHttpRedirectPolicyErrors() @@ -8325,20 +8329,11 @@ void tst_QNetworkReply::ioHttpRedirectPolicyErrors() QFETCH(const int, maxRedirects); QFETCH(const QNetworkReply::NetworkError, expectedError); -#ifdef QT_NO_SSL - if (ssl || location.contains("https")) - QSKIP("SSL required to run this test"); -#endif - // Setup the server. MiniHttpServer server("", ssl); server.setDataToTransmit(tempRedirectReplyStr().arg(location.arg(server.serverPort())).toLatin1()); - QUrl url(QLatin1String( -#ifndef QT_NO_SSL - ssl ? "https://localhost" : -#endif - "http://localhost")); + QUrl url(QLatin1String(ssl ? "https://localhost" : "http://localhost")); url.setPort(server.serverPort()); QNetworkRequest request(url); -- cgit v1.2.3 From 92d67b58b8dbe2c5e63c5e57a179a3dc9acf382b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 16 Oct 2017 11:54:21 +0200 Subject: macOS: Defer update request on drawRect: when a real expose event is needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The semantics of QWindow::requestUpdate() is that it's used when the window needs updates outside of the normal window invalidation callbacks such as expose and resize events, e.g. when doing animations. As a result, user code might not be prepared to handle window invalidations in the update-request callback, assuming those will still be delivered as normal, so that's what we do. This was exposed by resizing one of the simpler Qt Quick examples, where the resize's expose event was delivered as an update request, but didn't trigger an unconditional draw of the window as it should, as the scenegraph didn't change in response to the resize, which is typical for an update request. Change-Id: Ida8f85f1cf61c332aa9b199520e6854c48d3ab40 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.h | 2 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 33 +++++++++++++++-------------- src/plugins/platforms/cocoa/qnsview.mm | 11 +++++----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 3230c32133..6fbe29f683 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -262,7 +262,7 @@ public: // for QNSView bool m_hasModalSession; bool m_frameStrutEventsEnabled; - bool m_isExposed; + QRect m_exposedRect; int m_registerTouchCount; bool m_resizableTransientParent; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 8e5a9268ec..c825f03464 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -150,7 +150,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle) , m_needsInvalidateShadow(false) , m_hasModalSession(false) , m_frameStrutEventsEnabled(false) - , m_isExposed(false) , m_registerTouchCount(0) , m_resizableTransientParent(false) , m_alertRequest(NoAlertRequest) @@ -692,7 +691,7 @@ void QCocoaWindow::lower() bool QCocoaWindow::isExposed() const { - return m_isExposed; + return !m_exposedRect.isEmpty(); } bool QCocoaWindow::isOpaque() const @@ -1120,7 +1119,7 @@ void QCocoaWindow::handleGeometryChange() void QCocoaWindow::handleExposeEvent(const QRegion ®ion) { - const bool wasExposed = isExposed(); + const QRect previouslyExposedRect = m_exposedRect; // Ideally we'd implement isExposed() in terms of these properties, // plus the occlusionState of the NSWindow, and let the expose event @@ -1133,27 +1132,29 @@ void QCocoaWindow::handleExposeEvent(const QRegion ®ion) // a window being obscured is an empty region, and in the case of // a drawRect call is a non-null region, even if occlusionState // is still hidden. This ensures the window is prepared for display. - m_isExposed = m_view.window.visible - && m_view.window.screen - && !geometry().size().isEmpty() - && !region.isEmpty() - && !m_view.hiddenOrHasHiddenAncestor; + if (m_view.window.visible && m_view.window.screen + && !geometry().size().isEmpty() && !region.isEmpty() + && !m_view.hiddenOrHasHiddenAncestor) { + m_exposedRect = region.boundingRect(); + } else { + 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 the first expose event after - // becoming exposed as a real expose event, otherwise the exposed state - // of the QWindow is never updated. - // FIXME: Should this logic live in QGuiApplication? - if (wasExposed && m_isExposed) { + // 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. } - - // FIXME: Should we re-trigger setNeedsDisplay in case of !wasExposed && m_isExposed? - // Or possibly send the expose event first, and then the update request? } qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed(); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 054dca122f..9708aa4ce6 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -324,12 +324,13 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") m_platformWindow->handleExposeEvent(exposedRegion); - // A call to QWindow::requestUpdate was issued during the expose event, 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? if (qt_window_private(m_platformWindow->window())->updateRequestPending) { - qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:] deferring setNeedsDisplay"; + // 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 + // 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]; }); -- cgit v1.2.3 From 8fcf171b421cb71f97589e19b548a5eaa996cf72 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 29 Sep 2017 10:52:36 +0200 Subject: Android Accessibility: protect from accessing invalid interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I am not sure if this is going to help, but it is required that the bridge checks that the interfaces it accesses are valid, since that protects from accessing them when they are in the destructor. This should be done, whether it fixes the issue or not. Task-number: QTBUG-45855 Change-Id: I2b96999ca4043f8b33607c864d1d178695d03192 Reviewed-by: Jan Arve Sæther --- .../platforms/android/androidjniaccessibility.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index 06624415d3..e4d670239f 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -104,11 +104,11 @@ namespace QtAndroidAccessibility static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId) { QAccessibleInterface *iface = interfaceFromId(objectId); - if (iface) { + if (iface && iface->isValid()) { jintArray jArray = env->NewIntArray(jsize(iface->childCount())); for (int i = 0; i < iface->childCount(); ++i) { QAccessibleInterface *child = iface->child(i); - if (child) { + if (child && child->isValid()) { QAccessible::Id ifaceId = QAccessible::uniqueId(child); jint jid = ifaceId; env->SetIntArrayRegion(jArray, i, 1, &jid); @@ -123,9 +123,9 @@ namespace QtAndroidAccessibility static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId) { QAccessibleInterface *iface = interfaceFromId(objectId); - if (iface) { + if (iface && iface->isValid()) { QAccessibleInterface *parent = iface->parent(); - if (parent) { + if (parent && parent->isValid()) { if (parent->role() == QAccessible::Application) return -1; return QAccessible::uniqueId(parent); @@ -151,7 +151,7 @@ namespace QtAndroidAccessibility static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y) { QAccessibleInterface *root = interfaceFromId(-1); - if (root) { + if (root && root->isValid()) { QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window()); QAccessibleInterface *child = root->childAt(pos.x(), pos.y()); @@ -170,7 +170,7 @@ namespace QtAndroidAccessibility { // qDebug() << "A11Y: CLICK: " << objectId; QAccessibleInterface *iface = interfaceFromId(objectId); - if (iface && iface->actionInterface()) { + if (iface && iface->isValid() && iface->actionInterface()) { if (iface->actionInterface()->actionNames().contains(QAccessibleActionInterface::pressAction())) iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction()); else @@ -182,13 +182,17 @@ namespace QtAndroidAccessibility static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId) { QAccessibleInterface *iface = interfaceFromId(objectId); - return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::increaseAction()); + if (iface && iface->isValid()) + return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::increaseAction()); + return false; } static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId) { QAccessibleInterface *iface = interfaceFromId(objectId); - return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::decreaseAction()); + if (iface && iface->isValid()) + return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::decreaseAction()); + return false; } -- cgit v1.2.3 From 574c8ec13c89056f9a10c347b455ec6bfe864531 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 12 Oct 2017 11:11:32 +0200 Subject: Doc: State that qDebug and friends are thread-safe There's a common misconception that qDebug and friends are not thread-safe, so let's explicitly state this. Change-Id: I48d4ab8983017a9f2e7c9932a49ed573baa22929 Reviewed-by: Leena Miettinen Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 4 ++++ src/corelib/io/qloggingcategory.cpp | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index b5cc88534e..8d614b4f91 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4298,6 +4298,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qDebug(const char *message, ...) \relates + \threadsafe Calls the message handler with the debug message \a message. If no message handler has been installed, the message is printed to @@ -4334,6 +4335,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qInfo(const char *message, ...) \relates + \threadsafe \since 5.5 Calls the message handler with the informational message \a message. If no @@ -4371,6 +4373,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qWarning(const char *message, ...) \relates + \threadsafe Calls the message handler with the warning message \a message. If no message handler has been installed, the message is printed to @@ -4405,6 +4408,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) /*! \macro qCritical(const char *message, ...) \relates + \threadsafe Calls the message handler with the critical message \a message. If no message handler has been installed, the message is printed to diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 4256d4b6e1..b029274329 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -445,6 +445,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCDebug(category) \relates QLoggingCategory + \threadsafe \since 5.2 Returns an output stream for debug messages in the logging category @@ -469,6 +470,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCDebug(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.3 Logs a debug message \a message in the logging category \a category. @@ -490,6 +492,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCInfo(category) \relates QLoggingCategory + \threadsafe \since 5.5 Returns an output stream for informational messages in the logging category @@ -514,6 +517,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCInfo(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.5 Logs an informational message \a message in the logging category \a category. @@ -535,6 +539,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCWarning(category) \relates QLoggingCategory + \threadsafe \since 5.2 Returns an output stream for warning messages in the logging category @@ -559,6 +564,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCWarning(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.3 Logs a warning message \a message in the logging category \a category. @@ -580,6 +586,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCCritical(category) \relates QLoggingCategory + \threadsafe \since 5.2 Returns an output stream for critical messages in the logging category @@ -604,6 +611,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) /*! \macro qCCritical(category, const char *message, ...) \relates QLoggingCategory + \threadsafe \since 5.3 Logs a critical message \a message in the logging category \a category. -- cgit v1.2.3 From db333d6dba7703a67834a49e42e64c1e04b9ed3a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 16 Oct 2017 12:32:02 +0200 Subject: QNAM (redirects) - clear 'raw' headers before sending the next request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already cleared 'cookedHeaders', which is a QHash for 'known headers' (enumerators as keys instead of strings), now do the same for 'rawHeaders'- not to end up with some weird mix of headers from all possible redirect responses and the final response. Task-number: QTBUG-61300 Change-Id: Ifd6655c4167840bb00d29446d36ce65ba2d5491a Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/access/qnetworkreplyhttpimpl.cpp | 1 + .../network/access/qnetworkreply/tst_qnetworkreply.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 8ba2b12a46..fa60eb3564 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1183,6 +1183,7 @@ void QNetworkReplyHttpImplPrivate::followRedirect() { Q_Q(QNetworkReplyHttpImpl); + rawHeaders.clear(); cookedHeaders.clear(); if (managerPrivate->thread) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 439f1cd618..97fe9e04bf 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -516,6 +516,17 @@ bool tst_QNetworkReply::seedCreated = false; QFAIL(qPrintable(errorMsg)); \ } while (0) +static bool validateRedirectedResponseHeaders(QNetworkReplyPtr reply) +{ + // QTBUG-61300: previously we were mixing 'raw' headers from all responses + // along the redirect chain. The simplest test is to check/verify we have + // no 'location' header anymore. + Q_ASSERT(reply.data()); + + return !reply->hasRawHeader("location") + && !reply->header(QNetworkRequest::LocationHeader).isValid(); +} + #ifndef QT_NO_SSL static void setupSslServer(QSslSocket* serverSocket) { @@ -8106,6 +8117,7 @@ void tst_QNetworkReply::ioHttpSingleRedirect() // Reply url is set to the redirect url QCOMPARE(reply->url(), redirectUrl); QCOMPARE(reply->error(), QNetworkReply::NoError); + QVERIFY(validateRedirectedResponseHeaders(reply)); } void tst_QNetworkReply::ioHttpChangeMaxRedirects() @@ -8154,6 +8166,7 @@ void tst_QNetworkReply::ioHttpChangeMaxRedirects() QCOMPARE(redSpy2.count(), 2); QCOMPARE(reply2->url(), server3Url); QCOMPARE(reply2->error(), QNetworkReply::NoError); + QVERIFY(validateRedirectedResponseHeaders(reply2)); } void tst_QNetworkReply::ioHttpRedirectErrors_data() @@ -8274,6 +8287,7 @@ void tst_QNetworkReply::ioHttpRedirectPolicy() QCOMPARE(finishedSpy.count(), 1); QCOMPARE(redirectSpy.count(), redirectCount); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode); + QVERIFY(validateRedirectedResponseHeaders(reply) || statusCode != 200); } void tst_QNetworkReply::ioHttpRedirectPolicyErrors_data() @@ -8406,6 +8420,7 @@ void tst_QNetworkReply::ioHttpUserVerifiedRedirect() waitForFinish(reply); QCOMPARE(finishedSpy.count(), 1); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode); + QVERIFY(validateRedirectedResponseHeaders(reply) || statusCode != 200); } void tst_QNetworkReply::ioHttpCookiesDuringRedirect() @@ -8433,6 +8448,7 @@ void tst_QNetworkReply::ioHttpCookiesDuringRedirect() QVERIFY(waitForFinish(reply) == Success); QVERIFY(target.receivedData.contains("\r\nCookie: hello=world\r\n")); + QVERIFY(validateRedirectedResponseHeaders(reply)); } void tst_QNetworkReply::ioHttpRedirect_data() @@ -8471,6 +8487,7 @@ void tst_QNetworkReply::ioHttpRedirect() QCOMPARE(waitForFinish(reply), int(Success)); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QVERIFY(validateRedirectedResponseHeaders(reply)); } #ifndef QT_NO_SSL -- cgit v1.2.3 From 0aba5546ef69bddeb42c3dabe22e2856f0213b19 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 7 Sep 2017 14:40:58 +0200 Subject: tests: fix and un-blacklist tst_qgraphicsview::hoverLeave MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests should not use QCursor to emulate mouse move, see QCursor::setPos() docs. The flakiness of the test on XCB is not surprising when the test queries geometry even before the window has been shown. With the re-factored version I could not reproduce flakiness anymore. Removed Q_OS_MAC and closed QTBUG-26274 as test passes on macOS from which I assume that the underlying issue has been fixed. Removed Q_OS_QNX ifdef as test does not rely on QCursor anymore. This patch also fixes the issues on minimal / offscreen platform plugins. QCursor::setPos() is evil for auto test purposes. Note: We intentionally use QTest::mouseMove(QWindow *window, ..), not the QWidget overload. The QWindow version gets routed through QWSI, which ensures that all necessary events are generated as expect. In QWidget code path this is currently disabled by QTEST_QPA_MOUSE_HANDLING. Change-Id: I285c26cff09e3f2750f8c2abbb1f46c8f7be984a Reviewed-by: Tor Arne Vestbø (cherry picked from commit 1af927976ac953f922e35d71a16a32d328bb2efd) Reviewed-by: Tony Sarajärvi Reviewed-by: Friedemann Kleint Reviewed-by: Liang Qi --- .../widgets/graphicsview/qgraphicsview/BLACKLIST | 2 - .../qgraphicsview/tst_qgraphicsview.cpp | 48 +++++++++------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST index 3cba8bad7e..40d106e3ba 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST @@ -12,7 +12,5 @@ xcb xcb [forwardMousePress] xcb -[hoverLeave] -xcb [resizeAnchor] xcb diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 121836234d..5900c85627 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -4777,8 +4777,6 @@ class GraphicsItemWithHover : public QGraphicsRectItem { public: GraphicsItemWithHover() - : receivedEnterEvent(false), receivedLeaveEvent(false), - enterWidget(0), leaveWidget(0) { setRect(0, 0, 100, 100); setAcceptHoverEvents(true); @@ -4786,6 +4784,9 @@ public: bool sceneEvent(QEvent *event) { + if (!checkEvents) // ensures that we don't look at stray events before we are ready + return QGraphicsRectItem::sceneEvent(event); + if (event->type() == QEvent::GraphicsSceneHoverEnter) { receivedEnterEvent = true; enterWidget = static_cast(event)->widget(); @@ -4796,50 +4797,39 @@ public: return QGraphicsRectItem::sceneEvent(event); } - bool receivedEnterEvent; - bool receivedLeaveEvent; - QWidget *enterWidget; - QWidget *leaveWidget; + bool receivedEnterEvent = false; + bool receivedLeaveEvent = false; + QWidget *enterWidget = nullptr; + QWidget *leaveWidget = nullptr; + bool checkEvents = false; }; void tst_QGraphicsView::hoverLeave() { - if (platformName == QStringLiteral("cocoa")) { - QSKIP("Insignificant on OSX"); - } else if (platformName == QStringLiteral("minimal") - || (platformName == QStringLiteral("offscreen"))) { - QSKIP("Fails in minimal/offscreen platforms if forwardMouseDoubleClick has been run"); - } - const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); QGraphicsScene scene; QGraphicsView view(&scene); view.resize(160, 160); - view.move(availableGeometry.center() - QPoint(80, 80)); GraphicsItemWithHover *item = new GraphicsItemWithHover; scene.addItem(item); - // move the cursor out of the way - const QPoint outOfWindow = view.geometry().topRight() + QPoint(50, 0); - QCursor::setPos(outOfWindow); - view.showNormal(); qApp->setActiveWindow(&view); - QVERIFY(QTest::qWaitForWindowActive(&view)); - - QPoint pos = view.viewport()->mapToGlobal(view.mapFromScene(item->mapToScene(10, 10))); - QCursor::setPos(pos); + QVERIFY(QTest::qWaitForWindowExposed(&view)); -#if defined(Q_OS_QNX) - QEXPECT_FAIL("", "QCursor does not set native cursor on QNX", Abort); -#endif + QWindow *viewWindow = view.window()->windowHandle(); + QPoint posOutsideItem = view.mapFromScene(item->mapToScene(0, 0)) - QPoint(5, 0); + QPoint posOutsideItemGlobal = view.mapToGlobal(posOutsideItem); + QPoint posOutsideItemInWindow = viewWindow->mapFromGlobal(posOutsideItemGlobal); + QTest::mouseMove(viewWindow, posOutsideItemInWindow); + item->checkEvents = true; + QPoint posInItemGlobal = view.mapToGlobal(view.mapFromScene(item->mapToScene(10, 10))); + QTest::mouseMove(viewWindow, viewWindow->mapFromGlobal(posInItemGlobal)); QTRY_VERIFY(item->receivedEnterEvent); QCOMPARE(item->enterWidget, view.viewport()); - QCursor::setPos(outOfWindow); -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "QTBUG-26274 - behaviour regression", Abort); -#endif + QTest::mouseMove(viewWindow, posOutsideItemInWindow); + QTRY_VERIFY(item->receivedLeaveEvent); QCOMPARE(item->leaveWidget, view.viewport()); } -- cgit v1.2.3 From 377d2502e3d3116c4cbe7398c2aa6f4afbe32851 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 26 Sep 2017 12:20:30 +0200 Subject: tests: make exposeEventOnShrink_QTBUG54040 not flakey on xcb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: https://tronche.com/gui/x/xlib/events/exposure/expose.html "The circumstances in which the X server generates Expose events are not as definite as those for other events." On windows with XCB_GRAVITY_NORTH_WEST flag set we should not get expose events according to e2665600c09358854bb0b29389cc873a2684f77b, but as stated earlier this might not always be true. Nevertheless, sometimes we get expose event from X server when shrinking window, but most of the time we don't. Make the test not flakey by checking that we get at least 1 expose event, instead of exactly 1. Now running test 500 times in a loop does not fail. Task-number: QTBUG-63424 Change-Id: I8004e622020cc09e11b7d592faf6d9ee1b9cfee2 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 542e11ab2bd4a607fda8f559cc7efc32371b4e0e) Reviewed-by: Tony Sarajärvi Reviewed-by: Friedemann Kleint Reviewed-by: Liang Qi --- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index e1366ce2eb..6452b9ecd0 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -394,13 +394,17 @@ void tst_QWindow::exposeEventOnShrink_QTBUG54040() QVERIFY(QTest::qWaitForWindowExposed(&window)); - const int initialExposeCount = window.received(QEvent::Expose); + int exposeCount = window.received(QEvent::Expose); window.resize(window.width(), window.height() - 5); - QTRY_COMPARE(window.received(QEvent::Expose), initialExposeCount + 1); + QTRY_VERIFY(window.received(QEvent::Expose) > exposeCount); + + exposeCount = window.received(QEvent::Expose); window.resize(window.width() - 5, window.height()); - QTRY_COMPARE(window.received(QEvent::Expose), initialExposeCount + 2); + QTRY_VERIFY(window.received(QEvent::Expose) > exposeCount); + + exposeCount = window.received(QEvent::Expose); window.resize(window.width() - 5, window.height() - 5); - QTRY_COMPARE(window.received(QEvent::Expose), initialExposeCount + 3); + QTRY_VERIFY(window.received(QEvent::Expose) > exposeCount); } void tst_QWindow::positioning_data() -- cgit v1.2.3 From 8a39384e907e830c907f73009f498c486b22bd20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 10 Oct 2017 15:54:04 +0200 Subject: Open a session during redirects when needed In some cases when a session isn't needed (i.e. for localhost), the session is not opened at all. If a program (e.g. our tests) redirects from localhost to a different system (e.g. the qt network test servers, or the internet) it will wait for a session forever. So, we need to check if a session is needed for the redirect-target and then open one. It is usually opened in QNetworkReplyHttpImplPrivate::_q_startOperation Change-Id: Id3b78182a3fb3f63f0235ecb1fb665df8bd0c4ca Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkreplyhttpimpl.cpp | 78 ++++++++++++++++------ src/network/access/qnetworkreplyhttpimpl_p.h | 2 + .../access/qnetworkreply/tst_qnetworkreply.cpp | 28 ++++++++ 3 files changed, 87 insertions(+), 21 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index fa60eb3564..9756b43108 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -165,6 +165,16 @@ static QHash parseHttpOptionHeader(const QByteArray &hea } } +#if QT_CONFIG(bearermanagement) +static bool isSessionNeeded(const QUrl &url) +{ + // Connections to the local machine does not require a session + QString host = url.host().toLower(); + return !QHostAddress(host).isLoopback() && host != QLatin1String("localhost") + && host != QSysInfo::machineHostName().toLower(); +} +#endif // bearer management + QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manager, const QNetworkRequest& request, QNetworkAccessManager::Operation& operation, @@ -1189,6 +1199,24 @@ void QNetworkReplyHttpImplPrivate::followRedirect() if (managerPrivate->thread) managerPrivate->thread->disconnect(); +#if QT_CONFIG(bearermanagement) + // If the original request didn't need a session (i.e. it was to localhost) + // then we might not have a session open, to which to redirect, if the + // new URL is remote. When this happens, we need to open the session now: + if (managerPrivate && isSessionNeeded(url)) { + if (auto session = managerPrivate->getNetworkSession()) { + if (session->state() != QNetworkSession::State::Connected || !session->isOpen()) { + startWaitForSession(session); + // Need to set 'request' to the redirectRequest so that when QNAM restarts + // the request after the session starts it will not repeat the previous request. + request = redirectRequest; + // Return now, QNAM will start the request when the session has started. + return; + } + } + } +#endif // bearer management + QMetaObject::invokeMethod(q, "start", Qt::QueuedConnection, Q_ARG(QNetworkRequest, redirectRequest)); } @@ -1770,10 +1798,8 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest) } // This is not ideal. - const QString host = url.host(); - if (host == QLatin1String("localhost") || - QHostAddress(host).isLoopback()) { - // Don't need an open session for localhost access. + if (!isSessionNeeded(url)) { + // Don't need to check for an open session if we don't need one. postRequest(newHttpRequest); return true; } @@ -1797,6 +1823,32 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest) #endif } +bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer &session) +{ + Q_Q(QNetworkReplyHttpImpl); + state = WaitingForSession; + + if (session) { + QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)), + q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection); + + if (!session->isOpen()) { + QVariant isBackground = request.attribute(QNetworkRequest::BackgroundRequestAttribute, + QVariant::fromValue(false)); + session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground); + session->open(); + } + return true; + } + const Qt::ConnectionType connection = synchronous ? Qt::DirectConnection : Qt::QueuedConnection; + qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); + QMetaObject::invokeMethod(q, "_q_error", connection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError), + Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error."))); + QMetaObject::invokeMethod(q, "_q_finished", connection); + return false; +} + void QNetworkReplyHttpImplPrivate::_q_startOperation() { Q_Q(QNetworkReplyHttpImpl); @@ -1824,24 +1876,8 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() // backend failed to start because the session state is not Connected. // QNetworkAccessManager will call reply->backend->start() again for us when the session // state changes. - state = WaitingForSession; - - if (session) { - QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)), - q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection); - - if (!session->isOpen()) { - session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground); - session->open(); - } - } else { - qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); - QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection, - Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError), - Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error."))); - QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); + if (!startWaitForSession(session)) return; - } } else if (session) { QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index 9383149124..1b702bd2ec 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -160,6 +160,8 @@ signals: class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate { + bool startWaitForSession(QSharedPointer &session); + public: static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 97fe9e04bf..d236ef0490 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -490,6 +490,7 @@ private Q_SLOTS: void ioHttpCookiesDuringRedirect(); void ioHttpRedirect_data(); void ioHttpRedirect(); + void ioHttpRedirectFromLocalToRemote(); #ifndef QT_NO_SSL void putWithServerClosingConnectionImmediately(); #endif @@ -8490,6 +8491,33 @@ void tst_QNetworkReply::ioHttpRedirect() QVERIFY(validateRedirectedResponseHeaders(reply)); } +void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() +{ + QUrl targetUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + + QString redirectReply = tempRedirectReplyStr().arg(targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1(), false); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + + QFile reference(testDataDir + "/rfc3252.txt"); + QVERIFY(reference.open(QIODevice::ReadOnly)); + QNetworkRequest request(url); + + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + QNetworkReplyPtr reply(manager.get(request)); + // Restore previous policy + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + + QCOMPARE(reply->url(), targetUrl); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), reference.size()); + QCOMPARE(reply->readAll(), reference.readAll()); +} + #ifndef QT_NO_SSL class PutWithServerClosingConnectionImmediatelyHandler: public QObject -- cgit v1.2.3 From 66119a07e840daae61629762ad3763abd0c16754 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 4 Sep 2017 18:09:52 +0300 Subject: Address Book example: Replace QPair by struct Introduce Contact struct to store contact data and use it instead of QPair. Proper naming really clarifies the code. Task-number: QTBUG-60635 Change-Id: Ibfb421dfc854accc382212b0da46e7aafc0d528a Reviewed-by: Jesus Fernandez Reviewed-by: Friedemann Kleint --- examples/widgets/doc/src/addressbook.qdoc | 32 +++++++++---------- .../itemviews/addressbook/addresswidget.cpp | 20 ++++-------- .../widgets/itemviews/addressbook/tablemodel.cpp | 37 ++++++++++------------ .../widgets/itemviews/addressbook/tablemodel.h | 29 ++++++++++++++--- 4 files changed, 64 insertions(+), 54 deletions(-) diff --git a/examples/widgets/doc/src/addressbook.qdoc b/examples/widgets/doc/src/addressbook.qdoc index b9bcae21aa..cd7cd09f5b 100644 --- a/examples/widgets/doc/src/addressbook.qdoc +++ b/examples/widgets/doc/src/addressbook.qdoc @@ -60,8 +60,8 @@ the address book. \c TableModel is a subclass of QAbstractTableModel that provides - the standard model/view API to access data. It also holds a - QList of \l{QPair}s corresponding to the contacts added. + the standard model/view API to access data. It holds a list of + added contacts. However, this data is not all visible in a single tab. Instead, QTableView is used to provide 9 different views of the same data, according to the alphabet groups. @@ -80,7 +80,7 @@ \section1 TableModel Class Definition The \c TableModel class provides standard API to access data in - its QList of \l{QPair}s by subclassing QAbstractTableModel. The + its list of contacts by subclassing QAbstractTableModel. The basic functions that must be implemented in order to do so are: \c rowCount(), \c columnCount(), \c data(), \c headerData(). For TableModel to be editable, it has to provide implementations @@ -90,15 +90,14 @@ \snippet itemviews/addressbook/tablemodel.h 0 Two constructors are used, a default constructor which uses - \c TableModel's own \c {QList>} and one - that takes \c {QList} as an argument, - for convenience. + \c TableModel's own \c {QList} and one that takes + \c {QList} as an argument, for convenience. \section1 TableModel Class Implementation We implement the two constructors as defined in the header file. - The second constructor initializes the list of pairs in the + The second constructor initializes the list of contacts in the model, with the parameter value. \snippet itemviews/addressbook/tablemodel.cpp 0 @@ -117,7 +116,7 @@ The \c data() function returns either a \b Name or \b {Address}, based on the contents of the model index supplied. The row number stored in the model index is used to - reference an item in the list of pairs. Selection is handled + reference an item in the list of contacts. Selection is handled by the QItemSelectionModel, which will be explained with \c AddressWidget. @@ -164,12 +163,11 @@ use the editing features of the QTableView object, we enable them here so that we can reuse the model in other programs. - The last function in \c {TableModel}, \c getList() returns the - QList> object that holds all the - contacts in the address book. We use this function later to - obtain the list of contacts to check for existing entries, write - the contacts to a file and read them back. Further explanation is - given with \c AddressWidget. + The last function in \c {TableModel}, \c getContacts() returns the + QList object that holds all the contacts in the address + book. We use this function later to obtain the list of contacts to + check for existing entries, write the contacts to a file and read + them back. Further explanation is given with \c AddressWidget. \snippet itemviews/addressbook/tablemodel.cpp 8 @@ -250,7 +248,7 @@ Basic validation is done in the second \c addEntry() function to prevent duplicate entries in the address book. As mentioned with \c TableModel, this is part of the reason why we require the - getter method \c getList(). + getter method \c getContacts(). \snippet itemviews/addressbook/addresswidget.cpp 3 @@ -292,7 +290,7 @@ The \c writeToFile() function is used to save a file containing all the contacts in the address book. The file is saved in a - custom \c{.dat} format. The contents of the QList of \l{QPair}s + custom \c{.dat} format. The contents of the list of contacts are written to \c file using QDataStream. If the file cannot be opened, a QMessageBox is displayed with the related error message. @@ -301,7 +299,7 @@ The \c readFromFile() function loads a file containing all the contacts in the address book, previously saved using \c writeToFile(). QDataStream is used to read the contents of a - \c{.dat} file into a list of pairs and each of these is added + \c{.dat} file into a list of contacts and each of these is added using \c addEntry(). \snippet itemviews/addressbook/addresswidget.cpp 7 diff --git a/examples/widgets/itemviews/addressbook/addresswidget.cpp b/examples/widgets/itemviews/addressbook/addresswidget.cpp index cff35ad78f..9480d2ca8e 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.cpp +++ b/examples/widgets/itemviews/addressbook/addresswidget.cpp @@ -85,10 +85,7 @@ void AddressWidget::showAddEntryDialog() //! [3] void AddressWidget::addEntry(QString name, QString address) { - QList >list = table->getList(); - QPair pair(name, address); - - if (!list.contains(pair)) { + if (!table->getContacts().contains({ name, address })) { table->insertRows(0, 1, QModelIndex()); QModelIndex index = table->index(0, 0, QModelIndex()); @@ -211,18 +208,16 @@ void AddressWidget::readFromFile(const QString &fileName) return; } - QList > pairs = table->getList(); + QList contacts; QDataStream in(&file); - in >> pairs; + in >> contacts; - if (pairs.isEmpty()) { + if (contacts.isEmpty()) { QMessageBox::information(this, tr("No contacts in file"), tr("The file you are attempting to open contains no contacts.")); } else { - for (int i=0; i p = pairs.at(i); - addEntry(p.first, p.second); - } + for (const auto &contact: qAsConst(contacts)) + addEntry(contact.name, contact.address); } } //! [7] @@ -237,8 +232,7 @@ void AddressWidget::writeToFile(const QString &fileName) return; } - QList > pairs = table->getList(); QDataStream out(&file); - out << pairs; + out << table->getContacts(); } //! [6] diff --git a/examples/widgets/itemviews/addressbook/tablemodel.cpp b/examples/widgets/itemviews/addressbook/tablemodel.cpp index d701ef3223..674e312753 100644 --- a/examples/widgets/itemviews/addressbook/tablemodel.cpp +++ b/examples/widgets/itemviews/addressbook/tablemodel.cpp @@ -56,10 +56,10 @@ TableModel::TableModel(QObject *parent) { } -TableModel::TableModel(QList > pairs, QObject *parent) +TableModel::TableModel(QList contacts, QObject *parent) : QAbstractTableModel(parent) + , contacts(contacts) { - listOfPairs = pairs; } //! [0] @@ -67,7 +67,7 @@ TableModel::TableModel(QList > pairs, QObject *parent) int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return listOfPairs.size(); + return contacts.size(); } int TableModel::columnCount(const QModelIndex &parent) const @@ -83,16 +83,16 @@ QVariant TableModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - if (index.row() >= listOfPairs.size() || index.row() < 0) + if (index.row() >= contacts.size() || index.row() < 0) return QVariant(); if (role == Qt::DisplayRole) { - QPair pair = listOfPairs.at(index.row()); + const auto &contact = contacts.at(index.row()); if (index.column() == 0) - return pair.first; + return contact.name; else if (index.column() == 1) - return pair.second; + return contact.address; } return QVariant(); } @@ -126,10 +126,8 @@ bool TableModel::insertRows(int position, int rows, const QModelIndex &index) Q_UNUSED(index); beginInsertRows(QModelIndex(), position, position + rows - 1); - for (int row = 0; row < rows; ++row) { - QPair pair(" ", " "); - listOfPairs.insert(position, pair); - } + for (int row = 0; row < rows; ++row) + contacts.insert(position, { QString(), QString() }); endInsertRows(); return true; @@ -142,9 +140,8 @@ bool TableModel::removeRows(int position, int rows, const QModelIndex &index) Q_UNUSED(index); beginRemoveRows(QModelIndex(), position, position + rows - 1); - for (int row = 0; row < rows; ++row) { - listOfPairs.removeAt(position); - } + for (int row = 0; row < rows; ++row) + contacts.removeAt(position); endRemoveRows(); return true; @@ -157,16 +154,16 @@ bool TableModel::setData(const QModelIndex &index, const QVariant &value, int ro if (index.isValid() && role == Qt::EditRole) { int row = index.row(); - QPair p = listOfPairs.value(row); + auto contact = contacts.value(row); if (index.column() == 0) - p.first = value.toString(); + contact.name = value.toString(); else if (index.column() == 1) - p.second = value.toString(); + contact.address = value.toString(); else return false; - listOfPairs.replace(row, p); + contacts.replace(row, contact); emit(dataChanged(index, index)); return true; @@ -187,8 +184,8 @@ Qt::ItemFlags TableModel::flags(const QModelIndex &index) const //! [7] //! [8] -QList< QPair > TableModel::getList() +QList TableModel::getContacts() const { - return listOfPairs; + return contacts; } //! [8] diff --git a/examples/widgets/itemviews/addressbook/tablemodel.h b/examples/widgets/itemviews/addressbook/tablemodel.h index 9a669c508d..1004a35d31 100644 --- a/examples/widgets/itemviews/addressbook/tablemodel.h +++ b/examples/widgets/itemviews/addressbook/tablemodel.h @@ -53,16 +53,37 @@ #include #include -#include //! [0] + +struct Contact +{ + QString name; + QString address; + + bool operator==(const Contact &other) const + { + return name == other.name && address == other.address; + } +}; + +inline QDataStream &operator<<(QDataStream &stream, const Contact &contact) +{ + return stream << contact.name << contact.address; +} + +inline QDataStream &operator>>(QDataStream &stream, Contact &contact) +{ + return stream >> contact.name >> contact.address; +} + class TableModel : public QAbstractTableModel { Q_OBJECT public: TableModel(QObject *parent = 0); - TableModel(QList > listofPairs, QObject *parent = 0); + TableModel(QList contacts, QObject *parent = 0); int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; @@ -72,10 +93,10 @@ public: bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; - QList > getList(); + QList getContacts() const; private: - QList > listOfPairs; + QList contacts; }; //! [0] -- cgit v1.2.3 From c5b7a3c922ef7dcd7d3c670ea1dd318e27d53d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 3 Oct 2017 12:57:07 +0200 Subject: Windows: Fix inability to have two topmost windows Task-number: QTBUG-63621 Change-Id: I4ee6885d19907bff553149bef9efcffb209eb1f5 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 98749cd417..e60f62e4a5 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -695,7 +695,7 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang { if (!hwnd) return; - UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE; + UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER; if (frameChange) swpFlags |= SWP_FRAMECHANGED; if (topLevel) { -- cgit v1.2.3 From c4cf90b1f739c47383672de3d66b1d9d5427f5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 9 Oct 2017 14:57:46 +0200 Subject: Fix redirecting POST for HTTP 307 and 308 All POST requests that were redirected would previously turn into GET requests. This does not follow the standard for HTTP codes 307 and 308. Task-number: QTBUG-63142 Change-Id: Ibd25a9566066e589670a9bc34e5dc5111f8139d5 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/access/qhttpmultipart.cpp | 2 + .../access/qhttpnetworkconnectionchannel.cpp | 8 +- src/network/access/qnetworkreplyhttpimpl.cpp | 7 +- .../access/qnetworkreply/tst_qnetworkreply.cpp | 152 ++++++++++++++++++++- 4 files changed, 164 insertions(+), 5 deletions(-) diff --git a/src/network/access/qhttpmultipart.cpp b/src/network/access/qhttpmultipart.cpp index 5c704efeef..870e71ba1e 100644 --- a/src/network/access/qhttpmultipart.cpp +++ b/src/network/access/qhttpmultipart.cpp @@ -483,6 +483,8 @@ bool QHttpMultiPartIODevice::isSequential() const bool QHttpMultiPartIODevice::reset() { + // Reset QIODevice's data + QIODevice::reset(); for (int a = 0; a < multiPart->parts.count(); a++) if (!multiPart->parts[a].d->reset()) return false; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index e7bb8e6619..17520d0f4c 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -560,8 +560,14 @@ void QHttpNetworkConnectionChannel::handleStatus() if (redirectUrl.isValid()) reply->setRedirectUrl(redirectUrl); - if (qobject_cast(connection)) + if ((statusCode == 307 || statusCode == 308) && !resetUploadData()) { + // Couldn't reset the upload data, which means it will be unable to POST the data - + // this would lead to a long wait until it eventually failed and then retried. + // Instead of doing that we fail here instead, resetUploadData will already have emitted + // a ContentReSendError, so we're done. + } else if (qobject_cast(connection)) { QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + } break; } case 401: // auth required diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 9756b43108..89d552f431 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1115,10 +1115,15 @@ QNetworkAccessManager::Operation QNetworkReplyHttpImplPrivate::getRedirectOperat switch (currentOp) { case QNetworkAccessManager::HeadOperation: return QNetworkAccessManager::HeadOperation; + case QNetworkAccessManager::PostOperation: + // We MUST keep using POST when being redirected with 307 or 308. + if (statusCode == 307 || statusCode == 308) + return QNetworkAccessManager::PostOperation; + break; default: break; } - // For now, we're always returning GET for anything other than HEAD + // Use GET for everything else. return QNetworkAccessManager::GetOperation; } diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index d236ef0490..d22850ba4e 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -491,6 +491,10 @@ private Q_SLOTS: void ioHttpRedirect_data(); void ioHttpRedirect(); void ioHttpRedirectFromLocalToRemote(); + void ioHttpRedirectPost_data(); + void ioHttpRedirectPost(); + void ioHttpRedirectMultipartPost_data(); + void ioHttpRedirectMultipartPost(); #ifndef QT_NO_SSL void putWithServerClosingConnectionImmediately(); #endif @@ -542,7 +546,7 @@ static void setupSslServer(QSslSocket* serverSocket) } #endif -// Does not work for POST/PUT! +// Does not work for PUT! Limited support for POST. class MiniHttpServer: public QTcpServer { Q_OBJECT @@ -557,6 +561,10 @@ public: bool multiple; int totalConnections; + bool hasContent = false; + int contentRead = 0; + int contentLength = 0; + MiniHttpServer(const QByteArray &data, bool ssl = false, QThread *thread = 0, bool useipv6 = false) : dataToTransmit(data), doClose(true), doSsl(ssl), ipv6(useipv6), multiple(false), totalConnections(0) @@ -633,6 +641,18 @@ private: this, SLOT(slotError(QAbstractSocket::SocketError))); } + void parseContentLength() + { + int index = receivedData.indexOf("Content-Length:"); + index += sizeof("Content-Length:") - 1; + const auto end = std::find(receivedData.cbegin() + index, receivedData.cend(), '\r'); + auto num = receivedData.mid(index, std::distance(receivedData.cbegin() + index, end)); + bool ok; + contentLength = num.toInt(&ok); + if (!ok) + contentLength = -1; + } + private slots: #ifndef QT_NO_SSL void slotSslErrors(const QList& errors) @@ -654,12 +674,20 @@ public slots: { Q_ASSERT(!client.isNull()); receivedData += client->readAll(); - int doubleEndlPos = receivedData.indexOf("\r\n\r\n"); + const int doubleEndlPos = receivedData.indexOf("\r\n\r\n"); if (doubleEndlPos != -1) { + const int endOfHeader = doubleEndlPos + 4; + hasContent = receivedData.startsWith("POST"); + if (hasContent && contentLength == 0) + parseContentLength(); + contentRead = receivedData.length() - endOfHeader; + if (hasContent && contentRead < contentLength) + return; + // multiple requests incoming. remove the bytes of the current one if (multiple) - receivedData.remove(0, doubleEndlPos+4); + receivedData.remove(0, endOfHeader); reply(); } @@ -8518,6 +8546,124 @@ void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() QCOMPARE(reply->readAll(), reference.readAll()); } +void tst_QNetworkReply::ioHttpRedirectPost_data() +{ + QTest::addColumn("status"); + QTest::addColumn("data"); + QTest::addColumn("contentType"); + + QByteArray data; + data = "hello world"; + QTest::addRow("307") << "307 Temporary Redirect" << data << "text/plain"; + QString permanentRedirect = "308 Permanent Redirect"; + QTest::addRow("308") << permanentRedirect << data << "text/plain"; + + // Some data from ::putToFile_data + data = ""; + QTest::newRow("empty") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray("abcd\0\1\2\abcd",12); + QTest::newRow("with-nul") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray(4097, '\4'); + QTest::newRow("4k+1") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray(128*1024+1, '\177'); + QTest::newRow("128k+1") << permanentRedirect << data << "application/octet-stream"; + + data = QByteArray(2*1024*1024+1, '\177'); + QTest::newRow("2MB+1") << permanentRedirect << data << "application/octet-stream"; +} + +void tst_QNetworkReply::ioHttpRedirectPost() +{ + QFETCH(QString, status); + QFETCH(QByteArray, data); + QFETCH(QString, contentType); + + QUrl targetUrl("http://" + QtNetworkSettings::serverName() + "/qtest/cgi-bin/md5sum.cgi"); + + QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n" + "Content-Type: text/plain\r\n" + "location: %2\r\n" + "\r\n").arg(status, targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1()); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, contentType); + auto oldRedirectPolicy = manager.redirectPolicy(); + manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); + + QNetworkReplyPtr reply(manager.post(request, data)); + // Restore previous policy: + manager.setRedirectPolicy(oldRedirectPolicy); + + QCOMPARE(waitForFinish(reply), int(Success)); + QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex()); +} + +void tst_QNetworkReply::ioHttpRedirectMultipartPost_data() +{ + postToHttpMultipart_data(); +} + +void tst_QNetworkReply::ioHttpRedirectMultipartPost() +{ + // Note: This code is heavily based on postToHttpMultipart + QFETCH(QUrl, url); + + static QSet boundaries; + + QNetworkReplyPtr reply; + + QFETCH(QHttpMultiPart *, multiPart); + QFETCH(QByteArray, expectedReplyData); + QFETCH(QByteArray, contentType); + + QString redirectReply = tempRedirectReplyStr().arg(url.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1()); + QUrl redirectUrl("http://localhost/"); + redirectUrl.setPort(redirectServer.serverPort()); + QNetworkRequest request(redirectUrl); + + // Restore policy when we leave this scope: + struct PolicyRestorer + { + QNetworkAccessManager &qnam; + QNetworkRequest::RedirectPolicy policy; + PolicyRestorer(QNetworkAccessManager &qnam) + : qnam(qnam), policy(qnam.redirectPolicy()) + { qnam.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy); } + ~PolicyRestorer() { qnam.setRedirectPolicy(policy); } + } policyRestorer(manager); + + // hack for testing the setting of the content-type header by hand: + if (contentType == "custom") { + QByteArray contentType("multipart/custom; boundary=\"" + multiPart->boundary() + "\""); + request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); + } + + QVERIFY2(! boundaries.contains(multiPart->boundary()), "boundary '" + multiPart->boundary() + "' has been created twice"); + boundaries.insert(multiPart->boundary()); + + RUN_REQUEST(runMultipartRequest(request, reply, multiPart, "POST")); + multiPart->deleteLater(); + + QCOMPARE(reply->url(), url); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); // 200 OK + + QVERIFY(multiPart->boundary().count() > 20); // check that there is randomness after the "boundary_.oOo._" string + QVERIFY(multiPart->boundary().count() < 70); + QByteArray replyData = reply->readAll(); + + expectedReplyData.prepend("content type: multipart/" + contentType + "; boundary=\"" + multiPart->boundary() + "\"\n"); +// QEXPECT_FAIL("nested", "the server does not understand nested multipart messages", Continue); // see above + QCOMPARE(replyData, expectedReplyData); +} + #ifndef QT_NO_SSL class PutWithServerClosingConnectionImmediatelyHandler: public QObject -- cgit v1.2.3 From dc03ac15b074716cd1afdda2442c78c7583cf730 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Oct 2017 15:23:05 +0200 Subject: QTabletEvent/manual widgets test: Port to C++ 11 Change-Id: If5ebb45ce286d6a96c9f8bfe1fac70661d065460 Reviewed-by: Shawn Rutledge --- tests/manual/qtabletevent/regular_widgets/main.cpp | 48 +++++++++------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp index fd3c385b97..a43ea22b0f 100644 --- a/tests/manual/qtabletevent/regular_widgets/main.cpp +++ b/tests/manual/qtabletevent/regular_widgets/main.cpp @@ -63,46 +63,36 @@ class EventReportWidget : public QWidget { Q_OBJECT public: - EventReportWidget(); + EventReportWidget() { startTimer(1000); } public slots: void clearPoints() { m_points.clear(); update(); } signals: - void stats(QString s); + void stats(QString s, int timeOut = 0); protected: - void mouseDoubleClickEvent(QMouseEvent *event) { outputMouseEvent(event); } - void mouseMoveEvent(QMouseEvent *event) { outputMouseEvent(event); } - void mousePressEvent(QMouseEvent *event) { outputMouseEvent(event); } - void mouseReleaseEvent(QMouseEvent *event) { outputMouseEvent(event); } + void mouseDoubleClickEvent(QMouseEvent *event) override { outputMouseEvent(event); } + void mouseMoveEvent(QMouseEvent *event) override { outputMouseEvent(event); } + void mousePressEvent(QMouseEvent *event) override { outputMouseEvent(event); } + void mouseReleaseEvent(QMouseEvent *event) override { outputMouseEvent(event); } - void tabletEvent(QTabletEvent *); + void tabletEvent(QTabletEvent *) override; - void paintEvent(QPaintEvent *); - void timerEvent(QTimerEvent *); + void paintEvent(QPaintEvent *) override; + void timerEvent(QTimerEvent *) override; private: void outputMouseEvent(QMouseEvent *event); - bool m_lastIsMouseMove; - bool m_lastIsTabletMove; - Qt::MouseButton m_lastButton; + bool m_lastIsMouseMove = false; + bool m_lastIsTabletMove = false; + Qt::MouseButton m_lastButton = Qt::NoButton; QVector m_points; - int m_tabletMoveCount; - int m_paintEventCount; + int m_tabletMoveCount = 0; + int m_paintEventCount = 0; }; -EventReportWidget::EventReportWidget() - : m_lastIsMouseMove(false) - , m_lastIsTabletMove(false) - , m_lastButton(Qt::NoButton) - , m_tabletMoveCount(0) - , m_paintEventCount(0) -{ - startTimer(1000); -} - void EventReportWidget::paintEvent(QPaintEvent *) { QPainter p(this); @@ -114,7 +104,7 @@ void EventReportWidget::paintEvent(QPaintEvent *) p.setPen(Qt::white); QPainterPath ellipse; ellipse.addEllipse(0, 0, halfLineSpacing * 5, halfLineSpacing); - foreach (const TabletPoint &t, m_points) { + for (const TabletPoint &t : qAsConst(m_points)) { if (geom.contains(t.pos)) { QPainterPath pp; pp.addEllipse(t.pos, halfLineSpacing, halfLineSpacing); @@ -218,10 +208,10 @@ int main(int argc, char *argv[]) EventReportWidget *widget = new EventReportWidget; widget->setMinimumSize(640, 480); QMenu *fileMenu = mainWindow.menuBar()->addMenu("File"); - QObject::connect(fileMenu->addAction("Clear"), SIGNAL(triggered()), widget, SLOT(clearPoints())); - QObject::connect(widget, SIGNAL(stats(QString)), mainWindow.statusBar(), SLOT(showMessage(QString))); - QAction *quitAction = fileMenu->addAction("Quit"); - QObject::connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + fileMenu->addAction("Clear", widget, &EventReportWidget::clearPoints); + QObject::connect(widget, &EventReportWidget::stats, + mainWindow.statusBar(), &QStatusBar::showMessage); + QAction *quitAction = fileMenu->addAction("Quit", qApp, &QCoreApplication::quit); quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); mainWindow.setCentralWidget(widget); mainWindow.show(); -- cgit v1.2.3 From 3760bc759045c58c548b8f6b8a0a9c1efaa90cd4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Oct 2017 15:24:00 +0200 Subject: QTabletEvent/manual widgets test: Fix reporting of proximity events Proximit events are sent to the QGuiApplication, catch them via event filter. Change-Id: I7f896e7d9f5c90347b9e3c708feb69abd1c5fc95 Reviewed-by: Shawn Rutledge --- tests/manual/qtabletevent/regular_widgets/main.cpp | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp index a43ea22b0f..339d1d3633 100644 --- a/tests/manual/qtabletevent/regular_widgets/main.cpp +++ b/tests/manual/qtabletevent/regular_widgets/main.cpp @@ -59,6 +59,25 @@ struct TabletPoint qreal angle; }; +class ProximityEventFilter : public QObject +{ +public: + explicit ProximityEventFilter(QObject *parent) : QObject(parent) { } + + bool eventFilter(QObject *, QEvent *event) override + { + switch (event->type()) { + case QEvent::TabletEnterProximity: + case QEvent::TabletLeaveProximity: + qDebug() << event; + break; + default: + break; + } + return false; + } +}; + class EventReportWidget : public QWidget { Q_OBJECT @@ -149,10 +168,6 @@ void EventReportWidget::tabletEvent(QTabletEvent *event) QWidget::tabletEvent(event); bool isMove = false; switch (event->type()) { - case QEvent::TabletEnterProximity: - case QEvent::TabletLeaveProximity: - qDebug() << "proximity" << event; - break; case QEvent::TabletMove: m_points.push_back(TabletPoint(event->pos(), TabletMove, m_lastButton, event->pointerType(), event->pressure(), event->rotation())); update(); @@ -203,6 +218,7 @@ void EventReportWidget::timerEvent(QTimerEvent *) int main(int argc, char *argv[]) { QApplication app(argc, argv); + app.installEventFilter(new ProximityEventFilter(&app)); QMainWindow mainWindow; mainWindow.setWindowTitle(QString::fromLatin1("Tablet Test %1").arg(QT_VERSION_STR)); EventReportWidget *widget = new EventReportWidget; -- cgit v1.2.3 From 3fe74b76fd0eaf39d4c6681e2edca5adbf107883 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 7 Aug 2017 20:52:11 -0700 Subject: QHostInfo: Make getaddrinfo() mandatory All systems must implement it by now. If there's any system still without it, that means it has no IPv6 support, so they can disable QtNetwork entirely. [ChangeLog][Deprecation Notice] Starting with Qt 5.10, IPv6 support is mandatory for all platforms. Systems without proper IPv6 support, such as the getaddrinfo() function or the proper socket address structures, will not be able to build QtNetwork anymore. Change-Id: I3868166e5efc45538544fffd14d8c28046f9191b Reviewed-by: Edward Welbourne --- src/network/configure.json | 32 +--- src/network/kernel/qhostinfo_unix.cpp | 50 ------- src/network/kernel/qhostinfo_win.cpp | 161 ++++++--------------- src/network/socket/qnet_unix_p.h | 10 -- tests/auto/network/kernel/qhostinfo/BLACKLIST | 6 + .../network/kernel/qhostinfo/tst_qhostinfo.cpp | 15 +- .../tst_network_remote_stresstest.cpp | 2 +- .../network_stresstest/tst_network_stresstest.cpp | 2 +- 8 files changed, 55 insertions(+), 223 deletions(-) create mode 100644 tests/auto/network/kernel/qhostinfo/BLACKLIST diff --git a/src/network/configure.json b/src/network/configure.json index b1c943de6f..d46fbfc101 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -89,31 +89,6 @@ }, "tests": { - "getaddrinfo": { - "label": "getaddrinfo()", - "type": "compile", - "test": { - "head": [ - "#include ", - "#include ", - "#ifdef __MINGW32__", - "# include ", - "# include ", - "#else", - "# include ", - "# include ", - "# include ", - "#endif" - ], - "main": [ - "addrinfo *res = 0;", - "(void) getaddrinfo(\"foo\", 0, 0, &res);", - "freeaddrinfo(res);", - "gai_strerror(0);" - ] - }, - "use": "network" - }, "getifaddrs": { "label": "getifaddrs()", "type": "compile", @@ -170,11 +145,6 @@ "emitIf": "config.darwin", "output": [ "feature", "privateFeature" ] }, - "getaddrinfo": { - "label": "getaddrinfo()", - "condition": "tests.getaddrinfo", - "output": [ "feature" ] - }, "getifaddrs": { "label": "getifaddrs()", "condition": "tests.getifaddrs", @@ -337,7 +307,7 @@ For example: "args": "corewlan", "condition": "config.darwin" }, - "getaddrinfo", "getifaddrs", "ipv6ifname", "libproxy", + "getifaddrs", "ipv6ifname", "libproxy", { "type": "feature", "args": "securetransport", diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 9a24938284..8d2cffc304 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -66,10 +66,6 @@ # include #endif -#if defined (QT_NO_GETADDRINFO) -static QBasicMutex getHostByNameMutex; -#endif - QT_BEGIN_NAMESPACE // Almost always the same. If not, specify in qplatformdefs.h. @@ -150,7 +146,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) QHostAddress address; if (address.setAddress(hostName)) { // Reverse lookup -#if !defined (QT_NO_GETADDRINFO) sockaddr_in sa4; sockaddr_in6 sa6; sockaddr *sa = 0; @@ -173,12 +168,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) char hbuf[NI_MAXHOST]; if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) results.setHostName(QString::fromLatin1(hbuf)); -#else - in_addr_t inetaddr = qt_safe_inet_addr(hostName.toLatin1().constData()); - struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET); - if (ent) - results.setHostName(QString::fromLatin1(ent->h_name)); -#endif if (results.hostName().isEmpty()) results.setHostName(address.toString()); @@ -197,7 +186,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) return results; } -#if !defined (QT_NO_GETADDRINFO) // Call getaddrinfo, and place all IPv4 addresses at the start and // the IPv6 addresses at the end of the address list in results. addrinfo *res = 0; @@ -264,39 +252,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) results.setErrorString(QString::fromLocal8Bit(gai_strerror(result))); } -#else - // Fall back to gethostbyname for platforms that don't define - // getaddrinfo. gethostbyname does not support IPv6, and it's not - // reentrant on all platforms. For now this is okay since we only - // use one QHostInfoAgent, but if more agents are introduced, locking - // must be provided. - QMutexLocker locker(&getHostByNameMutex); - hostent *result = gethostbyname(aceHostname.constData()); - if (result) { - if (result->h_addrtype == AF_INET) { - QList addresses; - for (char **p = result->h_addr_list; *p != 0; p++) { - QHostAddress addr; - addr.setAddress(ntohl(*((quint32 *)*p))); - if (!addresses.contains(addr)) - addresses.prepend(addr); - } - results.setAddresses(addresses); - } else { - results.setError(QHostInfo::UnknownError); - results.setErrorString(tr("Unknown address type")); - } -#if !defined(Q_OS_VXWORKS) - } else if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA - || h_errno == NO_ADDRESS) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host not found")); -#endif - } else { - results.setError(QHostInfo::UnknownError); - results.setErrorString(tr("Unknown error")); - } -#endif // !defined (QT_NO_GETADDRINFO) #if defined(QHOSTINFO_DEBUG) if (results.error() != QHostInfo::NoError) { @@ -339,11 +294,6 @@ QString QHostInfo::localDomainName() if (local_res_init && local_res) { // using thread-unsafe version -#if defined(QT_NO_GETADDRINFO) - // We have to call res_init to be sure that _res was initialized - // So, for systems without getaddrinfo (which is thread-safe), we lock the mutex too - QMutexLocker locker(&getHostByNameMutex); -#endif local_res_init(); QString domainName = QUrl::fromAce(local_res->defdname); if (domainName.isEmpty()) diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index 9e5d556f2b..bea24b0af2 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -50,50 +50,12 @@ QT_BEGIN_NAMESPACE //#define QHOSTINFO_DEBUG -// Older SDKs do not include the addrinfo struct declaration, so we -// include a copy of it here. -struct qt_addrinfo -{ - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - char *ai_canonname; - sockaddr *ai_addr; - qt_addrinfo *ai_next; -}; - //### #define QT_SOCKLEN_T int #ifndef NI_MAXHOST // already defined to 1025 in ws2tcpip.h? #define NI_MAXHOST 1024 #endif -typedef int (__stdcall *getnameinfoProto)(const sockaddr *, QT_SOCKLEN_T, const char *, DWORD, const char *, DWORD, int); -typedef int (__stdcall *getaddrinfoProto)(const char *, const char *, const qt_addrinfo *, qt_addrinfo **); -typedef int (__stdcall *freeaddrinfoProto)(qt_addrinfo *); -static getnameinfoProto local_getnameinfo = 0; -static getaddrinfoProto local_getaddrinfo = 0; -static freeaddrinfoProto local_freeaddrinfo = 0; - -static bool resolveLibraryInternal() -{ - // Attempt to resolve getaddrinfo(); without it we'll have to fall - // back to gethostbyname(), which has no IPv6 support. -#if defined (Q_OS_WINRT) - local_getaddrinfo = (getaddrinfoProto) &getaddrinfo; - local_freeaddrinfo = (freeaddrinfoProto) &freeaddrinfo; - local_getnameinfo = (getnameinfoProto) getnameinfo; -#else - local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo"); - local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); - local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); -#endif - return true; -} -Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) - static void translateWSAError(int error, QHostInfo *results) { switch (error) { @@ -114,49 +76,39 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) { QSysInfo::machineHostName(); // this initializes ws2_32.dll - // Load res_init on demand. - resolveLibrary(); - QHostInfo results; #if defined(QHOSTINFO_DEBUG) qDebug("QHostInfoAgent::fromName(): looking up \"%s\" (IPv6 support is %s)", hostName.toLatin1().constData(), - (local_getaddrinfo && local_freeaddrinfo) ? "enabled" : "disabled"); + (getaddrinfo && freeaddrinfo) ? "enabled" : "disabled"); #endif QHostAddress address; if (address.setAddress(hostName)) { // Reverse lookup - if (local_getnameinfo) { - sockaddr_in sa4; - sockaddr_in6 sa6; - sockaddr *sa; - QT_SOCKLEN_T saSize; - if (address.protocol() == QAbstractSocket::IPv4Protocol) { - sa = (sockaddr *)&sa4; - saSize = sizeof(sa4); - memset(&sa4, 0, sizeof(sa4)); - sa4.sin_family = AF_INET; - sa4.sin_addr.s_addr = htonl(address.toIPv4Address()); - } else { - sa = (sockaddr *)&sa6; - saSize = sizeof(sa6); - memset(&sa6, 0, sizeof(sa6)); - sa6.sin6_family = AF_INET6; - memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr)); - } - - char hbuf[NI_MAXHOST]; - if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) - results.setHostName(QString::fromLatin1(hbuf)); + sockaddr_in sa4; + sockaddr_in6 sa6; + sockaddr *sa; + QT_SOCKLEN_T saSize; + if (address.protocol() == QAbstractSocket::IPv4Protocol) { + sa = (sockaddr *)&sa4; + saSize = sizeof(sa4); + memset(&sa4, 0, sizeof(sa4)); + sa4.sin_family = AF_INET; + sa4.sin_addr.s_addr = htonl(address.toIPv4Address()); } else { - unsigned long addr = inet_addr(hostName.toLatin1().constData()); - struct hostent *ent = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); - if (ent) - results.setHostName(QString::fromLatin1(ent->h_name)); + sa = (sockaddr *)&sa6; + saSize = sizeof(sa6); + memset(&sa6, 0, sizeof(sa6)); + sa6.sin6_family = AF_INET6; + memcpy(&sa6.sin6_addr, address.toIPv6Address().c, sizeof(sa6.sin6_addr)); } + char hbuf[NI_MAXHOST]; + if (getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) + results.setHostName(QString::fromLatin1(hbuf)); + if (results.hostName().isEmpty()) results.setHostName(address.toString()); results.setAddresses(QList() << address); @@ -172,64 +124,35 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) return results; } - if (local_getaddrinfo && local_freeaddrinfo) { - // Call getaddrinfo, and place all IPv4 addresses at the start - // and the IPv6 addresses at the end of the address list in - // results. - qt_addrinfo *res; - int err = local_getaddrinfo(aceHostname.constData(), 0, 0, &res); - if (err == 0) { - QList addresses; - for (qt_addrinfo *p = res; p != 0; p = p->ai_next) { - switch (p->ai_family) { - case AF_INET: { - QHostAddress addr; - addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr)); - if (!addresses.contains(addr)) - addresses.append(addr); - } - break; - case AF_INET6: { - QHostAddress addr; - addr.setAddress(((sockaddr_in6 *) p->ai_addr)->sin6_addr.s6_addr); - if (!addresses.contains(addr)) - addresses.append(addr); - } - break; - default: - results.setError(QHostInfo::UnknownError); - results.setErrorString(tr("Unknown address type")); - } + addrinfo *res; + int err = getaddrinfo(aceHostname.constData(), 0, 0, &res); + if (err == 0) { + QList addresses; + for (addrinfo *p = res; p != 0; p = p->ai_next) { + switch (p->ai_family) { + case AF_INET: { + QHostAddress addr; + addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr)); + if (!addresses.contains(addr)) + addresses.append(addr); + } + break; + case AF_INET6: { + QHostAddress addr; + addr.setAddress(((sockaddr_in6 *) p->ai_addr)->sin6_addr.s6_addr); + if (!addresses.contains(addr)) + addresses.append(addr); } - results.setAddresses(addresses); - local_freeaddrinfo(res); - } else { - translateWSAError(WSAGetLastError(), &results); - } - } else { - // Fall back to gethostbyname, which only supports IPv4. - hostent *ent = gethostbyname(aceHostname.constData()); - if (ent) { - char **p; - QList addresses; - switch (ent->h_addrtype) { - case AF_INET: - for (p = ent->h_addr_list; *p != 0; p++) { - long *ip4Addr = (long *) *p; - QHostAddress temp; - temp.setAddress(ntohl(*ip4Addr)); - addresses << temp; - } break; default: results.setError(QHostInfo::UnknownError); results.setErrorString(tr("Unknown address type")); - break; } - results.setAddresses(addresses); - } else { - translateWSAError(WSAGetLastError(), &results); } + results.setAddresses(addresses); + freeaddrinfo(res); + } else { + translateWSAError(WSAGetLastError(), &results); } #if defined(QHOSTINFO_DEBUG) diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 73d7ec2e77..5359872f96 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -174,16 +174,6 @@ static inline int qt_safe_ioctl(int sockfd, unsigned long request, T arg) #endif } -// VxWorks' headers do not specify any const modifiers -static inline in_addr_t qt_safe_inet_addr(const char *cp) -{ -#ifdef Q_OS_VXWORKS - return ::inet_addr((char *) cp); -#else - return ::inet_addr(cp); -#endif -} - static inline int qt_safe_sendmsg(int sockfd, const struct msghdr *msg, int flags) { #ifdef MSG_NOSIGNAL diff --git a/tests/auto/network/kernel/qhostinfo/BLACKLIST b/tests/auto/network/kernel/qhostinfo/BLACKLIST new file mode 100644 index 0000000000..87c5fe991f --- /dev/null +++ b/tests/auto/network/kernel/qhostinfo/BLACKLIST @@ -0,0 +1,6 @@ +# These tests fail due to a DNS server issue +# (this is not a Qt bug) +[lookupIPv6:a-plus-aaaa] +windows ci +[blockingLookup:a-plus-aaaa] +windows ci diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index cb7e66bad4..caf8145c19 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -64,14 +64,10 @@ #include #include "private/qhostinfo_p.h" -#if !defined(QT_NO_GETADDRINFO) -# include -# if defined(Q_OS_UNIX) +#include +#if defined(Q_OS_UNIX) # include -# endif -# if !defined(Q_OS_WIN) # include -# endif #endif #include "../../../network-settings.h" @@ -204,15 +200,13 @@ void tst_QHostInfo::initTestCase() ipv6Available = true; } -// HP-UX 11i does not support IPv6 reverse lookups. -#if !defined(QT_NO_GETADDRINFO) && !(defined(Q_OS_HPUX) && defined(__ia64)) // check if the system getaddrinfo can do IPv6 lookups struct addrinfo hint, *result = 0; memset(&hint, 0, sizeof hint); hint.ai_family = AF_UNSPEC; -# ifdef AI_ADDRCONFIG +#ifdef AI_ADDRCONFIG hint.ai_flags = AI_ADDRCONFIG; -# endif +#endif int res = getaddrinfo("::1", "80", &hint, &result); if (res == 0) { @@ -224,7 +218,6 @@ void tst_QHostInfo::initTestCase() ipv6LookupsAvailable = true; } } -#endif // run each testcase with and without test enabled QTest::addColumn("cache"); diff --git a/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp b/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp index 99e3d148df..f5c3bfde34 100644 --- a/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp +++ b/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp @@ -156,7 +156,7 @@ void tst_NetworkRemoteStressTest::clearManager() bool nativeLookup(const char *hostname, int port, QByteArray &buf) { -#if !defined(QT_NO_GETADDRINFO) && 0 +#if 0 addrinfo *res = 0; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); diff --git a/tests/manual/network_stresstest/tst_network_stresstest.cpp b/tests/manual/network_stresstest/tst_network_stresstest.cpp index d46703c671..03df1633d5 100644 --- a/tests/manual/network_stresstest/tst_network_stresstest.cpp +++ b/tests/manual/network_stresstest/tst_network_stresstest.cpp @@ -147,7 +147,7 @@ void tst_NetworkStressTest::clearManager() bool nativeLookup(const char *hostname, int port, QByteArray &buf) { -#if !defined(QT_NO_GETADDRINFO) && 0 +#if 0 addrinfo *res = 0; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); -- cgit v1.2.3 From 3fd641c3141b49b334dcbdb1a25649525445b724 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 18 Oct 2017 08:22:45 +0200 Subject: network: add a QT_CONFIG(bearermanagement) guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for QNetworkReplyHttpImplPrivate::startWaitForSession(). This amends 8a39384e907e830c907f73009f498c486b22bd20. Task-number: QTBUG-63847 Change-Id: Ic20a4ac3ab97ed25010e0679810ef64c3ff42c05 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkreplyhttpimpl.cpp | 2 ++ src/network/access/qnetworkreplyhttpimpl_p.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 89d552f431..fa49c8e05b 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1828,6 +1828,7 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest) #endif } +#if QT_CONFIG(bearermanagement) bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer &session) { Q_Q(QNetworkReplyHttpImpl); @@ -1853,6 +1854,7 @@ bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer &session); +#endif public: -- cgit v1.2.3 From 879f98106d5974ef19c96cb228ca032701b94556 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 24 Aug 2017 11:19:21 +0200 Subject: Revamp QtWidgets/DragAndDrop examples to C++11 Introduce nullptr and replace foreach with new C++11 range based for loops. Minor fixups of signals, file dialog usage. Apply the same changes to the ItemViews/puzzle example since it shares parts of the code with DragAndDrop/puzzle. Make some changes to both examples to that the diff of the two becomes small for easier comparison. Task-number: QTBUG-60635 Change-Id: I8af824229ebac24d6ec151eae92176d227695490 Reviewed-by: Venugopal Shivashankar Reviewed-by: Gatis Paeglis --- .../draganddrop/draggableicons/dragwidget.h | 2 +- .../draganddrop/draggabletext/dragwidget.cpp | 4 +- .../widgets/draganddrop/draggabletext/dragwidget.h | 2 +- examples/widgets/draganddrop/dropsite/droparea.h | 4 +- .../draganddrop/dropsite/dropsitewindow.cpp | 6 +- .../draganddrop/fridgemagnets/dragwidget.cpp | 2 +- .../widgets/draganddrop/fridgemagnets/dragwidget.h | 2 +- examples/widgets/draganddrop/puzzle/main.cpp | 4 +- examples/widgets/draganddrop/puzzle/mainwindow.cpp | 23 +++++--- examples/widgets/draganddrop/puzzle/mainwindow.h | 4 +- examples/widgets/draganddrop/puzzle/pieceslist.cpp | 2 +- examples/widgets/draganddrop/puzzle/pieceslist.h | 4 +- .../widgets/draganddrop/puzzle/puzzlewidget.cpp | 65 +++++++++++----------- examples/widgets/draganddrop/puzzle/puzzlewidget.h | 15 +++-- examples/widgets/itemviews/puzzle/main.cpp | 2 +- examples/widgets/itemviews/puzzle/mainwindow.cpp | 31 ++++++----- examples/widgets/itemviews/puzzle/mainwindow.h | 2 +- examples/widgets/itemviews/puzzle/puzzlewidget.cpp | 57 ++++++++----------- examples/widgets/itemviews/puzzle/puzzlewidget.h | 16 ++++-- 19 files changed, 125 insertions(+), 122 deletions(-) diff --git a/examples/widgets/draganddrop/draggableicons/dragwidget.h b/examples/widgets/draganddrop/draggableicons/dragwidget.h index 18be074b61..98e623a5e3 100644 --- a/examples/widgets/draganddrop/draggableicons/dragwidget.h +++ b/examples/widgets/draganddrop/draggableicons/dragwidget.h @@ -62,7 +62,7 @@ QT_END_NAMESPACE class DragWidget : public QFrame { public: - DragWidget(QWidget *parent = 0); + explicit DragWidget(QWidget *parent = nullptr); protected: void dragEnterEvent(QDragEnterEvent *event) override; diff --git a/examples/widgets/draganddrop/draggabletext/dragwidget.cpp b/examples/widgets/draganddrop/draggabletext/dragwidget.cpp index fb169b953b..2135ba2ef9 100644 --- a/examples/widgets/draganddrop/draggabletext/dragwidget.cpp +++ b/examples/widgets/draganddrop/draggabletext/dragwidget.cpp @@ -123,7 +123,7 @@ void DragWidget::dropEvent(QDropEvent *event) hotSpot.setY(hotSpotPos.last().toInt()); } - foreach (const QString &piece, pieces) { + for (const QString &piece : pieces) { QLabel *newLabel = createDragLabel(piece, this); newLabel->move(position - hotSpot); newLabel->show(); @@ -141,7 +141,7 @@ void DragWidget::dropEvent(QDropEvent *event) } else { event->ignore(); } - foreach (QWidget *widget, findChildren()) { + for (QWidget *widget : findChildren()) { if (!widget->isVisible()) widget->deleteLater(); } diff --git a/examples/widgets/draganddrop/draggabletext/dragwidget.h b/examples/widgets/draganddrop/draggabletext/dragwidget.h index 24d1f6f5c7..38abb0ceb8 100644 --- a/examples/widgets/draganddrop/draggabletext/dragwidget.h +++ b/examples/widgets/draganddrop/draggabletext/dragwidget.h @@ -61,7 +61,7 @@ QT_END_NAMESPACE class DragWidget : public QWidget { public: - DragWidget(QWidget *parent = 0); + explicit DragWidget(QWidget *parent = nullptr); protected: void dragEnterEvent(QDragEnterEvent *event) override; diff --git a/examples/widgets/draganddrop/dropsite/droparea.h b/examples/widgets/draganddrop/dropsite/droparea.h index 5b6e209dfa..ab1de8ea44 100644 --- a/examples/widgets/draganddrop/dropsite/droparea.h +++ b/examples/widgets/draganddrop/dropsite/droparea.h @@ -63,13 +63,13 @@ class DropArea : public QLabel Q_OBJECT public: - DropArea(QWidget *parent = 0); + explicit DropArea(QWidget *parent = nullptr); public slots: void clear(); signals: - void changed(const QMimeData *mimeData = 0); + void changed(const QMimeData *mimeData = nullptr); //! [DropArea header part1] //! [DropArea header part2] diff --git a/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp b/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp index dc865ac171..28a42ee614 100644 --- a/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp +++ b/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp @@ -88,8 +88,8 @@ DropSiteWindow::DropSiteWindow() buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole); buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); - connect(quitButton, &QAbstractButton::pressed, this, &QWidget::close); - connect(clearButton, &QAbstractButton::pressed, dropArea, &DropArea::clear); + connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close); + connect(clearButton, &QAbstractButton::clicked, dropArea, &DropArea::clear); //! [constructor part4] //! [constructor part5] @@ -113,7 +113,7 @@ void DropSiteWindow::updateFormatsTable(const QMimeData *mimeData) //! [updateFormatsTable() part1] //! [updateFormatsTable() part2] - foreach (QString format, mimeData->formats()) { + for (const QString &format : mimeData->formats()) { QTableWidgetItem *formatItem = new QTableWidgetItem(format); formatItem->setFlags(Qt::ItemIsEnabled); formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft); diff --git a/examples/widgets/draganddrop/fridgemagnets/dragwidget.cpp b/examples/widgets/draganddrop/fridgemagnets/dragwidget.cpp index b185b2900d..451b53f623 100644 --- a/examples/widgets/draganddrop/fridgemagnets/dragwidget.cpp +++ b/examples/widgets/draganddrop/fridgemagnets/dragwidget.cpp @@ -167,7 +167,7 @@ void DragWidget::dropEvent(QDropEvent *event) QString::SkipEmptyParts); QPoint position = event->pos(); - foreach (const QString &piece, pieces) { + for (const QString &piece : pieces) { DragLabel *newLabel = new DragLabel(piece, this); newLabel->move(position); newLabel->show(); diff --git a/examples/widgets/draganddrop/fridgemagnets/dragwidget.h b/examples/widgets/draganddrop/fridgemagnets/dragwidget.h index 104e500134..ff513a33d8 100644 --- a/examples/widgets/draganddrop/fridgemagnets/dragwidget.h +++ b/examples/widgets/draganddrop/fridgemagnets/dragwidget.h @@ -62,7 +62,7 @@ QT_END_NAMESPACE class DragWidget : public QWidget { public: - DragWidget(QWidget *parent = 0); + explicit DragWidget(QWidget *parent = nullptr); protected: void dragEnterEvent(QDragEnterEvent *event) override; diff --git a/examples/widgets/draganddrop/puzzle/main.cpp b/examples/widgets/draganddrop/puzzle/main.cpp index 0bf65a89c5..d013bf078d 100644 --- a/examples/widgets/draganddrop/puzzle/main.cpp +++ b/examples/widgets/draganddrop/puzzle/main.cpp @@ -48,10 +48,10 @@ ** ****************************************************************************/ -#include - #include "mainwindow.h" +#include + int main(int argc, char *argv[]) { Q_INIT_RESOURCE(puzzle); diff --git a/examples/widgets/draganddrop/puzzle/mainwindow.cpp b/examples/widgets/draganddrop/puzzle/mainwindow.cpp index 806133583a..1914519c68 100644 --- a/examples/widgets/draganddrop/puzzle/mainwindow.cpp +++ b/examples/widgets/draganddrop/puzzle/mainwindow.cpp @@ -67,12 +67,19 @@ MainWindow::MainWindow(QWidget *parent) void MainWindow::openImage() { - const QString fileName = - QFileDialog::getOpenFileName(this, tr("Open Image"), QString(), - tr("Image Files (*.png *.jpg *.bmp)")); - - if (!fileName.isEmpty()) - loadImage(fileName); + const QString directory = + QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath()); + QFileDialog dialog(this, tr("Open Image"), directory); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + QStringList mimeTypeFilters; + for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes()) + mimeTypeFilters.append(mimeTypeName); + mimeTypeFilters.sort(); + dialog.setMimeTypeFilters(mimeTypeFilters); + dialog.selectMimeTypeFilter("image/jpeg"); + if (dialog.exec() == QDialog::Accepted) + loadImage(dialog.selectedFiles().constFirst()); } void MainWindow::loadImage(const QString &fileName) @@ -101,8 +108,8 @@ void MainWindow::setCompleted() void MainWindow::setupPuzzle() { int size = qMin(puzzleImage.width(), puzzleImage.height()); - puzzleImage = puzzleImage.copy((puzzleImage.width() - size)/2, - (puzzleImage.height() - size)/2, size, size).scaled(puzzleWidget->width(), + puzzleImage = puzzleImage.copy((puzzleImage.width() - size) / 2, + (puzzleImage.height() - size) / 2, size, size).scaled(puzzleWidget->width(), puzzleWidget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); piecesList->clear(); diff --git a/examples/widgets/draganddrop/puzzle/mainwindow.h b/examples/widgets/draganddrop/puzzle/mainwindow.h index e43f52cab8..626612ebe8 100644 --- a/examples/widgets/draganddrop/puzzle/mainwindow.h +++ b/examples/widgets/draganddrop/puzzle/mainwindow.h @@ -51,8 +51,8 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include #include +#include class PiecesList; class PuzzleWidget; @@ -65,7 +65,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); void loadImage(const QString &path); public slots: diff --git a/examples/widgets/draganddrop/puzzle/pieceslist.cpp b/examples/widgets/draganddrop/puzzle/pieceslist.cpp index 30890ecf9b..7846d37ed2 100644 --- a/examples/widgets/draganddrop/puzzle/pieceslist.cpp +++ b/examples/widgets/draganddrop/puzzle/pieceslist.cpp @@ -101,7 +101,7 @@ void PiecesList::dropEvent(QDropEvent *event) } } -void PiecesList::addPiece(QPixmap pixmap, QPoint location) +void PiecesList::addPiece(const QPixmap &pixmap, const QPoint &location) { QListWidgetItem *pieceItem = new QListWidgetItem(this); pieceItem->setIcon(QIcon(pixmap)); diff --git a/examples/widgets/draganddrop/puzzle/pieceslist.h b/examples/widgets/draganddrop/puzzle/pieceslist.h index b67d2bdaf7..a508d17d72 100644 --- a/examples/widgets/draganddrop/puzzle/pieceslist.h +++ b/examples/widgets/draganddrop/puzzle/pieceslist.h @@ -58,8 +58,8 @@ class PiecesList : public QListWidget Q_OBJECT public: - explicit PiecesList(int pieceSize, QWidget *parent = 0); - void addPiece(QPixmap pixmap, QPoint location); + explicit PiecesList(int pieceSize, QWidget *parent = nullptr); + void addPiece(const QPixmap &pixmap, const QPoint &location); static QString puzzleMimeType() { return QStringLiteral("image/x-puzzle-piece"); } diff --git a/examples/widgets/draganddrop/puzzle/puzzlewidget.cpp b/examples/widgets/draganddrop/puzzle/puzzlewidget.cpp index 2093d7820c..72f2662bce 100644 --- a/examples/widgets/draganddrop/puzzle/puzzlewidget.cpp +++ b/examples/widgets/draganddrop/puzzle/puzzlewidget.cpp @@ -66,9 +66,7 @@ PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent) void PuzzleWidget::clear() { - pieceLocations.clear(); - piecePixmaps.clear(); - pieceRects.clear(); + pieces.clear(); highlightedRect = QRect(); inPlace = 0; update(); @@ -95,7 +93,7 @@ void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event) QRect updateRect = highlightedRect.united(targetSquare(event->pos())); if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType()) - && pieceRects.indexOf(targetSquare(event->pos())) == -1) { + && findPiece(targetSquare(event->pos())) == -1) { highlightedRect = targetSquare(event->pos()); event->setDropAction(Qt::MoveAction); @@ -111,26 +109,23 @@ void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event) void PuzzleWidget::dropEvent(QDropEvent *event) { if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType()) - && pieceRects.indexOf(targetSquare(event->pos())) == -1) { + && findPiece(targetSquare(event->pos())) == -1) { QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType()); QDataStream dataStream(&pieceData, QIODevice::ReadOnly); - QRect square = targetSquare(event->pos()); - QPixmap pixmap; - QPoint location; - dataStream >> pixmap >> location; + Piece piece; + piece.rect = targetSquare(event->pos()); + dataStream >> piece.pixmap >> piece.location; - pieceLocations.append(location); - piecePixmaps.append(pixmap); - pieceRects.append(square); + pieces.append(piece); highlightedRect = QRect(); - update(square); + update(piece.rect); event->setDropAction(Qt::MoveAction); event->accept(); - if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) { + if (piece.location == piece.rect.topLeft() / pieceSize()) { inPlace++; if (inPlace == 25) emit puzzleCompleted(); @@ -141,21 +136,26 @@ void PuzzleWidget::dropEvent(QDropEvent *event) } } +int PuzzleWidget::findPiece(const QRect &pieceRect) const +{ + for (int i = 0, size = pieces.size(); i < size; ++i) { + if (pieces.at(i).rect == pieceRect) + return i; + } + return -1; +} + void PuzzleWidget::mousePressEvent(QMouseEvent *event) { QRect square = targetSquare(event->pos()); - int found = pieceRects.indexOf(square); + const int found = findPiece(square); if (found == -1) return; - QPoint location = pieceLocations[found]; - QPixmap pixmap = piecePixmaps[found]; - pieceLocations.removeAt(found); - piecePixmaps.removeAt(found); - pieceRects.removeAt(found); + Piece piece = pieces.takeAt(found); - if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) + if (piece.location == square.topLeft() / pieceSize()) inPlace--; update(square); @@ -163,7 +163,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event) QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); - dataStream << pixmap << location; + dataStream << piece.pixmap << piece.location; QMimeData *mimeData = new QMimeData; mimeData->setData(PiecesList::puzzleMimeType(), itemData); @@ -171,23 +171,20 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event) QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->setHotSpot(event->pos() - square.topLeft()); - drag->setPixmap(pixmap); + drag->setPixmap(piece.pixmap); - if (!(drag->exec(Qt::MoveAction) == Qt::MoveAction)) { - pieceLocations.insert(found, location); - piecePixmaps.insert(found, pixmap); - pieceRects.insert(found, square); + if (drag->exec(Qt::MoveAction) != Qt::MoveAction) { + pieces.insert(found, piece); update(targetSquare(event->pos())); - if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) + if (piece.location == square.topLeft() / pieceSize()) inPlace++; } } void PuzzleWidget::paintEvent(QPaintEvent *event) { - QPainter painter; - painter.begin(this); + QPainter painter(this); painter.fillRect(event->rect(), Qt::white); if (highlightedRect.isValid()) { @@ -196,14 +193,14 @@ void PuzzleWidget::paintEvent(QPaintEvent *event) painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1)); } - for (int i = 0; i < pieceRects.size(); ++i) - painter.drawPixmap(pieceRects[i], piecePixmaps[i]); - painter.end(); + for (const Piece &piece : pieces) + painter.drawPixmap(piece.rect, piece.pixmap); } const QRect PuzzleWidget::targetSquare(const QPoint &position) const { - return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize()); + return QRect(position / pieceSize() * pieceSize(), + QSize(pieceSize(), pieceSize())); } int PuzzleWidget::pieceSize() const diff --git a/examples/widgets/draganddrop/puzzle/puzzlewidget.h b/examples/widgets/draganddrop/puzzle/puzzlewidget.h index 7dcb7dd497..40dd654af6 100644 --- a/examples/widgets/draganddrop/puzzle/puzzlewidget.h +++ b/examples/widgets/draganddrop/puzzle/puzzlewidget.h @@ -51,9 +51,9 @@ #ifndef PUZZLEWIDGET_H #define PUZZLEWIDGET_H -#include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -67,7 +67,7 @@ class PuzzleWidget : public QWidget Q_OBJECT public: - explicit PuzzleWidget(int imageSize, QWidget *parent = 0); + explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr); void clear(); int pieceSize() const; @@ -85,11 +85,16 @@ protected: void paintEvent(QPaintEvent *event) override; private: + struct Piece { + QPixmap pixmap; + QRect rect; + QPoint location; + }; + + int findPiece(const QRect &pieceRect) const; const QRect targetSquare(const QPoint &position) const; - QList piecePixmaps; - QList pieceRects; - QList pieceLocations; + QVector pieces; QRect highlightedRect; int inPlace; int m_ImageSize; diff --git a/examples/widgets/itemviews/puzzle/main.cpp b/examples/widgets/itemviews/puzzle/main.cpp index 1f5e7ee9b2..d013bf078d 100644 --- a/examples/widgets/itemviews/puzzle/main.cpp +++ b/examples/widgets/itemviews/puzzle/main.cpp @@ -58,7 +58,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); MainWindow window; - window.loadImage(":/images/example.jpg"); + window.loadImage(QStringLiteral(":/images/example.jpg")); window.show(); return app.exec(); } diff --git a/examples/widgets/itemviews/puzzle/mainwindow.cpp b/examples/widgets/itemviews/puzzle/mainwindow.cpp index 282a7b477b..8ee5cf659e 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.cpp +++ b/examples/widgets/itemviews/puzzle/mainwindow.cpp @@ -69,12 +69,19 @@ MainWindow::MainWindow(QWidget *parent) void MainWindow::openImage() { - const QString fileName = - QFileDialog::getOpenFileName(this, - tr("Open Image"), QString(), - tr("Image Files (*.png *.jpg *.bmp)")); - if (!fileName.isEmpty()) - loadImage(fileName); + const QString directory = + QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath()); + QFileDialog dialog(this, tr("Open Image"), directory); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + dialog.setFileMode(QFileDialog::ExistingFile); + QStringList mimeTypeFilters; + for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes()) + mimeTypeFilters.append(mimeTypeName); + mimeTypeFilters.sort(); + dialog.setMimeTypeFilters(mimeTypeFilters); + dialog.selectMimeTypeFilter("image/jpeg"); + if (dialog.exec() == QDialog::Accepted) + loadImage(dialog.selectedFiles().constFirst()); } void MainWindow::loadImage(const QString &fileName) @@ -83,7 +90,7 @@ void MainWindow::loadImage(const QString &fileName) if (!newImage.load(fileName)) { QMessageBox::warning(this, tr("Open Image"), tr("The image file could not be loaded."), - QMessageBox::Cancel); + QMessageBox::Close); return; } puzzleImage = newImage; @@ -117,19 +124,15 @@ void MainWindow::setupMenus() { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - QAction *openAction = fileMenu->addAction(tr("&Open...")); + QAction *openAction = fileMenu->addAction(tr("&Open..."), this, &MainWindow::openImage); openAction->setShortcuts(QKeySequence::Open); - QAction *exitAction = fileMenu->addAction(tr("E&xit")); + QAction *exitAction = fileMenu->addAction(tr("E&xit"), qApp, &QCoreApplication::quit); exitAction->setShortcuts(QKeySequence::Quit); QMenu *gameMenu = menuBar()->addMenu(tr("&Game")); - QAction *restartAction = gameMenu->addAction(tr("&Restart")); - - connect(openAction, &QAction::triggered, this, &MainWindow::openImage); - connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit); - connect(restartAction, &QAction::triggered, this, &MainWindow::setupPuzzle); + gameMenu->addAction(tr("&Restart"), this, &MainWindow::setupPuzzle); } void MainWindow::setupWidgets() diff --git a/examples/widgets/itemviews/puzzle/mainwindow.h b/examples/widgets/itemviews/puzzle/mainwindow.h index 7e27dc6f3a..208d3a5281 100644 --- a/examples/widgets/itemviews/puzzle/mainwindow.h +++ b/examples/widgets/itemviews/puzzle/mainwindow.h @@ -65,7 +65,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); public slots: void openImage(); diff --git a/examples/widgets/itemviews/puzzle/puzzlewidget.cpp b/examples/widgets/itemviews/puzzle/puzzlewidget.cpp index 78931a95a3..06968da80f 100644 --- a/examples/widgets/itemviews/puzzle/puzzlewidget.cpp +++ b/examples/widgets/itemviews/puzzle/puzzlewidget.cpp @@ -62,9 +62,7 @@ PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent) void PuzzleWidget::clear() { - pieceLocations.clear(); - piecePixmaps.clear(); - pieceRects.clear(); + pieces.clear(); highlightedRect = QRect(); inPlace = 0; update(); @@ -110,23 +108,20 @@ void PuzzleWidget::dropEvent(QDropEvent *event) && findPiece(targetSquare(event->pos())) == -1) { QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece"); - QDataStream stream(&pieceData, QIODevice::ReadOnly); - QRect square = targetSquare(event->pos()); - QPixmap pixmap; - QPoint location; - stream >> pixmap >> location; + QDataStream dataStream(&pieceData, QIODevice::ReadOnly); + Piece piece; + piece.rect = targetSquare(event->pos()); + dataStream >> piece.pixmap >> piece.location; - pieceLocations.append(location); - piecePixmaps.append(pixmap); - pieceRects.append(square); + pieces.append(piece); highlightedRect = QRect(); - update(square); + update(piece.rect); event->setDropAction(Qt::MoveAction); event->accept(); - if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) { + if (piece.location == piece.rect.topLeft() / pieceSize()) { inPlace++; if (inPlace == 25) emit puzzleCompleted(); @@ -139,8 +134,8 @@ void PuzzleWidget::dropEvent(QDropEvent *event) int PuzzleWidget::findPiece(const QRect &pieceRect) const { - for (int i = 0; i < pieceRects.size(); ++i) { - if (pieceRect == pieceRects[i]) + for (int i = 0, size = pieces.size(); i < size; ++i) { + if (pieces.at(i).rect == pieceRect) return i; } return -1; @@ -154,13 +149,9 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event) if (found == -1) return; - QPoint location = pieceLocations[found]; - QPixmap pixmap = piecePixmaps[found]; - pieceLocations.removeAt(found); - piecePixmaps.removeAt(found); - pieceRects.removeAt(found); + Piece piece = pieces.takeAt(found); - if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) + if (piece.location == square.topLeft() / pieceSize()) inPlace--; update(square); @@ -168,7 +159,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event) QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); - dataStream << pixmap << location; + dataStream << piece.pixmap << piece.location; QMimeData *mimeData = new QMimeData; mimeData->setData("image/x-puzzle-piece", itemData); @@ -176,23 +167,20 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event) QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->setHotSpot(event->pos() - square.topLeft()); - drag->setPixmap(pixmap); + drag->setPixmap(piece.pixmap); - if (drag->start(Qt::MoveAction) == 0) { - pieceLocations.insert(found, location); - piecePixmaps.insert(found, pixmap); - pieceRects.insert(found, square); + if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) { + pieces.insert(found, piece); update(targetSquare(event->pos())); - if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) + if (piece.location == QPoint(square.x() / pieceSize(), square.y() / pieceSize())) inPlace++; } } void PuzzleWidget::paintEvent(QPaintEvent *event) { - QPainter painter; - painter.begin(this); + QPainter painter(this); painter.fillRect(event->rect(), Qt::white); if (highlightedRect.isValid()) { @@ -201,15 +189,14 @@ void PuzzleWidget::paintEvent(QPaintEvent *event) painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1)); } - for (int i = 0; i < pieceRects.size(); ++i) { - painter.drawPixmap(pieceRects[i], piecePixmaps[i]); - } - painter.end(); + for (const Piece &piece : pieces) + painter.drawPixmap(piece.rect, piece.pixmap); } const QRect PuzzleWidget::targetSquare(const QPoint &position) const { - return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize()); + return QRect(position / pieceSize() * pieceSize(), + QSize(pieceSize(), pieceSize())); } int PuzzleWidget::pieceSize() const diff --git a/examples/widgets/itemviews/puzzle/puzzlewidget.h b/examples/widgets/itemviews/puzzle/puzzlewidget.h index 137e0b7162..40dd654af6 100644 --- a/examples/widgets/itemviews/puzzle/puzzlewidget.h +++ b/examples/widgets/itemviews/puzzle/puzzlewidget.h @@ -51,9 +51,9 @@ #ifndef PUZZLEWIDGET_H #define PUZZLEWIDGET_H -#include -#include #include +#include +#include #include QT_BEGIN_NAMESPACE @@ -67,7 +67,7 @@ class PuzzleWidget : public QWidget Q_OBJECT public: - explicit PuzzleWidget(int imageSize, QWidget *parent = 0); + explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr); void clear(); int pieceSize() const; @@ -85,12 +85,16 @@ protected: void paintEvent(QPaintEvent *event) override; private: + struct Piece { + QPixmap pixmap; + QRect rect; + QPoint location; + }; + int findPiece(const QRect &pieceRect) const; const QRect targetSquare(const QPoint &position) const; - QList piecePixmaps; - QList pieceRects; - QList pieceLocations; + QVector pieces; QRect highlightedRect; int inPlace; int m_ImageSize; -- cgit v1.2.3 From 6889626164b743d991e8b1681bbaa56949c0ca74 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 12 Oct 2017 14:40:29 +0200 Subject: Doc: replace screenshot widgets tutorial with more updated version Change-Id: I2b4fcd02c13fcd6569ebf035197da361aba40afd Reviewed-by: Venugopal Shivashankar --- src/widgets/doc/images/widgets-tutorial-toplevel.png | Bin 6087 -> 2496 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/widgets/doc/images/widgets-tutorial-toplevel.png b/src/widgets/doc/images/widgets-tutorial-toplevel.png index a80d13c50d..bf7879f5aa 100644 Binary files a/src/widgets/doc/images/widgets-tutorial-toplevel.png and b/src/widgets/doc/images/widgets-tutorial-toplevel.png differ -- cgit v1.2.3 From a92cf24f9c56833b14915a0f7d34c6d565fa03d4 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 12 Oct 2017 13:12:56 +0200 Subject: Doc: correct filename png files qpushbutton.h:55: warning: Missing image: windows-pushbutton.jpg widgets.qdoc:28: warning: Missing image: windowsvista-treeview.png Change-Id: I2ebf2aa809f8d532f597624f6ed2f9d636e860a6 Reviewed-by: Venugopal Shivashankar --- src/widgets/doc/src/widgets-and-layouts/widgets.qdoc | 2 +- src/widgets/widgets/qpushbutton.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc b/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc index 700a4479fd..3b134a3f96 100644 --- a/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc @@ -62,7 +62,7 @@ \table \row - \li \image windowsvista-treeview.png + \li \image windows-treeview.png \li \image fusion-calendarwidget.png \li \image qundoview.png \endtable diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp index caf175e6ff..8187b8f35c 100644 --- a/src/widgets/widgets/qpushbutton.cpp +++ b/src/widgets/widgets/qpushbutton.cpp @@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE \ingroup basicwidgets \inmodule QtWidgets - \image windows-pushbutton.jpg + \image windows-pushbutton.png The push button, or command button, is perhaps the most commonly used widget in any graphical user interface. Push (click) a button -- cgit v1.2.3 From 19ae653f7f774d62480915dc1a7bd26e1757e8f3 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 12 Oct 2017 12:40:02 +0200 Subject: Doc: qtwidgets index page: wrong name for image file windowsvista-treeview.png --> windows-treeview.png Change-Id: I19ccec1ff5fadf2107ad47109d65f170df4b0505 Reviewed-by: Venugopal Shivashankar --- src/widgets/doc/src/qtwidgets-index.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/doc/src/qtwidgets-index.qdoc b/src/widgets/doc/src/qtwidgets-index.qdoc index c05b16a0a0..7cd1c8d735 100644 --- a/src/widgets/doc/src/qtwidgets-index.qdoc +++ b/src/widgets/doc/src/qtwidgets-index.qdoc @@ -118,7 +118,7 @@ interfaces which use lists and tables are structured to separate the data and view using models, views, and delegates. - \image windowsvista-treeview.png + \image windows-treeview.png \section1 Graphics View -- cgit v1.2.3 From 03c3ba1815c1fe71261c6ba194188f1c52fadb53 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 12 Sep 2017 16:35:27 +0200 Subject: Doc: improve screenshots Application Example Task-number: QTBUG-60635 Change-Id: I963ecbf0b386e9f5d41b4c15e2af883cf21d3c83 Reviewed-by: Richard Moe Gustavsen --- doc/src/images/application-menus.png | Bin 8864 -> 30529 bytes doc/src/images/application.png | Bin 19503 -> 39984 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/images/application-menus.png b/doc/src/images/application-menus.png index 1815a2a4e3..44ac9ca75f 100644 Binary files a/doc/src/images/application-menus.png and b/doc/src/images/application-menus.png differ diff --git a/doc/src/images/application.png b/doc/src/images/application.png index bff37369a4..b5fd4597dc 100644 Binary files a/doc/src/images/application.png and b/doc/src/images/application.png differ -- cgit v1.2.3 From a1c985c10bf2212e911777568c6e344456293a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Thu, 12 Oct 2017 10:58:06 +0200 Subject: QAbstractItemView: Make it easier to drop above and below items Before this patch a very accurate drop position below or above an index was needed. Therefore it was not that easy to do. This patch increases the above/below area to be about 18% of the item (still leaving the most space for the item). An average user will likely be 2-3x faster with dropping below or above (while not losing much when dropping on items). [ChangeLog][QtWidgets][ItemViews] Made it easier to drop above and below items. Change-Id: I47f0f80c76878c17ebf3f93d0a0cc82755971c2a Reviewed-by: Andy Shaw Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qabstractitemview.cpp | 2 +- tests/manual/widgets/itemviews/qtreewidget/main.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 15e6b0eb99..23e727e670 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2194,7 +2194,7 @@ QAbstractItemViewPrivate::position(const QPoint &pos, const QRect &rect, const Q { QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport; if (!overwrite) { - const int margin = 2; + const int margin = qBound(2, qRound(qreal(rect.height()) / 5.5), 12); if (pos.y() - rect.top() < margin) { r = QAbstractItemView::AboveItem; } else if (rect.bottom() - pos.y() < margin) { diff --git a/tests/manual/widgets/itemviews/qtreewidget/main.cpp b/tests/manual/widgets/itemviews/qtreewidget/main.cpp index 5d129101fd..fb72c404a5 100644 --- a/tests/manual/widgets/itemviews/qtreewidget/main.cpp +++ b/tests/manual/widgets/itemviews/qtreewidget/main.cpp @@ -95,6 +95,18 @@ public: item5sl.append("Approver"); /* QTreeWidgetItem *item4 =*/ new QTreeWidgetItem(item4, item5sl); + treeWidget->setDragEnabled(true); + treeWidget->viewport()->setAcceptDrops(true); + treeWidget->setDragDropMode(QAbstractItemView::InternalMove); + + for (int u = 0; u < 12; ++u) { + const QString username = QString("Anonymous User %1").arg(u + 1); + QStringList info; + info << username << username << QString::number(u + 1) << QStringLiteral("Test user"); + new QTreeWidgetItem(item4, info); + } + + treeWidget->expandAll(); treeWidget->setColumnCount(item2sl.size()); QStringList itemInfo("First Name"); itemInfo.append("Last Name"); @@ -133,6 +145,7 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); ExampleDlg d; + d.resize(d.sizeHint() * 3); d.show(); app.exec(); } -- cgit v1.2.3 From 05219136761ddf69b0b26599ce35866c98e26010 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Oct 2017 15:48:41 +0200 Subject: QTabletEvent: Add doc note about Windows drivers Recent drivers no longer contain wintab32.dll, point out a version that still has it. Change-Id: I4125a0af3c11ab739f8006b91f58899aeed54458 Reviewed-by: Andre de la Rocha Reviewed-by: Gabriel de Dietrich Reviewed-by: Shawn Rutledge --- src/gui/kernel/qevent.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index a7848b5485..06d52aa78d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -2330,6 +2330,13 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const cursor and touchpad. Qt recognizes these by their names. Otherwise, if the tablet is configured to use the evdev driver, there will be only one device and applications may not be able to distinguish the stylus from the eraser. + + \section1 Notes for Windows Users + + Tablet support currently requires the WACOM windows driver providing the DLL + \c{wintab32.dll} to be installed. It is contained in older packages, + for example \c{pentablet_5.3.5-3.exe}. + */ /*! -- cgit v1.2.3 From 37afba28b152b9c5cb1dfaa9a89df1e8103cde26 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 17 Oct 2017 12:01:12 +0200 Subject: QTableGenerator: Fix handling of illegal characters in fromBase8 again Change-Id: Iaee19f71e5b74b0d43b628739039ca3c2be60cd0 Reviewed-by: Lars Knoll --- src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 809aa68365..b5a0a5bbeb 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -520,7 +520,7 @@ static inline int fromBase8(const char *s, const char *end) { int result = 0; while (*s && s != end) { - if (*s <= '0' || *s >= '7') + if (*s < '0' || *s > '7') return 0; result *= 8; result += *s - '0'; -- cgit v1.2.3 From f13e75345d035ec906846aaa3540454787edbd3f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 19 Oct 2017 11:55:32 +0700 Subject: Cocoa QPA: Remove usage of OBJECTIVE_SOURCES Change-Id: I5924ab0ddb442624f5aeeef023428be228348707 Reviewed-by: Jake Petroules --- src/plugins/platforms/cocoa/cocoa.pro | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 13e59906ca..5a00e1b7ec 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -1,6 +1,6 @@ TARGET = qcocoa -OBJECTIVE_SOURCES += main.mm \ +SOURCES += main.mm \ qcocoaintegration.mm \ qcocoatheme.mm \ qcocoabackingstore.mm \ @@ -30,9 +30,8 @@ OBJECTIVE_SOURCES += main.mm \ qcocoasystemtrayicon.mm \ qcocoaintrospection.mm \ qcocoakeymapper.mm \ - qcocoamimetypes.mm - -SOURCES += messages.cpp + qcocoamimetypes.mm \ + messages.cpp HEADERS += qcocoaintegration.h \ qcocoatheme.h \ @@ -66,7 +65,7 @@ HEADERS += qcocoaintegration.h \ qcocoamimetypes.h qtConfig(opengl.*) { - OBJECTIVE_SOURCES += qcocoaglcontext.mm + SOURCES += qcocoaglcontext.mm HEADERS += qcocoaglcontext.h } @@ -85,7 +84,7 @@ CONFIG += no_app_extension_api_only qtHaveModule(widgets) { QT_FOR_CONFIG += widgets - OBJECTIVE_SOURCES += \ + SOURCES += \ qpaintengine_mac.mm \ qprintengine_mac.mm \ qcocoaprintersupport.mm \ -- cgit v1.2.3 From d57a7c41712f8627a462d893329dc3f0dbb52d32 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 28 Sep 2017 23:54:32 +0300 Subject: MinGW: Globally define WINVER and _WIN32_WINNT to enable Windows 7 API Change-Id: I637b33ba6d05f40486d8da927ae5cc5148299348 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_build_config.prf | 3 +++ src/corelib/corelib.pro | 2 -- src/corelib/global/qt_windows.h | 4 ++-- src/network/kernel/kernel.pri | 2 -- src/network/kernel/qnetworkinterface_win.cpp | 1 + src/plugins/bearer/generic/qgenericengine.cpp | 6 +++--- src/plugins/bearer/platformdefs_win.h | 1 + src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 4 +++- src/plugins/platforms/windows/qwindowsmousehandler.cpp | 4 ++-- src/plugins/platforms/windows/qwindowstheme.cpp | 4 ++-- src/widgets/kernel/win.pri | 2 -- tests/auto/network/kernel/qhostinfo/qhostinfo.pro | 3 --- 12 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 150d2b2cc3..76e1d15319 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -100,6 +100,9 @@ unix: CONFIG += explicitlib # By default we want tests on macOS to be built as standalone executables macos: CONFIG += testcase_no_bundle +# Override MinGW's definition in _mingw.h +mingw: DEFINES += WINVER=0x0601 _WIN32_WINNT=0x0601 + defineTest(qtBuildPart) { bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS) isEmpty(bp): bp = $$QT_BUILD_PARTS diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 7f018bdb94..6dc11e1a4d 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -50,8 +50,6 @@ win32 { mingw { # otherwise mingw headers do not declare common functions like putenv CONFIG -= strict_c++ - # Override MinGW's definition in _mingw.h - DEFINES += WINVER=0x600 _WIN32_WINNT=0x0600 } LIBS_PRIVATE += -lws2_32 !winrt { diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index bc48104edc..67ba27f072 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -48,10 +48,10 @@ #if defined(Q_CC_MINGW) // mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation # ifndef WINVER -# define WINVER 0x600 +# define WINVER 0x601 # endif # ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x600 +# define _WIN32_WINNT 0x601 # endif # ifndef NTDDI_VERSION # define NTDDI_VERSION 0x06000000 diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 716f745bc9..54b61f3ad3 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -49,8 +49,6 @@ win32: { SOURCES += kernel/qdnslookup_win.cpp \ kernel/qnetworkinterface_win.cpp LIBS_PRIVATE += -ldnsapi -liphlpapi - DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600 - } else { SOURCES += kernel/qdnslookup_winrt.cpp \ kernel/qnetworkinterface_winrt.cpp diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index 8344fb04c2..64c3fa6f83 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -56,6 +56,7 @@ // (http://sourceforge.net/p/mingw-w64/mailman/message/32935366/) #include #include +#include #include #include diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp index cd3b202001..7b0aa52831 100644 --- a/src/plugins/bearer/generic/qgenericengine.cpp +++ b/src/plugins/bearer/generic/qgenericengine.cpp @@ -55,10 +55,10 @@ #if defined(Q_OS_WIN32) // PMIB_TCPTABLE2 is only available since Vista -#if _WIN32_WINNT < 0x0600 +#if _WIN32_WINNT < 0x0601 # undef _WIN32_WINNT -# define _WIN32_WINNT 0x0600 -#endif // _WIN32_WINNT < 0x0600 +# define _WIN32_WINNT 0x0601 +#endif // _WIN32_WINNT < 0x0601 #include "../platformdefs_win.h" #include #endif diff --git a/src/plugins/bearer/platformdefs_win.h b/src/plugins/bearer/platformdefs_win.h index 5a8487d868..0477dc45c3 100644 --- a/src/plugins/bearer/platformdefs_win.h +++ b/src/plugins/bearer/platformdefs_win.h @@ -45,6 +45,7 @@ #include #include #undef interface +#include #include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index c4aeb15bd1..26779f0c01 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -39,7 +39,9 @@ #define QT_NO_URL_CAST_FROM_STRING 1 -#define _WIN32_WINNT 0x0600 +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 +#endif #include "qwindowscombase.h" #include "qwindowsdialoghelpers.h" diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 2b14edc804..9544fb81f7 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -60,7 +60,7 @@ * are present in the Windows SDK's, but not in older MSVC Express * versions. */ -#if defined(Q_CC_MINGW) || !defined(TOUCHEVENTF_MOVE) +#if !defined(TOUCHEVENTF_MOVE) typedef struct tagTOUCHINPUT { LONG x; @@ -85,7 +85,7 @@ typedef TOUCHINPUT const * PCTOUCHINPUT; # define TOUCHEVENTF_PALM 0x0080 # define TOUCHINPUTMASKF_CONTACTAREA 0x0004 # define TOUCHINPUTMASKF_EXTRAINFO 0x0002 -#endif // if defined(Q_CC_MINGW) || !defined(TOUCHEVENTF_MOVE) +#endif // if !defined(TOUCHEVENTF_MOVE) QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index a1ccf1f83c..651c661d6b 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -38,9 +38,9 @@ ****************************************************************************/ // SHSTOCKICONINFO is only available since Vista -#if _WIN32_WINNT < 0x0600 +#if _WIN32_WINNT < 0x0601 # undef _WIN32_WINNT -# define _WIN32_WINNT 0x0600 +# define _WIN32_WINNT 0x0601 #endif #include "qwindowstheme.h" diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri index 7cef2d14a8..f6877b02db 100644 --- a/src/widgets/kernel/win.pri +++ b/src/widgets/kernel/win.pri @@ -3,5 +3,3 @@ INCLUDEPATH += ../3rdparty/wintab !winrt: LIBS_PRIVATE *= -lshell32 -luxtheme -ldwmapi -# Override MinGW's definition in _mingw.h -mingw: DEFINES += WINVER=0x600 _WIN32_WINNT=0x0600 diff --git a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro index 67a37faeb5..3d8457dd46 100644 --- a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro +++ b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro @@ -8,7 +8,4 @@ QT = core-private network-private testlib win32:LIBS += -lws2_32 -# needed for getaddrinfo with official MinGW -mingw:DEFINES += _WIN32_WINNT=0x0501 - winrt: WINRT_MANIFEST.capabilities += internetClientServer -- cgit v1.2.3 From 0354ba816ff479791f43226aeb30ef35086148b5 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 28 Aug 2017 08:32:47 +0300 Subject: Clean dynamic function resolving done for XP in QFileInfo tests Change-Id: I15364b1e8c4f4406fef2be68ca221a8867d0dcfa Reviewed-by: Thiago Macieira --- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 54 +++++++---------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 8945daff4a..44e79985d4 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -48,7 +48,6 @@ #endif #ifdef Q_OS_WIN #include -#include #if !defined(Q_OS_WINRT) #include #endif @@ -684,18 +683,12 @@ void tst_QFileInfo::canonicalFilePath() #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD); - PtrCreateSymbolicLink ptrCreateSymbolicLink = - (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLinkW"); - - if (!ptrCreateSymbolicLink) { - QSKIP("Symbolic links aren't supported by FS"); - } else { + { // CreateSymbolicLink can return TRUE & still fail to create the link, // the error code in that case is ERROR_PRIVILEGE_NOT_HELD (1314) SetLastError(0); const QString linkTarget = QStringLiteral("res"); - BOOL ret = ptrCreateSymbolicLink((wchar_t*)linkTarget.utf16(), (wchar_t*)m_resourcesDir.utf16(), 1); + BOOL ret = CreateSymbolicLink((wchar_t*)linkTarget.utf16(), (wchar_t*)m_resourcesDir.utf16(), 1); DWORD dwErr = GetLastError(); if (!ret) QSKIP("Symbolic links aren't supported by FS"); @@ -1443,16 +1436,6 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() QDir pwd; pwd.mkdir("target"); - QLibrary kernel32("kernel32"); - typedef BOOLEAN (WINAPI *PtrCreateSymbolicLink)(LPCWSTR, LPCWSTR, DWORD); - PtrCreateSymbolicLink createSymbolicLinkW = 0; - createSymbolicLinkW = (PtrCreateSymbolicLink) kernel32.resolve("CreateSymbolicLinkW"); - if (!createSymbolicLinkW) { - //we need at least one data set for the test not to fail when skipping _data function - QDir target("target"); - QTest::newRow("dummy") << target.path() << false << "" << target.canonicalPath(); - QSKIP("symbolic links not supported by operating system"); - } { //Directory symlinks QDir target("target"); @@ -1472,10 +1455,10 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() DWORD err = ERROR_SUCCESS ; if (!pwd.exists("abs_symlink")) - if (!createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1)) + if (!CreateSymbolicLink((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x1)) err = GetLastError(); if (err == ERROR_SUCCESS && !pwd.exists(relSymlink)) - if (!createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1)) + if (!CreateSymbolicLink((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x1)) err = GetLastError(); if (err != ERROR_SUCCESS) { wchar_t errstr[0x100]; @@ -1505,10 +1488,9 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() QString relSymlink = "rel_symlink.cpp"; QString relToRelTarget = QDir::toNativeSeparators(relativeDir.relativeFilePath(target.absoluteFilePath())); QString relToRelSymlink = "relative/rel_symlink"; - QVERIFY(pwd.exists("abs_symlink.cpp") || createSymbolicLinkW((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0)); - QVERIFY(pwd.exists(relSymlink) || createSymbolicLinkW((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0)); - QVERIFY(pwd.exists(relToRelSymlink) - || createSymbolicLinkW((wchar_t*)relToRelSymlink.utf16(), (wchar_t*)relToRelTarget.utf16(),0x0)); + QVERIFY(pwd.exists("abs_symlink.cpp") || CreateSymbolicLink((wchar_t*)absSymlink.utf16(),(wchar_t*)absTarget.utf16(),0x0)); + QVERIFY(pwd.exists(relSymlink) || CreateSymbolicLink((wchar_t*)relSymlink.utf16(),(wchar_t*)relTarget.utf16(),0x0)); + QVERIFY(pwd.exists(relToRelSymlink) || CreateSymbolicLink((wchar_t*)relToRelSymlink.utf16(), (wchar_t*)relToRelTarget.utf16(),0x0)); QTest::newRow("absolute file symlink") << absSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath(); QTest::newRow("relative file symlink") << relSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath(); QTest::newRow("relative to relative file symlink") << relToRelSymlink << true << QDir::fromNativeSeparators(absTarget) << target.canonicalFilePath(); @@ -1535,20 +1517,14 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() QTest::newRow("junction_root") << junction << false << QString() << QString(); //Mountpoint - typedef BOOLEAN (WINAPI *PtrGetVolumeNameForVolumeMountPointW)(LPCWSTR, LPWSTR, DWORD); - PtrGetVolumeNameForVolumeMountPointW getVolumeNameForVolumeMountPointW = 0; - getVolumeNameForVolumeMountPointW = (PtrGetVolumeNameForVolumeMountPointW) kernel32.resolve("GetVolumeNameForVolumeMountPointW"); - if(getVolumeNameForVolumeMountPointW) - { - wchar_t buffer[MAX_PATH]; - QString rootPath = QDir::toNativeSeparators(QDir::rootPath()); - QVERIFY(getVolumeNameForVolumeMountPointW((wchar_t*)rootPath.utf16(), buffer, MAX_PATH)); - QString rootVolume = QString::fromWCharArray(buffer); - junction = "mountpoint"; - rootVolume.replace("\\\\?\\","\\??\\"); - FileSystem::createNtfsJunction(rootVolume, junction); - QTest::newRow("mountpoint") << junction << false << QString() << QString(); - } + wchar_t buffer[MAX_PATH]; + QString rootPath = QDir::toNativeSeparators(QDir::rootPath()); + QVERIFY(GetVolumeNameForVolumeMountPoint((wchar_t*)rootPath.utf16(), buffer, MAX_PATH)); + QString rootVolume = QString::fromWCharArray(buffer); + junction = "mountpoint"; + rootVolume.replace("\\\\?\\","\\??\\"); + FileSystem::createNtfsJunction(rootVolume, junction); + QTest::newRow("mountpoint") << junction << false << QString() << QString(); } void tst_QFileInfo::ntfsJunctionPointsAndSymlinks() -- cgit v1.2.3 From ca5f5de5c9eb2bc3d2c87d6f15791f5069c645bc Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 28 Sep 2017 23:46:27 +0300 Subject: GitIgnore qvkgen Change-Id: I6f6551821ffcd73841e4b5cab5892bd17f5c70b9 Reviewed-by: Jake Petroules Reviewed-by: Oswald Buddenhagen --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4e8ce90b8e..af2afcba7f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ /src/corelib/global/qconfig_p.h /bin/qt.conf /bin/qmake +/bin/qvkgen /qmake/qmake qt*-config.h qt*-config_p.h -- cgit v1.2.3 From fc988786588bf86ebc46fdd12629efbec8ae1841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 17 Oct 2017 15:16:40 +0200 Subject: Fix cookie path matching for empty url path The path wouldn't match if the cookie's path was root ('/') and the URLs path was empty. Change-Id: I6dcd10f1fdf4f48f14e50f1b169cbdfda7005849 Reviewed-by: Thiago Macieira Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/access/qnetworkcookiejar.cpp | 2 +- .../access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 232c2b47a5..f62a03b11d 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -140,7 +140,7 @@ void QNetworkCookieJar::setAllCookies(const QList &cookieList) static inline bool isParentPath(const QString &path, const QString &reference) { - if (path.startsWith(reference)) { + if ((path.isEmpty() && reference == QLatin1String("/")) || path.startsWith(reference)) { //The cookie-path and the request-path are identical. if (path.length() == reference.length()) return true; diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index a0459021be..ed5d0c69a0 100644 --- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -340,6 +340,17 @@ void tst_QNetworkCookieJar::cookiesForUrl_data() QTest::newRow("no-match-domain-dot") << allCookies << "http://example.com" << result; result += cookieDot; QTest::newRow("match-domain-dot") << allCookies << "http://example.com." << result; + + // Root path in cookie, empty url path + allCookies.clear(); + QNetworkCookie rootCookie; + rootCookie.setName("a"); + rootCookie.setPath("/"); + rootCookie.setDomain("qt-project.org"); + allCookies += rootCookie; + result.clear(); + result += rootCookie; + QTest::newRow("root-path-match") << allCookies << "http://qt-project.org" << result; } void tst_QNetworkCookieJar::cookiesForUrl() -- cgit v1.2.3 From 6c1a2224f31be51b26634f02fc2b2cb3247a4668 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 31 Mar 2017 14:08:28 +0200 Subject: iOS: add support for adding mimetypes other than text on the clipboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A QVariant can only be converted to a QByteArray if it has user type QMetaType::QByteArray or QMetaType::QString. The way it stood, we always tried to convert the mime data to a QByteArray, and then put the result into a QVariant. This would fail if the mime data contained e.g a QPixmap. This patch will inspect what kind of data the QMimeData contains, and convert it to a QVariant using the expected API. Backport of 6d3c483 Task-number: QTBUG-57428 Task-number: QTBUG-63660 Change-Id: I09b4a94aef7b52773e1a79c468ead71b36dfbfc5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosclipboard.mm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm index ef3b453bbf..6a585c9052 100644 --- a/src/plugins/platforms/ios/qiosclipboard.mm +++ b/src/plugins/platforms/ios/qiosclipboard.mm @@ -227,7 +227,19 @@ void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) if (uti.isEmpty() || !converter->canConvert(mimeType, uti)) continue; - QByteArray byteArray = converter->convertFromMime(mimeType, mimeData->data(mimeType), uti).first(); + QVariant mimeDataAsVariant; + if (mimeData->hasImage()) { + mimeDataAsVariant = mimeData->imageData(); + } else if (mimeData->hasUrls()) { + QVariantList urlList; + for (const QUrl &url : mimeData->urls()) + urlList << url; + mimeDataAsVariant = QVariant(urlList); + } else { + mimeDataAsVariant = QVariant(mimeData->data(mimeType)); + } + + QByteArray byteArray = converter->convertFromMime(mimeType, mimeDataAsVariant, uti).first(); NSData *nsData = [NSData dataWithBytes:byteArray.constData() length:byteArray.size()]; [pbItem setValue:nsData forKey:uti.toNSString()]; break; -- cgit v1.2.3 From 02dc39fa8ee6fd9945728e12208a9e313ac4dd4b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Oct 2017 19:00:40 -0700 Subject: QBasicMutex: mark the bootstrap constructor constexpr QBasicMutex and QMutex are the same in bootstrap mode. Change-Id: Icaa86fc7b54d4b368c0efffd14eed63343ddb51b Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/thread/qmutex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h index 12987f16c3..607cc13a2f 100644 --- a/src/corelib/thread/qmutex.h +++ b/src/corelib/thread/qmutex.h @@ -251,7 +251,7 @@ class Q_CORE_EXPORT QMutex public: enum RecursionMode { NonRecursive, Recursive }; - inline explicit QMutex(RecursionMode mode = NonRecursive) Q_DECL_NOTHROW { Q_UNUSED(mode); } + inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) Q_DECL_NOTHROW { } inline void lock() Q_DECL_NOTHROW {} inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; } -- cgit v1.2.3 From c99d8532c892f72f897c9e686be75d1ebba67618 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 18 Oct 2017 14:13:18 +0700 Subject: QCocoaSystemTrayIcon: Remove unused classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both QNSMenu and QSystemTrayIconQMenu aren't referenced anywhere else, including within qcocoasystemtrayicon.mm, since the QPA backend was added. Change-Id: I632c1b230226b2d08afce7f0f0019e9f7c030ba5 Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoasystemtrayicon.mm | 31 ---------------------- 1 file changed, 31 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 6af22facf9..13e9d8809e 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -92,7 +92,6 @@ QT_USE_NAMESPACE -@class QT_MANGLE_NAMESPACE(QNSMenu); @class QT_MANGLE_NAMESPACE(QNSImageView); @interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject @@ -123,16 +122,8 @@ QT_USE_NAMESPACE -(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton; @end -@interface QT_MANGLE_NAMESPACE(QNSMenu) : NSMenu { - QPlatformMenu *qmenu; -} --(QPlatformMenu*)menu; --(id)initWithQMenu:(QPlatformMenu*)qmenu; -@end - QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem); QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView); -QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSMenu); QT_BEGIN_NAMESPACE class QSystemTrayIconSys @@ -447,26 +438,4 @@ QT_END_NAMESPACE @end -class QSystemTrayIconQMenu : public QPlatformMenu -{ -public: - void doAboutToShow() { emit aboutToShow(); } -private: - QSystemTrayIconQMenu(); -}; - -@implementation QNSMenu --(id)initWithQMenu:(QPlatformMenu*)qm { - self = [super init]; - if (self) { - self->qmenu = qm; - [self setDelegate:self]; - } - return self; -} --(QPlatformMenu*)menu { - return qmenu; -} -@end - #endif // QT_NO_SYSTEMTRAYICON -- cgit v1.2.3 From 34c879f2e1c8a371ba5af664395d87aa878d0ed0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Oct 2017 15:39:48 +0200 Subject: QNativeGestureEvent: Fix qdoc warning Rename the parameter back to 'device', fixing: src/gui/kernel/qevent.cpp:2776: warning: Undocumented parameter 'dev' in QNativeGestureEvent::QNativeGestureEvent() Amends 36af37c99c13244cac54313d38af183ef40133f5. Change-Id: I2a3f016dd6a5dda784dc851a052cb5aa1841a472 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qevent.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index abbc393c7c..1b03801ffc 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -2783,13 +2783,13 @@ Q_GLOBAL_STATIC(NativeGestureEventDataHash, g_nativeGestureEventDataHash) \a realValue is the \macos event parameter, \a sequenceId and \a intValue are the Windows event parameters. \since 5.10 */ -QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *dev, const QPointF &localPos, const QPointF &windowPos, +QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *device, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue) : QInputEvent(QEvent::NativeGesture), mGestureType(type), mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue), mSequenceId(sequenceId), mIntValue(intValue) { - g_nativeGestureEventDataHash->insert(this, dev); + g_nativeGestureEventDataHash->insert(this, device); } QNativeGestureEvent::~QNativeGestureEvent() -- cgit v1.2.3 From c05268222c654fec92dc904554797c0d17997bd6 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 19 Oct 2017 14:32:09 +0200 Subject: winrt: Fully initialize CREATEFILE2_EXTENDED_PARAMETERS struct Not properly initializing all members of the extended parameter struct will cause an "invalid handle specified" exception on use. Task-number: QTBUG-63883 Change-Id: Ic3a58df864c9e29ccbadc04bd71c18c8ef34374c Reviewed-by: Maurice Kalinowski --- src/corelib/io/qfilesystemengine_win.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 79407afefc..b01aa55756 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -628,6 +628,9 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) params.dwSize = sizeof(params); params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; params.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; + params.dwSecurityQosFlags = SECURITY_ANONYMOUS; + params.lpSecurityAttributes = NULL; + params.hTemplateFile = NULL; const HANDLE handle = CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), 0, FILE_SHARE_READ, OPEN_EXISTING, ¶ms); -- cgit v1.2.3 From dcc8aa8f4e664283bf7b900bbd07d6b570797eac Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Oct 2017 13:22:36 +0200 Subject: Windows/Direct2D QPA: Fix build with -no-accessibility Task-number: QTBUG-63876 Change-Id: Ib9216977dd495e05d032e679c2f23ffe6a6953a6 Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/direct2d/direct2d.pro | 4 +++- src/plugins/platforms/windows/windows.pro | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 224f122fc4..3fe0d5e660 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -2,9 +2,11 @@ TARGET = qdirect2d QT += \ core-private gui-private \ - eventdispatcher_support-private accessibility_support-private \ + eventdispatcher_support-private \ fontdatabase_support-private theme_support-private +qtConfig(accessibility): QT += accessibility_support-private + LIBS += -ldwmapi -ld2d1 -ld3d11 -ldwrite -lVersion -lgdi32 include(../windows/windows.pri) diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 23168c10dc..c5d76c5d1d 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -2,9 +2,11 @@ TARGET = qwindows QT += \ core-private gui-private \ - eventdispatcher_support-private accessibility_support-private \ + eventdispatcher_support-private \ fontdatabase_support-private theme_support-private +qtConfig(accessibility): QT += accessibility_support-private + LIBS += -lgdi32 -ldwmapi include(windows.pri) -- cgit v1.2.3 From 571b11d41c9dadd5ef11e4e954c16c5ca39d718e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 19 Oct 2017 13:10:28 +0200 Subject: Windows QPA: Fix build with -no-feature-tabletevent Guard #include by QT_CONFIG. Task-number: QTBUG-63874 Change-Id: I33f4a4c4fbdae3d25874ee9cdc3f1c7e1ab783e3 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscontext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index f108be96e7..cda6c99ad0 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -46,7 +46,9 @@ #include "qtwindowsglobal.h" #include "qwindowsmime.h" #include "qwindowsinputcontext.h" -#include "qwindowstabletsupport.h" +#if QT_CONFIG(tabletevent) +# include "qwindowstabletsupport.h" +#endif #include "qwindowstheme.h" #include #ifndef QT_NO_ACCESSIBILITY -- cgit v1.2.3 From 8aadfbc6572b0cbb8d435ceb7cd288c9d5cb909c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Thu, 19 Oct 2017 00:00:39 +0200 Subject: xcb: Convert synthetic mouse enter event position to native pixels Mouse position is converted from native pixels later, so we must provide native pixels for "QWindowSystemInterface::handleEnterEvent". Amends 7091be1b7999d93fe2126042161dcd1d8fd20026 Task-number: QTBUG-63865 Change-Id: I813c171f2fc1d321af702ac30eb5f2e4232e97c4 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/xcb/qxcbwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 4acc827bf6..c4649ac818 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -907,7 +907,9 @@ void QXcbWindow::hide() if (QWindow *childWindow = childWindowAt(enterWindow, cursorPos)) enterWindow = childWindow; const QPoint localPos = enterWindow->mapFromGlobal(cursorPos); - QWindowSystemInterface::handleEnterEvent(enterWindow, localPos, cursorPos); + QWindowSystemInterface::handleEnterEvent(enterWindow, + localPos * QHighDpiScaling::factor(enterWindow), + nativePos); } } } -- cgit v1.2.3 From 68092ba6c0f26f679c0a9c086e13e44557b76b11 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Oct 2017 18:46:23 -0700 Subject: QRandomGenerator: fix the timing of the closing of the Unix random fd Let's make it happen even later: at the time of QtCore's unloading from memory. This prevents issues with something using QRandomGenerator after the global static destructor would have run. Change-Id: Icaa86fc7b54d4b368c0efffd14eed56bbbb51cb6 Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qrandom.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index a7696719d1..3ae7e3bad8 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -152,15 +152,15 @@ class SystemRandom { static QBasicAtomicInt s_fdp1; // "file descriptor plus 1" static int openDevice(); + static __attribute__((destructor)) void closeDevice(); // assume GCC or a compiler able to understand GCC extensions SystemRandom() {} - ~SystemRandom(); public: enum { EfficientBufferFill = true }; static qssize_t fillBuffer(void *buffer, qssize_t count); }; QBasicAtomicInt SystemRandom::s_fdp1 = Q_BASIC_ATOMIC_INITIALIZER(0); -SystemRandom::~SystemRandom() +void SystemRandom::closeDevice() { int fd = s_fdp1.loadAcquire() - 1; if (fd >= 0) -- cgit v1.2.3 From c90d9f95d27cf12747446ce8f7ee1cefe1f0f818 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 12 Oct 2017 13:40:18 -0700 Subject: QRandomGenerator: improve floating-point random generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous version was good, just not optimal. Because the input was an unsigned 64-bit number, compilers needed to generate extra code to deal with HW instructions that only convert 64-bit signed input. And that was useless because a double uniformly distributed from 0 to 1 can only have 53 bits of randomness. The previous implementation did exactly what the Microsoft libstdc++ and libc++ implementations do. In my opinion, those implementations have an imperfect distribution, which is corrected in this commit. In those, all random input bigger than 0x20000000000000 has a different frequency compared to input below that mark. For example, both 0x20000000000000 and 0x20000000000001 produce the same result (4.8828125e-4). What's more, for the libc++ and MSVC implementations, input between 0xfffffffffffff001 and 0xffffffffffffffff results in 1.0 (probability 1 in 2⁵³), even though the Standard is very clear that the result should be strictly less than 1. GCC 7's libstdc++ doesn't have this issue, whereas the versions before would enter an infinite loop. Change-Id: Ib17dde1a1dbb49a7bba8fffd14eced3c375dd2ec Reviewed-by: Lars Knoll Reviewed-by: Edward Welbourne --- src/corelib/global/qrandom.h | 12 +++++- .../qrandomgenerator/tst_qrandomgenerator.cpp | 50 +++++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qrandom.h b/src/corelib/global/qrandom.h index 7f96cd6749..2259f2657a 100644 --- a/src/corelib/global/qrandom.h +++ b/src/corelib/global/qrandom.h @@ -62,8 +62,16 @@ public: static Q_CORE_EXPORT quint64 generate64(); static double generateDouble() { - // use get64() to get enough bits - return double(generate64()) / ((std::numeric_limits::max)() + double(1.0)); + // IEEE 754 double precision has: + // 1 bit sign + // 10 bits exponent + // 53 bits mantissa + // In order for our result to be normalized in the range [0, 1), we + // need exactly 53 bits of random data. Use generate64() to get enough. + quint64 x = generate64(); + quint64 limit = Q_UINT64_C(1) << std::numeric_limits::digits; + x >>= std::numeric_limits::digits - std::numeric_limits::digits; + return double(x) / double(limit); } static qreal bounded(qreal sup) diff --git a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp index 2195bf8ec8..d1c0c8e965 100644 --- a/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp +++ b/tests/auto/corelib/global/qrandomgenerator/tst_qrandomgenerator.cpp @@ -97,6 +97,8 @@ private slots: void generateReal_data() { generate32_data(); } void generateReal(); + void qualityReal_data() { generate32_data(); } + void qualityReal(); void seedStdRandomEngines(); void stdUniformIntDistribution_data(); @@ -445,7 +447,7 @@ void tst_QRandomGenerator::generateReal() for (int i = 0; i < 4; ++i) { QVERIFY_3TIMES([] { qreal value = QRandomGenerator::generateDouble(); - return value > 0 && value < 1 && value != RandomValueFP; + return value >= 0 && value < 1 && value != RandomValueFP; }()); } @@ -454,6 +456,52 @@ void tst_QRandomGenerator::generateReal() QVERIFY_3TIMES(QRandomGenerator::generateDouble() != QRandomGenerator::generateDouble()); } +void tst_QRandomGenerator::qualityReal() +{ + QFETCH(uint, control); + setRNGControl(control); + + enum { + SampleSize = 160, + + // Expected value: sample size times proportion of the range: + PerfectOctile = SampleSize / 8, + PerfectHalf = SampleSize / 2, + + // Variance is (1 - proportion of range) * expected; sqrt() for standard deviations. + // Should usually be within twice that and almost never outside four times: + RangeHalf = 25, // floor(4 * sqrt((1 - 0.5) * PerfectHalf)) + RangeOctile = 16 // floor(4 * sqrt((1 - 0.125) * PerfectOctile)) + }; + + double data[SampleSize]; + std::generate(std::begin(data), std::end(data), &QRandomGenerator::generateDouble); + + int aboveHalf = 0; + int belowOneEighth = 0; + int aboveSevenEighths = 0; + for (double x : data) { + aboveHalf += x >= 0.5; + belowOneEighth += x < 0.125; + aboveSevenEighths += x >= 0.875; + + // these are strict requirements + QVERIFY(x >= 0); + QVERIFY(x < 1); + } + + qInfo("Halfway distribution: %.1f - %.1f", 100. * aboveHalf / SampleSize, 100 - 100. * aboveHalf / SampleSize); + qInfo("%.1f below 1/8 (expected 12.5%% ideally)", 100. * belowOneEighth / SampleSize); + qInfo("%.1f above 7/8 (expected 12.5%% ideally)", 100. * aboveSevenEighths / SampleSize); + + QVERIFY(aboveHalf < PerfectHalf + RangeHalf); + QVERIFY(aboveHalf > PerfectHalf - RangeHalf); + QVERIFY(aboveSevenEighths < PerfectOctile + RangeOctile); + QVERIFY(aboveSevenEighths > PerfectOctile - RangeOctile); + QVERIFY(belowOneEighth < PerfectOctile + RangeOctile); + QVERIFY(belowOneEighth > PerfectOctile - RangeOctile); +} + template void seedStdRandomEngine() { QRandomGenerator rd; -- cgit v1.2.3 From 88e6f8cff2974c46b1262f3a1a61e1440c664e0c Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Tue, 3 Oct 2017 10:47:38 +0700 Subject: Fix implementation of spell check underline styles The QTextCharFormat documentation said that the used style is based on QStyle::SH_SpellCheckUnderlineStyle style hint, however in fact the implementation (drawTextItemDecoration in qpainter.cpp) uses themeHint(QPlatformTheme::SpellCheckUnderlineStyle) instead since Qt 5 (see commit 1f9ae50457a3750f). Make the documentation match that behavior, and update QPlatformTheme to use the correct default value. Also, switch Cocoa theme to use DotLine, as that is what native macOS applications use. Change-Id: I2a6bb3da6c7b0686dca87ed2c251b6abc006123c Task-number: QTBUG-50499 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Gabriel de Dietrich --- src/gui/kernel/qplatformtheme.cpp | 2 +- src/gui/text/qtextformat.cpp | 6 +++--- src/plugins/platforms/cocoa/qcocoatheme.mm | 3 +++ src/widgets/styles/qstyle.cpp | 5 ++--- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index ebf65eda12..cd3966fb47 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -531,7 +531,7 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint) case UiEffects: return QVariant(int(0)); case SpellCheckUnderlineStyle: - return QVariant(int(QTextCharFormat::SpellCheckUnderline)); + return QVariant(int(QTextCharFormat::WaveUnderline)); case TabFocusBehavior: return QVariant(int(Qt::TabFocusAllControls)); case IconPixmapSizes: diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 1653ac8c33..8fe474af2c 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1333,9 +1333,9 @@ bool QTextFormat::operator==(const QTextFormat &rhs) const \value DashDotLine Dashs and dots are drawn using Qt::DashDotLine. \value DashDotDotLine Underlines draw drawn using Qt::DashDotDotLine. \value WaveUnderline The text is underlined using a wave shaped line. - \value SpellCheckUnderline The underline is drawn depending on the QStyle::SH_SpellCeckUnderlineStyle - style hint of the QApplication style. By default this is mapped to - WaveUnderline, on \macos it is mapped to DashDotLine. + \value SpellCheckUnderline The underline is drawn depending on the SpellCheckUnderlineStyle + theme hint of QPlatformTheme. By default this is mapped to + WaveUnderline, on \macos it is mapped to DotLine. \sa Qt::PenStyle */ diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 04dce802f3..5239864ad8 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -344,6 +345,8 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const return QVariant(QChar(0x2022)); case QPlatformTheme::UiEffects: return QVariant(int(HoverEffect)); + case QPlatformTheme::SpellCheckUnderlineStyle: + return QVariant(int(QTextCharFormat::DotLine)); default: break; } diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 0350d5e1a5..faa5f1e67e 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1840,9 +1840,8 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value SH_UnderlineShortcut Whether shortcuts are underlined. - \value SH_SpellCheckUnderlineStyle A - QTextCharFormat::UnderlineStyle value that specifies the way - misspelled words should be underlined. + \value SH_SpellCheckUnderlineStyle Obsolete. Use SpellCheckUnderlineStyle + hint in QPlatformTheme instead. \value SH_SpinBox_AnimateButton Animate a click when up or down is pressed in a spin box. -- cgit v1.2.3 From 9c58dd15885d813aeb5d83d2869c0f3a3ee5fcfe Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Fri, 20 Oct 2017 16:09:29 +0300 Subject: Blacklist and skip failing tests for Boot2Qt / 64 bit arm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-60263 Change-Id: I05978915b5bb7ae31069e8e9ae1dc273e483ddb0 Reviewed-by: Tony Sarajärvi --- tests/auto/auto.pro | 5 +++++ tests/auto/corelib/global/qlogging/BLACKLIST | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 tests/auto/corelib/global/qlogging/BLACKLIST diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 0f8129cb74..3caa6a3b65 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -43,3 +43,8 @@ else:!qtConfig(process): SUBDIRS -= tools SUBDIRS -= dbus } } + +# QTBUG-63915 +boot2qt: { + contains(QT_ARCH, arm64): SUBDIRS -= dbus +} diff --git a/tests/auto/corelib/global/qlogging/BLACKLIST b/tests/auto/corelib/global/qlogging/BLACKLIST new file mode 100644 index 0000000000..1dcee92361 --- /dev/null +++ b/tests/auto/corelib/global/qlogging/BLACKLIST @@ -0,0 +1,3 @@ +[qMessagePattern:backtrace depth,separator] +# QTBUG-63915 +b2qt 64bit -- cgit v1.2.3 From 87eff0ea31bbaf4d3c3ff349ce32ff456794e2b5 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Fri, 20 Oct 2017 12:45:58 +0200 Subject: Fix resolution of QMAKE_INFO_PLIST for non-bundle artifacts Change-Id: Id56cea1f09d7675fe60cdbd598e6f585a6b230d1 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/mac/mac.prf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/mac/mac.prf b/mkspecs/features/mac/mac.prf index 52f06ef773..73d8b1208b 100644 --- a/mkspecs/features/mac/mac.prf +++ b/mkspecs/features/mac/mac.prf @@ -13,5 +13,6 @@ } $$add_plist: \ - QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,$$shell_quote($$QMAKE_INFO_PLIST) + QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,$$shell_quote( \ + $$relative_path($$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_), $$OUT_PWD)) } -- cgit v1.2.3 From 82c787ec3b0dc4ddc54639ad47eb82a052446858 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Oct 2017 18:46:23 -0700 Subject: Fix build on Integrity: the compiler doesn't understand this construct "global/qrandom.cpp", line 155: error #2000-D: attribute "destructor" is not implemented and will be ignored Task-number: QTBUG-63948 Change-Id: Icaa86fc7b54d4b368c0efffd14efa35381d4e797 Reviewed-by: Liang Qi Reviewed-by: Lars Knoll --- src/corelib/global/qrandom.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 3ae7e3bad8..0bbe79aeb4 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -152,7 +152,11 @@ class SystemRandom { static QBasicAtomicInt s_fdp1; // "file descriptor plus 1" static int openDevice(); - static __attribute__((destructor)) void closeDevice(); // assume GCC or a compiler able to understand GCC extensions +#ifdef Q_CC_GNU + // If it's not GCC or GCC-like, then we'll leak the file descriptor + __attribute__((destructor)) +#endif + static void closeDevice(); SystemRandom() {} public: enum { EfficientBufferFill = true }; -- cgit v1.2.3 From c181f418b9dd72e25ceff8ee7ccb030aa74f1cef Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 20 Oct 2017 14:10:42 +0300 Subject: Address Book example: Correctly update "Edit entry" and "Remove entry" actions They are not updated after switching tabs. Thus they can be enabled even when no entry is selected: select an entry on the current tab and then switch to an empty tab. Emit AddressWidget::selectionChanged() signal after changing the current tab to update these actions. Change-Id: I00da15ed6c3d3839210ae3ffbe1436e234695522 Reviewed-by: Friedemann Kleint --- examples/widgets/doc/src/addressbook.qdoc | 11 ++++++----- examples/widgets/itemviews/addressbook/addresswidget.cpp | 6 ++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/examples/widgets/doc/src/addressbook.qdoc b/examples/widgets/doc/src/addressbook.qdoc index cd7cd09f5b..1fa0bfa9d4 100644 --- a/examples/widgets/doc/src/addressbook.qdoc +++ b/examples/widgets/doc/src/addressbook.qdoc @@ -220,11 +220,12 @@ The QItemSelectionModel class provides a \l{QItemSelectionModel::selectionChanged()}{selectionChanged} signal that is connected to \c{AddressWidget}'s - \c selectionChanged() signal. This signal to signal connection - is necessary to enable the \uicontrol{Edit Entry...} and - \uicontrol{Remove Entry} actions in \c MainWindow's Tools menu. This - connection is further explained in \c MainWindow's - implementation. + \c selectionChanged() signal. We also connect + QTabWidget::currentChanged() signal to the lambda expression which + emits \c{AddressWidget}'s \c selectionChanged() as well. These + connections are necessary to enable the \uicontrol{Edit Entry...} and + \uicontrol{Remove Entry} actions in \c MainWindow's Tools menu. + It is further explained in \c MainWindow's implementation. Each table view in the address book is added as a tab to the QTabWidget with the relevant label, obtained from the QStringList diff --git a/examples/widgets/itemviews/addressbook/addresswidget.cpp b/examples/widgets/itemviews/addressbook/addresswidget.cpp index 9480d2ca8e..143f6266dd 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.cpp +++ b/examples/widgets/itemviews/addressbook/addresswidget.cpp @@ -192,6 +192,12 @@ void AddressWidget::setupTabs() &QItemSelectionModel::selectionChanged, this, &AddressWidget::selectionChanged); + connect(this, &QTabWidget::currentChanged, this, [this](int tabIndex) { + auto *tableView = qobject_cast(widget(tabIndex)); + if (tableView) + emit selectionChanged(tableView->selectionModel()->selection()); + }); + addTab(tableView, str); } } -- cgit v1.2.3 From f174d31667dca184439f520b9624a1471d9556a6 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 23 Oct 2017 14:45:15 +0200 Subject: QHstsStore - use qAsConst in a range-loop Found by clazy-range-loop. Change-Id: If43e8d127697f768dc7b1871dc9fef9dcc57ad54 Reviewed-by: Edward Welbourne --- src/network/access/qhstsstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qhstsstore.cpp b/src/network/access/qhstsstore.cpp index 239a52b7a4..6d7f60ba8d 100644 --- a/src/network/access/qhstsstore.cpp +++ b/src/network/access/qhstsstore.cpp @@ -114,7 +114,7 @@ void QHstsStore::synchronize() if (observedPolicies.size()) { beginHstsGroups(); - for (const QHstsPolicy &policy : observedPolicies) { + for (const QHstsPolicy &policy : qAsConst(observedPolicies)) { const QString key(host_name_to_settings_key(policy.host())); // If we fail to write a new, updated policy, we also remove the old one. if (policy.isExpired() || !serializePolicy(key, policy)) -- cgit v1.2.3