summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-07-17 01:00:27 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2019-07-17 10:44:21 +0200
commit64df0eda36fea91b71783b23bfdf733b6983c250 (patch)
tree92cbd069b534a873a33a46c7735592eaca78d9cd
parent8b34296e6a86ce5ad9dba6ac54c84a64cec09b96 (diff)
parenta837ec15fec100567730a7bedb06655ef891ac96 (diff)
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts: src/corelib/global/qlogging.cpp src/gui/painting/qtextureglyphcache_p.h src/gui/text/qfontengine.cpp src/widgets/widgets/qlineedit.cpp Change-Id: Ic8798538df466b7141caa8bbf1fb7605eb56be37
-rw-r--r--config.tests/arch/arch.pro1
-rw-r--r--config.tests/arch/arch_host.pro2
-rw-r--r--configure.json4
-rw-r--r--configure.pri41
-rw-r--r--examples/widgets/desktop/systray/window.cpp9
-rw-r--r--mkspecs/features/qt_module_headers.prf1
-rw-r--r--qmake/library/qmakeevaluator.cpp39
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp47
-rw-r--r--src/corelib/io/qsavefile.cpp1
-rw-r--r--src/corelib/text/qbytearray.cpp7
-rw-r--r--src/gui/image/qimagereader.cpp2
-rw-r--r--src/gui/image/qpixmapcache.cpp33
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp4
-rw-r--r--src/gui/opengl/qopengltextureglyphcache_p.h2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp4
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp2
-rw-r--r--src/gui/painting/qtextureglyphcache_p.h8
-rw-r--r--src/gui/text/qfontengine.cpp12
-rw-r--r--src/gui/text/qfontengine_p.h4
-rw-r--r--src/gui/text/qfontengineglyphcache_p.h7
-rw-r--r--src/network/kernel/qhostinfo.cpp34
-rw-r--r--src/network/kernel/qhostinfo_p.h9
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp115
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp4
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h2
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm10
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h4
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp42
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h4
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp2
-rw-r--r--src/platformsupport/input/libinput/qlibinputhandler.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm7
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm8
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbeventqueue.cpp9
-rw-r--r--src/src.pro10
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp2
-rw-r--r--src/widgets/doc/macOS/AppKit/AppKit.h1
-rw-r--r--src/widgets/doc/qtwidgets.qdocconf3
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp4
-rw-r--r--src/widgets/itemviews/qlistview.cpp2
-rw-r--r--src/widgets/kernel/qapplication.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp71
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/widgets/qlineedit.cpp2
-rw-r--r--src/widgets/widgets/qmenu.cpp2
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp34
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp39
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp1
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp65
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp6
53 files changed, 461 insertions, 290 deletions
diff --git a/config.tests/arch/arch.pro b/config.tests/arch/arch.pro
index 2ffdb2c889..45a7eb33af 100644
--- a/config.tests/arch/arch.pro
+++ b/config.tests/arch/arch.pro
@@ -1,2 +1 @@
-TARGET = arch
SOURCES = arch.cpp
diff --git a/config.tests/arch/arch_host.pro b/config.tests/arch/arch_host.pro
index f7acef0c5d..cefdbc77ef 100644
--- a/config.tests/arch/arch_host.pro
+++ b/config.tests/arch/arch_host.pro
@@ -1,2 +1,2 @@
option(host_build)
-include(arch.pro)
+SOURCES = arch.cpp
diff --git a/configure.json b/configure.json
index f817101de1..6a7b5924cd 100644
--- a/configure.json
+++ b/configure.json
@@ -252,12 +252,14 @@
"label": "target architecture",
"type": "architecture",
"test": "arch",
+ "output": "arch",
"log": "arch"
},
"host_architecture": {
"label": "host architecture",
"type": "architecture",
"test": "arch",
+ "output": "arch_host",
"host": true,
"pro": "arch_host.pro",
"log": "arch"
@@ -1323,7 +1325,7 @@
"ccache": {
"label": "Using ccache",
"autoDetect": false,
- "condition": "config.unix && tests.ccache",
+ "condition": "tests.ccache",
"output": [ "privateConfig" ]
},
"msvc_mp": {
diff --git a/configure.pri b/configure.pri
index 81133da3d7..7b8dee0953 100644
--- a/configure.pri
+++ b/configure.pri
@@ -286,20 +286,39 @@ defineTest(qtConfTest_architecture) {
!qtConfTest_compile($${1}): \
error("Could not determine $$eval($${1}.label). See config.log for details.")
+ host = $$eval($${1}.host)
+ isEmpty(host): host = false
+ file_prefix =
+ exts = -
+ $$host {
+ equals(QMAKE_HOST.os, Windows): \
+ exts = .exe
+ } else {
+ win32 {
+ exts = .exe
+ } else:android {
+ file_prefix = lib
+ exts = .so
+ } else:wasm {
+ exts = .wasm .o
+ }
+ }
+
test = $$eval($${1}.test)
+ output = $$eval($${1}.output)
test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test
- unix:exists($$test_out_dir/arch): \
- content = $$cat($$test_out_dir/arch, blob)
- else: win32:exists($$test_out_dir/arch.exe): \
- content = $$cat($$test_out_dir/arch.exe, blob)
- else: android:exists($$test_out_dir/libarch.so): \
- content = $$cat($$test_out_dir/libarch.so, blob)
- else: wasm:exists($$test_out_dir/arch.wasm): \
- content = $$cat($$test_out_dir/arch.wasm, blob)
- else: wasm:exists($$test_out_dir/arch.o): \
- content = $$cat($$test_out_dir/arch.o, blob)
- else: \
+ test_out_file =
+ for(ext, exts) {
+ equals(ext, -): ext =
+ f = $$test_out_dir/$$file_prefix$$output$$ext
+ exists($$f) {
+ test_out_file = $$f
+ break()
+ }
+ }
+ isEmpty(test_out_file): \
error("$$eval($${1}.label) detection binary not found.")
+ content = $$cat($$test_out_file, blob)
arch_magic = ".*==Qt=magic=Qt== Architecture:([^\\0]*).*"
subarch_magic = ".*==Qt=magic=Qt== Sub-architecture:([^\\0]*).*"
diff --git a/examples/widgets/desktop/systray/window.cpp b/examples/widgets/desktop/systray/window.cpp
index 31fcd84821..e30166beac 100644
--- a/examples/widgets/desktop/systray/window.cpp
+++ b/examples/widgets/desktop/systray/window.cpp
@@ -160,9 +160,10 @@ void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
void Window::showMessage()
{
showIconCheckBox->setChecked(true);
- QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(
- typeComboBox->itemData(typeComboBox->currentIndex()).toInt());
- if (msgIcon == QSystemTrayIcon::NoIcon) {
+ int selectedIcon = typeComboBox->itemData(typeComboBox->currentIndex()).toInt();
+ QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(selectedIcon);
+
+ if (selectedIcon == -1) { // custom icon
QIcon icon(iconComboBox->itemIcon(iconComboBox->currentIndex()));
trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon,
durationSpinBox->value() * 1000);
@@ -222,7 +223,7 @@ void Window::createMessageGroupBox()
QStyle::SP_MessageBoxCritical), tr("Critical"),
QSystemTrayIcon::Critical);
typeComboBox->addItem(QIcon(), tr("Custom icon"),
- QSystemTrayIcon::NoIcon);
+ -1);
typeComboBox->setCurrentIndex(1);
durationLabel = new QLabel(tr("Duration:"));
diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf
index 899a40103a..7ee1a956f4 100644
--- a/mkspecs/features/qt_module_headers.prf
+++ b/mkspecs/features/qt_module_headers.prf
@@ -304,7 +304,6 @@ headersclean:!internal_module {
header_check.variable_out = PRE_TARGETDEPS
header_check.name = headercheck ${QMAKE_FILE_IN}
header_check.commands = $$hcleanCOMMAND
- silent:header_check.commands = @echo compiling[header] ${QMAKE_FILE_IN} && $$hcleanCOMMAND
QMAKE_EXTRA_COMPILERS += header_check
}
unset(hcleanCOMMAND)
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index e15a4bfc50..70897214b2 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -1130,48 +1130,35 @@ bool QMakeEvaluator::prepareProject(const QString &inDir)
}
superdir = qdfi.path();
}
+ QString sdir = inDir;
QString dir = m_outputDir;
forever {
+ conffile = sdir + QLatin1String("/.qmake.conf");
+ if (!m_vfs->exists(conffile, flags))
+ conffile.clear();
cachefile = dir + QLatin1String("/.qmake.cache");
if (!m_vfs->exists(cachefile, flags))
cachefile.clear();
- if (!cachefile.isEmpty()) {
+ if (!conffile.isEmpty() || !cachefile.isEmpty()) {
+ if (dir != sdir)
+ m_sourceRoot = sdir;
m_buildRoot = dir;
break;
}
if (dir == superdir)
goto no_cache;
- QFileInfo qdfi(dir);
- if (qdfi.isRoot()) {
- cachefile.clear();
- break;
- }
- dir = qdfi.path();
- }
- QString sdir = inDir;
- forever {
- conffile = sdir + QLatin1String("/.qmake.conf");
- if (!m_vfs->exists(conffile, flags))
- conffile.clear();
- if (!conffile.isEmpty()) {
- if (sdir != m_buildRoot)
- m_sourceRoot = sdir;
- break;
- }
QFileInfo qsdfi(sdir);
- if (qsdfi.isRoot()) {
- conffile.clear();
- break;
- }
+ QFileInfo qdfi(dir);
+ if (qsdfi.isRoot() || qdfi.isRoot())
+ goto no_cache;
sdir = qsdfi.path();
+ dir = qdfi.path();
}
} else {
m_buildRoot = QFileInfo(cachefile).path();
}
- if (!conffile.isEmpty())
- m_conffile = QDir::cleanPath(conffile);
- if (!cachefile.isEmpty())
- m_cachefile = QDir::cleanPath(cachefile);
+ m_conffile = QDir::cleanPath(conffile);
+ m_cachefile = QDir::cleanPath(cachefile);
}
no_cache:
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index 5ac7e13a2e..2d09c277eb 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -40,13 +40,54 @@
#include "qplatformdefs.h"
#include "qfilesystemiterator_p.h"
+#if QT_CONFIG(textcodec)
+# include <qtextcodec.h>
+# include <private/qutfcodec_p.h>
+#endif
+
#ifndef QT_NO_FILESYSTEMITERATOR
+#include <memory>
+
#include <stdlib.h>
#include <errno.h>
QT_BEGIN_NAMESPACE
+static bool checkNameDecodable(const char *d_name, qsizetype len)
+{
+ // This function is called in a loop from advance() below, but the loop is
+ // usually run only once.
+
+#if QT_CONFIG(textcodec)
+ // We identify the codecs by their RFC 2978 MIBenum values. In this
+ // function:
+ // 3 US-ASCII (ANSI X3.4-1986)
+ // 4 Latin1 (ISO-8859-1)
+ // 106 UTF-8
+ QTextCodec *codec = QTextCodec::codecForLocale();
+# ifdef QT_LOCALE_IS_UTF8
+ int mibEnum = 106;
+# else
+ int mibEnum = codec->mibEnum();
+# endif
+ if (Q_LIKELY(mibEnum == 106)) // UTF-8
+ return QUtf8::isValidUtf8(d_name, len).isValidUtf8;
+ if (mibEnum == 3) // US-ASCII
+ return QtPrivate::isAscii(QLatin1String(d_name, len));
+ if (mibEnum == 4) // Latin 1
+ return true;
+
+ // fall back to generic QTextCodec
+ QTextCodec::ConverterState cs(QTextCodec::IgnoreHeader);
+ codec->toUnicode(d_name, len, &cs);
+ return cs.invalidChars == 0 && cs.remainingChars == 0;
+#else
+ // if we have no text codecs, then QString::fromLocal8Bit is fromLatin1
+ return true;
+#endif
+}
+
QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters,
const QStringList &nameFilters, QDirIterator::IteratorFlags flags)
: nativePath(entry.nativeFilePath())
@@ -81,9 +122,9 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
dirEntry = QT_READDIR(dir);
if (dirEntry) {
- // process entries with correct UTF-8 names only
- if (QFile::encodeName(QFile::decodeName(dirEntry->d_name)) == dirEntry->d_name) {
- fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath());
+ qsizetype len = strlen(dirEntry->d_name);
+ if (checkNameDecodable(dirEntry->d_name, len)) {
+ fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name, len), QFileSystemEntry::FromNativePath());
metaData.fillFromDirEnt(*dirEntry);
return true;
}
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 915d0a0a00..04f440fea2 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -197,6 +197,7 @@ bool QSaveFile::open(OpenMode mode)
return false;
}
unsetError();
+ d->writeError = QFileDevice::NoError;
if ((mode & (ReadOnly | WriteOnly)) == 0) {
qWarning("QSaveFile::open: Open mode not specified");
return false;
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index fcf7b5e709..c50e087c10 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -972,12 +972,11 @@ QByteArray qUncompress(const uchar* data, int nbytes)
\section2 8-bit Character Comparisons
In QByteArray, the notion of uppercase and lowercase and of which
- character is greater than or less than another character is
- locale dependent. This affects functions that support a case
+ character is greater than or less than another character is done
+ in the Latin-1 locale. This affects functions that support a case
insensitive option or that compare or lowercase or uppercase
their arguments. Case insensitive operations and comparisons will
- be accurate if both strings contain only ASCII characters. (If \c
- $LC_CTYPE is set, most Unix systems do "the right thing".)
+ be accurate if both strings contain only Latin-1 characters.
Functions that this affects include contains(), indexOf(),
lastIndexOf(), operator<(), operator<=(), operator>(),
operator>=(), isLower(), isUpper(), toLower() and toUpper().
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 2762b702b2..25b9698559 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -1074,7 +1074,7 @@ QList<QByteArray> QImageReader::supportedSubTypes() const
\since 5.5
Returns the transformation metadata of the image, including image orientation. If the format
- does not support transformation metadata \c QImageIOHandler::Transformation_None is returned.
+ does not support transformation metadata, QImageIOHandler::TransformationNone is returned.
\sa setAutoTransform(), autoTransform()
*/
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index a41ec8f35c..483d6d79a2 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -42,6 +42,8 @@
#include "qobject.h"
#include "qdebug.h"
#include "qpixmapcache_p.h"
+#include "qthread.h"
+#include "qcoreapplication.h"
QT_BEGIN_NAMESPACE
@@ -83,6 +85,9 @@ QT_BEGIN_NAMESPACE
with QPixmapCache} explains how to use QPixmapCache to speed up
applications by caching the results of painting.
+ \note QPixmapCache is only usable from the application's main thread.
+ Access from other threads will be ignored and return failure.
+
\sa QCache, QPixmap
*/
@@ -98,6 +103,14 @@ static inline int cost(const QPixmap &pixmap)
return static_cast<int>(qBound(1LL, costKb, costMax));
}
+static inline bool qt_pixmapcache_thread_test()
+{
+ if (Q_LIKELY(QCoreApplication::instance() && QThread::currentThread() == QCoreApplication::instance()->thread()))
+ return true;
+
+ return false;
+}
+
/*!
\class QPixmapCache::Key
\brief The QPixmapCache::Key class can be used for efficient access
@@ -490,6 +503,8 @@ QPixmapCacheEntry::~QPixmapCacheEntry()
QPixmap *QPixmapCache::find(const QString &key)
{
+ if (!qt_pixmapcache_thread_test())
+ return nullptr;
return pm_cache()->object(key);
}
@@ -519,6 +534,8 @@ bool QPixmapCache::find(const QString &key, QPixmap &pixmap)
bool QPixmapCache::find(const QString &key, QPixmap *pixmap)
{
+ if (!qt_pixmapcache_thread_test())
+ return false;
QPixmap *ptr = pm_cache()->object(key);
if (ptr && pixmap)
*pixmap = *ptr;
@@ -536,6 +553,8 @@ bool QPixmapCache::find(const QString &key, QPixmap *pixmap)
*/
bool QPixmapCache::find(const Key &key, QPixmap *pixmap)
{
+ if (!qt_pixmapcache_thread_test())
+ return false;
//The key is not valid anymore, a flush happened before probably
if (!key.d || !key.d->isValid)
return false;
@@ -567,6 +586,8 @@ bool QPixmapCache::find(const Key &key, QPixmap *pixmap)
bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
{
+ if (!qt_pixmapcache_thread_test())
+ return false;
return pm_cache()->insert(key, pixmap, cost(pixmap));
}
@@ -587,6 +608,8 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap)
*/
QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
{
+ if (!qt_pixmapcache_thread_test())
+ return QPixmapCache::Key();
return pm_cache()->insert(pixmap, cost(pixmap));
}
@@ -601,6 +624,8 @@ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap)
*/
bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap)
{
+ if (!qt_pixmapcache_thread_test())
+ return false;
//The key is not valid anymore, a flush happened before probably
if (!key.d || !key.d->isValid)
return false;
@@ -630,6 +655,8 @@ int QPixmapCache::cacheLimit()
void QPixmapCache::setCacheLimit(int n)
{
+ if (!qt_pixmapcache_thread_test())
+ return;
pm_cache()->setMaxCost(n);
}
@@ -638,6 +665,8 @@ void QPixmapCache::setCacheLimit(int n)
*/
void QPixmapCache::remove(const QString &key)
{
+ if (!qt_pixmapcache_thread_test())
+ return;
pm_cache()->remove(key);
}
@@ -649,6 +678,8 @@ void QPixmapCache::remove(const QString &key)
*/
void QPixmapCache::remove(const Key &key)
{
+ if (!qt_pixmapcache_thread_test())
+ return;
//The key is not valid anymore, a flush happened before probably
if (!key.d || !key.d->isValid)
return;
@@ -661,6 +692,8 @@ void QPixmapCache::remove(const Key &key)
void QPixmapCache::clear()
{
+ if (!QCoreApplication::closingDown() && !qt_pixmapcache_thread_test())
+ return;
QT_TRY {
if (pm_cache.exists())
pm_cache->clear();
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
index e3cbba955d..490dc99749 100644
--- a/src/gui/opengl/qopengltextureglyphcache.cpp
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -53,8 +53,8 @@ static int next_qopengltextureglyphcache_serial_number()
return 1 + serial.fetchAndAddRelaxed(1);
}
-QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix)
- : QImageTextureGlyphCache(format, matrix)
+QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color)
+ : QImageTextureGlyphCache(format, matrix, color)
, m_textureResource(0)
, pex(0)
, m_blitProgram(0)
diff --git a/src/gui/opengl/qopengltextureglyphcache_p.h b/src/gui/opengl/qopengltextureglyphcache_p.h
index aed128cf9e..4bea4a463a 100644
--- a/src/gui/opengl/qopengltextureglyphcache_p.h
+++ b/src/gui/opengl/qopengltextureglyphcache_p.h
@@ -110,7 +110,7 @@ public:
class Q_GUI_EXPORT QOpenGLTextureGlyphCache : public QImageTextureGlyphCache
{
public:
- QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat glyphFormat, const QTransform &matrix);
+ QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat glyphFormat, const QTransform &matrix, const QColor &color = QColor());
~QOpenGLTextureGlyphCache();
virtual void createTextureData(int width, int height) override;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 461ad51200..8ff77c8063 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2902,9 +2902,9 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : d->glyphCacheFormat;
QImageTextureGlyphCache *cache =
- static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphFormat, s->matrix));
+ static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphFormat, s->matrix, QColor(s->penData.solidColor)));
if (!cache) {
- cache = new QImageTextureGlyphCache(glyphFormat, s->matrix);
+ cache = new QImageTextureGlyphCache(glyphFormat, s->matrix, QColor(s->penData.solidColor));
fontEngine->setGlyphCache(0, cache);
}
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index e8c47df21c..7a3dd04965 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -267,7 +267,7 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition
case QFontEngine::Format_A32:
return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, m_transform);
case QFontEngine::Format_ARGB:
- return m_current_fontengine->bitmapForGlyph(g, subPixelPosition, m_transform);
+ return m_current_fontengine->bitmapForGlyph(g, subPixelPosition, m_transform, color());
default:
return m_current_fontengine->alphaMapForGlyph(g, subPixelPosition, m_transform);
}
diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h
index 1e83ab46d1..b6fc7230a8 100644
--- a/src/gui/painting/qtextureglyphcache_p.h
+++ b/src/gui/painting/qtextureglyphcache_p.h
@@ -74,8 +74,8 @@ class QTextItemInt;
class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache
{
public:
- QTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix)
- : QFontEngineGlyphCache(format, matrix), m_current_fontengine(nullptr),
+ QTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor())
+ : QFontEngineGlyphCache(format, matrix, color), m_current_fontengine(nullptr),
m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0)
{ }
@@ -165,8 +165,8 @@ inline uint qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g)
class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache
{
public:
- QImageTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix)
- : QTextureGlyphCache(format, matrix) { }
+ QImageTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor())
+ : QTextureGlyphCache(format, matrix, color) { }
~QImageTextureGlyphCache();
virtual void createTextureData(int width, int height) override;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 537d4bcefd..4198df6e43 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -899,7 +899,7 @@ QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition
return rgbMask;
}
-QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&)
+QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&, const QColor &)
{
Q_UNUSED(subPixelPosition);
@@ -1075,7 +1075,10 @@ void QFontEngine::setGlyphCache(const void *context, QFontEngineGlyphCache *cach
}
-QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, GlyphFormat format, const QTransform &transform) const
+QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context,
+ GlyphFormat format,
+ const QTransform &transform,
+ const QColor &color) const
{
const QHash<const void*, GlyphCaches>::const_iterator caches = m_glyphCaches.constFind(context);
if (caches == m_glyphCaches.cend())
@@ -1083,8 +1086,11 @@ QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, GlyphFormat
for (auto &e : *caches) {
QFontEngineGlyphCache *cache = e.cache.data();
- if (format == cache->glyphFormat() && qtransform_equals_no_translate(cache->m_transform, transform))
+ if (format == cache->glyphFormat()
+ && (format != Format_ARGB || color == cache->color())
+ && qtransform_equals_no_translate(cache->m_transform, transform)) {
return cache;
+ }
}
return nullptr;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 8dcfd7d66c..e20b52cb65 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -189,7 +189,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
- virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
+ virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color = QColor());
virtual QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
GlyphFormat neededFormat,
const QTransform &t = QTransform(),
@@ -251,7 +251,7 @@ public:
void clearGlyphCache(const void *key);
void setGlyphCache(const void *key, QFontEngineGlyphCache *data);
- QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform) const;
+ QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform, const QColor &color = QColor()) const;
static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode);
diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h
index fd5db1ecf5..532be10a83 100644
--- a/src/gui/text/qfontengineglyphcache_p.h
+++ b/src/gui/text/qfontengineglyphcache_p.h
@@ -65,7 +65,10 @@ QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QFontEngineGlyphCache: public QSharedData
{
public:
- QFontEngineGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : m_format(format), m_transform(matrix)
+ QFontEngineGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor())
+ : m_format(format)
+ , m_transform(matrix)
+ , m_color(color)
{
Q_ASSERT(m_format != QFontEngine::Format_None);
}
@@ -74,9 +77,11 @@ public:
QFontEngine::GlyphFormat glyphFormat() const { return m_format; }
const QTransform &transform() const { return m_transform; }
+ const QColor &color() const { return m_color; }
QFontEngine::GlyphFormat m_format;
QTransform m_transform;
+ QColor m_color;
};
typedef QHash<void *, QList<QFontEngineGlyphCache *> > GlyphPointerHash;
typedef QHash<int, QList<QFontEngineGlyphCache *> > GlyphIntHash;
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index 6caee5e097..c17ba38e36 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -891,7 +891,9 @@ QHostInfoLookupManager::QHostInfoLookupManager() : wasDeleted(false)
QHostInfoLookupManager::~QHostInfoLookupManager()
{
+ QMutexLocker locker(&mutex);
wasDeleted = true;
+ locker.unlock();
// don't qDeleteAll currentLookups, the QThreadPool has ownership
clear();
@@ -919,6 +921,8 @@ void QHostInfoLookupManager::clear()
void QHostInfoLookupManager::work()
{
+ QMutexLocker locker(&mutex);
+
if (wasDeleted)
return;
@@ -926,8 +930,6 @@ void QHostInfoLookupManager::work()
// - launch new lookups via the thread pool
// - make sure only one lookup per host/IP is in progress
- QMutexLocker locker(&mutex);
-
if (!finishedLookups.isEmpty()) {
// remove ID from aborted if it is in there
for (int i = 0; i < finishedLookups.length(); i++) {
@@ -979,10 +981,11 @@ void QHostInfoLookupManager::work()
// called by QHostInfo
void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r)
{
+ QMutexLocker locker(&this->mutex);
+
if (wasDeleted)
return;
- QMutexLocker locker(&this->mutex);
scheduledLookups.enqueue(r);
work();
}
@@ -990,11 +993,11 @@ void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r)
// called by QHostInfo
void QHostInfoLookupManager::abortLookup(int id)
{
+ QMutexLocker locker(&this->mutex);
+
if (wasDeleted)
return;
- QMutexLocker locker(&this->mutex);
-
#if QT_CONFIG(thread)
// is postponed? delete and return
for (int i = 0; i < postponedLookups.length(); i++) {
@@ -1020,20 +1023,22 @@ void QHostInfoLookupManager::abortLookup(int id)
// called from QHostInfoRunnable
bool QHostInfoLookupManager::wasAborted(int id)
{
+ QMutexLocker locker(&this->mutex);
+
if (wasDeleted)
return true;
- QMutexLocker locker(&this->mutex);
return abortedLookups.contains(id);
}
// called from QHostInfoRunnable
void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r)
{
+ QMutexLocker locker(&this->mutex);
+
if (wasDeleted)
return;
- QMutexLocker locker(&this->mutex);
#if QT_CONFIG(thread)
currentLookups.removeOne(r);
#endif
@@ -1095,23 +1100,10 @@ void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolut
QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(128)
{
#ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT
- enabled = false;
+ enabled.store(false, std::memory_order_relaxed);
#endif
}
-bool QHostInfoCache::isEnabled()
-{
- return enabled;
-}
-
-// this function is currently only used for the auto tests
-// and not usable by public API
-void QHostInfoCache::setEnabled(bool e)
-{
- enabled = e;
-}
-
-
QHostInfo QHostInfoCache::get(const QString &name, bool *valid)
{
QMutexLocker locker(&this->mutex);
diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h
index 7df3f5414c..0433d1d17b 100644
--- a/src/network/kernel/qhostinfo_p.h
+++ b/src/network/kernel/qhostinfo_p.h
@@ -73,6 +73,7 @@
#include <QNetworkSession>
#include <QSharedPointer>
+#include <atomic>
QT_BEGIN_NAMESPACE
@@ -177,10 +178,12 @@ public:
void put(const QString &name, const QHostInfo &info);
void clear();
- bool isEnabled();
- void setEnabled(bool e);
+ bool isEnabled() { return enabled.load(std::memory_order_relaxed); }
+ // this function is currently only used for the auto tests
+ // and not usable by public API
+ void setEnabled(bool e) { enabled.store(e, std::memory_order_relaxed); }
private:
- bool enabled;
+ std::atomic<bool> enabled;
struct QHostInfoCacheElement {
QHostInfo info;
QElapsedTimer age;
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index b429b3c365..9edabd7822 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -623,6 +623,53 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
}
+static void setErrorFromWSAError(int error, QNativeSocketEnginePrivate *d)
+{
+ Q_ASSERT(d);
+ switch (error) {
+ case WSAEISCONN:
+ d->socketState = QAbstractSocket::ConnectedState;
+ break;
+ case WSAEHOSTUNREACH:
+ d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ break;
+ case WSAEADDRNOTAVAIL:
+ d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::AddressNotAvailableErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ break;
+ case WSAEINPROGRESS:
+ d->setError(QAbstractSocket::UnfinishedSocketOperationError, QNativeSocketEnginePrivate::InvalidSocketErrorString);
+ d->socketState = QAbstractSocket::ConnectingState;
+ break;
+ case WSAEADDRINUSE:
+ d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::AddressInuseErrorString);
+ break;
+ case WSAECONNREFUSED:
+ d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ break;
+ case WSAETIMEDOUT:
+ d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ break;
+ case WSAEACCES:
+ d->setError(QAbstractSocket::SocketAccessError, QNativeSocketEnginePrivate::AccessErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ break;
+ case WSAENETUNREACH:
+ d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::NetworkUnreachableErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ break;
+ case WSAEINVAL:
+ case WSAEALREADY:
+ d->setError(QAbstractSocket::UnfinishedSocketOperationError, QNativeSocketEnginePrivate::InvalidSocketErrorString);
+ break;
+ default:
+ break;
+ }
+}
+
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quint16 port)
{
@@ -651,9 +698,6 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
case WSANOTINITIALISED:
//###
break;
- case WSAEISCONN:
- socketState = QAbstractSocket::ConnectedState;
- break;
case WSAEWOULDBLOCK: {
// If WSAConnect returns WSAEWOULDBLOCK on the second
// connection attempt, we have to check SO_ERROR's
@@ -668,82 +712,33 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
do {
if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
if (value != NOERROR) {
+ WS_ERROR_DEBUG(value);
+ errorDetected = true;
// MSDN says getsockopt with SO_ERROR clears the error, but it's not actually cleared
// and this can affect all subsequent WSAConnect attempts, so clear it now.
const int val = NO_ERROR;
::setsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, reinterpret_cast<const char*>(&val), sizeof val);
- }
-
- if (value == WSAECONNREFUSED) {
- setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- errorDetected = true;
- break;
- }
- if (value == WSAETIMEDOUT) {
- setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- errorDetected = true;
- break;
- }
- if (value == WSAEHOSTUNREACH) {
- setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- errorDetected = true;
- break;
- }
- if (value == WSAEADDRNOTAVAIL) {
- setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- errorDetected = true;
- break;
- }
- if (value == NOERROR) {
+ } else {
// When we get WSAEWOULDBLOCK the outcome was not known, so a
// NOERROR might indicate that the result of the operation
// is still unknown. We try again to increase the chance that we did
// get the correct result.
tryAgain = !tryAgain;
}
+ setErrorFromWSAError(value, this);
}
tries++;
} while (tryAgain && (tries < 2));
if (errorDetected)
break;
+ // fall through to unfinished operation error handling
+ err = WSAEINPROGRESS;
Q_FALLTHROUGH();
}
- case WSAEINPROGRESS:
- setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString);
- socketState = QAbstractSocket::ConnectingState;
- break;
- case WSAEADDRINUSE:
- setError(QAbstractSocket::NetworkError, AddressInuseErrorString);
- break;
- case WSAECONNREFUSED:
- setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- case WSAETIMEDOUT:
- setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
- break;
- case WSAEACCES:
- setError(QAbstractSocket::SocketAccessError, AccessErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- case WSAEHOSTUNREACH:
- setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- case WSAENETUNREACH:
- setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- case WSAEINVAL:
- case WSAEALREADY:
- setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString);
- break;
+
default:
+ setErrorFromWSAError(err, this);
break;
}
if (socketState != QAbstractSocket::ConnectedState) {
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 8d0a20f7b9..b608e7f483 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -1929,8 +1929,10 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
}
-QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
+QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t, const QColor &color)
{
+ Q_UNUSED(color);
+
Glyph *glyph = loadGlyphFor(g, subPixelPosition, defaultFormat, t);
if (glyph == nullptr)
return QImage();
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
index 2765db2946..b636c42e63 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
@@ -236,7 +236,7 @@ private:
QImage alphaMapForGlyph(glyph_t, QFixed) override;
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
+ QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
QFixed subPixelPosition,
const QTransform &matrix,
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 25e7c6df72..072dd1a28a 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -747,7 +747,7 @@ qreal QCoreTextFontEngine::fontSmoothingGamma()
return 2.0;
}
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix)
+QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, const QColor &color)
{
glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
@@ -827,6 +827,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx);
}
} else {
+ CGContextSetRGBFillColor(ctx, color.redF(), color.greenF(), color.blueF(), color.alphaF());
+
// CGContextSetTextMatrix does not work with color glyphs, so we use
// the CTM instead. This means we must translate the CTM as well, to
// set the glyph position, instead of using CGContextSetTextPosition.
@@ -884,12 +886,12 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo
return imageForGlyph(glyph, subPixelPosition, x);
}
-QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
+QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color)
{
if (t.type() > QTransform::TxScale)
- return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t);
+ return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t, color);
- return imageForGlyph(glyph, subPixelPosition, t);
+ return imageForGlyph(glyph, subPixelPosition, t, color);
}
void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index 4064507058..51d839688d 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -110,7 +110,7 @@ public:
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) override;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
+ QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
QFixed emSquareSize() const override;
void doKerning(QGlyphLayout *g, ShaperFlags flags) const override;
@@ -137,7 +137,7 @@ public:
protected:
QCoreTextFontEngine(const QFontDef &def);
void init();
- QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m);
+ QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m, const QColor &color = QColor());
void loadAdvancesForGlyphs(QVarLengthArray<CGGlyph> &cgGlyphs, QGlyphLayout *glyphs) const;
bool hasColorGlyphs() const;
bool shouldAntialias() const;
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
index 60a5896e7b..a4490a6664 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
@@ -650,7 +650,8 @@ bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const
QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
QFixed subPixelPosition,
int margin,
- const QTransform &originalTransform)
+ const QTransform &originalTransform,
+ const QColor &color)
{
UINT16 glyphIndex = t;
FLOAT glyphAdvance = 0;
@@ -735,6 +736,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
#if defined(QT_USE_DIRECTWRITE2)
BOOL ok = true;
+
if (SUCCEEDED(hr)) {
while (SUCCEEDED(hr) && ok) {
const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0;
@@ -759,10 +761,18 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
break;
}
- float r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f);
- float g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f);
- float b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f);
- float a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f);
+ float r, g, b, a;
+ if (colorGlyphRun->paletteIndex == 0xFFFF) {
+ r = float(color.redF());
+ g = float(color.greenF());
+ b = float(color.blueF());
+ a = float(color.alphaF());
+ } else {
+ r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f);
+ g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f);
+ b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f);
+ a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f);
+ }
if (!qFuzzyIsNull(a)) {
renderGlyphRun(&image,
@@ -784,11 +794,21 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
} else
#endif
{
+ float r, g, b, a;
+ if (glyphFormat == QFontEngine::Format_ARGB) {
+ r = float(color.redF());
+ g = float(color.greenF());
+ b = float(color.blueF());
+ a = float(color.alphaF());
+ } else {
+ r = g = b = a = 0.0;
+ }
+
renderGlyphRun(&image,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
+ r,
+ g,
+ b,
+ a,
glyphAnalysis,
boundingRect);
}
@@ -1001,9 +1021,9 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
}
}
-QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
+QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color)
{
- return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_A32), t);
+ return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_A32), t, color);
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
index 3eaf8cf3d8..c8c6b83bf9 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
@@ -112,7 +112,7 @@ public:
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) override;
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) override;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
+ QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
QFontEngine *cloneWithSize(qreal pixelSize) const override;
Qt::HANDLE handle() const override;
@@ -126,7 +126,7 @@ public:
void setUniqueFamilyName(const QString &newName) { m_uniqueFamilyName = newName; }
private:
- QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
+ QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform, const QColor &color = QColor());
void collectMetrics();
void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect);
static QString filenameFromFontFile(IDWriteFontFile *fontFile);
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
index 0c19294905..daa52d690e 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
@@ -96,7 +96,7 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif
}
QInputDeviceManager *manager = QGuiApplicationPrivate::inputDeviceManager();
- connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [=](const QPoint &pos) {
+ connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [this](const QPoint &pos) {
m_x = pos.x();
m_y = pos.y();
clampPosition();
diff --git a/src/platformsupport/input/libinput/qlibinputhandler.cpp b/src/platformsupport/input/libinput/qlibinputhandler.cpp
index bb81890a67..95dfb46d16 100644
--- a/src/platformsupport/input/libinput/qlibinputhandler.cpp
+++ b/src/platformsupport/input/libinput/qlibinputhandler.cpp
@@ -115,7 +115,7 @@ QLibInputHandler::QLibInputHandler(const QString &key, const QString &spec)
m_touch.reset(new QLibInputTouch);
QInputDeviceManager *manager = QGuiApplicationPrivate::inputDeviceManager();
- connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [=](const QPoint &pos) {
+ connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [this](const QPoint &pos) {
m_pointer->setPos(pos);
});
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index de5cf85854..464c16d66f 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -264,7 +264,6 @@ bool QCocoaSystemTrayIcon::supportsMessages() const
void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message,
const QIcon& icon, MessageIcon, int)
{
- Q_UNUSED(icon);
if (!m_sys)
return;
@@ -272,6 +271,12 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
notification.title = [NSString stringWithUTF8String:title.toUtf8().data()];
notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()];
+ if (!icon.isNull()) {
+ auto *nsimage = qt_mac_create_nsimage(icon);
+ [nsimage setTemplate:icon.isMask()];
+ notification.contentImage = [nsimage autorelease];
+ }
+
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index f2f29b26ee..58ad53a6e1 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -522,16 +522,16 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice->supportedDuplexModes().contains(mode))
break;
switch (mode) {
- case QPrinter::DuplexNone:
+ case QPrint::DuplexNone:
PMSetDuplex(d->settings(), kPMDuplexNone);
break;
- case QPrinter::DuplexAuto:
+ case QPrint::DuplexAuto:
PMSetDuplex(d->settings(), d->m_pageLayout.orientation() == QPageLayout::Landscape ? kPMDuplexTumble : kPMDuplexNoTumble);
break;
- case QPrinter::DuplexLongSide:
+ case QPrint::DuplexLongSide:
PMSetDuplex(d->settings(), kPMDuplexNoTumble);
break;
- case QPrinter::DuplexShortSide:
+ case QPrint::DuplexShortSide:
PMSetDuplex(d->settings(), kPMDuplexTumble);
break;
default:
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index e681dbb0cb..d5258ca6a3 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
#include <QtCore/qtextboundaryfinder.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/qevent.h>
#include <QtGui/qtextformat.h>
@@ -279,7 +280,13 @@ void QWindowsInputContext::showInputPanel()
// with Windows 10 if the Windows IME is (re)enabled _after_ the caret is shown.
if (m_caretCreated) {
cursorRectChanged();
- ShowCaret(platformWindow->handle());
+ // We only call ShowCaret() on Windows 10 as in earlier versions the caret
+ // would actually be visible (QTBUG-74492) and the workaround for the
+ // Surface seems unnecessary there anyway. But leave it hidden for IME.
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10)
+ ShowCaret(platformWindow->handle());
+ else
+ HideCaret(platformWindow->handle());
setWindowsImeEnabled(platformWindow, false);
setWindowsImeEnabled(platformWindow, true);
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index b3d961db72..cffd8427a2 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -80,13 +80,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
*result = 0;
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
- POINTER_INPUT_TYPE pointerType;
- if (!QWindowsContext::user32dll.getPointerType(pointerId, &pointerType)) {
+ if (!QWindowsContext::user32dll.getPointerType(pointerId, &m_pointerType)) {
qWarning() << "GetPointerType() failed:" << qt_error_string();
return false;
}
- switch (pointerType) {
+ switch (m_pointerType) {
case QT_PT_POINTER:
case QT_PT_MOUSE:
case QT_PT_TOUCHPAD: {
@@ -684,7 +683,7 @@ bool QWindowsPointerHandler::translateMouseWheelEvent(QWindow *window,
QPoint localPos = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos);
- QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
+ QWindowSystemInterface::handleWheelEvent(receiver, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
return true;
}
@@ -734,7 +733,11 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
}
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
- if (isMouseEventSynthesizedFromPenOrTouch()) {
+ // Following the logic of the old mouse handler, only events synthesized
+ // for touch screen are marked as such. On some systems, using the bit 7 of
+ // the extra msg info for checking if synthesized for touch does not work,
+ // so we use the pointer type of the last pointer message.
+ if (isMouseEventSynthesizedFromPenOrTouch() && m_pointerType == QT_PT_TOUCH) {
if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)
return false;
source = Qt::MouseEventSynthesizedBySystem;
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
index 068e804007..8874db27e3 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.h
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -82,6 +82,7 @@ private:
bool m_needsEnterOnPointerUpdate = false;
QEvent::Type m_lastEventType = QEvent::None;
Qt::MouseButton m_lastEventButton = Qt::NoButton;
+ DWORD m_pointerType = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
index 82a36c0727..759ee3cc95 100644
--- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp
+++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
@@ -226,11 +226,13 @@ void QXcbEventQueue::run()
};
while (!m_closeConnectionDetected && (event = xcb_wait_for_event(connection))) {
+ m_newEventsMutex.lock();
enqueueEvent(event);
while (!m_closeConnectionDetected && (event = xcb_poll_for_queued_event(connection)))
enqueueEvent(event);
m_newEventsCondition.wakeOne();
+ m_newEventsMutex.unlock();
wakeUpDispatcher();
}
@@ -350,9 +352,12 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData,
void QXcbEventQueue::waitForNewEvents(unsigned long time)
{
- m_newEventsMutex.lock();
+ QMutexLocker locker(&m_newEventsMutex);
+ QXcbEventNode *tailBeforeFlush = m_flushedTail;
+ flushBufferedEvents();
+ if (tailBeforeFlush != m_flushedTail)
+ return;
m_newEventsCondition.wait(&m_newEventsMutex, time);
- m_newEventsMutex.unlock();
}
void QXcbEventQueue::sendCloseConnectionEvent() const
diff --git a/src/src.pro b/src/src.pro
index 9ccc1e8f65..832a3b6d82 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,8 +1,10 @@
TEMPLATE = subdirs
-QT_FOR_CONFIG += core-private gui-private
+QT_FOR_CONFIG += core-private gui-private printsupport
+
include($$OUT_PWD/corelib/qtcore-config.pri)
include($$OUT_PWD/gui/qtgui-config.pri)
+include($$OUT_PWD/printsupport/qtprintsupport-config.pri)
force_bootstrap|!qtConfig(commandlineparser): \
CONFIG += force_dbus_bootstrap
@@ -225,11 +227,13 @@ qtConfig(gui) {
src_testlib.depends += src_gui # if QtGui is enabled, QtTest requires QtGui's headers
qtConfig(widgets) {
SUBDIRS += src_tools_uic src_widgets
- !android-embedded: SUBDIRS += src_printsupport
TOOLS += src_tools_uic
src_plugins.depends += src_widgets
- !android-embedded: src_plugins.depends += src_printsupport
src_testlib.depends += src_widgets # if QtWidgets is enabled, QtTest requires QtWidgets's headers
+ qtConfig(printer) {
+ SUBDIRS += src_printsupport
+ src_plugins.depends += src_printsupport
+ }
qtConfig(opengl) {
SUBDIRS += src_opengl
src_plugins.depends += src_opengl
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 82c341b47c..fc00290536 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1745,7 +1745,7 @@ void QColorDialogPrivate::initWidgets()
q->connect(custom, SIGNAL(selected(int,int)), SLOT(_q_newCustom(int,int)));
q->connect(custom, SIGNAL(currentChanged(int,int)), SLOT(_q_nextCustom(int,int)));
- q->connect(custom, &QWellArray::colorChanged, [=] (int index, QRgb color) {
+ q->connect(custom, &QWellArray::colorChanged, [this] (int index, QRgb color) {
QColorDialogOptions::setCustomColor(index, color);
if (custom)
custom->update();
diff --git a/src/widgets/doc/macOS/AppKit/AppKit.h b/src/widgets/doc/macOS/AppKit/AppKit.h
new file mode 100644
index 0000000000..29e2004423
--- /dev/null
+++ b/src/widgets/doc/macOS/AppKit/AppKit.h
@@ -0,0 +1 @@
+// Dummy header used in documentation build
diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf
index 6e04372a8b..548224bf61 100644
--- a/src/widgets/doc/qtwidgets.qdocconf
+++ b/src/widgets/doc/qtwidgets.qdocconf
@@ -5,6 +5,9 @@ project = QtWidgets
description = Qt Widgets Reference Documentation
version = $QT_VERSION
+# dummy macOS headers for generating docs under non-mac platforms
+includepaths += -I./macOS
+
examplesinstallpath = widgets
qhp.projects = QtWidgets
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index d5919eb55f..7f14218720 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -691,7 +691,7 @@ void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event)
}
// Find the topmost item under the mouse with a cursor.
foreach (QGraphicsItem *item, scene->d_func()->cachedItemsUnderMouse) {
- if (item->hasCursor()) {
+ if (item->isEnabled() && item->hasCursor()) {
_q_setViewportCursor(item->cursor());
return;
}
@@ -808,7 +808,7 @@ void QGraphicsViewPrivate::_q_unsetViewportCursor()
Q_Q(QGraphicsView);
const auto items = q->items(lastMouseEvent.pos());
for (QGraphicsItem *item : items) {
- if (item->hasCursor()) {
+ if (item->isEnabled() && item->hasCursor()) {
_q_setViewportCursor(item->cursor());
return;
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 0415dc4e56..7d18c06def 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1895,7 +1895,7 @@ bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QMo
void QListViewPrivate::removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const
{
- auto isCurrentOrDisabled = [=](const QModelIndex &index) {
+ auto isCurrentOrDisabled = [this, current](const QModelIndex &index) {
return !isIndexEnabled(index) || index == current;
};
indexes->erase(std::remove_if(indexes->begin(), indexes->end(),
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 7feb18e839..19ef76fe4d 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -1964,7 +1964,7 @@ bool QApplication::event(QEvent *e)
*/
// ### FIXME: topLevelWindows does not contain QWidgets without a parent
-// until create_sys is called. So we have to override the
+// until QWidgetPrivate::create is called. So we have to override the
// QGuiApplication::notifyLayoutDirectionChange
// to do the right thing.
void QApplicationPrivate::notifyLayoutDirectionChange()
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 89b0e56297..3dad7dad1e 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1193,7 +1193,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea);
q->setAttribute(Qt::WA_WState_Hidden);
- //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later
+ //give potential windows a bigger "pre-initial" size; create() will give them a new size later
data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480);
focus_next = focus_prev = q;
@@ -1287,27 +1287,19 @@ QScreen *QWidgetPrivate::associatedScreen() const
/*!
Creates a new widget window.
- The parameter \a window is ignored in Qt 5. Please use
- QWindow::fromWinId() to create a QWindow wrapping a foreign
- window and pass it to QWidget::createWindowContainer() instead.
-
- Initializes the window (sets the geometry etc.) if \a
- initializeWindow is true. If \a initializeWindow is false, no
- initialization is performed. This parameter only makes sense if \a
- window is a valid window.
-
- Destroys the old window if \a destroyOldWindow is true. If \a
- destroyOldWindow is false, you are responsible for destroying the
- window yourself (using platform native code).
-
- The QWidget constructor calls create(0,true,true) to create a
- window for this widget.
+ The parameters \a window, \a initializeWindow, and \a destroyOldWindow
+ are ignored in Qt 5. Please use QWindow::fromWinId() to create a
+ QWindow wrapping a foreign window and pass it to
+ QWidget::createWindowContainer() instead.
\sa createWindowContainer(), QWindow::fromWinId()
*/
void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
{
+ Q_UNUSED(initializeWindow);
+ Q_UNUSED(destroyOldWindow);
+
Q_D(QWidget);
if (Q_UNLIKELY(window))
qWarning("QWidget::create(): Parameter 'window' does not have any effect.");
@@ -1367,7 +1359,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
d->updateIsOpaque();
setAttribute(Qt::WA_WState_Created); // set created flag
- d->create_sys(window, initializeWindow, destroyOldWindow);
+ d->create();
// a real toplevel window needs a backing store
if (isWindow() && windowType() != Qt::Desktop) {
@@ -1431,14 +1423,10 @@ void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
}
-void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
+void QWidgetPrivate::create()
{
Q_Q(QWidget);
- Q_UNUSED(window);
- Q_UNUSED(initializeWindow);
- Q_UNUSED(destroyOldWindow);
-
if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
return; // we only care about real toplevels
@@ -7474,6 +7462,17 @@ QByteArray QWidget::saveGeometry() const
return array;
}
+static void checkRestoredGeometry(const QRect &availableGeometry, QRect *restoredGeometry,
+ int frameHeight)
+{
+ if (!restoredGeometry->intersects(availableGeometry)) {
+ restoredGeometry->moveBottom(qMin(restoredGeometry->bottom(), availableGeometry.bottom()));
+ restoredGeometry->moveLeft(qMax(restoredGeometry->left(), availableGeometry.left()));
+ restoredGeometry->moveRight(qMin(restoredGeometry->right(), availableGeometry.right()));
+ }
+ restoredGeometry->moveTop(qMax(restoredGeometry->top(), availableGeometry.top() + frameHeight));
+}
+
/*!
\since 4.2
@@ -7528,7 +7527,7 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
quint8 fullScreen;
qint32 restoredScreenWidth = 0;
- stream >> restoredFrameGeometry
+ stream >> restoredFrameGeometry // Only used for sanity checks in version 0
>> restoredNormalGeometry
>> restoredScreenNumber
>> maximized
@@ -7558,8 +7557,6 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
}
const int frameHeight = 20;
- if (!restoredFrameGeometry.isValid())
- restoredFrameGeometry = QRect(QPoint(0,0), sizeHint());
if (!restoredNormalGeometry.isValid())
restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint());
@@ -7579,23 +7576,11 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
// - (Mac only) The window is higher than the available geometry. It must
// be possible to bring the size grip on screen by moving the window.
#if 0 // Used to be included in Qt4 for Q_WS_MAC
- restoredFrameGeometry.setHeight(qMin(restoredFrameGeometry.height(), availableGeometry.height()));
restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight));
#endif
- if (!restoredFrameGeometry.intersects(availableGeometry)) {
- restoredFrameGeometry.moveBottom(qMin(restoredFrameGeometry.bottom(), availableGeometry.bottom()));
- restoredFrameGeometry.moveLeft(qMax(restoredFrameGeometry.left(), availableGeometry.left()));
- restoredFrameGeometry.moveRight(qMin(restoredFrameGeometry.right(), availableGeometry.right()));
- }
- restoredFrameGeometry.moveTop(qMax(restoredFrameGeometry.top(), availableGeometry.top()));
-
- if (!restoredNormalGeometry.intersects(availableGeometry)) {
- restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom()));
- restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left()));
- restoredNormalGeometry.moveRight(qMin(restoredNormalGeometry.right(), availableGeometry.right()));
- }
- restoredNormalGeometry.moveTop(qMax(restoredNormalGeometry.top(), availableGeometry.top() + frameHeight));
+ checkRestoredGeometry(availableGeometry, &restoredGeometry, frameHeight);
+ checkRestoredGeometry(availableGeometry, &restoredNormalGeometry, frameHeight);
if (maximized || fullScreen) {
// set geometry before setting the window state to make
@@ -9408,12 +9393,6 @@ bool QWidget::event(QEvent *event)
d->renderToTextureReallyDirty = 1;
#endif
break;
- case QEvent::PlatformSurface: {
- auto surfaceEvent = static_cast<QPlatformSurfaceEvent*>(event);
- if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed)
- d->setWinId(0);
- break;
- }
#ifndef QT_NO_PROPERTIES
case QEvent::DynamicPropertyChange: {
const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
@@ -11392,7 +11371,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
// windowModality property and then reshown.
}
if (testAttribute(Qt::WA_WState_Created)) {
- // don't call setModal_sys() before create_sys()
+ // don't call setModal_sys() before create()
d->setModal_sys();
}
break;
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 99ec38e050..7cb9a3895a 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -360,7 +360,7 @@ public:
void update(T t);
void init(QWidget *desktopWidget, Qt::WindowFlags f);
- void create_sys(WId window, bool initializeWindow, bool destroyOldWindow);
+ void create();
void createRecursively();
void createWinId();
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 68e3de05bc..19389cbf83 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -684,7 +684,7 @@ QSize QLineEdit::sizeHint() const
ensurePolished();
QFontMetrics fm(font());
const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
- int h = qMax(fm.height(), iconSize - 2) + 2 * QLineEditPrivate::verticalMargin
+ int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2 * QLineEditPrivate::verticalMargin
+ d->topTextMargin + d->bottomTextMargin
+ d->topmargin + d->bottommargin;
int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2 * QLineEditPrivate::horizontalMargin
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 7ec33acbbf..53964303fc 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -200,7 +200,7 @@ void QMenuPrivate::init()
q->setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu);
defaultMenuAction = menuAction = new QAction(q);
menuAction->d_func()->menu = q;
- QObject::connect(menuAction, &QAction::changed, [=] {
+ QObject::connect(menuAction, &QAction::changed, [this] {
if (!tornPopup.isNull())
tornPopup->updateWindowTitle();
});
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index 96970421d3..f1327933c4 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -72,6 +72,7 @@ public slots:
private slots:
void transactionalWrite();
+ void retryTransactionalWrite();
void textStreamManualFlush();
void textStreamAutoFlush();
void saveTwice();
@@ -129,6 +130,39 @@ void tst_QSaveFile::transactionalWrite()
QCOMPARE(QFile::permissions(targetFile), QFile::permissions(otherFile));
}
+// QTBUG-77007: Simulate the case of an application with a loop prompting
+// to retry saving on failure. Create a read-only file first (Unix only)
+void tst_QSaveFile::retryTransactionalWrite()
+{
+#ifndef Q_OS_UNIX
+ QSKIP("This test is Unix only");
+#endif
+ QTemporaryDir dir;
+ QVERIFY2(dir.isValid(), qPrintable(dir.errorString()));
+
+ QString targetFile = dir.path() + QLatin1String("/outfile");
+ const QString readOnlyName = targetFile + QLatin1String(".ro");
+ {
+ QFile readOnlyFile(readOnlyName);
+ QVERIFY2(readOnlyFile.open(QIODevice::WriteOnly), msgCannotOpen(readOnlyFile).constData());
+ readOnlyFile.write("Hello");
+ readOnlyFile.close();
+ auto permissions = readOnlyFile.permissions();
+ permissions &= ~(QFileDevice::WriteOwner | QFileDevice::WriteGroup | QFileDevice::WriteUser);
+ QVERIFY(readOnlyFile.setPermissions(permissions));
+ }
+
+ QSaveFile file(readOnlyName);
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+
+ file.setFileName(targetFile);
+ QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData());
+ QVERIFY(file.isOpen());
+ QCOMPARE(file.write("Hello"), Q_INT64_C(5));
+ QCOMPARE(file.error(), QFile::NoError);
+ QVERIFY(file.commit());
+}
+
void tst_QSaveFile::saveTwice()
{
// Check that we can reuse a QSaveFile object
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index 7733b0a62b..75b9b23259 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -164,9 +164,8 @@ private slots:
void waitForReadyReadInASlot();
void remoteCloseError();
void nestedEventLoopInErrorSlot();
-#ifndef Q_OS_WIN
- void connectToLocalHostNoService();
-#endif
+ void connectToHostError_data();
+ void connectToHostError();
void waitForConnectedInHostLookupSlot();
void waitForConnectedInHostLookupSlot2();
void readyReadSignalsAfterWaitForReadyRead();
@@ -2066,18 +2065,38 @@ void tst_QTcpSocket::nestedEventLoopInErrorSlot()
}
//----------------------------------------------------------------------------------
-#ifndef Q_OS_WIN
-void tst_QTcpSocket::connectToLocalHostNoService()
+
+void tst_QTcpSocket::connectToHostError_data()
+{
+ QTest::addColumn<QString>("host");
+ QTest::addColumn<int>("port");
+ QTest::addColumn<QAbstractSocket::SocketError>("expectedError");
+
+ QTest::newRow("localhost no service") << QStringLiteral("localhost") << 31415 << QAbstractSocket::ConnectionRefusedError;
+ QTest::newRow("unreachable") << QStringLiteral("0.0.0.1") << 65000 << QAbstractSocket::NetworkError;
+}
+
+
+void tst_QTcpSocket::connectToHostError()
{
- // This test was created after we received a report that claimed
- // QTcpSocket would crash if trying to connect to "localhost" on a random
- // port with no service listening.
QTcpSocket *socket = newSocket();
- socket->connectToHost("localhost", 31415); // no service running here, one suspects
+
+ QAbstractSocket::SocketError error = QAbstractSocket::UnknownSocketError;
+
+ QFETCH(QString, host);
+ QFETCH(int, port);
+ QFETCH(QAbstractSocket::SocketError, expectedError);
+
+ connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),[&](QAbstractSocket::SocketError socketError){
+ error = socketError;
+ });
+ socket->connectToHost(host, port); // no service running here, one suspects
QTRY_COMPARE(socket->state(), QTcpSocket::UnconnectedState);
+ if (error != expectedError && error == QAbstractSocket::ConnectionRefusedError)
+ QEXPECT_FAIL("unreachable", "CI firewall interfers with this test", Continue);
+ QCOMPARE(error, expectedError);
delete socket;
}
-#endif
//----------------------------------------------------------------------------------
void tst_QTcpSocket::waitForConnectedInHostLookupSlot()
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 4035dfbf5f..9924688bdf 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -2755,7 +2755,6 @@ void tst_QSslSocket::encryptWithoutConnecting()
void tst_QSslSocket::resume_data()
{
- QSKIP("Temporary skip while updating certificates");
QTest::addColumn<bool>("ignoreErrorsAfterPause");
QTest::addColumn<QList<QSslError> >("errorsToIgnore");
QTest::addColumn<bool>("expectSuccess");
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index 4f3ff15ae0..432d8d75b7 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -1811,7 +1811,8 @@ void tst_QGraphicsItem::selected_multi()
{
// Ctrl-move on item1
- QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->scenePos()) + QPoint(1, 0), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier);
+ const QPoint item1Point = view.mapFromScene(item1->scenePos()) + QPoint(1, 0);
+ QMouseEvent event(QEvent::MouseMove, item1Point, view.viewport()->mapToGlobal(item1Point), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier);
QApplication::sendEvent(view.viewport(), &event);
QVERIFY(!item1->isSelected());
QVERIFY(!item2->isSelected());
@@ -1832,7 +1833,8 @@ void tst_QGraphicsItem::selected_multi()
{
// Ctrl-move on item1
- QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->scenePos()) + QPoint(1, 0), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier);
+ const QPoint item1Point = view.mapFromScene(item1->scenePos()) + QPoint(1, 0);
+ QMouseEvent event(QEvent::MouseMove, item1Point, view.viewport()->mapToGlobal(item1Point), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier);
QApplication::sendEvent(view.viewport(), &event);
QVERIFY(item1->isSelected());
QVERIFY(!item2->isSelected());
@@ -4151,6 +4153,8 @@ void tst_QGraphicsItem::cursor()
QGraphicsView view(&scene);
view.showFullScreen();
QVERIFY(QTest::qWaitForWindowExposed(&view));
+ const Qt::CursorShape viewportShape = view.viewport()->cursor().shape();
+
QGraphicsRectItem *item1 = scene.addRect(QRectF(-100, 0, 50, 50));
QGraphicsRectItem *item2 = scene.addRect(QRectF(50, 0, 50, 50));
@@ -4178,41 +4182,45 @@ void tst_QGraphicsItem::cursor()
item1->setCursor(Qt::IBeamCursor);
item2->setCursor(Qt::PointingHandCursor);
- QTest::mouseMove(&view, view.rect().center());
+ QPoint viewCenter = view.rect().center();
+ QPoint item1Center = view.mapFromScene(item1->sceneBoundingRect().center());
+ QPoint item2Center = view.mapFromScene(item2->sceneBoundingRect().center());
- const Qt::CursorShape viewportShape = view.viewport()->cursor().shape();
+ {
+ QMouseEvent event(QEvent::MouseMove, viewCenter, view.viewport()->mapToGlobal(viewCenter), Qt::NoButton, 0, 0);
+ QApplication::sendEvent(view.viewport(), &event);
+ }
+
+ QCOMPARE(view.viewport()->cursor().shape(), viewportShape);
{
- QTest::mouseMove(view.viewport(), QPoint(100, 50));
- QMouseEvent event(QEvent::MouseMove, QPoint(100, 50), Qt::NoButton, 0, 0);
+ QMouseEvent event(QEvent::MouseMove, item1Center, view.viewport()->mapToGlobal(item1Center), Qt::NoButton, 0, 0);
QApplication::sendEvent(view.viewport(), &event);
}
- QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape);
+ QCOMPARE(view.viewport()->cursor().shape(), item1->cursor().shape());
{
- QTest::mouseMove(view.viewport(), view.mapFromScene(item1->sceneBoundingRect().center()));
- QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->sceneBoundingRect().center()), Qt::NoButton, 0, 0);
+ QMouseEvent event(QEvent::MouseMove, item2Center, view.viewport()->mapToGlobal(item2Center), Qt::NoButton, 0, 0);
QApplication::sendEvent(view.viewport(), &event);
}
- QTRY_COMPARE(view.viewport()->cursor().shape(), item1->cursor().shape());
+ QCOMPARE(view.viewport()->cursor().shape(), item2->cursor().shape());
{
- QTest::mouseMove(view.viewport(), view.mapFromScene(item2->sceneBoundingRect().center()));
- QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item2->sceneBoundingRect().center()), Qt::NoButton, 0, 0);
+ QMouseEvent event(QEvent::MouseMove, viewCenter, view.viewport()->mapToGlobal(viewCenter), Qt::NoButton, 0, 0);
QApplication::sendEvent(view.viewport(), &event);
}
- QTRY_COMPARE(view.viewport()->cursor().shape(), item2->cursor().shape());
+ QCOMPARE(view.viewport()->cursor().shape(), viewportShape);
+ item1->setEnabled(false);
{
- QTest::mouseMove(view.viewport(), view.rect().center());
- QMouseEvent event(QEvent::MouseMove, QPoint(100, 25), Qt::NoButton, 0, 0);
+ QMouseEvent event(QEvent::MouseMove, item1Center, view.viewport()->mapToGlobal(item1Center), Qt::NoButton, 0, 0);
QApplication::sendEvent(view.viewport(), &event);
}
- QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape);
+ QCOMPARE(view.viewport()->cursor().shape(), viewportShape);
}
#endif
/*
@@ -5055,12 +5063,6 @@ public:
void tst_QGraphicsItem::paint()
{
-#if defined(Q_OS_MACOS)
- if (QSysInfo::productVersion() == QLatin1String("10.12")) {
- QSKIP("Test is very flaky on MacOS_10_12, see QTBUG-76566");
- }
-#endif
-
QGraphicsScene scene;
PaintTester paintTester;
@@ -5090,22 +5092,25 @@ void tst_QGraphicsItem::paint()
PaintTester tester2;
scene2.addItem(&tester2);
- //First show one paint
- QTRY_COMPARE(tester2.painted, 1);
+ //First show at least one paint
+ QCOMPARE(tester2.painted, 0);
+ QTRY_VERIFY(tester2.painted > 0);
+ int painted = tester2.painted;
//nominal case, update call paint
tester2.update();
- QTRY_COMPARE(tester2.painted, 2);
+ QTRY_COMPARE(tester2.painted, painted + 1);
+ painted = tester2.painted;
//we remove the item from the scene, number of updates is still the same
tester2.update();
scene2.removeItem(&tester2);
- QTRY_COMPARE(tester2.painted, 2);
+ QTRY_COMPARE(tester2.painted, painted);
//We re-add the item, the number of paint should increase
scene2.addItem(&tester2);
tester2.update();
- QTRY_COMPARE(tester2.painted, 3);
+ QTRY_COMPARE(tester2.painted, painted + 1);
}
class HarakiriItem : public QGraphicsRectItem
@@ -11375,7 +11380,7 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2()
origView.reset();
childYellow->setOpacity(0.0);
- QTRY_COMPARE(origView.repaints, 1);
+ QTRY_VERIFY(origView.repaints > 0);
view.show();
qApp->setActiveWindow(&view);
@@ -11390,8 +11395,8 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2()
QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort);
#endif
- QTRY_COMPARE(origView.repaints, 1);
- QTRY_COMPARE(view.repaints, 1);
+ QTRY_VERIFY(origView.repaints > 0);
+ QTRY_VERIFY(view.repaints > 0);
}
void tst_QGraphicsItem::QT_2649_focusScope()
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 103be88f86..0064eb2713 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -6142,7 +6142,7 @@ void tst_QWidget::minAndMaxSizeWithX11BypassWindowManagerHint()
{
if (m_platform != QStringLiteral("xcb"))
QSKIP("This test is for X11 only.");
- // Same size as in QWidget::create_sys().
+ // Same size as in QWidgetPrivate::create.
const QSize desktopSize = QApplication::desktop()->size();
const QSize originalSize(desktopSize.width() / 2, desktopSize.height() * 4 / 10);
@@ -9425,7 +9425,7 @@ void tst_QWidget::initialPosForDontShowOnScreenWidgets()
const QPoint expectedPos(0, 0);
QWidget widget;
widget.setAttribute(Qt::WA_DontShowOnScreen);
- widget.winId(); // Make sure create_sys is called.
+ widget.winId(); // Make sure QWidgetPrivate::create is called.
QCOMPARE(widget.pos(), expectedPos);
QCOMPARE(widget.geometry().topLeft(), expectedPos);
}
@@ -9435,7 +9435,7 @@ void tst_QWidget::initialPosForDontShowOnScreenWidgets()
QWidget widget;
widget.setAttribute(Qt::WA_DontShowOnScreen);
widget.move(expectedPos);
- widget.winId(); // Make sure create_sys is called.
+ widget.winId(); // Make sure QWidgetPrivate::create is called.
QCOMPARE(widget.pos(), expectedPos);
QCOMPARE(widget.geometry().topLeft(), expectedPos);
}