summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/global/externalsites/qtcreator.qdoc28
-rw-r--r--doc/global/manifest-meta.qdocconf5
-rw-r--r--doc/global/qt-cpp-defines.qdocconf4
-rw-r--r--examples/widgets/painting/fontsampler/mainwindow.cpp6
-rw-r--r--examples/widgets/painting/fontsampler/mainwindow.h10
-rw-r--r--mkspecs/features/moc.prf5
-rw-r--r--mkspecs/features/qlalr.prf2
-rw-r--r--mkspecs/linux-icc/qmake.conf2
-rw-r--r--mkspecs/macx-icc/qmake.conf2
-rw-r--r--mkspecs/win32-icc/qmake.conf2
-rw-r--r--qmake/generators/win32/mingw_make.cpp6
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp5
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp10
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp9
-rw-r--r--qmake/generators/win32/msvc_vcproj.h3
-rw-r--r--qmake/generators/win32/winmakefile.cpp3
-rw-r--r--src/android/jar/jar.pri4
-rw-r--r--src/android/templates/res/values/libs.xml2
-rw-r--r--src/corelib/global/qcompilerdetection.h4
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qlogging.cpp4
-rw-r--r--src/corelib/global/qnumeric_p.h12
-rw-r--r--src/corelib/io/qdebug.cpp16
-rw-r--r--src/corelib/kernel/qdeadlinetimer.cpp6
-rw-r--r--src/corelib/kernel/qmetatype.h5
-rw-r--r--src/corelib/thread/qmutex.cpp4
-rw-r--r--src/corelib/tools/qalgorithms.h4
-rw-r--r--src/gui/image/qbmphandler_p.h14
-rw-r--r--src/gui/image/qiconengine.cpp8
-rw-r--r--src/gui/image/qiconengine.h4
-rw-r--r--src/gui/image/qimage.cpp31
-rw-r--r--src/gui/image/qpnghandler_p.h14
-rw-r--r--src/gui/image/qppmhandler_p.h14
-rw-r--r--src/gui/image/qxbmhandler_p.h14
-rw-r--r--src/gui/image/qxpmhandler_p.h14
-rw-r--r--src/gui/kernel/qevent.cpp88
-rw-r--r--src/gui/kernel/qevent.h31
-rw-r--r--src/gui/kernel/qevent_p.h2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h2
-rw-r--r--src/gui/opengl/qopenglpaintdevice.h6
-rw-r--r--src/gui/painting/QIMAGETRANSFORM_LICENSE.txt60
-rw-r--r--src/gui/painting/qdrawhelper.cpp6
-rw-r--r--src/gui/painting/qemulationpaintengine_p.h48
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h2
-rw-r--r--src/gui/painting/qpdfwriter.h12
-rw-r--r--src/gui/painting/qstroker_p.h8
-rw-r--r--src/gui/painting/qt_attribution.json43
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp1
-rw-r--r--src/network/kernel/qhostaddress.cpp28
-rw-r--r--src/network/kernel/qhostaddress.h5
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp456
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h16
-rw-r--r--src/platformheaders/nativecontexts/qeglnativecontext.h3
-rw-r--r--src/platformheaders/nativecontexts/qeglnativecontext.qdoc6
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp4
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp31
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp1
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp2
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm25
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm2
-rw-r--r--src/plugins/platforms/directfb/directfb.pro3
-rw-r--r--src/plugins/platforms/windows/qwin10helpers.cpp3
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp76
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h7
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp23
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h3
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp10
-rw-r--r--src/src.pro2
-rw-r--r--src/tools/moc/main.cpp3
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpgbin0 -> 910 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpgbin0 -> 910 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_ifds.jpgbin0 -> 964 bytes
-rw-r--r--tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_tags.jpgbin0 -> 910 bytes
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp17
-rw-r--r--tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp39
-rw-r--r--tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp63
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp26
80 files changed, 999 insertions, 455 deletions
diff --git a/doc/global/externalsites/qtcreator.qdoc b/doc/global/externalsites/qtcreator.qdoc
index f73b17c92f..0e66610d84 100644
--- a/doc/global/externalsites/qtcreator.qdoc
+++ b/doc/global/externalsites/qtcreator.qdoc
@@ -82,6 +82,34 @@
\title Qt Creator: Using Version Control Systems
*/
/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-bazaar.html
+ \title Qt Creator: Using Bazaar
+*/
+/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-clearcase.html
+ \title Qt Creator: Using ClearCase
+*/
+/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-cvs.html
+ \title Qt Creator: Using CVS
+*/
+/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-git.html
+ \title Qt Creator: Using Git
+*/
+/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-mercurial.html
+ \title Qt Creator: Using Mercurial
+*/
+/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-perforce.html
+ \title Qt Creator: Using Perforce
+*/
+/*!
+ \externalpage http://doc.qt.io/qtcreator/creator-vcs-subversion.html
+ \title Qt Creator: Using Subversion
+*/
+/*!
\externalpage http://doc.qt.io/qtcreator/creator-keyboard-shortcuts.html
\title Qt Creator: Keyboard Shortcuts
*/
diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf
index 7ebe86a431..865a457581 100644
--- a/doc/global/manifest-meta.qdocconf
+++ b/doc/global/manifest-meta.qdocconf
@@ -33,7 +33,6 @@ manifestmeta.filters = highlighted android thumbnail ios
manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \
"QtQuick/Qt Quick Demo - Photo Surface" \
"QtQuick/Qt Quick Demo - Tweet Search" \
- "QtQuick/Qt Quick Demo - Maroon*" \
"QtQuick/Qt Quick Demo - Calqlatr" \
"QtQuick/Qt Quick Demo - StocQt" \
"QtQuick/Qt Quick Demo - Clocks" \
@@ -45,14 +44,12 @@ manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \
"QtQuickDialogs/Qt Quick System Dialog Examples" \
"QtWinExtras/Quick Player" \
"QtMultimedia/QML Video Shader Effects Example" \
- "QtCanvas3D/Planets Example" \
"QtCanvas3D/Interactive Mobile Phone Example" \
"QtLocation/Map Viewer (QML)"
manifestmeta.highlighted.attributes = isHighlighted:true
-manifestmeta.android.names = "QtQuick/Qt Quick Demo - Maroon*" \
- "QtQuick/Qt Quick Demo - Calqlatr" \
+manifestmeta.android.names = "QtQuick/Qt Quick Demo - Calqlatr" \
"QtWidgets/Application Chooser Example" \
"QtWidgets/Stickman Example" \
"QtWidgets/Move Blocks Example" \
diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf
index 5ebb208bcc..28f3dade07 100644
--- a/doc/global/qt-cpp-defines.qdocconf
+++ b/doc/global/qt-cpp-defines.qdocconf
@@ -14,12 +14,14 @@ defines += Q_QDOC \
Q_NO_USING_KEYWORD \
__cplusplus \
Q_COMPILER_INITIALIZER_LISTS \
+ Q_COMPILER_UNICODE_STRINGS \
Q_COMPILER_UNIFORM_INIT \
Q_COMPILER_RVALUE_REFS
Cpp.ignoretokens += \
ENGINIOCLIENT_EXPORT \
PHONON_EXPORT \
+ Q_ALWAYS_INLINE \
Q_AUTOTEST_EXPORT \
Q_BLUETOOTH_EXPORT \
Q_COMPAT_EXPORT \
@@ -121,6 +123,7 @@ Cpp.ignoretokens += \
QT_END_NAMESPACE \
QT_FASTCALL \
QT_MUTEX_LOCK_NOEXCEPT \
+ QT_WARNING_DISABLE_DEPRECATED \
QT_WARNING_PUSH \
QT_WARNING_POP \
QT_WIDGET_PLUGIN_EXPORT \
@@ -152,6 +155,7 @@ Cpp.ignoredirectives += \
Q_FLAG \
Q_FLAGS \
Q_FLAG_NS \
+ QT_HAS_INCLUDE \
Q_INTERFACES \
Q_PRIVATE_PROPERTY \
QT_FORWARD_DECLARE_CLASS \
diff --git a/examples/widgets/painting/fontsampler/mainwindow.cpp b/examples/widgets/painting/fontsampler/mainwindow.cpp
index 06ffac3728..88b23d5cfb 100644
--- a/examples/widgets/painting/fontsampler/mainwindow.cpp
+++ b/examples/widgets/painting/fontsampler/mainwindow.cpp
@@ -49,7 +49,9 @@
****************************************************************************/
#include <QtWidgets>
+#if defined(QT_PRINTSUPPORT_LIB)
#include <QPrintPreviewDialog>
+#endif
#include "mainwindow.h"
@@ -210,7 +212,7 @@ QMap<QString, StyleItems> MainWindow::currentPageMap()
return pageMap;
}
-#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
void MainWindow::on_printAction_triggered()
{
pageMap = currentPageMap();
@@ -342,4 +344,4 @@ void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
painter->restore();
}
-#endif // QT_NO_PRINTER
+#endif
diff --git a/examples/widgets/painting/fontsampler/mainwindow.h b/examples/widgets/painting/fontsampler/mainwindow.h
index ada0d47354..21e76f1a62 100644
--- a/examples/widgets/painting/fontsampler/mainwindow.h
+++ b/examples/widgets/painting/fontsampler/mainwindow.h
@@ -55,6 +55,9 @@
#include <QPrinter>
#include <QPrintDialog>
+#if defined(QT_PRINTSUPPORT_LIB)
+#include <QtPrintSupport/qtprintsupportglobal.h>
+#endif
QT_BEGIN_NAMESPACE
class QPrinter;
class QTextEdit;
@@ -74,12 +77,11 @@ public:
public slots:
void on_clearAction_triggered();
void on_markAction_triggered();
-#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
+ void on_unmarkAction_triggered();
+
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
void on_printAction_triggered();
void on_printPreviewAction_triggered();
-#endif
- void on_unmarkAction_triggered();
-#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
void printDocument(QPrinter *printer);
void printPage(int index, QPainter *painter, QPrinter *printer);
#endif
diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf
index dc14d71db7..825c706950 100644
--- a/mkspecs/features/moc.prf
+++ b/mkspecs/features/moc.prf
@@ -28,12 +28,13 @@ win32:count(MOC_INCLUDEPATH, 40, >) {
# UIKit builds are always multi-arch due to simulator_and_device (unless
# -sdk is used) so this feature cannot possibly work.
if(gcc|intel_icl|msvc):!rim_qcc:!uikit {
+ moc_predefs.name = "Generate moc_predefs.h"
moc_predefs.CONFIG = no_link
gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
- else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+ else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Za -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
else:msvc {
moc_predefs.commands += $$QMAKE_CXX -Bx$$shell_quote($$shell_path($$QMAKE_QMAKE)) $$QMAKE_CXXFLAGS \
- -E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT}
+ -E -Za ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT}
} else: error("Oops, I messed up")
moc_predefs.output = $$MOC_DIR/moc_predefs.h
moc_predefs.input = MOC_PREDEF_FILE
diff --git a/mkspecs/features/qlalr.prf b/mkspecs/features/qlalr.prf
index 941bfe0d9f..54d8b583c6 100644
--- a/mkspecs/features/qlalr.prf
+++ b/mkspecs/features/qlalr.prf
@@ -25,7 +25,7 @@ for (s, QLALRSOURCES) {
$${base}.variable_out = GENERATED_SOURCES
$${base}.depends += $$QMAKE_QLALR_EXE
$${base}.commands = $$QMAKE_QLALR $$QMAKE_QLALRFLAGS ${QMAKE_FILE_IN}
- silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $${base}.commands
+ silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $$eval($${base}.commands)
$${base}.name = QLALR ${QMAKE_FILE_IN}
$${base}_h.input = $$invar
diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf
index 495fd15e80..2c66e80db4 100644
--- a/mkspecs/linux-icc/qmake.conf
+++ b/mkspecs/linux-icc/qmake.conf
@@ -14,7 +14,7 @@ QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS =
QMAKE_CFLAGS_APP = -fPIC
QMAKE_CFLAGS_DEPS = -M
-QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261
+QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261,3373
QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE = -O2 -falign-functions=16 -ansi-alias -fstrict-aliasing
QMAKE_CFLAGS_DEBUG = -O0 -g
diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf
index 35e55f799e..0a94ae472d 100644
--- a/mkspecs/macx-icc/qmake.conf
+++ b/mkspecs/macx-icc/qmake.conf
@@ -14,7 +14,7 @@ QMAKE_COMPILER = gcc clang intel_icc # icc pretends to be gcc and cla
QMAKE_CC = icc
QMAKE_CFLAGS =
QMAKE_CFLAGS_DEPS = -M
-QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280
+QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280,3373
QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE =
QMAKE_CFLAGS_DEBUG = -g
diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf
index dd54131526..cfd8399a3c 100644
--- a/mkspecs/win32-icc/qmake.conf
+++ b/mkspecs/win32-icc/qmake.conf
@@ -19,7 +19,7 @@ QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = bison -y
QMAKE_YACCFLAGS = -d
-QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809
+QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809,3373
QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673
QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673
QMAKE_CFLAGS_RELEASE = -O2 -MD
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index e3d76cd76e..8d5a9a7d0f 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -308,13 +308,13 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t)
{
t << "first: all\n";
t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName()))
- << ' ' << depVar("ALL_DEPS");
+ << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n";
+ t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
if (project->first("TEMPLATE") == "aux") {
t << "\n\n";
return;
}
- t << " $(DESTDIR_TARGET)\n\n";
- t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
+
if(!project->isEmpty("QMAKE_PRE_LINK"))
t << "\n\t" <<var("QMAKE_PRE_LINK");
if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 3a4f6242b2..da10b1984f 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -517,13 +517,12 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t)
t << "first: all\n";
t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName()))
- << ' ' << depVar("ALL_DEPS");
+ << ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n";
+ t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
if (templateName == "aux") {
t << "\n\n";
return;
}
- t << " $(DESTDIR_TARGET)\n\n";
- t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
if(!project->isEmpty("QMAKE_PRE_LINK"))
t << "\n\t" <<var("QMAKE_PRE_LINK");
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 2d8d1fed0a..ac57a3379c 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -2264,10 +2264,14 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
QString inFile = info.file;
// is the extracompiler rule on a file with a built in compiler?
- const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile];
+ const QString objectMappedFile = Project->extraCompilerOutputs.value(inFile);
bool hasBuiltIn = false;
if (!objectMappedFile.isEmpty()) {
- hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0));
+ hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile);
+
+ // Remove the fake file suffix we've added initially to generate correct command lines.
+ inFile.chop(Project->customBuildToolFilterFileSuffix.length());
+
// qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' ')));
}
@@ -2309,7 +2313,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
// compiler, too bad..
if (hasBuiltIn) {
out = inFile;
- inFile = objectMappedFile.at(0);
+ inFile = objectMappedFile;
}
// Dependency for the output
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 018c70089d..8a77bbe672 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -204,7 +204,8 @@ const char _slnExtSections[] = "\n\tGlobalSection(ExtensibilityGlobals) = pos
VcprojGenerator::VcprojGenerator()
: Win32MakefileGenerator(),
is64Bit(false),
- projectWriter(0)
+ projectWriter(0),
+ customBuildToolFilterFileSuffix(QStringLiteral(".cbt"))
{
}
@@ -892,10 +893,14 @@ void VcprojGenerator::init()
if (!hasBuiltinCompiler(file)) {
extraCompilerSources[file] += quc.toQString();
} else {
+ // Use a fake file name foo.moc.cbt for the project view.
+ // This prevents VS from complaining about a circular
+ // dependency from foo.moc -> foo.moc.
QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables(
compiler_out, file, QString(), NoShell), false);
+ out += customBuildToolFilterFileSuffix;
extraCompilerSources[out] += quc.toQString();
- extraCompilerOutputs[out] = QStringList(file); // Can only have one
+ extraCompilerOutputs[out] = file;
}
}
}
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index 9ccd8c2552..e3e67d64b9 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -63,7 +63,8 @@ public:
static bool hasBuiltinCompiler(const QString &file);
QHash<QString, QStringList> extraCompilerSources;
- QHash<QString, QStringList> extraCompilerOutputs;
+ QHash<QString, QString> extraCompilerOutputs;
+ const QString customBuildToolFilterFileSuffix;
bool usePCH;
VCProjectWriter *projectWriter;
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index 48df4ff916..3c029c8004 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -165,6 +165,9 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
void Win32MakefileGenerator::processVars()
{
+ if (project->first("TEMPLATE").endsWith("aux"))
+ return;
+
project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
if (project->isEmpty("QMAKE_PROJECT_NAME"))
project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET");
diff --git a/src/android/jar/jar.pri b/src/android/jar/jar.pri
index 58caacb837..4535880536 100644
--- a/src/android/jar/jar.pri
+++ b/src/android/jar/jar.pri
@@ -17,7 +17,9 @@ JAVASOURCES += \
$$PATHPREFIX/QtNativeLibrariesDir.java \
$$PATHPREFIX/QtSurface.java \
$$PATHPREFIX/ExtractStyle.java \
- $$PATHPREFIX/QtServiceDelegate.java
+ $$PATHPREFIX/EditMenu.java \
+ $$PATHPREFIX/EditPopupMenu.java \
+ $$PATHPREFIX/CursorHandle.java
# install
target.path = $$[QT_INSTALL_PREFIX]/jar
diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml
index 43296f2e7a..77f422cfb2 100644
--- a/src/android/templates/res/values/libs.xml
+++ b/src/android/templates/res/values/libs.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
- <item>https://download.qt.io/ministro/android/qt5/qt-5.7</item>
+ <item>https://download.qt.io/ministro/android/qt5/qt-5.8</item>
</array>
<!-- The following is handled automatically by the deployment tool. It should
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index d978c141a4..4142c17b42 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -1273,7 +1273,7 @@
# define QT_WARNING_DISABLE_INTEL(number) __pragma(warning(disable: number))
# define QT_WARNING_DISABLE_CLANG(text)
# define QT_WARNING_DISABLE_GCC(text)
-# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1786)
+# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786)
#elif defined(Q_CC_INTEL)
/* icc: Intel compiler on Linux or OS X */
# define QT_WARNING_PUSH QT_DO_PRAGMA(warning(push))
@@ -1282,7 +1282,7 @@
# define QT_WARNING_DISABLE_MSVC(number)
# define QT_WARNING_DISABLE_CLANG(text)
# define QT_WARNING_DISABLE_GCC(text)
-# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1786)
+# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786)
#elif defined(Q_CC_MSVC) && _MSC_VER >= 1500 && !defined(Q_CC_CLANG)
# undef QT_DO_PRAGMA /* not needed */
# define QT_WARNING_PUSH __pragma(warning(push))
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 1737f58c87..32176913ea 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -921,10 +921,10 @@ template <typename T>
class QForeachContainer {
QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
public:
- QForeachContainer(const T &t) : c(t) {}
- QForeachContainer(T &&t) : c(std::move(t)) {}
+ QForeachContainer(const T &t) : c(t), i(c.begin()), e(c.end()) {}
+ QForeachContainer(T &&t) : c(std::move(t)), i(c.begin()), e(c.end()) {}
const T c;
- typename T::const_iterator i = c.begin(), e = c.end();
+ typename T::const_iterator i, e;
int control = 1;
};
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 0506d372b6..6b90a47388 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1042,6 +1042,10 @@ void QMessagePattern::setPattern(const QString &pattern)
delete [] literals;
}
delete [] tokens;
+ timeArgs.clear();
+#ifdef QLOGGING_HAVE_BACKTRACE
+ backtraceArgs.clear();
+#endif
// scanner
QList<QString> lexemes;
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 23fcf340f1..01b8772ee1 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -68,7 +68,8 @@
#if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL) || !defined(__cplusplus))
# include <math.h>
-# define QT_MATH_H_DEFINES_MACROS
+# ifdef isnan
+# define QT_MATH_H_DEFINES_MACROS
QT_BEGIN_NAMESPACE
namespace qnumeric_std_wrapper {
// the 'using namespace std' below is cases where the stdlib already put the math.h functions in the std namespace and undefined the macros.
@@ -81,10 +82,11 @@ static inline bool math_h_isfinite(float f) { using namespace std; return isfini
}
QT_END_NAMESPACE
// These macros from math.h conflict with the real functions in the std namespace.
-#undef signbit
-#undef isnan
-#undef isinf
-#undef isfinite
+# undef signbit
+# undef isnan
+# undef isinf
+# undef isfinite
+# endif // defined(isnan)
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index fa919e9f10..be33ec2d23 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -579,6 +579,22 @@ QDebug &QDebug::resetFormat()
*/
/*!
+ \fn QDebug &QDebug::operator<<(char16_t t)
+ \since 5.5
+
+ Writes the UTF-16 character, \a t, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ \fn QDebug &QDebug::operator<<(char32_t t)
+ \since 5.5
+
+ Writes the UTF-32 character, \a t, to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
\fn QDebug &QDebug::operator<<(const QString &s)
Writes the string, \a s, to the stream and returns a reference to the
diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp
index d670637d53..1f554c9f2e 100644
--- a/src/corelib/kernel/qdeadlinetimer.cpp
+++ b/src/corelib/kernel/qdeadlinetimer.cpp
@@ -122,6 +122,7 @@ Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64
\code
using namespace std::chrono;
+ using namespace std::chrono_literals;
QDeadlineTimer deadline(30s);
device->waitForReadyRead(deadline);
@@ -141,6 +142,7 @@ Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64
\code
using namespace std::chrono;
+ using namespace std::chrono_literals;
auto now = steady_clock::now();
QDeadlineTimer deadline(now + 1s);
Q_ASSERT(deadline == now + 1s);
@@ -240,7 +242,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW
This constructor can be used with C++14's user-defined literals for time, such as in:
\code
- using namespace std::chrono;
+ using namespace std::chrono_literals;
QDeadlineTimer deadline(250ms);
\endcode
@@ -333,7 +335,7 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time
This function can be used with C++14's user-defined literals for time, such as in:
\code
- using namespace std::chrono;
+ using namespace std::chrono_literals;
deadline.setRemainingTime(250ms);
\endcode
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index e64812b3ae..7b0a9f986b 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1389,10 +1389,6 @@ namespace QtPrivate
};
-QT_WARNING_PUSH
-// In C++03 mode, clang consider local or unnamed type and throw a warning instead of ignoring them
-QT_WARNING_DISABLE_CLANG("-Wunnamed-type-template-args")
-QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args")
template<typename T> char qt_getEnumMetaObject(const T&);
template<typename T>
@@ -1405,7 +1401,6 @@ QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args")
enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
};
template<> struct IsQEnumHelper<void> { enum { Value = false }; };
-QT_WARNING_POP
template<typename T, typename Enable = void>
struct MetaObjectForType
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 0aee4aeda4..653c3efe1c 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -279,7 +279,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
for the mutex to become available.
Note: Passing a negative duration as the \a duration is equivalent to
- calling try_lock(). This behavior is different from tryLock.
+ calling try_lock(). This behavior differs from tryLock().
If the lock was obtained, the mutex must be unlocked with unlock()
before another thread can successfully lock it.
@@ -303,7 +303,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
for the mutex to become available.
Note: Passing a \a timePoint which has already passed is equivalent
- to calling try_lock. This behavior is different from tryLock.
+ to calling try_lock(). This behavior differs from tryLock().
If the lock was obtained, the mutex must be unlocked with unlock()
before another thread can successfully lock it.
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index 7e846956f5..fb7031ce71 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -535,7 +535,7 @@ QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessItera
# define QT_HAS_BUILTIN_CTZS
Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW
{
-# if QT_HAS_BUILTIN(__builtin_ctzs) || defined(__BMI__)
+# if QT_HAS_BUILTIN(__builtin_ctzs)
return __builtin_ctzs(v);
# else
return __builtin_ctz(v);
@@ -544,7 +544,7 @@ Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW
#define QT_HAS_BUILTIN_CLZS
Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) Q_DECL_NOTHROW
{
-# if QT_HAS_BUILTIN(__builtin_clzs) || defined(__BMI__)
+# if QT_HAS_BUILTIN(__builtin_clzs)
return __builtin_clzs(v);
# else
return __builtin_clz(v) - 16U;
diff --git a/src/gui/image/qbmphandler_p.h b/src/gui/image/qbmphandler_p.h
index 258ce0fce6..7d3cbab322 100644
--- a/src/gui/image/qbmphandler_p.h
+++ b/src/gui/image/qbmphandler_p.h
@@ -94,17 +94,17 @@ public:
};
explicit QBmpHandler(InternalFormat fmt = BmpFormat);
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const override;
+ bool read(QImage *image) override;
+ bool write(const QImage &image) override;
- QByteArray name() const;
+ QByteArray name() const override;
static bool canRead(QIODevice *device);
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const override;
+ void setOption(ImageOption option, const QVariant &value) override;
+ bool supportsOption(ImageOption option) const override;
private:
bool readHeader();
diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp
index 16cd4aa954..0ba9844f7a 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/gui/image/qiconengine.cpp
@@ -92,6 +92,14 @@ QIconEngine::QIconEngine()
}
/*!
+ \since 5.8
+ \internal
+ */
+QIconEngine::QIconEngine(const QIconEngine &)
+{
+}
+
+/*!
Destroys the icon engine.
*/
QIconEngine::~QIconEngine()
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
index b0c92ced73..783770cd30 100644
--- a/src/gui/image/qiconengine.h
+++ b/src/gui/image/qiconengine.h
@@ -51,6 +51,7 @@ class Q_GUI_EXPORT QIconEngine
{
public:
QIconEngine();
+ QIconEngine(const QIconEngine &other); // ### Qt6: make protected
virtual ~QIconEngine();
virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0;
virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
@@ -80,6 +81,9 @@ public:
bool isNull() const; // ### Qt6 make virtual
virtual void virtual_hook(int id, void *data);
+
+private:
+ QIconEngine &operator=(const QIconEngine &other) Q_DECL_EQ_DELETE;
};
#if QT_DEPRECATED_SINCE(5, 0)
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 9e911bdcea..9e9f01a46a 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -596,37 +596,6 @@ bool QImageData::checkForAlphaPixels() const
\endtable
- \target qimage-legalese
- \section1 Legal Information
-
- For smooth scaling, the transformed() functions use code based on
- smooth scaling algorithm by Daniel M. Duley.
-
- \badcode
- Copyright (C) 2004, 2005 Daniel M. Duley
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. 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.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- \endcode
-
\sa QImageReader, QImageWriter, QPixmap, QSvgRenderer, {Image Composition Example},
{Image Viewer Example}, {Scribble Example}, {Pixelator Example}
*/
diff --git a/src/gui/image/qpnghandler_p.h b/src/gui/image/qpnghandler_p.h
index 269df25794..4ca716e7c2 100644
--- a/src/gui/image/qpnghandler_p.h
+++ b/src/gui/image/qpnghandler_p.h
@@ -65,15 +65,15 @@ public:
QPngHandler();
~QPngHandler();
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const override;
+ bool read(QImage *image) override;
+ bool write(const QImage &image) override;
- QByteArray name() const;
+ QByteArray name() const override;
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const override;
+ void setOption(ImageOption option, const QVariant &value) override;
+ bool supportsOption(ImageOption option) const override;
static bool canRead(QIODevice *device);
diff --git a/src/gui/image/qppmhandler_p.h b/src/gui/image/qppmhandler_p.h
index 8889d9e663..1c6fbd6869 100644
--- a/src/gui/image/qppmhandler_p.h
+++ b/src/gui/image/qppmhandler_p.h
@@ -63,17 +63,17 @@ class QPpmHandler : public QImageIOHandler
{
public:
QPpmHandler();
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const override;
+ bool read(QImage *image) override;
+ bool write(const QImage &image) override;
- QByteArray name() const;
+ QByteArray name() const override;
static bool canRead(QIODevice *device, QByteArray *subType = 0);
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const override;
+ void setOption(ImageOption option, const QVariant &value) override;
+ bool supportsOption(ImageOption option) const override;
private:
bool readHeader();
diff --git a/src/gui/image/qxbmhandler_p.h b/src/gui/image/qxbmhandler_p.h
index 561153376d..26439af527 100644
--- a/src/gui/image/qxbmhandler_p.h
+++ b/src/gui/image/qxbmhandler_p.h
@@ -62,17 +62,17 @@ class QXbmHandler : public QImageIOHandler
{
public:
QXbmHandler();
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const override;
+ bool read(QImage *image) override;
+ bool write(const QImage &image) override;
- QByteArray name() const;
+ QByteArray name() const override;
static bool canRead(QIODevice *device);
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const override;
+ void setOption(ImageOption option, const QVariant &value) override;
+ bool supportsOption(ImageOption option) const override;
private:
bool readHeader();
diff --git a/src/gui/image/qxpmhandler_p.h b/src/gui/image/qxpmhandler_p.h
index af3e98d3ff..f118bf2309 100644
--- a/src/gui/image/qxpmhandler_p.h
+++ b/src/gui/image/qxpmhandler_p.h
@@ -62,17 +62,17 @@ class QXpmHandler : public QImageIOHandler
{
public:
QXpmHandler();
- bool canRead() const;
- bool read(QImage *image);
- bool write(const QImage &image);
+ bool canRead() const override;
+ bool read(QImage *image) override;
+ bool write(const QImage &image) override;
static bool canRead(QIODevice *device);
- QByteArray name() const;
+ QByteArray name() const override;
- QVariant option(ImageOption option) const;
- void setOption(ImageOption option, const QVariant &value);
- bool supportsOption(ImageOption option) const;
+ QVariant option(ImageOption option) const override;
+ void setOption(ImageOption option, const QVariant &value) override;
+ bool supportsOption(ImageOption option) const override;
private:
bool readHeader();
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 254b8926c8..219f782737 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -44,6 +44,7 @@
#include "qpa/qplatformdrag.h"
#include "private/qevent_p.h"
#include "qfile.h"
+#include "qhashfunctions.h"
#include "qmetaobject.h"
#include "qmimedata.h"
#include "private/qdnd_p.h"
@@ -4474,14 +4475,14 @@ int QTouchEvent::TouchPoint::id() const
\since 5.8
Returns the unique ID of this touch point or token, if any.
- It is normally invalid (with a \l {QPointerUniqueId::numeric()} {numeric()} value of -1),
+ It is normally invalid (see \l {QPointingDeviceUniqueId::isValid()} {isValid()}),
because touchscreens cannot uniquely identify fingers. But when the
\l {TouchPoint::InfoFlag} {Token} flag is set, it is expected to uniquely
identify a specific token (fiducial object).
\sa flags
*/
-QPointerUniqueId QTouchEvent::TouchPoint::uniqueId() const
+QPointingDeviceUniqueId QTouchEvent::TouchPoint::uniqueId() const
{
return d->uniqueId;
}
@@ -4757,7 +4758,7 @@ void QTouchEvent::TouchPoint::setUniqueId(qint64 uid)
{
if (d->ref.load() != 1)
d = d->detach();
- d->uniqueId = QPointerUniqueId(uid);
+ d->uniqueId = QPointingDeviceUniqueId::fromNumericId(uid);
}
/*! \internal */
@@ -5176,36 +5177,99 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const
}
/*!
- \class QPointerUniqueId
+ \class QPointingDeviceUniqueId
\since 5.8
\ingroup events
\inmodule QtGui
- \brief QPointerUniqueId identifies a unique object, such as a tagged token
+ \brief QPointingDeviceUniqueId identifies a unique object, such as a tagged token
or stylus, which is used with a pointing device.
+ QPointingDeviceUniqueIds can be compared for equality, and can be used as keys in a QHash.
+ You get access to the numerical ID via numericId(), if the device supports such IDs.
+ For future extensions, though, you should not use that function, but compare objects
+ of this type using the equality operator.
+
+ This class is a thin wrapper around an integer ID. You pass it into and out of
+ functions by value.
+
+ This type actively prevents you from holding it in a QList, because doing so would
+ be very inefficient. Use a QVector instead, which has the same API as QList, but more
+ efficient storage.
+
\sa QTouchEvent::TouchPoint
*/
/*!
- Constructs a unique pointer ID with a numeric \a id provided by the hardware.
- The default is -1, which means an invalid pointer ID.
+ \fn QPointingDeviceUniqueId::QPointingDeviceUniqueId()
+ Constructs an invalid unique pointer ID.
+*/
+
+/*!
+ Constructs a unique pointer ID from numeric ID \a id.
*/
-QPointerUniqueId::QPointerUniqueId(qint64 id)
- : m_numericId(id)
+QPointingDeviceUniqueId QPointingDeviceUniqueId::fromNumericId(qint64 id)
{
+ QPointingDeviceUniqueId result;
+ result.m_numericId = id;
+ return result;
}
/*!
- \property QPointerUniqueId::numeric
+ \fn bool QPointingDeviceUniqueId::isValid() const
+
+ Returns whether this unique pointer ID is valid, that is, it represents an actual
+ pointer.
+*/
+
+/*!
+ \property QPointingDeviceUniqueId::numericId
\brief the numeric unique ID of the token represented by a touchpoint
- This is the numeric unique ID if the device provides that type of ID;
+ If the device provides a numeric ID, isValid() returns true, and this
+ property provides the numeric ID;
otherwise it is -1.
+
+ You should not use the value of this property in portable code, but
+ instead rely on equality to identify pointers.
+
+ \sa isValid()
*/
-qint64 QPointerUniqueId::numeric() const
+qint64 QPointingDeviceUniqueId::numericId() const Q_DECL_NOTHROW
{
return m_numericId;
}
+/*!
+ \relates QPointingDeviceUniqueId
+ \since 5.8
+
+ Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer
+ (\c true) or not (\c false).
+*/
+bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW
+{
+ return lhs.numericId() == rhs.numericId();
+}
+
+/*!
+ \fn bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs)
+ \relates QPointingDeviceUniqueId
+ \since 5.8
+
+ Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers
+ (\c true) or not (\c false).
+*/
+
+/*!
+ \relates QPointingDeviceUniqueId
+ \since 5.8
+
+ Returns the hash value for \a key, using \a seed to seed the calculation.
+*/
+uint qHash(QPointingDeviceUniqueId key, uint seed) Q_DECL_NOTHROW
+{
+ return qHash(key.numericId(), seed);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index a062331bd8..7881df205a 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -793,21 +793,36 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ?
inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);}
#endif // QT_NO_SHORTCUT
-class QPointerUniqueIdPrivate;
-class Q_GUI_EXPORT QPointerUniqueId
+class Q_GUI_EXPORT QPointingDeviceUniqueId
{
Q_GADGET
- Q_PROPERTY(qint64 numeric READ numeric CONSTANT)
+ Q_PROPERTY(qint64 numericId READ numericId CONSTANT)
public:
- explicit QPointerUniqueId(qint64 id = -1);
+ Q_ALWAYS_INLINE
+ Q_DECL_CONSTEXPR QPointingDeviceUniqueId() Q_DECL_NOTHROW : m_numericId(-1) {}
+ // compiler-generated copy/move ctor/assignment operators are ok!
+ // compiler-generated dtor is ok!
- qint64 numeric() const;
+ static QPointingDeviceUniqueId fromNumericId(qint64 id);
+
+ Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW { return m_numericId != -1; }
+ qint64 numericId() const Q_DECL_NOTHROW;
private:
- // TODO for TUIO 2, or any other type of complex token ID, a d-pointer can replace
- // m_numericId without changing the size of this class.
+ // TODO: for TUIO 2, or any other type of complex token ID, an internal
+ // array (or hash) can be added to hold additional properties.
+ // In this case, m_numericId will then turn into an index into that array (or hash).
qint64 m_numericId;
};
+Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE);
+template <> class QList<QPointingDeviceUniqueId> {}; // to prevent instantiation: use QVector instead
+
+Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW;
+inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW
+{ return !operator==(lhs, rhs); }
+Q_GUI_EXPORT uint qHash(QPointingDeviceUniqueId key, uint seed = 0) Q_DECL_NOTHROW;
+
+
class QTouchEventTouchPointPrivate;
class Q_GUI_EXPORT QTouchEvent : public QInputEvent
@@ -844,7 +859,7 @@ public:
{ qSwap(d, other.d); }
int id() const;
- QPointerUniqueId uniqueId() const;
+ QPointingDeviceUniqueId uniqueId() const;
Qt::TouchPointState state() const;
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index 7e82b9c654..898ad16cf6 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -80,7 +80,7 @@ public:
QAtomicInt ref;
int id;
- QPointerUniqueId uniqueId;
+ QPointingDeviceUniqueId uniqueId;
Qt::TouchPointStates state;
QRectF rect, sceneRect, screenRect;
QPointF normalizedPos,
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 3be3c3188c..a28d1c93df 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -129,7 +129,7 @@ public:
TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(Qt::TouchPointStationary) { }
int id; // for application use
qint64 uniqueId; // for TUIO: object/token ID; otherwise empty
- // TODO for TUIO 2.0: add registerPointerUniqueID(QPointerUniqueId)
+ // TODO for TUIO 2.0: add registerPointerUniqueID(QPointingDeviceUniqueId)
QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1)
QRectF area; // the touched area, centered at position in screen coordinates
qreal pressure; // 0 to 1
diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h
index 27b7fba84f..300002a9c1 100644
--- a/src/gui/opengl/qopenglpaintdevice.h
+++ b/src/gui/opengl/qopenglpaintdevice.h
@@ -61,8 +61,8 @@ public:
QOpenGLPaintDevice(int width, int height);
virtual ~QOpenGLPaintDevice();
- int devType() const { return QInternal::OpenGL; }
- QPaintEngine *paintEngine() const;
+ int devType() const override { return QInternal::OpenGL; }
+ QPaintEngine *paintEngine() const override;
QOpenGLContext *context() const;
QSize size() const;
@@ -82,7 +82,7 @@ public:
protected:
QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd);
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ int metric(QPaintDevice::PaintDeviceMetric metric) const override;
Q_DISABLE_COPY(QOpenGLPaintDevice)
QScopedPointer<QOpenGLPaintDevicePrivate> d_ptr;
diff --git a/src/gui/painting/QIMAGETRANSFORM_LICENSE.txt b/src/gui/painting/QIMAGETRANSFORM_LICENSE.txt
new file mode 100644
index 0000000000..67c910826a
--- /dev/null
+++ b/src/gui/painting/QIMAGETRANSFORM_LICENSE.txt
@@ -0,0 +1,60 @@
+qimagetransform.cpp was contributed by Daniel M. Duley based on code from Imlib2.
+
+Copyright (C) 2004, 2005 Daniel M. Duley
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. 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.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+
+
+Imlib2 License
+
+Copyright (C) 2000 Carsten Haitzler and various contributors (see
+AUTHORS)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies of the Software and its Copyright notices. In addition
+publicly documented acknowledgment must be given that this software has
+been used if no source code of this software is made available publicly.
+This includes acknowledgments in either Copyright notices, Manuals,
+Publicity and Marketing documents or any documentation provided with any
+product containing this software. This License does not apply to any
+software that links to the libraries provided by this software
+(statically or dynamically), but only to the software provided.
+
+Please see the COPYING.PLAIN for a plain-english explanation of this
+notice and it's intent.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index af32811d34..a2e49dbfdb 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1581,7 +1581,7 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1
Q_ASSERT(layout->bpp == bpp);
// When templated 'fetch' should be inlined at compile time:
- const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel<bpp>;
+ const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel<bpp>);
uint *const end = buffer + length;
uint *b = buffer;
@@ -2532,8 +2532,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1
Q_ASSERT(layout->bpp == bpp);
// When templated 'fetch' should be inlined at compile time:
- const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : fetchPixels<bpp>;
- const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel<bpp>;
+ const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : FetchPixelsFunc(fetchPixels<bpp>);
+ const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel<bpp>);
int image_width = data->texture.width;
int image_height = data->texture.height;
diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h
index 457cc06d63..a2eb9b008c 100644
--- a/src/gui/painting/qemulationpaintengine_p.h
+++ b/src/gui/painting/qemulationpaintengine_p.h
@@ -62,37 +62,37 @@ class QEmulationPaintEngine : public QPaintEngineEx
public:
QEmulationPaintEngine(QPaintEngineEx *engine);
- virtual bool begin(QPaintDevice *pdev);
- virtual bool end();
+ bool begin(QPaintDevice *pdev) override;
+ bool end() override;
- virtual Type type() const;
- virtual QPainterState *createState(QPainterState *orig) const;
+ Type type() const override;
+ QPainterState *createState(QPainterState *orig) const override;
- virtual void fill(const QVectorPath &path, const QBrush &brush);
- virtual void stroke(const QVectorPath &path, const QPen &pen);
- virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
+ void fill(const QVectorPath &path, const QBrush &brush) override;
+ void stroke(const QVectorPath &path, const QPen &pen) override;
+ void clip(const QVectorPath &path, Qt::ClipOperation op) override;
- virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
- virtual void drawStaticTextItem(QStaticTextItem *item);
- virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override;
+ void drawTextItem(const QPointF &p, const QTextItem &textItem) override;
+ void drawStaticTextItem(QStaticTextItem *item) override;
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override;
+ void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags) override;
- virtual void clipEnabledChanged();
- virtual void penChanged();
- virtual void brushChanged();
- virtual void brushOriginChanged();
- virtual void opacityChanged();
- virtual void compositionModeChanged();
- virtual void renderHintsChanged();
- virtual void transformChanged();
+ void clipEnabledChanged() override;
+ void penChanged() override;
+ void brushChanged() override;
+ void brushOriginChanged() override;
+ void opacityChanged() override;
+ void compositionModeChanged() override;
+ void renderHintsChanged() override;
+ void transformChanged() override;
- virtual void setState(QPainterState *s);
+ void setState(QPainterState *s) override;
- virtual void beginNativePainting();
- virtual void endNativePainting();
+ void beginNativePainting() override;
+ void endNativePainting() override;
- virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;}
+ uint flags() const override { return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate; }
inline QPainterState *state() { return (QPainterState *)QPaintEngine::state; }
inline const QPainterState *state() const { return (const QPainterState *)QPaintEngine::state; }
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 8cde88fa82..59213220a6 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -287,7 +287,7 @@ public:
void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
- void systemStateChanged();
+ void systemStateChanged() override;
void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
const QRect &clip, int alpha, const QRect &sr = QRect());
diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h
index baad274818..17c73dd480 100644
--- a/src/gui/painting/qpdfwriter.h
+++ b/src/gui/painting/qpdfwriter.h
@@ -67,7 +67,7 @@ public:
QString creator() const;
void setCreator(const QString &creator);
- bool newPage();
+ bool newPage() override;
void setResolution(int resolution);
int resolution() const;
@@ -83,14 +83,14 @@ public:
using QPagedPaintDevice::setPageSize;
#endif
- void setPageSize(PageSize size);
- void setPageSizeMM(const QSizeF &size);
+ void setPageSize(PageSize size) override;
+ void setPageSizeMM(const QSizeF &size) override;
- void setMargins(const Margins &m);
+ void setMargins(const Margins &m) override;
protected:
- QPaintEngine *paintEngine() const;
- int metric(PaintDeviceMetric id) const;
+ QPaintEngine *paintEngine() const override;
+ int metric(PaintDeviceMetric id) const override;
private:
Q_DISABLE_COPY(QPdfWriter)
diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h
index ededb5d80b..1a7c184e1a 100644
--- a/src/gui/painting/qstroker_p.h
+++ b/src/gui/painting/qstroker_p.h
@@ -234,7 +234,7 @@ protected:
static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
- virtual void processCurrentSubpath();
+ void processCurrentSubpath() override;
qfixed m_strokeWidth;
qfixed m_miterLimit;
@@ -265,14 +265,14 @@ public:
void setDashOffset(qreal offset) { m_dashOffset = offset; }
qreal dashOffset() const { return m_dashOffset; }
- virtual void begin(void *data);
- virtual void end();
+ void begin(void *data) override;
+ void end() override;
inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
protected:
- virtual void processCurrentSubpath();
+ void processCurrentSubpath() override;
QStroker *m_stroker;
QVector<qfixed> m_dashPattern;
diff --git a/src/gui/painting/qt_attribution.json b/src/gui/painting/qt_attribution.json
index f635cf98ac..06a62d9d66 100644
--- a/src/gui/painting/qt_attribution.json
+++ b/src/gui/painting/qt_attribution.json
@@ -1,14 +1,31 @@
-{
- "Id": "grayraster",
- "Name": "Anti-aliasing rasterizer from FreeType 2",
- "QDocModule": "qtgui",
- "QtUsage": "Used in Qt GUI.",
- "Path": "qgrayraster.c",
+[
+ {
+ "Id": "grayraster",
+ "Name": "Anti-aliasing rasterizer from FreeType 2",
+ "QDocModule": "qtgui",
+ "QtUsage": "Used in Qt GUI.",
+ "Path": "qgrayraster.c",
- "Description": "FreeType is a freely available software library to render fonts.",
- "Homepage": "http://www.freetype.org",
- "License": "Freetype Project License or GNU General Public License v2.0 only",
- "LicenseId": "FTL or GPL-2.0",
- "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
- "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg."
-}
+ "Description": "FreeType is a freely available software library to render fonts.",
+ "Homepage": "http://www.freetype.org",
+ "License": "Freetype Project License or GNU General Public License v2.0 only",
+ "LicenseId": "FTL or GPL-2.0",
+ "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
+ "Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg."
+ },
+ {
+ "Id": "smooth-scaling-algorithm",
+ "Name": "Smooth Scaling Algorithm",
+ "QDocModule": "qtgui",
+ "QtUsage": "Used in Qt Gui (QImage::transformed() functions).",
+ "Files": "qimagescale.cpp",
+
+ "Description": "Normal smoothscale method, based on Imlib2's smoothscale.",
+ "LicenseId": "BSD-2-Clause AND Imlib2",
+ "License": "BSD 2-clause \"Simplified\" License and Imlib2 License",
+ "LicenseFile": "QIMAGETRANSFORM_LICENSE.txt",
+ "Copyright": "Copyright (C) 2004, 2005 Daniel M. Duley.
+ (C) Carsten Haitzler and various contributors.
+ (C) Willem Monsuwe <willem@stack.nl>"
+ }
+]
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 6f837de27f..128f75f93b 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -118,6 +118,7 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
{
for (int i = 0; i < channelCount; ++i) {
if (channels[i].socket) {
+ QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
channels[i].socket->close();
delete channels[i].socket;
}
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 7e3d2c5d6e..8fac76f86a 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -517,6 +517,19 @@ QHostAddress::QHostAddress(const QHostAddress &address)
QHostAddress::QHostAddress(SpecialAddress address)
: d(new QHostAddressPrivate)
{
+ 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;
@@ -567,6 +580,7 @@ QHostAddress &QHostAddress::operator=(const QHostAddress &address)
return *this;
}
+#if QT_DEPRECATED_SINCE(5, 8)
/*!
Assigns the host address \a address to this object, and returns a
reference to this object.
@@ -578,6 +592,20 @@ QHostAddress &QHostAddress::operator=(const QString &address)
setAddress(address);
return *this;
}
+#endif
+
+/*!
+ \since 5.8
+ Assigns the special address \a address to this object, and returns a
+ reference to this object.
+
+ \sa setAddress()
+*/
+QHostAddress &QHostAddress::operator=(SpecialAddress address)
+{
+ setAddress(address);
+ return *this;
+}
/*!
\fn bool QHostAddress::operator!=(const QHostAddress &other) const
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index 58af14ee33..10fe33f6fa 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -108,7 +108,11 @@ public:
#endif
QHostAddress &operator=(const QHostAddress &other);
+#if QT_DEPRECATED_SINCE(5, 8)
+ QT_DEPRECATED_X("use = QHostAddress(string) instead")
QHostAddress &operator=(const QString &address);
+#endif
+ QHostAddress &operator=(SpecialAddress address);
void swap(QHostAddress &other) Q_DECL_NOTHROW { d.swap(other.d); }
@@ -118,6 +122,7 @@ public:
void setAddress(const Q_IPV6ADDR &ip6Addr);
void setAddress(const sockaddr *address);
bool setAddress(const QString &address);
+ void setAddress(SpecialAddress address);
QAbstractSocket::NetworkLayerProtocol protocol() const;
quint32 toIPv4Address() const; // ### Qt6: merge with next overload
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index 8257eec9ea..8b36406c67 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -126,6 +126,33 @@ static HRESULT qt_winrt_try_create_thread_network_context(QString host, ComPtr<I
}
#endif // _MSC_VER >= 1900
+typedef QHash<qintptr, IStreamSocket *> TcpSocketHash;
+
+struct SocketHandler
+{
+ SocketHandler() : socketCount(0) {}
+ qintptr socketCount;
+ TcpSocketHash pendingTcpSockets;
+};
+
+Q_GLOBAL_STATIC(SocketHandler, gSocketHandler)
+
+struct SocketGlobal
+{
+ SocketGlobal()
+ {
+ HRESULT hr;
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
+ &bufferFactory);
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
+ ComPtr<IBufferFactory> bufferFactory;
+};
+Q_GLOBAL_STATIC(SocketGlobal, g)
+
+#define READ_BUFFER_SIZE 65536
+
static inline QString qt_QStringFromHString(const HString &string)
{
UINT32 length;
@@ -136,8 +163,43 @@ static inline QString qt_QStringFromHString(const HString &string)
class SocketEngineWorker : public QObject
{
Q_OBJECT
+public:
+ SocketEngineWorker(QNativeSocketEnginePrivate *engine)
+ : enginePrivate(engine)
+ {
+ }
+
+ ~SocketEngineWorker()
+ {
+ if (Q_UNLIKELY(initialReadOp)) {
+ ComPtr<IAsyncInfo> info;
+ HRESULT hr = initialReadOp.As(&info);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (info) {
+ hr = info->Cancel();
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = info->Close();
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ }
+
+ if (readOp) {
+ ComPtr<IAsyncInfo> info;
+ HRESULT hr = readOp.As(&info);
+ Q_ASSERT_SUCCEEDED(hr);
+ if (info) {
+ hr = info->Cancel();
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = info->Close();
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+ }
+ }
+
signals:
void newDatagramsReceived(const QList<WinRtDatagram> &datagram);
+ void newDataReceived(const QVector<QByteArray> &data);
+ void socketErrorOccured(QAbstractSocket::SocketError error);
public slots:
Q_INVOKABLE void notifyAboutNewDatagrams()
@@ -148,7 +210,30 @@ public slots:
emit newDatagramsReceived(datagrams);
}
+ Q_INVOKABLE void notifyAboutNewData()
+ {
+ QMutexLocker locker(&mutex);
+ const QVector<QByteArray> newData = std::move(pendingData);
+ pendingData.clear();
+ emit newDataReceived(newData);
+ }
+
public:
+ void startReading()
+ {
+ ComPtr<IBuffer> buffer;
+ HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
+ Q_ASSERT_SUCCEEDED(hr);
+ ComPtr<IInputStream> stream;
+ hr = tcpSocket->get_InputStream(&stream);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, initialReadOp.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ enginePrivate->socketState = QAbstractSocket::ConnectedState;
+ hr = initialReadOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &SocketEngineWorker::onReadyRead).Get());
+ Q_ASSERT_SUCCEEDED(hr);
+ }
+
HRESULT OnNewDatagramReceived(IDatagramSocket *, IDatagramSocketMessageReceivedEventArgs *args)
{
WinRtDatagram datagram;
@@ -184,9 +269,127 @@ public:
return S_OK;
}
+ HRESULT onReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status)
+ {
+ if (asyncInfo == initialReadOp.Get()) {
+ initialReadOp.Reset();
+ } else if (asyncInfo == readOp.Get()) {
+ readOp.Reset();
+ } else {
+ Q_ASSERT(false);
+ }
+
+ // A read in UnconnectedState will close the socket and return -1 and thus tell the caller,
+ // that the connection was closed. The socket cannot be closed here, as the subsequent read
+ // might fail then.
+ if (status == Error || status == Canceled) {
+ emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError);
+ return S_OK;
+ }
+
+ ComPtr<IBuffer> buffer;
+ HRESULT hr = asyncInfo->GetResults(&buffer);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get read results buffer");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+
+ UINT32 bufferLength;
+ hr = buffer->get_Length(&bufferLength);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get buffer length");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+ // A zero sized buffer length signals, that the remote host closed the connection. The socket
+ // cannot be closed though, as the following read might have socket descriptor -1 and thus and
+ // the closing of the socket won't be communicated to the caller. So only the error is set. The
+ // actual socket close happens inside of read.
+ if (!bufferLength) {
+ emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError);
+ return S_OK;
+ }
+
+ ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
+ hr = buffer.As(&byteArrayAccess);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get cast buffer");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+ byte *data;
+ hr = byteArrayAccess->Buffer(&data);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to access buffer data");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+
+ QByteArray newData(reinterpret_cast<const char*>(data), qint64(bufferLength));
+ QMutexLocker readLocker(&mutex);
+ if (pendingData.isEmpty())
+ QMetaObject::invokeMethod(this, "notifyAboutNewData", Qt::QueuedConnection);
+ pendingData << newData;
+ readLocker.unlock();
+
+ hr = QEventDispatcherWinRT::runOnXamlThread([buffer, this]() {
+ UINT32 readBufferLength;
+ ComPtr<IInputStream> stream;
+ HRESULT hr = tcpSocket->get_InputStream(&stream);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to obtain input stream");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+
+ // Reuse the stream buffer
+ hr = buffer->get_Capacity(&readBufferLength);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to get buffer capacity");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+ hr = buffer->put_Length(0);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "Failed to set buffer length");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+
+ hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp);
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "onReadyRead(): Could not read into socket stream buffer.");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+ hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &SocketEngineWorker::onReadyRead).Get());
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "onReadyRead(): Failed to set socket read callback.");
+ emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
+ return S_OK;
+ }
+ return S_OK;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+ return S_OK;
+ }
+
+ void setTcpSocket(ComPtr<IStreamSocket> socket) { tcpSocket = socket; }
+
private:
+ ComPtr<IStreamSocket> tcpSocket;
+
QList<WinRtDatagram> pendingDatagrams;
+ QVector<QByteArray> pendingData;
+
+ // Protects pendingData/pendingDatagrams which are accessed from native callbacks
QMutex mutex;
+
+ ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> initialReadOp;
+ ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> readOp;
+
+ QNativeSocketEnginePrivate *enginePrivate;
};
static QByteArray socketDescription(const QAbstractSocketEngine *s)
@@ -239,33 +442,6 @@ static QByteArray socketDescription(const QAbstractSocketEngine *s)
} } while (0)
#define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a)
-typedef QHash<qintptr, IStreamSocket *> TcpSocketHash;
-
-struct SocketHandler
-{
- SocketHandler() : socketCount(0) {}
- qintptr socketCount;
- TcpSocketHash pendingTcpSockets;
-};
-
-Q_GLOBAL_STATIC(SocketHandler, gSocketHandler)
-
-struct SocketGlobal
-{
- SocketGlobal()
- {
- HRESULT hr;
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
- &bufferFactory);
- Q_ASSERT_SUCCEEDED(hr);
- }
-
- ComPtr<IBufferFactory> bufferFactory;
-};
-Q_GLOBAL_STATIC(SocketGlobal, g)
-
-#define READ_BUFFER_SIZE 65536
-
template <typename T>
static AsyncStatus opStatus(const ComPtr<T> &op)
{
@@ -315,6 +491,10 @@ QNativeSocketEngine::QNativeSocketEngine(QObject *parent)
connect(this, SIGNAL(readReady()), SLOT(readNotification()), Qt::QueuedConnection);
connect(this, SIGNAL(writeReady()), SLOT(writeNotification()), Qt::QueuedConnection);
connect(d->worker, &SocketEngineWorker::newDatagramsReceived, this, &QNativeSocketEngine::handleNewDatagrams, Qt::QueuedConnection);
+ connect(d->worker, &SocketEngineWorker::newDataReceived,
+ this, &QNativeSocketEngine::handleNewData, Qt::QueuedConnection);
+ connect(d->worker, &SocketEngineWorker::socketErrorOccured,
+ this, &QNativeSocketEngine::handleTcpError, Qt::QueuedConnection);
}
QNativeSocketEngine::~QNativeSocketEngine()
@@ -358,23 +538,9 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
// Start processing incoming data
if (d->socketType == QAbstractSocket::TcpSocket) {
- HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, socketState, this]() {
- ComPtr<IBuffer> buffer;
- HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
- RETURN_HR_IF_FAILED("initialize(): Could not create buffer");
- ComPtr<IInputStream> stream;
- hr = socket->get_InputStream(&stream);
- RETURN_HR_IF_FAILED("initialize(): Could not obtain input stream");
- ComPtr<IAsyncBufferOperation> readOp;
- hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf());
- RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).",
- socketDescription(this).constData());
- QMutexLocker locker(&d->readOperationsMutex);
- d->pendingReadOps.append(readOp);
- d->socketState = socketState;
- hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get());
- RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to set socket read callback (%s).",
- socketDescription(this).constData());
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() {
+ d->worker->setTcpSocket(socket);
+ d->worker->startReading();
return S_OK;
});
if (FAILED(hr))
@@ -639,20 +805,6 @@ void QNativeSocketEngine::close()
}
#endif // _MSC_VER >= 1900
- QMutexLocker locker(&d->readOperationsMutex);
- for (ComPtr<IAsyncBufferOperation> readOp : d->pendingReadOps) {
- ComPtr<IAsyncInfo> info;
- hr = readOp.As(&info);
- Q_ASSERT_SUCCEEDED(hr);
- if (info) {
- hr = info->Cancel();
- Q_ASSERT_SUCCEEDED(hr);
- hr = info->Close();
- Q_ASSERT_SUCCEEDED(hr);
- }
- }
- locker.unlock();
-
if (d->socketDescriptor != -1) {
ComPtr<IClosable> socket;
if (d->socketType == QAbstractSocket::TcpSocket) {
@@ -730,14 +882,32 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen)
// happens and there isn't anything left in the buffer, we have to return -1 in order to signal
// the closing of the socket.
QMutexLocker mutexLocker(&d->readMutex);
- if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) {
+ if (d->pendingData.isEmpty() && d->socketState != QAbstractSocket::ConnectedState) {
close();
return -1;
}
- qint64 b = d->readBytes.read(data, maxlen);
- d->bytesAvailable = d->readBytes.size() - d->readBytes.pos();
- return b;
+ QByteArray readData;
+ qint64 leftToMaxLen = maxlen;
+ while (leftToMaxLen > 0 && !d->pendingData.isEmpty()) {
+ QByteArray pendingData = d->pendingData.takeFirst();
+ // Do not read the whole data. Put the rest of it back into the "queue"
+ if (leftToMaxLen < pendingData.length()) {
+ readData += pendingData.left(leftToMaxLen);
+ pendingData = pendingData.remove(0, maxlen);
+ d->pendingData.prepend(pendingData);
+ break;
+ } else {
+ readData += pendingData;
+ leftToMaxLen -= pendingData.length();
+ }
+ }
+ const int copyLength = qMin(maxlen, qint64(readData.length()));
+ d->bytesAvailable -= copyLength;
+ mutexLocker.unlock();
+
+ memcpy(data, readData, copyLength);
+ return copyLength;
}
qint64 QNativeSocketEngine::write(const char *data, qint64 len)
@@ -913,7 +1083,7 @@ bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
// If we are a client, we are ready to read if our buffer has data
QMutexLocker locker(&d->readMutex);
- if (!d->readBytes.atEnd())
+ if (!d->pendingData.isEmpty())
return true;
// Nothing to do, wait for more events
@@ -1001,21 +1171,8 @@ void QNativeSocketEngine::establishRead()
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
- ComPtr<IInputStream> stream;
- HRESULT hr = d->tcpSocket()->get_InputStream(&stream);
- RETURN_HR_IF_FAILED("establishRead(): Failed to get socket input stream");
-
- ComPtr<IBuffer> buffer;
- hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
- RETURN_HR_IF_FAILED("establishRead(): Failed to create buffer");
-
- ComPtr<IAsyncBufferOperation> readOp;
- hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf());
- RETURN_HR_IF_FAILED("establishRead(): Failed to initiate socket read");
- QMutexLocker locker(&d->readOperationsMutex);
- d->pendingReadOps.append(readOp);
- hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get());
- RETURN_HR_IF_FAILED("establishRead(): Failed to register read callback");
+ d->worker->setTcpSocket(d->tcpSocket());
+ d->worker->startReading();
return S_OK;
});
Q_ASSERT_SUCCEEDED(hr);
@@ -1032,6 +1189,32 @@ void QNativeSocketEngine::handleNewDatagrams(const QList<WinRtDatagram> &datagra
emit readReady();
}
+void QNativeSocketEngine::handleNewData(const QVector<QByteArray> &data)
+{
+ // Defer putting the data into the list until the next event loop iteration
+ // (where the readyRead signal is emitted as well)
+ QMetaObject::invokeMethod(this, "putIntoPendingData", Qt::QueuedConnection,
+ Q_ARG(QVector<QByteArray>, data));
+}
+
+void QNativeSocketEngine::handleTcpError(QAbstractSocket::SocketError error)
+{
+ Q_D(QNativeSocketEngine);
+ QNativeSocketEnginePrivate::ErrorString errorString;
+ switch (error) {
+ case QAbstractSocket::RemoteHostClosedError:
+ errorString = QNativeSocketEnginePrivate::RemoteHostClosedErrorString;
+ break;
+ default:
+ errorString = QNativeSocketEnginePrivate::UnknownSocketErrorString;
+ }
+
+ d->setError(error, errorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ if (d->notifyOnRead)
+ emit readReady();
+}
+
void QNativeSocketEngine::putIntoPendingDatagramsList(const QList<WinRtDatagram> &datagrams)
{
Q_D(QNativeSocketEngine);
@@ -1039,6 +1222,18 @@ void QNativeSocketEngine::putIntoPendingDatagramsList(const QList<WinRtDatagram>
d->pendingDatagrams.append(datagrams);
}
+void QNativeSocketEngine::putIntoPendingData(const QVector<QByteArray> &data)
+{
+ Q_D(QNativeSocketEngine);
+ QMutexLocker locker(&d->readMutex);
+ d->pendingData.append(data);
+ for (const QByteArray &newData : data)
+ d->bytesAvailable += newData.length();
+ locker.unlock();
+ if (d->notifyOnRead)
+ readNotification();
+}
+
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
{
Q_UNUSED(socketProtocol);
@@ -1093,7 +1288,7 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
, notifyOnException(false)
, closingDown(false)
, socketDescriptor(-1)
- , worker(new SocketEngineWorker)
+ , worker(new SocketEngineWorker(this))
, sslSocket(Q_NULLPTR)
, connectionToken( { -1 } )
{
@@ -1481,109 +1676,6 @@ HRESULT QNativeSocketEnginePrivate::handleConnectOpFinished(IAsyncAction *action
return S_OK;
}
-HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status)
-{
- if (closingDown || wasDeleted || isDeletingChildren
- || socketState == QAbstractSocket::UnconnectedState) {
- return S_OK;
- }
-
- Q_Q(QNativeSocketEngine);
- QMutexLocker locker(&readOperationsMutex);
- for (int i = 0; i < pendingReadOps.count(); ++i) {
- if (pendingReadOps.at(i).Get() == asyncInfo) {
- pendingReadOps.takeAt(i);
- break;
- }
- }
- locker.unlock();
-
- // A read in UnconnectedState will close the socket and return -1 and thus tell the caller,
- // that the connection was closed. The socket cannot be closed here, as the subsequent read
- // might fail then.
- if (status == Error || status == Canceled) {
- setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- if (notifyOnRead)
- emit q->readReady();
- return S_OK;
- }
-
- ComPtr<IBuffer> buffer;
- HRESULT hr = asyncInfo->GetResults(&buffer);
- RETURN_OK_IF_FAILED("Failed to get read results buffer");
-
- UINT32 bufferLength;
- hr = buffer->get_Length(&bufferLength);
- Q_ASSERT_SUCCEEDED(hr);
- // A zero sized buffer length signals, that the remote host closed the connection. The socket
- // cannot be closed though, as the following read might have socket descriptor -1 and thus and
- // the closing of the socket won't be communicated to the caller. So only the error is set. The
- // actual socket close happens inside of read.
- if (!bufferLength) {
- setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- if (notifyOnRead)
- emit q->readReady();
- return S_OK;
- }
-
- ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
- hr = buffer.As(&byteArrayAccess);
- Q_ASSERT_SUCCEEDED(hr);
- byte *data;
- hr = byteArrayAccess->Buffer(&data);
- Q_ASSERT_SUCCEEDED(hr);
-
- QMutexLocker readLocker(&readMutex);
- if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset
- readBytes.close();
- if (!readBytes.isOpen())
- readBytes.open(QBuffer::ReadWrite|QBuffer::Truncate);
- qint64 readPos = readBytes.pos();
- readBytes.seek(readBytes.size());
- Q_ASSERT(readBytes.atEnd());
- readBytes.write(reinterpret_cast<const char*>(data), qint64(bufferLength));
- readBytes.seek(readPos);
- bytesAvailable = readBytes.size() - readBytes.pos();
- readLocker.unlock();
-
- if (notifyOnRead)
- emit q->readReady();
-
- hr = QEventDispatcherWinRT::runOnXamlThread([buffer, q, this]() {
- UINT32 readBufferLength;
- ComPtr<IInputStream> stream;
- HRESULT hr = tcpSocket()->get_InputStream(&stream);
- RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain input stream");
-
- // Reuse the stream buffer
- hr = buffer->get_Capacity(&readBufferLength);
- RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain buffer capacity");
- hr = buffer->put_Length(0);
- RETURN_HR_IF_FAILED("handleReadyRead(): Could not set buffer length");
-
- ComPtr<IAsyncBufferOperation> readOp;
- hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "handleReadyRead(): Could not read into socket stream buffer (%s).",
- socketDescription(q).constData());
- return S_OK;
- }
- QMutexLocker locker(&readOperationsMutex);
- pendingReadOps.append(readOp);
- hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get());
- if (FAILED(hr)) {
- qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).",
- socketDescription(q).constData());
- return S_OK;
- }
- return S_OK;
- });
- Q_ASSERT_SUCCEEDED(hr);
- return S_OK;
-}
-
HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args)
{
Q_Q(QNativeSocketEngine);
diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h
index 085704275c..9758310902 100644
--- a/src/network/socket/qnativesocketengine_winrt_p.h
+++ b/src/network/socket/qnativesocketengine_winrt_p.h
@@ -144,9 +144,12 @@ signals:
private slots:
void establishRead();
void handleNewDatagrams(const QList<WinRtDatagram> &datagram);
+ void handleNewData(const QVector<QByteArray> &data);
+ void handleTcpError(QAbstractSocket::SocketError error);
private:
Q_INVOKABLE void putIntoPendingDatagramsList(const QList<WinRtDatagram> &datagrams);
+ Q_INVOKABLE void putIntoPendingData(const QVector<QByteArray> &data);
Q_DECLARE_PRIVATE(QNativeSocketEngine)
Q_DISABLE_COPY(QNativeSocketEngine)
@@ -215,23 +218,17 @@ private:
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> connectOp;
- // Protected by readOperationsMutex. Written in handleReadyRead (native callback)
- QVector<Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32>>> pendingReadOps;
-
- // Protected by readMutex. Written in handleReadyRead (native callback)
- QBuffer readBytes;
-
// In case of TCP readMutex protects readBytes and bytesAvailable. In case of UDP it is
// pendingDatagrams. They are written inside native callbacks (handleReadyRead and
// handleNewDatagrams/putIntoPendingDatagramsList)
mutable QMutex readMutex;
- // As pendingReadOps is changed inside handleReadyRead(native callback) it has to be protected
- QMutex readOperationsMutex;
-
// Protected by readMutex. Written in handleReadyRead (native callback)
QAtomicInteger<int> bytesAvailable;
+ // Protected by readMutex. Written in handleNewData/putIntoPendingData (native callback)
+ QVector<QByteArray> pendingData;
+
// Protected by readMutex. Written in handleNewDatagrams/putIntoPendingDatagramsList
QList<WinRtDatagram> pendingDatagrams;
@@ -246,7 +243,6 @@ private:
HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener,
ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args);
HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus);
- HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32> *asyncInfo, ABI::Windows::Foundation::AsyncStatus);
};
QT_END_NAMESPACE
diff --git a/src/platformheaders/nativecontexts/qeglnativecontext.h b/src/platformheaders/nativecontexts/qeglnativecontext.h
index 697b3ef3fd..eae74126fd 100644
--- a/src/platformheaders/nativecontexts/qeglnativecontext.h
+++ b/src/platformheaders/nativecontexts/qeglnativecontext.h
@@ -41,7 +41,8 @@
#define QEGLNATIVECONTEXT_H
#include <QtCore/QMetaType>
-#include <QtEglSupport/private/qt_egl_p.h>
+
+// Leave including egl.h with the appropriate defines to the client.
QT_BEGIN_NAMESPACE
diff --git a/src/platformheaders/nativecontexts/qeglnativecontext.qdoc b/src/platformheaders/nativecontexts/qeglnativecontext.qdoc
index e6a4048376..22e763ec24 100644
--- a/src/platformheaders/nativecontexts/qeglnativecontext.qdoc
+++ b/src/platformheaders/nativecontexts/qeglnativecontext.qdoc
@@ -36,6 +36,12 @@
that an application using it is only guaranteed to work with the Qt version it was
developed against.
+ \note Due to being public while relying on otherwise hidden EGL types, this header
+ itself does not include \c{EGL/egl.h}. It is the application's responsibility to
+ include egl.h with any appropriate defines (for example, \c{MESA_EGL_NO_X11_HEADERS}
+ or other vendor-specific defines controlling the typedefs for EGL's native resources)
+ before this header.
+
\sa QOpenGLContext::setNativeHandle(), QOpenGLContext::nativeHandle()
*/
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
index 6130107cc8..683b7f65ad 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
@@ -663,7 +663,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
glyphRun.glyphOffsets = &glyphOffset;
QTransform xform = originalTransform;
- if (fontDef.stretch != 100)
+ if (fontDef.stretch != 100 && fontDef.stretch != QFont::AnyStretch)
xform.scale(fontDef.stretch / 100.0, 1.0);
DWRITE_MATRIX transform;
@@ -933,7 +933,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
Q_UNUSED(format);
QTransform matrix = originalTransform;
- if (fontDef.stretch != 100)
+ if (fontDef.stretch != 100 && fontDef.stretch != QFont::AnyStretch)
matrix.scale(fontDef.stretch / 100.0, 1.0);
glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index d89b8d398b..68619928d3 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -767,6 +767,10 @@ static bool readExifHeader(QDataStream &stream)
*/
static int getExifOrientation(QByteArray &exifData)
{
+ // Current EXIF version (2.3) says there can be at most 5 IFDs,
+ // byte we allow for 10 so we're able to deal with future extensions.
+ const int maxIfdCount = 10;
+
QDataStream stream(&exifData, QIODevice::ReadOnly);
if (!readExifHeader(stream))
@@ -774,7 +778,8 @@ static int getExifOrientation(QByteArray &exifData)
quint16 val;
quint32 offset;
- const qint64 headerStart = stream.device()->pos();
+ const qint64 headerStart = 6; // the EXIF header has a constant size
+ Q_ASSERT(headerStart == stream.device()->pos());
// read byte order marker
stream >> val;
@@ -785,7 +790,7 @@ static int getExifOrientation(QByteArray &exifData)
else
return -1; // unknown byte order
- // read size
+ // confirm byte order
stream >> val;
if (val != 0x2a)
return -1;
@@ -793,18 +798,22 @@ static int getExifOrientation(QByteArray &exifData)
stream >> offset;
// read IFD
- while (!stream.atEnd()) {
+ for (int n = 0; n < maxIfdCount; ++n) {
quint16 numEntries;
- // skip offset bytes to get the next IFD
const qint64 bytesToSkip = offset - (stream.device()->pos() - headerStart);
-
- if (stream.skipRawData(bytesToSkip) != bytesToSkip)
+ if (bytesToSkip < 0 || (offset + headerStart >= exifData.size())) {
+ // disallow going backwards, though it's permitted in the spec
return -1;
+ } else if (bytesToSkip != 0) {
+ // seek to the IFD
+ if (!stream.device()->seek(offset + headerStart))
+ return -1;
+ }
stream >> numEntries;
- for (; numEntries > 0; --numEntries) {
+ for (; numEntries > 0 && stream.status() == QDataStream::Ok; --numEntries) {
quint16 tag;
quint16 type;
quint32 components;
@@ -828,12 +837,14 @@ static int getExifOrientation(QByteArray &exifData)
// read offset to next IFD
stream >> offset;
+ if (stream.status() != QDataStream::Ok)
+ return -1;
if (offset == 0) // this is the last IFD
- break;
+ return 0; // No Exif orientation was found
}
- // No Exif orientation was found
- return 0;
+ // too many IFDs
+ return -1;
}
static QImageIOHandler::Transformations exif2Qt(int exifOrientation)
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index a987092862..3b1ce6d21d 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -54,7 +54,6 @@
static const char m_qtTag[] = "Qt A11Y";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
-static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 5f05ab395e..d3bb089aa4 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -810,7 +810,7 @@ namespace QtAndroidInput
#endif
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
if (inputContext && qGuiApp)
- QMetaObject::invokeMethod(inputContext, "handleLocationChanged",
+ QMetaObject::invokeMethod(inputContext, "handleLocationChanged", Qt::BlockingQueuedConnection,
Q_ARG(int, id), Q_ARG(int, x), Q_ARG(int, y));
}
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index df8883ab34..1f681cc1a3 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -122,8 +122,6 @@ static int m_desktopHeightPixels = 0;
static double m_scaledDensity = 0;
static double m_density = 1.0;
-static volatile bool m_pauseApplication;
-
static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = nullptr;
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 2656d45d5f..12e85046f8 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -578,6 +578,11 @@ void QAndroidInputContext::updateSelectionHandles()
*/
void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
{
+ if (m_batchEditNestingLevel.load() || m_blockUpdateSelection)
+ return;
+
+ finishComposingText();
+
auto im = qGuiApp->inputMethod();
auto leftRect = im->cursorRectangle();
// The handle is down of the cursor, but we want the position in the middle.
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index ce0ec8724c..e7692bf720 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -152,7 +152,7 @@ private:
CursorHandleShowPopup = 3
};
CursorHandleShowMode m_cursorHandleShown;
- int m_batchEditNestingLevel;
+ QAtomicInt m_batchEditNestingLevel;
QObject *m_focusObject;
};
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 88ffd48538..e177a24e73 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -331,11 +331,12 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
{
- item->nsItem().target = m_nativeMenu.delegate;
- item->nsItem().action = @selector(itemFired:);
+ NSMenuItem *nativeItem = item->nsItem();
+ nativeItem.target = m_nativeMenu.delegate;
+ nativeItem.action = @selector(itemFired:);
// Someone's adding new items after aboutToShow() was emitted
- if (isOpen() && item->menu() && item->nsItem())
- item->menu()->setAttachedItem(item->nsItem());
+ if (isOpen() && nativeItem && item->menu())
+ item->menu()->setAttachedItem(nativeItem);
item->setParentEnabled(isEnabled());
@@ -348,15 +349,20 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
beforeItem = itemOrNull(m_menuItems.indexOf(beforeItem) + 1);
}
+ if (nativeItem.menu) {
+ qWarning() << "Menu item" << item->text() << "already in menu" << QString::fromNSString(nativeItem.menu.title);
+ return;
+ }
+
if (beforeItem) {
if (beforeItem->isMerged()) {
qWarning("No non-merged before menu item found");
return;
}
- NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem->nsItem()];
- [m_nativeMenu insertItem: item->nsItem() atIndex: nativeIndex];
+ const NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem->nsItem()];
+ [m_nativeMenu insertItem:nativeItem atIndex:nativeIndex];
} else {
- [m_nativeMenu addItem: item->nsItem()];
+ [m_nativeMenu addItem:nativeItem];
}
item->setMenuParent(this);
}
@@ -413,9 +419,8 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem)
return;
}
- bool wasMerged = cocoaItem->isMerged();
- NSMenu *oldMenu = wasMerged ? [[QCocoaMenuLoader sharedMenuLoader] applicationMenu] : m_nativeMenu;
- NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem];
+ const bool wasMerged = cocoaItem->isMerged();
+ NSMenuItem *oldItem = cocoaItem->nsItem();
if (cocoaItem->sync() != oldItem) {
// native item was changed for some reason
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index e32ff26ff5..21f2b4de85 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -288,7 +288,7 @@ NSMenuItem *QCocoaMenuItem::sync()
}
default:
- qWarning() << "menu item" << m_text << "has unsupported role" << (int)m_role;
+ qWarning() << "Menu item" << m_text << "has unsupported role" << m_role;
}
if (mergeItem) {
diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro
index 4e95aebe35..e500d8c419 100644
--- a/src/plugins/platforms/directfb/directfb.pro
+++ b/src/plugins/platforms/directfb/directfb.pro
@@ -3,7 +3,7 @@ TARGET = qdirectfb
QT += \
core-private gui-private \
eventdispatcher_support-private service_support-private \
- fontdatabase_support-private egl_support-private
+ fontdatabase_support-private
QMAKE_USE += directfb
@@ -28,6 +28,7 @@ HEADERS = qdirectfbintegration.h \
# ### port the GL context
contains(QT_CONFIG, directfb_egl) {
+ QT += egl_support-private
HEADERS += qdirectfb_egl.h
SOURCES += qdirectfb_egl.cpp
DEFINES += DIRECTFB_GL_EGL
diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp
index 3ded96b9d6..977bbfd11b 100644
--- a/src/plugins/platforms/windows/qwin10helpers.cpp
+++ b/src/plugins/platforms/windows/qwin10helpers.cpp
@@ -44,7 +44,8 @@
#if defined(Q_CC_MINGW)
# define HAS_UI_VIEW_SETTINGS_INTEROP
-#elif !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // MSVC2013 is lacking both
+// Present from MSVC2015 + SDK 10 onwards
+#elif (!defined(Q_CC_MSVC) || _MSC_VER >= 1900) && NTDDI_VERSION >= 0xa000000
# define HAS_UI_VIEW_SETTINGS_INTEROP
# define HAS_UI_VIEW_SETTINGS
#endif
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 6d4edcc8dc..f87ae9fd24 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -486,6 +486,9 @@ public:
QHash<ApplicationView2CallbackRemover, EventRegistrationToken> view2Tokens;
ComPtr<IApplicationView2> view2;
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
+ QAtomicPointer<QWinRTWindow> mouseGrabWindow;
+ QAtomicPointer<QWinRTWindow> keyboardGrabWindow;
+ QWindow *currentPressWindow = 0;
};
// To be called from the XAML thread
@@ -877,6 +880,44 @@ void QWinRTScreen::lower(QWindow *window)
handleExpose();
}
+bool QWinRTScreen::setMouseGrabWindow(QWinRTWindow *window, bool grab)
+{
+ Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window
+ << "(" << window->window()->objectName() << "):" << grab;
+
+ if (!grab || window == nullptr)
+ d->mouseGrabWindow = nullptr;
+ else if (d->mouseGrabWindow != window)
+ d->mouseGrabWindow = window;
+ return grab;
+}
+
+QWinRTWindow *QWinRTScreen::mouseGrabWindow() const
+{
+ Q_D(const QWinRTScreen);
+ return d->mouseGrabWindow;
+}
+
+bool QWinRTScreen::setKeyboardGrabWindow(QWinRTWindow *window, bool grab)
+{
+ Q_D(QWinRTScreen);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window
+ << "(" << window->window()->objectName() << "):" << grab;
+
+ if (!grab || window == nullptr)
+ d->keyboardGrabWindow = nullptr;
+ else if (d->keyboardGrabWindow != window)
+ d->keyboardGrabWindow = window;
+ return grab;
+}
+
+QWinRTWindow *QWinRTScreen::keyboardGrabWindow() const
+{
+ Q_D(const QWinRTScreen);
+ return d->keyboardGrabWindow;
+}
+
void QWinRTScreen::updateWindowTitle(const QString &title)
{
Q_D(QWinRTScreen);
@@ -1022,7 +1063,11 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
pointerPoint->get_Position(&point);
QPoint pos(point.X * d->scaleFactor, point.Y * d->scaleFactor);
- QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
+ QWindow *targetWindow = topWindow();
+ if (d->mouseGrabWindow)
+ targetWindow = d->mouseGrabWindow.load()->window();
+
+ QWindowSystemInterface::handleEnterEvent(targetWindow, pos, pos);
}
return S_OK;
}
@@ -1041,7 +1086,11 @@ HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
d->touchPoints.remove(id);
- QWindowSystemInterface::handleLeaveEvent(0);
+ QWindow *targetWindow = nullptr;
+ if (d->mouseGrabWindow)
+ targetWindow = d->mouseGrabWindow.load()->window();
+
+ QWindowSystemInterface::handleLeaveEvent(targetWindow);
return S_OK;
}
@@ -1063,7 +1112,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
QPointF localPos = pos;
const QPoint posPoint = pos.toPoint();
- QWindow *targetWindow = windowAt(posPoint);
+ QWindow *windowUnderPointer = windowAt(posPoint);
+ QWindow *targetWindow = windowUnderPointer;
+
+ if (d->mouseGrabWindow)
+ targetWindow = d->mouseGrabWindow.load()->window();
+
if (targetWindow) {
const QPointF globalPosDelta = pos - posPoint;
localPos = targetWindow->mapFromGlobal(posPoint) + globalPosDelta;
@@ -1127,6 +1181,22 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
if (isPressed)
buttons |= Qt::XButton2;
+ // In case of a mouse grab we have to store the target of a press event
+ // to be able to send one additional release event to this target when the mouse
+ // button is released. This is a similar approach to AutoMouseCapture in the
+ // windows qpa backend. Otherwise the release might not be propagated and the original
+ // press event receiver considers a button to still be pressed, as in Qt Quick Controls 1
+ // menus.
+ if (buttons != Qt::NoButton && d->currentPressWindow == nullptr && !d->mouseGrabWindow)
+ d->currentPressWindow = windowUnderPointer;
+ if (!isPressed && d->currentPressWindow && d->mouseGrabWindow) {
+ const QPointF globalPosDelta = pos - posPoint;
+ const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta;
+
+ QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos, buttons, mods);
+ d->currentPressWindow = nullptr;
+ }
+
QWindowSystemInterface::handleMouseEvent(targetWindow, localPos, pos, buttons, mods);
break;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index 2f1112472c..7dcdb98ead 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -83,6 +83,7 @@ class QTouchDevice;
class QWinRTCursor;
class QWinRTInputContext;
class QWinRTScreenPrivate;
+class QWinRTWindow;
class QWinRTScreen : public QPlatformScreen
{
public:
@@ -110,6 +111,12 @@ public:
void raise(QWindow *window);
void lower(QWindow *window);
+ bool setMouseGrabWindow(QWinRTWindow *window, bool grab);
+ QWinRTWindow* mouseGrabWindow() const;
+
+ bool setKeyboardGrabWindow(QWinRTWindow *window, bool grab);
+ QWinRTWindow* keyboardGrabWindow() const;
+
void updateWindowTitle(const QString &title);
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 297e6618d1..8f3b86ff3b 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -191,6 +191,11 @@ QWinRTWindow::~QWinRTWindow()
});
RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down");
+ if (d->screen->mouseGrabWindow() == this)
+ d->screen->setMouseGrabWindow(this, false);
+ if (d->screen->keyboardGrabWindow() == this)
+ d->screen->setKeyboardGrabWindow(this, false);
+
d->screen->removeWindow(window());
if (!d->surface)
@@ -384,6 +389,24 @@ void QWinRTWindow::setWindowState(Qt::WindowState state)
d->state = state;
}
+bool QWinRTWindow::setMouseGrabEnabled(bool grab)
+{
+ Q_D(QWinRTWindow);
+ if (!isActive() && grab) {
+ qWarning("%s: Not setting mouse grab for invisible window %s/'%s'",
+ __FUNCTION__, window()->metaObject()->className(),
+ qPrintable(window()->objectName()));
+ return false;
+ }
+ return d->screen->setMouseGrabWindow(this, grab);
+}
+
+bool QWinRTWindow::setKeyboardGrabEnabled(bool grab)
+{
+ Q_D(QWinRTWindow);
+ return d->screen->setKeyboardGrabWindow(this, grab);
+}
+
EGLSurface QWinRTWindow::eglSurface() const
{
Q_D(const QWinRTWindow);
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 968edcfa85..26c2fa800d 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -70,6 +70,9 @@ public:
qreal devicePixelRatio() const override;
void setWindowState(Qt::WindowState state) override;
+ bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
+ bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE;
+
EGLSurface eglSurface() const;
void createEglSurface(EGLDisplay display, EGLConfig config);
diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
index ba5089a8bc..699b058932 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
@@ -135,10 +135,12 @@ bool QGtk3Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWind
GdkWindow *gdkWindow = gtk_widget_get_window(gtkWidget);
if (parent) {
- GdkDisplay *gdkDisplay = gdk_window_get_display(gdkWindow);
- XSetTransientForHint(gdk_x11_display_get_xdisplay(gdkDisplay),
- gdk_x11_window_get_xid(gdkWindow),
- parent->winId());
+ if (GDK_IS_X11_WINDOW(gdkWindow)) {
+ GdkDisplay *gdkDisplay = gdk_window_get_display(gdkWindow);
+ XSetTransientForHint(gdk_x11_display_get_xdisplay(gdkDisplay),
+ gdk_x11_window_get_xid(gdkWindow),
+ parent->winId());
+ }
}
if (modality != Qt::NonModal) {
diff --git a/src/src.pro b/src/src.pro
index b13bc4fa43..90d7e2b76c 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -164,7 +164,7 @@ qtConfig(gui) {
SUBDIRS += src_angle
src_gui.depends += src_angle
}
- qtConfig(png) {
+ qtConfig(png):!qtConfig(system-png) {
SUBDIRS += src_3rdparty_libpng
src_3rdparty_freetype.depends += src_3rdparty_libpng
src_gui.depends += src_3rdparty_libpng
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index 55cf7ed872..6128d5490b 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -477,9 +477,6 @@ int runMoc(int argc, char **argv)
}
moc.symbols += pp.preprocessed(moc.filename, &in);
- // We obviously do not support MS extensions
- pp.macros.remove("_MSC_EXTENSIONS");
-
if (!pp.preprocessOnly) {
// 2. parse
moc.parse();
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpg
new file mode 100644
index 0000000000..164d3080a3
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_back_pointers.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpg
new file mode 100644
index 0000000000..7e2451e6f9
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_past_end.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_ifds.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_ifds.jpg
new file mode 100644
index 0000000000..52c6a93f08
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_ifds.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_tags.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_tags.jpg
new file mode 100644
index 0000000000..6a080aada7
--- /dev/null
+++ b/tests/auto/gui/image/qimage/images/jpeg_exif_invalid_data_too_many_tags.jpg
Binary files differ
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index a1ab812aaa..2433fa4115 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -188,7 +188,8 @@ private slots:
void exifOrientation();
void exif_QTBUG45865();
- void exif_invalid_data_QTBUG46870();
+ void exifInvalidData_data();
+ void exifInvalidData();
void cleanupFunctions();
@@ -3049,10 +3050,20 @@ void tst_QImage::exif_QTBUG45865()
QCOMPARE(image.size(), QSize(5, 8));
}
-void tst_QImage::exif_invalid_data_QTBUG46870()
+void tst_QImage::exifInvalidData_data()
+{
+ QTest::addColumn<bool>("$never used");
+ QTest::newRow("QTBUG-46870");
+ QTest::newRow("back_pointers");
+ QTest::newRow("past_end");
+ QTest::newRow("too_many_ifds");
+ QTest::newRow("too_many_tags");
+}
+
+void tst_QImage::exifInvalidData()
{
QImage image;
- QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_QTBUG-46870.jpg"));
+ QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_" + QTest::currentDataTag() + ".jpg"));
QVERIFY(!image.isNull());
}
diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp
index e6fd67e3a8..364b9332af 100644
--- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp
+++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp
@@ -194,6 +194,7 @@ public:
private slots:
void cleanup();
+ void qPointerUniqueId();
void touchDisabledByDefault();
void touchEventAcceptedByDefault();
void touchBeginPropagatesWhenIgnored();
@@ -224,6 +225,44 @@ void tst_QTouchEvent::cleanup()
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
}
+void tst_QTouchEvent::qPointerUniqueId()
+{
+ QPointingDeviceUniqueId id1, id2;
+
+ QCOMPARE(id1.numericId(), Q_INT64_C(-1));
+ QVERIFY(!id1.isValid());
+
+ QVERIFY( id1 == id2);
+ QVERIFY(!(id1 != id2));
+
+ QSet<QPointingDeviceUniqueId> set; // compile test
+ set.insert(id1);
+ set.insert(id2);
+ QCOMPARE(set.size(), 1);
+
+
+ const auto id3 = QPointingDeviceUniqueId::fromNumericId(-1);
+ QCOMPARE(id3.numericId(), Q_INT64_C(-1));
+ QVERIFY(!id3.isValid());
+
+ QVERIFY( id1 == id3);
+ QVERIFY(!(id1 != id3));
+
+ set.insert(id3);
+ QCOMPARE(set.size(), 1);
+
+
+ const auto id4 = QPointingDeviceUniqueId::fromNumericId(4);
+ QCOMPARE(id4.numericId(), Q_INT64_C(4));
+ QVERIFY(id4.isValid());
+
+ QVERIFY( id1 != id4);
+ QVERIFY(!(id1 == id4));
+
+ set.insert(id4);
+ QCOMPARE(set.size(), 2);
+}
+
void tst_QTouchEvent::touchDisabledByDefault()
{
// QWidget
diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
index 419c781aab..364e435d3d 100644
--- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
+++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
@@ -46,6 +46,8 @@
# include <netinet/in.h>
#endif
+Q_DECLARE_METATYPE(QHostAddress::SpecialAddress)
+
class tst_QHostAddress : public QObject
{
Q_OBJECT
@@ -232,51 +234,55 @@ void tst_QHostAddress::setAddress_QString()
void tst_QHostAddress::specialAddresses_data()
{
QTest::addColumn<QString>("text");
- QTest::addColumn<int>("address");
+ QTest::addColumn<QHostAddress::SpecialAddress>("address");
QTest::addColumn<bool>("result");
- QTest::newRow("localhost_1") << QString("127.0.0.1") << (int)QHostAddress::LocalHost << true;
- QTest::newRow("localhost_2") << QString("127.0.0.2") << (int)QHostAddress::LocalHost << false;
- QTest::newRow("localhost_3") << QString("127.0.0.2") << (int)QHostAddress::LocalHostIPv6 << false;
+ QTest::newRow("localhost_1") << QString("127.0.0.1") << QHostAddress::LocalHost << true;
+ QTest::newRow("localhost_2") << QString("127.0.0.2") << QHostAddress::LocalHost << false;
+ QTest::newRow("localhost_3") << QString("127.0.0.2") << QHostAddress::LocalHostIPv6 << false;
- QTest::newRow("localhost_ipv6_4") << QString("::1") << (int)QHostAddress::LocalHostIPv6 << true;
- QTest::newRow("localhost_ipv6_5") << QString("::2") << (int)QHostAddress::LocalHostIPv6 << false;
- QTest::newRow("localhost_ipv6_6") << QString("::1") << (int)QHostAddress::LocalHost << false;
+ QTest::newRow("localhost_ipv6_4") << QString("::1") << QHostAddress::LocalHostIPv6 << true;
+ QTest::newRow("localhost_ipv6_5") << QString("::2") << QHostAddress::LocalHostIPv6 << false;
+ QTest::newRow("localhost_ipv6_6") << QString("::1") << QHostAddress::LocalHost << false;
- QTest::newRow("null_1") << QString("") << (int)QHostAddress::Null << true;
- QTest::newRow("null_2") << QString("bjarne") << (int)QHostAddress::Null << true;
+ QTest::newRow("null_1") << QString("") << QHostAddress::Null << true;
+ QTest::newRow("null_2") << QString("bjarne") << QHostAddress::Null << true;
- QTest::newRow("compare_from_null") << QString("") << (int)QHostAddress::Broadcast << false;
+ QTest::newRow("compare_from_null") << QString("") << QHostAddress::Broadcast << false;
- QTest::newRow("broadcast_1") << QString("255.255.255.255") << (int)QHostAddress::Any << false;
- QTest::newRow("broadcast_2") << QString("255.255.255.255") << (int)QHostAddress::Broadcast << true;
+ QTest::newRow("broadcast_1") << QString("255.255.255.255") << QHostAddress::Any << false;
+ QTest::newRow("broadcast_2") << QString("255.255.255.255") << QHostAddress::Broadcast << true;
- QTest::newRow("any_ipv6") << QString("::") << (int)QHostAddress::AnyIPv6 << true;
- QTest::newRow("any_ipv4") << QString("0.0.0.0") << (int)QHostAddress::AnyIPv4 << true;
+ QTest::newRow("any_ipv6") << QString("::") << QHostAddress::AnyIPv6 << true;
+ QTest::newRow("any_ipv4") << QString("0.0.0.0") << QHostAddress::AnyIPv4 << true;
- QTest::newRow("dual_not_ipv6") << QString("::") << (int)QHostAddress::Any << false;
- QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << (int)QHostAddress::Any << false;
+ QTest::newRow("dual_not_ipv6") << QString("::") << QHostAddress::Any << false;
+ QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << QHostAddress::Any << false;
}
void tst_QHostAddress::specialAddresses()
{
QFETCH(QString, text);
- QFETCH(int, address);
+ QFETCH(QHostAddress::SpecialAddress, address);
QFETCH(bool, result);
- QVERIFY((QHostAddress(text) == (QHostAddress::SpecialAddress)address) == result);
+ QCOMPARE(QHostAddress(text) == address, result);
//check special address equal to itself (QTBUG-22898), note two overloads of operator==
- QVERIFY(QHostAddress((QHostAddress::SpecialAddress)address) == QHostAddress((QHostAddress::SpecialAddress)address));
- QVERIFY(QHostAddress((QHostAddress::SpecialAddress)address) == (QHostAddress::SpecialAddress)address);
+ QVERIFY(QHostAddress(address) == QHostAddress(address));
+ QVERIFY(QHostAddress(address) == address);
+ QVERIFY(!(QHostAddress(address) != QHostAddress(address)));
+ QVERIFY(!(QHostAddress(address) != address));
+
+ {
+ QHostAddress ha;
+ ha.setAddress(address);
+ QVERIFY(ha == address);
+ }
QHostAddress setter;
setter.setAddress(text);
- if (result) {
- QVERIFY(setter == (QHostAddress::SpecialAddress) address);
- } else {
- QVERIFY(!((QHostAddress::SpecialAddress) address == setter));
- }
+ QCOMPARE(setter == address, result);
}
@@ -359,6 +365,11 @@ void tst_QHostAddress::isEqual()
QCOMPARE(second.isEqual(first, QHostAddress::ConversionModeFlag(flags)), result);
}
+QT_WARNING_PUSH
+#ifdef QT_WARNING_DISABLE_DEPRECATED
+QT_WARNING_DISABLE_DEPRECATED
+#endif
+
void tst_QHostAddress::assignment()
{
QHostAddress address;
@@ -379,6 +390,8 @@ void tst_QHostAddress::assignment()
#endif // !Q_OS_WINRT
}
+QT_WARNING_POP
+
void tst_QHostAddress::scopeId()
{
QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0");
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index a5b33ed8e7..b04fb7cd5d 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -132,6 +132,7 @@ private slots:
void taskQTBUG53205_crashReparentNested();
#ifdef Q_OS_MACOS
void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
+ void QTBUG_57404_existingMenuItemException();
#endif
void taskQTBUG55966_subMenuRemoved();
@@ -1540,6 +1541,31 @@ void tst_QMenuBar::taskQTBUG56275_reinsertMenuInParentlessQMenuBar()
QVERIFY(tst_qmenubar_taskQTBUG56275(&menubar));
}
+
+void tst_QMenuBar::QTBUG_57404_existingMenuItemException()
+{
+ QMainWindow mw1;
+ QMainWindow mw2;
+ mw1.show();
+ mw2.show();
+
+ QMenuBar *mb = new QMenuBar(&mw1);
+ mw1.setMenuBar(mb);
+ mb->show();
+ QMenu *editMenu = new QMenu(QLatin1String("Edit"), &mw1);
+ mb->addMenu(editMenu);
+ QAction *copyAction = editMenu->addAction("&Copy");
+ copyAction->setShortcut(QKeySequence("Ctrl+C"));
+ QTest::ignoreMessage(QtWarningMsg, "Menu item \"&Copy\" has unsupported role QPlatformMenuItem::MenuRole(NoRole)");
+ copyAction->setMenuRole(QAction::NoRole);
+
+ QVERIFY(QTest::qWaitForWindowExposed(&mw2));
+ QTest::qWait(100);
+ mw2.close();
+ mw1.activateWindow();
+ QTest::qWait(100);
+ // No crash, all fine. Ideally, there should be only one warning.
+}
#endif // Q_OS_MACOS
void tst_QMenuBar::taskQTBUG55966_subMenuRemoved()