summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/jar/jar.pri4
-rw-r--r--src/android/templates/res/values/libs.xml2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp2
-rw-r--r--src/corelib/global/qcompilerdetection.h4
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qlibraryinfo.cpp116
-rw-r--r--src/corelib/global/qlibraryinfo.h2
-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/qguiapplication.cpp2
-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/qdatabuffer_p.h12
-rw-r--r--src/gui/painting/qdrawhelper.cpp7
-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/gui/text/qtextdocument.cpp9
-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/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java13
-rw-r--r--src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp12
-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/eglfs/deviceintegration/deviceintegration.pro4
-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/platforms/xcb/qxcbdrag.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp10
-rw-r--r--src/sql/configure.json6
-rw-r--r--src/sql/configure.pri8
-rw-r--r--src/src.pro2
-rw-r--r--src/tools/moc/main.cpp3
-rw-r--r--src/widgets/widgets/qdockwidget.cpp6
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp47
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h5
74 files changed, 1016 insertions, 445 deletions
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/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp
index d222ca32a7..b84cf0ae2d 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.cpp
@@ -52,7 +52,7 @@
class MyXcbEventFilter : public QAbstractNativeEventFilter
{
public:
- virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override
{
if (eventType == "xcb_generic_event_t") {
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h
index 6666bc56c5..9734f99d50 100644
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h
+++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qabstractnativeeventfilter.h
@@ -44,6 +44,6 @@
class MyCocoaEventFilter : public QAbstractNativeEventFilter
{
public:
- bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
+ bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override;
};
//! [0]
diff --git a/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp b/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp
index a621109c0d..7c687a0430 100644
--- a/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp
@@ -55,7 +55,7 @@ class MyObject;
class WorkerThread : public QThread
{
Q_OBJECT
- void run() Q_DECL_OVERRIDE {
+ void run() override {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
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 4354c85bfe..7a0804d436 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -925,8 +925,8 @@ 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()) {}
QForeachContainer(const QForeachContainer &other)
: c(other.c),
i(c.begin()),
@@ -936,7 +936,7 @@ public:
}
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/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 27fe10a79e..87ee75fa45 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -41,15 +41,18 @@
#include "qdir.h"
#include "qstringlist.h"
#include "qfile.h"
+#include "qtemporaryfile.h"
#include "qsettings.h"
#include "qlibraryinfo.h"
#include "qscopedpointer.h"
#ifdef QT_BUILD_QMAKE
QT_BEGIN_NAMESPACE
+extern QString qmake_absoluteLocation();
extern QString qmake_libraryInfoFile();
QT_END_NAMESPACE
#else
+# include "qconfig.cpp"
# include "qcoreapplication.h"
#endif
@@ -57,7 +60,6 @@ QT_END_NAMESPACE
# include "private/qcore_mac_p.h"
#endif
-#include "qconfig.cpp"
#include "archdetect.cpp"
QT_BEGIN_NAMESPACE
@@ -70,9 +72,16 @@ struct QLibrarySettings
{
QLibrarySettings();
void load();
+#ifdef QT_BUILD_QMAKE
+ void loadBuiltinValues(QSettings *config);
+#endif
QScopedPointer<QSettings> settings;
#ifdef QT_BUILD_QMAKE
+ QString builtinValues[QLibraryInfo::LastHostPath + 1];
+# ifndef Q_OS_WIN
+ QString builtinSettingsPath;
+# endif
bool haveDevicePaths;
bool haveEffectiveSourcePaths;
bool haveEffectivePaths;
@@ -88,6 +97,11 @@ class QLibraryInfoPrivate
public:
static QSettings *findConfiguration();
#ifdef QT_BUILD_QMAKE
+ static void reload()
+ {
+ if (qt_library_settings.exists())
+ qt_library_settings->load();
+ }
static bool haveGroup(QLibraryInfo::PathGroup group)
{
QLibrarySettings *ls = qt_library_settings();
@@ -99,6 +113,25 @@ public:
? ls->haveDevicePaths
: ls->havePaths) : false;
}
+ static bool sysrootify()
+ {
+ // This is actually bogus, as it does not consider post-configure settings.
+ QLibrarySettings *ls = qt_library_settings();
+ return ls ? (!ls->builtinValues[QLibraryInfo::SysrootPath].isEmpty()
+ && ls->builtinValues[QLibraryInfo::ExtPrefixPath].isEmpty()) : false;
+ }
+ static QString builtinValue(int loc)
+ {
+ QLibrarySettings *ls = qt_library_settings();
+ return ls ? ls->builtinValues[loc] : QString();
+ }
+# ifndef Q_OS_WIN
+ static QString builtinSettingsPath()
+ {
+ QLibrarySettings *ls = qt_library_settings();
+ return ls ? ls->builtinSettingsPath : QString();
+ }
+# endif
#endif
static QSettings *configuration()
{
@@ -122,6 +155,20 @@ QLibrarySettings::QLibrarySettings()
load();
}
+#ifdef QT_BUILD_QMAKE
+static QByteArray qtconfSeparator()
+{
+# ifdef Q_OS_WIN
+ QByteArray header = QByteArrayLiteral("\r\n===========================================================\r\n");
+# else
+ QByteArray header = QByteArrayLiteral("\n===========================================================\n");
+# endif
+ QByteArray content = QByteArrayLiteral("==================== qt.conf beginning ====================");
+ // Assemble from pieces to avoid that the string appears in a raw executable
+ return header + content + header;
+}
+#endif
+
void QLibrarySettings::load()
{
// If we get any settings here, those won't change when the application shows up.
@@ -159,6 +206,27 @@ void QLibrarySettings::load()
havePaths = false;
#endif
}
+
+#ifdef QT_BUILD_QMAKE
+ // Try to use an embedded qt.conf appended to the QMake executable.
+ QFile qmakeFile(qmake_absoluteLocation());
+ if (!qmakeFile.open(QIODevice::ReadOnly))
+ return;
+ qmakeFile.seek(qmakeFile.size() - 10000);
+ QByteArray tail = qmakeFile.read(10000);
+ QByteArray separator = qtconfSeparator();
+ int qtconfOffset = tail.lastIndexOf(separator);
+ if (qtconfOffset < 0)
+ return;
+ tail.remove(0, qtconfOffset + separator.size());
+ // If QSettings had a c'tor taking a QIODevice, we'd pass a QBuffer ...
+ QTemporaryFile tmpFile;
+ tmpFile.open();
+ tmpFile.write(tail);
+ tmpFile.close();
+ QSettings builtinSettings(tmpFile.fileName(), QSettings::IniFormat);
+ loadBuiltinValues(&builtinSettings);
+#endif
}
QSettings *QLibraryInfoPrivate::findConfiguration()
@@ -420,10 +488,30 @@ static const struct {
{ "HostData", "." },
{ "TargetSpec", "" },
{ "HostSpec", "" },
+ { "ExtPrefix", "" },
{ "HostPrefix", "" },
#endif
};
+#ifdef QT_BUILD_QMAKE
+void QLibrarySettings::loadBuiltinValues(QSettings *config)
+{
+ config->beginGroup(QLatin1String("Paths"));
+ for (int i = 0; i <= QLibraryInfo::LastHostPath; i++)
+ builtinValues[i] = config->value(QLatin1String(qtConfEntries[i].key),
+ QLatin1String(qtConfEntries[i].value)).toString();
+# ifndef Q_OS_WIN
+ builtinSettingsPath = config->value(QLatin1String("Settings")).toString();
+# endif
+ config->endGroup();
+}
+
+void QLibraryInfo::reload()
+{
+ QLibraryInfoPrivate::reload();
+}
+#endif
+
/*!
Returns the location specified by \a loc.
*/
@@ -434,7 +522,7 @@ QLibraryInfo::location(LibraryLocation loc)
QString ret = rawLocation(loc, FinalPaths);
// Automatically prepend the sysroot to target paths
- if ((loc < SysrootPath || loc > LastHostPath) && QT_CONFIGURE_SYSROOTIFY_PREFIX) {
+ if ((loc < SysrootPath || loc > LastHostPath) && QLibraryInfoPrivate::sysrootify()) {
QString sysroot = rawLocation(SysrootPath, FinalPaths);
if (!sysroot.isEmpty() && ret.length() > 2 && ret.at(1) == QLatin1Char(':')
&& (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\')))
@@ -528,28 +616,32 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
#endif // QT_NO_SETTINGS
if (!fromConf) {
+#ifdef QT_BUILD_QMAKE
+ if ((unsigned)loc <= (unsigned)LastHostPath) {
+ if (loc == PrefixPath && group != DevicePaths)
+ ret = QLibraryInfoPrivate::builtinValue(ExtPrefixPath);
+ else
+ ret = QLibraryInfoPrivate::builtinValue(loc);
+# ifndef Q_OS_WIN // On Windows we use the registry
+ } else if (loc == SettingsPath) {
+ ret = QLibraryInfoPrivate::builtinSettingsPath();
+# endif
+ }
+#else // QT_BUILD_QMAKE
const char * volatile path = 0;
if (loc == PrefixPath) {
- path =
-#ifdef QT_BUILD_QMAKE
- (group != DevicePaths) ?
- QT_CONFIGURE_EXT_PREFIX_PATH :
-#endif
- QT_CONFIGURE_PREFIX_PATH;
+ path = QT_CONFIGURE_PREFIX_PATH;
} else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) {
path = qt_configure_strs + qt_configure_str_offsets[loc - 1];
#ifndef Q_OS_WIN // On Windows we use the registry
} else if (loc == SettingsPath) {
path = QT_CONFIGURE_SETTINGS_PATH;
#endif
-#ifdef QT_BUILD_QMAKE
- } else if (loc == HostPrefixPath) {
- path = QT_CONFIGURE_HOST_PREFIX_PATH;
-#endif
}
if (path)
ret = QString::fromLocal8Bit(path);
+#endif
}
#ifdef QT_BUILD_QMAKE
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 55be706382..9d794ce1da 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -96,6 +96,7 @@ public:
HostDataPath,
TargetSpecPath,
HostSpecPath,
+ ExtPrefixPath,
HostPrefixPath,
LastHostPath = HostPrefixPath,
#endif
@@ -105,6 +106,7 @@ public:
#ifdef QT_BUILD_QMAKE
enum PathGroup { FinalPaths, EffectivePaths, EffectiveSourcePaths, DevicePaths };
static QString rawLocation(LibraryLocation, PathGroup);
+ static void reload();
#endif
static QStringList platformPluginArguments(const QString &platformName);
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 99d223ca88..ad549dcd7b 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 7e0922a90a..b1dcf6a9f8 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 468523ab9c..44ec9c95da 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"
@@ -4476,14 +4477,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;
}
@@ -4795,7 +4796,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 */
@@ -5226,36 +5227,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 d7b7b636b2..cfc3b842d7 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 f67284eebb..1eccfaea78 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -81,7 +81,7 @@ public:
QAtomicInt ref;
int id;
- QPointerUniqueId uniqueId;
+ QPointingDeviceUniqueId uniqueId;
Qt::TouchPointStates state;
QPointF pos, scenePos, screenPos, normalizedPos,
startPos, startScenePos, startScreenPos, startNormalizedPos,
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index d3f3827d6e..568b010792 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2603,7 +2603,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
break;
}
- if (w->d_func()->blockedByModalWindow) {
+ if (w->d_func()->blockedByModalWindow && !qApp->d_func()->popupActive()) {
// a modal window is blocking this window, don't allow touch events through
// QTBUG-37371 temporary fix; TODO: revisit in 5.4 when we have a forwarding solution
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index b6b57e01f5..11864e7adc 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; // dimensions of the elliptical contact patch, unrotated, and centered at position in screen coordinates
// width is the horizontal diameter, height is the vertical diameter
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/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h
index 77b5be0c4c..7cac2ac358 100644
--- a/src/gui/painting/qdatabuffer_p.h
+++ b/src/gui/painting/qdatabuffer_p.h
@@ -65,10 +65,12 @@ public:
QDataBuffer(int res)
{
capacity = res;
- if (res)
+ if (res) {
buffer = (Type*) malloc(capacity * sizeof(Type));
- else
+ Q_CHECK_PTR(buffer);
+ } else {
buffer = 0;
+ }
siz = 0;
}
@@ -115,14 +117,16 @@ public:
while (capacity < size)
capacity *= 2;
buffer = (Type*) realloc(buffer, capacity * sizeof(Type));
+ Q_CHECK_PTR(buffer);
}
}
inline void shrink(int size) {
capacity = size;
- if (size)
+ if (size) {
buffer = (Type*) realloc(buffer, capacity * sizeof(Type));
- else {
+ Q_CHECK_PTR(buffer);
+ } else {
free(buffer);
buffer = 0;
}
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 08f96bd654..772291b22b 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -844,6 +844,7 @@ template <QPixelLayout::BPP bpp> static
uint QT_FASTCALL fetchPixel(const uchar *, int)
{
Q_UNREACHABLE();
+ return 0;
}
template <>
@@ -1581,7 +1582,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 +2533,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/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 5e9fac5f86..6074917087 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1163,9 +1163,12 @@ QString QTextDocument::toRawText() const
formatting information use a QTextCursor instead.
This function returns the same as toRawText(), but will replace
- some unicode characters, such as line separators and non-breaking
- spaces, with ASCII alternatives. If you need the precise contents
- of the document, use toRawText() instead.
+ some unicode characters with ASCII alternatives.
+ In particular, no-break space (U+00A0) is replaced by a regular
+ space (U+0020), and both paragraph (U+2029) and line (U+2028)
+ separators are replaced by line feed (U+000A).
+ If you need the precise contents of the document, use toRawText()
+ instead.
\note Embedded objects, such as images, are represented by a
Unicode value U+FFFC (OBJECT REPLACEMENT CHARACTER).
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 2a905101a4..2b5fde2a76 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/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java b/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java
index 8170188ecb..805c90548b 100644
--- a/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java
+++ b/src/plugins/bearer/android/jar/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java
@@ -44,7 +44,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
-import android.app.Activity;
import android.net.ConnectivityManager;
public class QtNetworkReceiver
@@ -65,29 +64,29 @@ public class QtNetworkReceiver
private QtNetworkReceiver() {}
- public static void registerReceiver(final Activity activity)
+ public static void registerReceiver(final Context context)
{
synchronized (m_lock) {
if (m_broadcastReceiver == null) {
m_broadcastReceiver = new BroadcastReceiverPrivate();
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- activity.registerReceiver(m_broadcastReceiver, intentFilter);
+ context.registerReceiver(m_broadcastReceiver, intentFilter);
}
}
}
- public static void unregisterReceiver(final Activity activity)
+ public static void unregisterReceiver(final Context context)
{
synchronized (m_lock) {
if (m_broadcastReceiver == null)
return;
- activity.unregisterReceiver(m_broadcastReceiver);
+ context.unregisterReceiver(m_broadcastReceiver);
}
}
- public static ConnectivityManager getConnectivityManager(final Activity activity)
+ public static ConnectivityManager getConnectivityManager(final Context context)
{
- return (ConnectivityManager)activity.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ return (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
diff --git a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
index 3a5030d1f3..6787690246 100644
--- a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
+++ b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
@@ -250,15 +250,15 @@ AndroidConnectivityManager::AndroidConnectivityManager()
m_connectivityManager = QJNIObjectPrivate::callStaticObjectMethod(networkReceiverClass,
"getConnectivityManager",
- "(Landroid/app/Activity;)Landroid/net/ConnectivityManager;",
- QtAndroidPrivate::activity());
+ "(Landroid/content/Context;)Landroid/net/ConnectivityManager;",
+ QtAndroidPrivate::context());
if (!m_connectivityManager.isValid())
return;
QJNIObjectPrivate::callStaticMethod<void>(networkReceiverClass,
"registerReceiver",
- "(Landroid/app/Activity;)V",
- QtAndroidPrivate::activity());
+ "(Landroid/content/Context;)V",
+ QtAndroidPrivate::context());
}
AndroidConnectivityManager *AndroidConnectivityManager::getInstance()
@@ -272,8 +272,8 @@ AndroidConnectivityManager::~AndroidConnectivityManager()
{
QJNIObjectPrivate::callStaticMethod<void>(networkReceiverClass,
"unregisterReceiver",
- "(Landroid/app/Activity;)V",
- QtAndroidPrivate::activity());
+ "(Landroid/content/Context;)V",
+ QtAndroidPrivate::context());
}
AndroidNetworkInfo AndroidConnectivityManager::getActiveNetworkInfo() const
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/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
index 52cc5739aa..aca0078bfb 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
@@ -2,8 +2,8 @@ TEMPLATE = subdirs
QT_FOR_CONFIG += gui-private
qtConfig(egl_x11): SUBDIRS += eglfs_x11
-qtConfig(eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms
-qtConfig(eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice
+qtConfig(eglfs_gbm): SUBDIRS *= eglfs_kms_support eglfs_kms
+qtConfig(eglfs_egldevice): SUBDIRS *= eglfs_kms_support eglfs_kms_egldevice
qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm
qtConfig(eglfs_mali): SUBDIRS += eglfs_mali
qtConfig(eglfs_viv): SUBDIRS += eglfs_viv
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/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 494cecb3d1..58fb1f3918 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -1121,6 +1121,9 @@ void QXcbDrag::cancel()
QBasicDrag::cancel();
if (current_target)
send_leave();
+
+ // remove canceled object
+ currentDrag()->deleteLater();
}
// find an ancestor with XdndAware on it
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5fa8541f26..ff01fa019e 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2738,7 +2738,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
return false;
- const QPoint globalPos = window()->mapToGlobal(pos);
+ const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
#ifdef XCB_USE_XINPUT22
if (connection()->startSystemResizeForTouchBegin(m_window, globalPos, corner))
return true;
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/sql/configure.json b/src/sql/configure.json
index 96c82e84f9..72671b6df9 100644
--- a/src/sql/configure.json
+++ b/src/sql/configure.json
@@ -58,8 +58,10 @@
"label": "MySQL",
"test": "unix/mysql",
"sources": [
- { "type": "mysqlConfig", "query": "--libs_r" },
- { "type": "mysqlConfig", "query": "--libs" },
+ { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": true },
+ { "type": "mysqlConfig", "query": "--libs", "cleanlibs": true },
+ { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": false },
+ { "type": "mysqlConfig", "query": "--libs", "cleanlibs": false },
{ "libs": "-lmysqlclient_r", "condition": "!config.win32" },
{ "libs": "-llibmysql", "condition": "config.win32" },
{ "libs": "-lmysqlclient", "condition": "!config.win32" }
diff --git a/src/sql/configure.pri b/src/sql/configure.pri
index 1d8847b4bc..62d56e2186 100644
--- a/src/sql/configure.pri
+++ b/src/sql/configure.pri
@@ -57,6 +57,14 @@ defineTest(qtConfLibrary_mysqlConfig) {
libs = $$filterLibraryPath($$libs)
# -rdynamic should not be returned by mysql_config, but is on RHEL 6.6
libs -= -rdynamic
+ equals($${1}.cleanlibs, true) {
+ for(l, libs) {
+ # Drop all options besides the -L one and the -lmysqlclient one
+ # so we don't unnecessarily link to libs like OpenSSL
+ contains(l, "^(-L|-lmysqlclient).*"): cleanlibs += $$l
+ }
+ libs = $$cleanlibs
+ }
$${1}.libs = "$$val_escape(libs)"
eval(includedir = $$includedir)
includedir ~= s/^-I//g
diff --git a/src/src.pro b/src/src.pro
index 13aa08c12a..9f3dbfa712 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/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index c9cb826213..53cb21186f 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -219,8 +219,10 @@ QDockWidgetLayout::~QDockWidgetLayout()
bool QDockWidgetLayout::nativeWindowDeco() const
{
bool floating = parentWidget()->isWindow();
- if (!floating && qobject_cast<QDockWidgetGroupWindow*>(parentWidget()->parentWidget()))
- return wmSupportsNativeWindowDeco();
+ if (!floating) {
+ if (auto groupWindow = qobject_cast<const QDockWidgetGroupWindow*>(parentWidget()->parentWidget()))
+ return groupWindow->hasNativeDecos();
+ }
return nativeWindowDeco(floating);
}
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 8df197e05c..aef8b9cbd5 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -183,7 +183,7 @@ class QDockWidgetGroupLayout : public QLayout {
QDockAreaLayoutInfo info;
QWidgetResizeHandler *resizer;
public:
- QDockWidgetGroupLayout(QWidget* parent) : QLayout(parent) {
+ QDockWidgetGroupLayout(QDockWidgetGroupWindow* parent) : QLayout(parent) {
setSizeConstraint(QLayout::SetMinAndMaxSize);
resizer = new QWidgetResizeHandler(parent);
resizer->setMovingEnabled(false);
@@ -221,7 +221,7 @@ public:
}
void setGeometry(const QRect&r) Q_DECL_OVERRIDE
{
- static_cast<QDockWidgetGroupWindow *>(parent())->destroyOrHideIfEmpty();
+ groupWindow()->destroyOrHideIfEmpty();
QDockAreaLayoutInfo *li = layoutInfo();
if (li->isEmpty())
return;
@@ -239,7 +239,7 @@ public:
bool nativeWindowDeco() const
{
- return QDockWidgetLayout::wmSupportsNativeWindowDeco();
+ return groupWindow()->hasNativeDecos();
}
int frameWidth() const
@@ -247,6 +247,11 @@ public:
return nativeWindowDeco() ? 0 :
parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, parentWidget());
}
+
+ QDockWidgetGroupWindow *groupWindow() const
+ {
+ return static_cast<QDockWidgetGroupWindow *>(parent());
+ }
};
bool QDockWidgetGroupWindow::event(QEvent *e)
@@ -390,16 +395,49 @@ void QDockWidgetGroupWindow::adjustFlags()
flags.setFlag(Qt::WindowCloseButtonHint, top->features() & QDockWidget::DockWidgetClosable);
flags &= ~Qt::FramelessWindowHint;
} else {
+ flags &= ~(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
flags |= Qt::FramelessWindowHint;
}
+
if (oldFlags != flags) {
setWindowFlags(flags);
+ const bool gainedNativeDecos = (oldFlags & Qt::FramelessWindowHint) && !(flags & Qt::FramelessWindowHint);
+ const bool lostNativeDecos = !(oldFlags & Qt::FramelessWindowHint) && (flags & Qt::FramelessWindowHint);
+
+ // Adjust the geometry after gaining/losing decos, so that the client area appears always
+ // at the same place when tabbing
+ if (lostNativeDecos) {
+ QRect newGeometry = geometry();
+ newGeometry.setTop(frameGeometry().top());
+ const int bottomFrame = geometry().top() - frameGeometry().top();
+ m_removedFrameSize = QSize((frameSize() - size()).width(), bottomFrame);
+ setGeometry(newGeometry);
+ } else if (gainedNativeDecos && m_removedFrameSize.isValid()) {
+ QRect r = geometry();
+ r.adjust(-m_removedFrameSize.width() / 2, 0,
+ -m_removedFrameSize.width() / 2, -m_removedFrameSize.height());
+ setGeometry(r);
+ m_removedFrameSize = QSize();
+ }
+
show(); // setWindowFlags hides the window
}
setWindowTitle(top->windowTitle());
setWindowIcon(top->windowIcon());
}
+
+bool QDockWidgetGroupWindow::hasNativeDecos() const
+{
+ if (!QDockWidgetLayout::wmSupportsNativeWindowDeco())
+ return false;
+
+ if (QDockWidget *dw = topDockWidget())
+ return dw->titleBarWidget() == nullptr;
+
+ return true;
+}
+
#endif
/******************************************************************************
@@ -1704,6 +1742,9 @@ void QMainWindowLayout::tabChanged()
if (activated)
emit static_cast<QMainWindow *>(parentWidget())->tabifiedDockWidgetActivated(activated);
+ if (auto dwgw = qobject_cast<QDockWidgetGroupWindow*>(tb->parentWidget()))
+ dwgw->adjustFlags();
+
if (QWidget *w = centralWidget())
w->raise();
}
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 6e8b965431..40336caeba 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -83,9 +83,14 @@ public:
QDockWidget *topDockWidget() const;
void destroyOrHideIfEmpty();
void adjustFlags();
+ bool hasNativeDecos() const;
+
protected:
bool event(QEvent *) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE;
+
+private:
+ QSize m_removedFrameSize;
};
// This item will be used in the layout for the gap item. We cannot use QWidgetItem directly