diff options
Diffstat (limited to 'src')
34 files changed, 237 insertions, 162 deletions
diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 9ab545d783..16a9b8a7c3 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -610,7 +610,7 @@ QSimpleTextCodec::QSimpleTextCodec(int i) : forwardIndex(i), reverseMap(0) QSimpleTextCodec::~QSimpleTextCodec() { - delete reverseMap.load(); + delete reverseMap.loadAcquire(); } static QByteArray *buildReverseMap(int forwardIndex) @@ -662,12 +662,12 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?'; int invalid = 0; - QByteArray *rmap = reverseMap.load(); + QByteArray *rmap = reverseMap.loadAcquire(); if (!rmap){ rmap = buildReverseMap(this->forwardIndex); if (!reverseMap.testAndSetRelease(0, rmap)) { delete rmap; - rmap = reverseMap.load(); + rmap = reverseMap.loadAcquire(); } } diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 63be0952ff..7776dd8c4e 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -218,7 +218,7 @@ template <typename T, typename ConstantsType> inline QFreeList<T, ConstantsType>::~QFreeList() { for (int i = 0; i < ConstantsType::BlockCount; ++i) - delete [] _v[i].load(); + delete [] _v[i].loadAcquire(); } template <typename T, typename ConstantsType> diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index ade6a9eaaa..360cc16319 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 66907bebd7..f6684eac7d 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 598cb00ee5..38c9aede7d 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 2d2041c907..4b06afd4eb 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2927,9 +2927,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 99b04aaba6..06fa4bf95e 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 3da28872b1..c105e89e50 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(0), + QTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor()) + : QFontEngineGlyphCache(format, matrix, color), m_current_fontengine(0), 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 1719855e68..e435177843 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 (GlyphCaches::const_iterator it = caches->begin(), end = caches->end(); it != end; ++it) { QFontEngineGlyphCache *cache = it->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 708c79c2ae..682395ece6 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -190,7 +190,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(), @@ -252,7 +252,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 4b5acc1c53..12fd257c11 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -734,7 +734,9 @@ QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), was QHostInfoLookupManager::~QHostInfoLookupManager() { + QMutexLocker locker(&mutex); wasDeleted = true; + locker.unlock(); // don't qDeleteAll currentLookups, the QThreadPool has ownership clear(); @@ -762,6 +764,8 @@ void QHostInfoLookupManager::clear() void QHostInfoLookupManager::work() { + QMutexLocker locker(&mutex); + if (wasDeleted) return; @@ -769,8 +773,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++) { @@ -822,10 +824,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(); } @@ -833,11 +836,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++) { @@ -863,20 +866,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 @@ -938,23 +943,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 8cce302166..8898d6ff50 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 @@ -176,10 +177,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 771350c709..2aef71a418 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -2105,8 +2105,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 d498b0ac8b..109bae86e9 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 ae81bca00f..06025c016e 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp @@ -102,7 +102,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 52eaa18f4b..e5dc182bec 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/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 878f55e56b..8054f9fe83 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 8b88007949..71a09304c5 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; } @@ -728,7 +727,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 ccbb1d3939..b6b89cefed 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 1c76a2e46f..b704ccd7ab 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 @@ -221,11 +223,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 8a1bd1431e..1cb6cb8a2d 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1740,7 +1740,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/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 5fe520132f..6079e41bfc 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 641b15f85b..568084640a 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 ¤t) 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/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 0a07726f25..f5ef12cb89 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7453,6 +7453,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 @@ -7507,7 +7518,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 @@ -7537,8 +7548,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()); @@ -7558,23 +7567,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 diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 3c0f0b791b..dee06ba577 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*d->verticalMargin + int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2*d->verticalMargin + d->topTextMargin + d->bottomTextMargin + d->topmargin + d->bottommargin; int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2*d->horizontalMargin diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 7b6a1b6da8..c61b68e10a 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(); }); |