diff options
Diffstat (limited to 'src')
39 files changed, 257 insertions, 160 deletions
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index e1bd769e77..0895f9a3fc 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -71,12 +71,12 @@ #elif defined(Q_OS_HAIKU) # include <kernel/OS.h> #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) -# if !defined(Q_OS_NETBSD) -# include <sys/user.h> -# endif # include <sys/cdefs.h> # include <sys/param.h> # include <sys/sysctl.h> +# if !defined(Q_OS_NETBSD) +# include <sys/user.h> +# endif #endif QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 68d12d85af..cef91efb14 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -2411,26 +2411,40 @@ QString &QString::replace(const QString &before, const QString &after, Qt::CaseS return replace(before.constData(), before.size(), after.constData(), after.size(), cs); } +namespace { // helpers for replace and its helper: +QChar *textCopy(const QChar *start, int len) +{ + const size_t size = len * sizeof(QChar); + QChar *const copy = static_cast<QChar *>(::malloc(size)); + Q_CHECK_PTR(copy); + ::memcpy(copy, start, size); + return copy; +} + +bool pointsIntoRange(const QChar *ptr, const ushort *base, int len) +{ + const QChar *const start = reinterpret_cast<const QChar *>(base); + return start <= ptr && ptr < start + len; +} +} // end namespace + /*! \internal */ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen) { - // copy *after in case it lies inside our own d->data() area - // (which we could possibly invalidate via a realloc or corrupt via memcpy operations.) - QChar *afterBuffer = const_cast<QChar *>(after); - if (after >= reinterpret_cast<QChar *>(d->data()) && after < reinterpret_cast<QChar *>(d->data()) + d->size) { - afterBuffer = static_cast<QChar *>(::malloc(alen*sizeof(QChar))); - Q_CHECK_PTR(afterBuffer); - ::memcpy(afterBuffer, after, alen*sizeof(QChar)); - } + // Copy after if it lies inside our own d->data() area (which we could + // possibly invalidate via a realloc or modify by replacement). + QChar *afterBuffer = 0; + if (pointsIntoRange(after, d->data(), d->size)) // Use copy in place of vulnerable original: + after = afterBuffer = textCopy(after, alen); QT_TRY { if (blen == alen) { // replace in place detach(); for (int i = 0; i < nIndices; ++i) - memcpy(d->data() + indices[i], afterBuffer, alen * sizeof(QChar)); + memcpy(d->data() + indices[i], after, alen * sizeof(QChar)); } else if (alen < blen) { // replace from front detach(); @@ -2446,7 +2460,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar to += msize; } if (alen) { - memcpy(d->data() + to, afterBuffer, alen*sizeof(QChar)); + memcpy(d->data() + to, after, alen * sizeof(QChar)); to += alen; } movestart = indices[i] + blen; @@ -2469,17 +2483,15 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar int moveto = insertstart + alen; memmove(d->data() + moveto, d->data() + movestart, (moveend - movestart)*sizeof(QChar)); - memcpy(d->data() + insertstart, afterBuffer, alen*sizeof(QChar)); + memcpy(d->data() + insertstart, after, alen * sizeof(QChar)); moveend = movestart-blen; } } } QT_CATCH(const std::bad_alloc &) { - if (afterBuffer != after) - ::free(afterBuffer); + ::free(afterBuffer); QT_RETHROW; } - if (afterBuffer != after) - ::free(afterBuffer); + ::free(afterBuffer); } /*! @@ -2508,31 +2520,48 @@ QString &QString::replace(const QChar *before, int blen, return *this; QStringMatcher matcher(before, blen, cs); + QChar *beforeBuffer = 0, *afterBuffer = 0; int index = 0; while (1) { uint indices[1024]; uint pos = 0; - while (pos < 1023) { + while (pos < 1024) { index = matcher.indexIn(*this, index); if (index == -1) break; indices[pos++] = index; - index += blen; - // avoid infinite loop - if (!blen) + if (blen) // Step over before: + index += blen; + else // Only count one instance of empty between any two characters: index++; } - if (!pos) + if (!pos) // Nothing to replace break; + if (Q_UNLIKELY(index != -1)) { + /* + We're about to change data, that before and after might point + into, and we'll need that data for our next batch of indices. + */ + if (!afterBuffer && pointsIntoRange(after, d->data(), d->size)) + after = afterBuffer = textCopy(after, alen); + + if (!beforeBuffer && pointsIntoRange(before, d->data(), d->size)) { + beforeBuffer = textCopy(before, blen); + matcher = QStringMatcher(beforeBuffer, blen, cs); + } + } + replace_helper(indices, pos, blen, after, alen); - if (index == -1) + if (Q_LIKELY(index == -1)) // Nothing left to replace break; - // index has to be adjusted in case we get back into the loop above. + // The call to replace_helper just moved what index points at: index += pos*(alen-blen); } + ::free(afterBuffer); + ::free(beforeBuffer); return *this; } @@ -2563,26 +2592,26 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs uint indices[1024]; uint pos = 0; if (cs == Qt::CaseSensitive) { - while (pos < 1023 && index < d->size) { + while (pos < 1024 && index < d->size) { if (d->data()[index] == cc) indices[pos++] = index; index++; } } else { - while (pos < 1023 && index < d->size) { + while (pos < 1024 && index < d->size) { if (QChar::toCaseFolded(d->data()[index]) == cc) indices[pos++] = index; index++; } } - if (!pos) + if (!pos) // Nothing to replace break; replace_helper(indices, pos, 1, after.constData(), after.d->size); - if (index == -1) + if (Q_LIKELY(index == -1)) // Nothing left to replace break; - // index has to be adjusted in case we get back into the loop above. + // The call to replace_helper just moved what index points at: index += pos*(after.d->size - 1); } return *this; @@ -5008,7 +5037,7 @@ void QString::truncate(int pos) Removes \a n characters from the end of the string. If \a n is greater than or equal to size(), the result is an - empty string. + empty string; if \a n is negative, it is equivalent to passing zero. Example: \snippet qstring/main.cpp 15 diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 8ce98cbd71..b2832b5fbe 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -82,7 +82,7 @@ struct QStringBuilderCommon T toLower() const { return resolved().toLower(); } protected: - const T resolved() const { return *static_cast<const Builder*>(this); } + T resolved() const { return *static_cast<const Builder*>(this); } }; template<typename Builder, typename T> diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm index a21a8fd56f..77c04ac20c 100644 --- a/src/corelib/tools/qtimezoneprivate_mac.mm +++ b/src/corelib/tools/qtimezoneprivate_mac.mm @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE // Create the system default time zone QMacTimeZonePrivate::QMacTimeZonePrivate() + : m_nstz(0) { init(systemTimeZoneId()); } diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 757543281c..e95315aea8 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -758,7 +758,7 @@ void QAccessible::deleteAccessibleInterface(Id id) */ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) { - Id id = QAccessibleCache::instance()->idToInterface.key(iface); + Id id = QAccessibleCache::instance()->idForInterface(iface); if (!id) id = registerAccessibleInterface(iface); return id; @@ -771,7 +771,7 @@ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) */ QAccessibleInterface *QAccessible::accessibleInterface(Id id) { - return QAccessibleCache::instance()->idToInterface.value(id); + return QAccessibleCache::instance()->interfaceForId(id); } diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp index 6fbe9b5582..43c4b15cb0 100644 --- a/src/gui/accessible/qaccessiblecache.cpp +++ b/src/gui/accessible/qaccessiblecache.cpp @@ -83,6 +83,11 @@ QAccessibleInterface *QAccessibleCache::interfaceForId(QAccessible::Id id) const return idToInterface.value(id); } +QAccessible::Id QAccessibleCache::idForInterface(QAccessibleInterface *iface) const +{ + return interfaceToId.value(iface); +} + QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface *iface) const { Q_ASSERT(iface); @@ -90,7 +95,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface * // object might be 0 Q_ASSERT(!objectToId.contains(object)); - Q_ASSERT_X(!idToInterface.values().contains(iface), "", "Accessible interface inserted into cache twice!"); + Q_ASSERT_X(!interfaceToId.contains(iface), "", "Accessible interface inserted into cache twice!"); QAccessible::Id id = acquireId(); QObject *obj = iface->object(); @@ -100,6 +105,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface * connect(obj, &QObject::destroyed, this, &QAccessibleCache::objectDestroyed); } idToInterface.insert(id, iface); + interfaceToId.insert(iface, id); return id; } @@ -115,6 +121,7 @@ void QAccessibleCache::objectDestroyed(QObject* obj) void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj) { QAccessibleInterface *iface = idToInterface.take(id); + interfaceToId.take(iface); if (!obj) obj = iface->object(); if (obj) diff --git a/src/gui/accessible/qaccessiblecache_p.h b/src/gui/accessible/qaccessiblecache_p.h index b1fc0bbee5..a9208702e4 100644 --- a/src/gui/accessible/qaccessiblecache_p.h +++ b/src/gui/accessible/qaccessiblecache_p.h @@ -70,6 +70,7 @@ class Q_GUI_EXPORT QAccessibleCache :public QObject public: static QAccessibleCache *instance(); QAccessibleInterface *interfaceForId(QAccessible::Id id) const; + QAccessible::Id idForInterface(QAccessibleInterface *iface) const; QAccessible::Id insert(QObject *object, QAccessibleInterface *iface) const; void deleteInterface(QAccessible::Id id, QObject *obj = 0); @@ -85,6 +86,7 @@ private: QAccessible::Id acquireId() const; mutable QHash<QAccessible::Id, QAccessibleInterface *> idToInterface; + mutable QHash<QAccessibleInterface *, QAccessible::Id> interfaceToId; mutable QHash<QObject *, QAccessible::Id> objectToId; #ifdef Q_OS_MAC diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 137310ffbd..33b3d3f715 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3331,28 +3331,6 @@ bool QGuiApplication::isSavingSession() const return d->is_saving_session; } -/*! - \since 5.2 - - Function that can be used to sync Qt state with the Window Systems state. - - This function will first empty Qts events by calling QCoreApplication::processEvents(), - then the platform plugin will sync up with the windowsystem, and finally Qts events - will be delived by another call to QCoreApplication::processEvents(); - - This function is timeconsuming and its use is discouraged. -*/ -void QGuiApplication::sync() -{ - QCoreApplication::processEvents(); - if (QGuiApplicationPrivate::platform_integration - && QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::SyncState)) { - QGuiApplicationPrivate::platform_integration->sync(); - QCoreApplication::processEvents(); - QWindowSystemInterface::flushWindowSystemEvents(); - } -} - void QGuiApplicationPrivate::commitData() { Q_Q(QGuiApplication); @@ -3378,6 +3356,28 @@ void QGuiApplicationPrivate::saveState() #endif //QT_NO_SESSIONMANAGER /*! + \since 5.2 + + Function that can be used to sync Qt state with the Window Systems state. + + This function will first empty Qts events by calling QCoreApplication::processEvents(), + then the platform plugin will sync up with the windowsystem, and finally Qts events + will be delived by another call to QCoreApplication::processEvents(); + + This function is timeconsuming and its use is discouraged. +*/ +void QGuiApplication::sync() +{ + QCoreApplication::processEvents(); + if (QGuiApplicationPrivate::platform_integration + && QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::SyncState)) { + QGuiApplicationPrivate::platform_integration->sync(); + QCoreApplication::processEvents(); + QWindowSystemInterface::flushWindowSystemEvents(); + } +} + +/*! \property QGuiApplication::layoutDirection \brief the default layout direction for this application @@ -3623,7 +3623,8 @@ QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape) void QGuiApplicationPrivate::notifyThemeChanged() { - if (!(applicationResourceFlags & ApplicationPaletteExplicitlySet)) { + if (!(applicationResourceFlags & ApplicationPaletteExplicitlySet) && + !QCoreApplication::testAttribute(Qt::AA_SetPalette)) { clearPalette(); initPalette(); } diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index c5818e9373..0eee0c9879 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1289,6 +1289,7 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ const char *ver = reinterpret_cast<const char *>(funcs->glGetString(GL_VERSION)); // Blacklist GPU chipsets that have problems with their BGRA support. +#ifndef Q_OS_IOS const bool blackListed = (qstrcmp(renderer, "PowerVR Rogue G6200") == 0 && ::strstr(ver, "1.3") != 0) || (qstrcmp(renderer, "Mali-T760") == 0 @@ -1296,7 +1297,9 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ (qstrcmp(renderer, "Mali-T720") == 0 && ::strstr(ver, "3.1") != 0) || qstrcmp(renderer, "PowerVR SGX 554") == 0; - +#else + const bool blackListed = true; +#endif const bool supports_bgra = has_bgra_ext && !blackListed; if (supports_bgra) { diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index a73f01a2fc..6da231d019 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -1278,10 +1278,10 @@ static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx, // 369 years, 89 leap years // ((369 * 365) + 89) * 24 * 3600 = 11644473600 - time = Q_UINT64_C(currentTime.toTime_t() + 11644473600); + time = currentTime.toTime_t() + Q_UINT64_C(11644473600); // represented as 100 nano seconds - time = Q_UINT64_C(time * 10000000); + time = time * Q_UINT64_C(10000000); ds << time; } diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index ba346f77d1..fd82d53fa8 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -583,7 +583,7 @@ void QSslSocketBackendPrivate::startClientEncryption() // Error description/code were set, 'error' emitted // by initSslContext, but OpenSSL socket also sets error // emits a signal twice, so ... - setErrorAndEmit(QAbstractSocket::SslInternalError, "Unable to init SSL Context"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context")); return; } @@ -596,7 +596,7 @@ void QSslSocketBackendPrivate::startServerEncryption() // Error description/code were set, 'error' emitted // by initSslContext, but OpenSSL socket also sets error // emits a signal twice, so ... - setErrorAndEmit(QAbstractSocket::SslInternalError, "Unable to init SSL Context"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context")); return; } @@ -927,7 +927,7 @@ bool QSslSocketBackendPrivate::initSslContext() context.reset(qt_createSecureTransportContext(mode)); if (!context) { - setErrorAndEmit(QAbstractSocket::SslInternalError, "SSLCreateContext failed"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("SSLCreateContext failed")); return false; } @@ -955,7 +955,7 @@ bool QSslSocketBackendPrivate::initSslContext() if (!setSessionProtocol()) { destroySslContext(); - setErrorAndEmit(QAbstractSocket::SslInternalError, "Failed to set protocol version"); + setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Failed to set protocol version")); return false; } @@ -1397,8 +1397,7 @@ bool QSslSocketBackendPrivate::startHandshake() // check protocol version ourselves, as Secure Transport does not enforce // the requested min / max versions. if (!verifySessionProtocol()) { - setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, - "Protocol version mismatch"); + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, QStringLiteral("Protocol version mismatch")); plainSocket->disconnectFromHost(); return false; } diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 68a367cce3..f2b9afa2b5 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -412,9 +412,7 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q // I can only handle two types (system and unicode) so deal with them that way QVariant ret; if (flavor == QLatin1String("public.utf8-plain-text")) { - ret = QString(QCFString(CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast<const UInt8 *>(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false))); + ret = QString::fromUtf8(firstData); } else if (flavor == QLatin1String("public.utf16-plain-text")) { ret = QString(reinterpret_cast<const QChar *>(firstData.constData()), firstData.size() / sizeof(QChar)); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index e1f4ddd360..5be7e3aadc 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -594,8 +594,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo fallbackList.append(familyNameFromPostScriptName(item)); } - if (QCoreTextFontEngine::supportsColorGlyphs()) - fallbackList.append(QLatin1String("Apple Color Emoji")); + fallbackList.append(QLatin1String("Apple Color Emoji")); // Since we are only returning a list of default fonts for the current language, we do not // cover all unicode completely. This was especially an issue for some of the common script diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 942bb6c6bb..d11676ced7 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -224,11 +224,9 @@ void QCoreTextFontEngine::init() synthesisFlags = 0; CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); -#if defined(Q_OS_IOS) || MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (supportsColorGlyphs() && (traits & kCTFontColorGlyphsTrait)) + if (traits & kCTFontColorGlyphsTrait) glyphFormat = QFontEngine::Format_ARGB; else -#endif glyphFormat = defaultGlyphFormat; if (traits & kCTFontItalicTrait) @@ -656,9 +654,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &CGSizeZero, 1); } - } -#if defined(Q_OS_IOS) || MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - else if (supportsColorGlyphs()) { + } else { // 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. @@ -669,7 +665,6 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition // glyphs in the Apple Color Emoji font, so we use CTFontDrawGlyphs instead. CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx); } -#endif CGContextRelease(ctx); CGColorSpaceRelease(colorspace); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 67a5a3185b..22008162f7 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -113,21 +113,6 @@ public: QFontEngine::Properties properties() const Q_DECL_OVERRIDE; - static bool supportsColorGlyphs() - { -#if defined(Q_OS_IOS) - return true; -#elif MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - return &CTFontDrawGlyphs; - #else - return true; - #endif -#else - return false; -#endif - } - static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length); static QFont::Weight qtWeightFromCFWeight(float value); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index e773db9b20..0e774d50c3 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -218,6 +218,7 @@ protected: private: QVariantMap properties(); QVariantMap propertiesMap; +private Q_SLOTS: void scanReply(QDBusPendingCallWatcher *call); }; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f6a3b3943f..f02dad675e 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -457,6 +457,10 @@ QCocoaScreen *QCocoaIntegration::screenAtIndex(int index) if (index >= mScreens.count()) updateScreens(); + // It is possible that the screen got removed while updateScreens was called + // so we do a sanity check to be certain + if (index >= mScreens.count()) + return 0; return mScreens.at(index); } diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 7951a2ff70..6b80162e4d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -93,6 +93,9 @@ public: void setAttachedItem(NSMenuItem *item); NSMenuItem *attachedItem() const; + bool isOpen() const; + void setIsOpen(bool isOpen); + private: QCocoaMenuItem *itemOrNull(int index) const; void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem); @@ -100,9 +103,10 @@ private: QList<QCocoaMenuItem *> m_menuItems; NSMenu *m_nativeMenu; NSMenuItem *m_attachedItem; + quintptr m_tag; bool m_enabled; bool m_visible; - quintptr m_tag; + bool m_isOpen; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index a388155c03..06ec2aa479 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -137,12 +137,14 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (void) menuWillOpen:(NSMenu*)m { Q_UNUSED(m); + m_menu->setIsOpen(true); emit m_menu->aboutToShow(); } - (void) menuDidClose:(NSMenu*)m { Q_UNUSED(m); + m_menu->setIsOpen(false); // wrong, but it's the best we can do emit m_menu->aboutToHide(); } @@ -257,9 +259,10 @@ QT_BEGIN_NAMESPACE QCocoaMenu::QCocoaMenu() : m_attachedItem(0), + m_tag(0), m_enabled(true), m_visible(true), - m_tag(0) + m_isOpen(false) { QMacAutoReleasePool pool; @@ -330,6 +333,8 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) item->nsItem().target = m_nativeMenu.delegate; if (!item->menu()) [item->nsItem() setAction:@selector(itemFired:)]; + else if (isOpen() && item->nsItem()) // Someone's adding new items after aboutToShow() was emitted + item->menu()->setAttachedItem(item->nsItem()); if (item->isMerged()) return; @@ -353,6 +358,16 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) item->setMenuParent(this); } +bool QCocoaMenu::isOpen() const +{ + return m_isOpen; +} + +void QCocoaMenu::setIsOpen(bool isOpen) +{ + m_isOpen = isOpen; +} + void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) { QMacAutoReleasePool pool; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 86f6dda2e9..96b40259b4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -179,9 +179,11 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) } } - NSMenuItem *nativeMenuItem = nativeItemForMenu(cocoaMenu); - nativeMenuItem.title = cocoaMenu->nsMenu().title; - nativeMenuItem.hidden = shouldHide; + if (NSMenuItem *attachedItem = cocoaMenu->attachedItem()) { + // Non-nil attached item means the item's submenu is set + attachedItem.title = cocoaMenu->nsMenu().title; + attachedItem.hidden = shouldHide; + } } NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 9e2fca23a1..831f1cfcf4 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -260,34 +260,14 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const } if (iconType != 0) { QPixmap pixmap; - IconRef icon; - IconRef overlayIcon = 0; - if (iconType != kGenericApplicationIcon) { - GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon); - } else { - FSRef fsRef; - ProcessSerialNumber psn = { 0, kCurrentProcess }; - GetProcessBundleLocation(&psn, &fsRef); - GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0); - if (sp == MessageBoxCritical) { - overlayIcon = icon; - GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon); - } - } + IconRef icon = Q_NULLPTR; + GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon); if (icon) { pixmap = qt_mac_convert_iconref(icon, size.width(), size.height()); ReleaseIconRef(icon); } - if (overlayIcon) { - QSizeF littleSize = size / 2; - QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize.width(), littleSize.height()); - QPainter painter(&pixmap); - painter.drawPixmap(littleSize.width(), littleSize.height(), overlayPix); - ReleaseIconRef(overlayIcon); - } - return pixmap; } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3469166fdc..d4f2cf32fc 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -474,7 +474,8 @@ QT_WARNING_POP NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; if (screenIndex != NSNotFound) { QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex); - QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen()); + if (cocoaScreen) + QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen()); m_platformWindow->updateExposedGeometry(); } } diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index bd6f2d8e6f..3aca27b555 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -11,7 +11,7 @@ HEADERS = qminimalintegration.h \ OTHER_FILES += minimal.json CONFIG += qpa/genericunixfontdatabase -darwin: DEFINES += QT_NO_FONTCONFIG +win32|darwin: DEFINES += QT_NO_FONTCONFIG PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp index 0fe80d856d..3ac3d23c88 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp @@ -178,7 +178,7 @@ void QQnxRasterWindow::adjustBufferSize() { // When having a raster window we don't need any buffers, since // Qt will draw to the parent TLW backing store. - const QSize windowSize = window()->parent() ? QSize(1,1) : window()->size(); + const QSize windowSize = window()->parent() ? QSize(0,0) : window()->size(); if (windowSize != bufferSize()) setBufferSize(windowSize); } @@ -194,6 +194,13 @@ void QQnxRasterWindow::resetBuffers() m_currentBufferIndex = -1; m_previousDirty = QRegion(); m_scrolled = QRegion(); + if (window()->parent() && bufferSize() == QSize(1,1)) { + // If we have a parent then we're not really rendering. But if we don't render we'll + // be invisible and any children won't show up. This should be harmless since we're + // rendering into a 1x1 window that has transparency set to discard. + renderBuffer(); + post(QRegion(0,0,1,1)); + } } void QQnxRasterWindow::blitPreviousToCurrent(const QRegion ®ion, int dx, int dy, bool flush) diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index e04f16db92..f4e6ca9804 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -386,7 +386,12 @@ void QQnxWindow::setBufferSize(const QSize &size) // Set the transparency. According to QNX technical support, setting the window // transparency property should always be done *after* creating the window // buffers in order to guarantee the property is paid attention to. - if (window()->requestedFormat().alphaBufferSize() == 0) { + if (size.isEmpty()) { + // We can't create 0x0 buffers and instead make them 1x1. But to allow these windows to + // still be 'visible' (thus allowing their children to be visible), we need to allow + // them to be posted but still not show up. + val[0] = SCREEN_TRANSPARENCY_DISCARD; + } else if (window()->requestedFormat().alphaBufferSize() == 0) { // To avoid overhead in the composition manager, disable blending // when the underlying window buffer doesn't have an alpha channel. val[0] = SCREEN_TRANSPARENCY_NONE; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 1cc992dda6..1dbac78fca 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -47,6 +47,7 @@ #include "qwindowsmime.h" #include "qwindowsinputcontext.h" #include "qwindowstabletsupport.h" +#include "qwindowstheme.h" #include <private/qguiapplication_p.h> #ifndef QT_NO_ACCESSIBILITY # include "accessible/qwindowsaccessibility.h" @@ -1014,6 +1015,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, #endif case QtWindows::DisplayChangedEvent: return d->m_screenManager.handleDisplayChange(wParam, lParam); + if (QWindowsTheme *t = QWindowsTheme::instance()) + t->displayChanged(); case QtWindows::SettingChangedEvent: return d->m_screenManager.handleScreenChanges(); default: diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index dbc0b0a77a..46306d438f 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -53,7 +53,7 @@ #include <QtGui/QGuiApplication> #include <QtGui/QWindow> #include <QtCore/QDebug> -#include <QtCore/QScopedArrayPointer> +#include <QtCore/QVarLengthArray> #include <QtCore/QtMath> #include <private/qguiapplication_p.h> @@ -233,7 +233,7 @@ QString QWindowsTabletSupport::description() const const unsigned size = m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, 0); if (!size) return QString(); - QScopedPointer<TCHAR> winTabId(new TCHAR[size + 1]); + QVarLengthArray<TCHAR> winTabId(size + 1); m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_WINTABID, winTabId.data()); WORD implementationVersion = 0; m_winTab32DLL.wTInfo(WTI_INTERFACE, IFC_IMPLVERSION, &implementationVersion); diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 3947f823d6..f57446cf0d 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -335,6 +335,7 @@ QWindowsTheme::QWindowsTheme() std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0)); std::fill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0)); refresh(); + refreshIconPixmapSizes(); } QWindowsTheme::~QWindowsTheme() @@ -400,16 +401,8 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const return QVariant(int(WindowsKeyboardScheme)); case UiEffects: return QVariant(uiEffects()); - case IconPixmapSizes: { - QList<int> sizes; - sizes << 16 << 32; -#ifdef USE_IIMAGELIST - sizes << 48; // sHIL_EXTRALARGE - if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) - sizes << 256; // SHIL_JUMBO -#endif // USE_IIMAGELIST - return QVariant::fromValue(sizes); - } + case IconPixmapSizes: + return m_fileIconSizes; case DialogSnapToDefaultButton: return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false)); case ContextMenuOnMouseRelease: @@ -479,6 +472,15 @@ void QWindowsTheme::refreshFonts() #endif // !Q_OS_WINCE } +enum FileIconSize { + // Standard icons obtainable via shGetFileInfo(), SHGFI_SMALLICON, SHGFI_LARGEICON + SmallFileIcon, LargeFileIcon, + // Larger icons obtainable via SHGetImageList() + ExtraLargeFileIcon, + JumboFileIcon, // Vista onwards + FileIconSizeCount +}; + bool QWindowsTheme::usePlatformNativeDialog(DialogType type) const { return QWindowsDialogs::useHelper(type); @@ -495,6 +497,27 @@ void QWindowsTheme::windowsThemeChanged(QWindow * window) QWindowSystemInterface::handleThemeChange(window); } +static int fileIconSizes[FileIconSizeCount]; + +void QWindowsTheme::refreshIconPixmapSizes() +{ + // Standard sizes: 16, 32, 48, 256 + fileIconSizes[SmallFileIcon] = GetSystemMetrics(SM_CXSMICON); // corresponds to SHGFI_SMALLICON); + fileIconSizes[LargeFileIcon] = GetSystemMetrics(SM_CXICON); // corresponds to SHGFI_LARGEICON + fileIconSizes[ExtraLargeFileIcon] = + fileIconSizes[LargeFileIcon] + fileIconSizes[LargeFileIcon] / 2; + fileIconSizes[JumboFileIcon] = 8 * fileIconSizes[LargeFileIcon]; // empirical, has not been observed to work + QList<int> sizes; + sizes << fileIconSizes[SmallFileIcon] << fileIconSizes[LargeFileIcon]; +#ifdef USE_IIMAGELIST + sizes << fileIconSizes[ExtraLargeFileIcon]; // sHIL_EXTRALARGE + if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) + sizes << fileIconSizes[JumboFileIcon]; // SHIL_JUMBO +#endif // USE_IIMAGELIST + qCDebug(lcQpaWindows) << __FUNCTION__ << sizes; + m_fileIconSizes = QVariant::fromValue(sizes); +} + // Defined in qpixmap_win.cpp Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon); @@ -741,10 +764,12 @@ QPixmap QWindowsTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &s QPixmap pixmap; const QString filePath = QDir::toNativeSeparators(fileInfo.filePath()); const int width = int(size.width()); - const int iconSize = width > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON; + const int iconSize = width > fileIconSizes[SmallFileIcon] ? SHGFI_LARGEICON : SHGFI_SMALLICON; const int requestedImageListSize = #ifdef USE_IIMAGELIST - width > 48 ? sHIL_JUMBO : (width > 32 ? sHIL_EXTRALARGE : 0); + width > fileIconSizes[ExtraLargeFileIcon] + ? sHIL_JUMBO + : (width > fileIconSizes[LargeFileIcon] ? sHIL_EXTRALARGE : 0); #else 0; #endif // !USE_IIMAGELIST diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index acf89306c2..fa1fb4d998 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -43,6 +43,8 @@ #include "qwindowsthreadpoolrunner.h" #include <qpa/qplatformtheme.h> +#include <QtCore/QVariant> + QT_BEGIN_NAMESPACE class QWindow; @@ -68,6 +70,7 @@ public: QPlatformTheme::IconOptions iconOptions = 0) const Q_DECL_OVERRIDE; void windowsThemeChanged(QWindow *window); + void displayChanged() { refreshIconPixmapSizes(); } static const char *name; @@ -77,11 +80,13 @@ private: void refreshPalettes(); void clearFonts(); void refreshFonts(); + void refreshIconPixmapSizes(); static QWindowsTheme *m_instance; QPalette *m_palettes[NPalettes]; QFont *m_fonts[NFonts]; mutable QWindowsThreadPoolRunner m_threadPoolRunner; + QVariant m_fileIconSizes; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 76a36851ce..9eb1b26786 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2522,9 +2522,10 @@ void QWindowsWindow::aboutToMakeCurrent() void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border) { - if (!window->handle()) - return; - static_cast<QWindowsWindow *>(window->handle())->setHasBorderInFullScreen(border); + if (QPlatformWindow *handle = window->handle()) + static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border); + else + qWarning("%s invoked without window handle; call has no effect.", Q_FUNC_INFO); } void QWindowsWindow::setHasBorderInFullScreen(bool border) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index bc62b500e5..fded4de76a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -265,8 +265,8 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) } else { screen = createScreen(virtualDesktop, output, outputInfo.data()); qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; - QHighDpiScaling::updateHighDpiScaling(); } + QHighDpiScaling::updateHighDpiScaling(); } } else if (screen) { if (output.crtc == XCB_NONE && output.mode == XCB_NONE) { diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 85a0d1cc0c..cf8dee4646 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -108,37 +108,57 @@ template<> inline char *toString(const QDateTime &dateTime) template<> inline char *toString(const QChar &c) { + const ushort uc = c.unicode(); + if (uc < 128) { + char msg[32] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QChar: '%c' (0x%x)", char(uc), unsigned(uc)); + return qstrdup(msg); + } return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast<int>(c.unicode()), 16)))); } template<> inline char *toString(const QPoint &p) { - return qstrdup(QString::fromLatin1("QPoint(%1,%2)").arg(p.x()).arg(p.y()).toLatin1().constData()); + char msg[128] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QPoint(%d,%d)", p.x(), p.y()); + return qstrdup(msg); } template<> inline char *toString(const QSize &s) { - return qstrdup(QString::fromLatin1("QSize(%1x%2)").arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[128] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QSize(%dx%d)", s.width(), s.height()); + return qstrdup(msg); } template<> inline char *toString(const QRect &s) { - return qstrdup(QString::fromLatin1("QRect(%1,%2 %5x%6) (bottomright %3,%4)").arg(s.left()).arg(s.top()).arg(s.right()).arg(s.bottom()).arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[256] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QRect(%d,%d %dx%d) (bottomright %d,%d)", + s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom()); + return qstrdup(msg); } template<> inline char *toString(const QPointF &p) { - return qstrdup(QString::fromLatin1("QPointF(%1,%2)").arg(p.x()).arg(p.y()).toLatin1().constData()); + char msg[64] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QPointF(%g,%g)", p.x(), p.y()); + return qstrdup(msg); } template<> inline char *toString(const QSizeF &s) { - return qstrdup(QString::fromLatin1("QSizeF(%1x%2)").arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[64] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QSizeF(%gx%g)", s.width(), s.height()); + return qstrdup(msg); } template<> inline char *toString(const QRectF &s) { - return qstrdup(QString::fromLatin1("QRectF(%1,%2 %5x%6) (bottomright %3,%4)").arg(s.left()).arg(s.top()).arg(s.right()).arg(s.bottom()).arg(s.width()).arg(s.height()).toLatin1().constData()); + char msg[256] = {'\0'}; + qsnprintf(msg, sizeof(msg), "QRectF(%g,%g %gx%g) (bottomright %g,%g)", + s.left(), s.top(), s.width(), s.height(), s.right(), s.bottom()); + return qstrdup(msg); } template<> inline char *toString(const QUrl &uri) diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 6ae785f417..74c75eda5b 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -188,7 +188,8 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso token = keywords[state].ident; if (token == NOTOKEN) { - ++data; + if (*data) + ++data; // an error really, but let's ignore this input // to not confuse moc later. However in pre-processor // only mode let's continue. @@ -362,7 +363,6 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso ++data; continue; } - int nextindex = pp_keywords[state].next; int next = 0; if (*data == pp_keywords[state].defchar) @@ -381,7 +381,8 @@ Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocesso switch (token) { case NOTOKEN: - ++data; + if (*data) + ++data; break; case PP_DEFINE: mode = PrepareDefine; @@ -1255,7 +1256,6 @@ void Preprocessor::parseDefineArguments(Macro *m) error("missing ')' in macro argument list"); break; } else if (!is_identifier(l.constData(), l.length())) { - qDebug() << l; error("Unexpected character in macro argument list."); } } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 03211b4e4c..4d37c7f682 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1024,9 +1024,11 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) // The Windows compositor handles fullscreen OpenGL window specially. Besides // having trouble with popups, it also has issues with flip-flopping between // OpenGL-based and normal flushing. Therefore, stick with GL for fullscreen -// windows. (QTBUG-53515) +// windows (QTBUG-53515). Similary, translucent windows should not switch to +// layered native windows (QTBUG-54734). #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) || tlw->windowState().testFlag(Qt::WindowFullScreen) + || tlw->testAttribute(Qt::WA_TranslucentBackground) #endif ) { diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 3a875f9372..0c034777ff 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -2935,7 +2935,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w QImage img; QSize pixmapSize = opt->rect.size(); - if (pixmapSize.isValid()) { + if (!pixmapSize.isEmpty()) { QPixmap pix(pixmapSize); pix.fill(QColor(fillR, fillG, fillB)); QPainter pix_paint(&pix); diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 3e17b22102..c8970cc397 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -733,7 +733,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value State_None Indicates that the widget does not have a state. \value State_Active Indicates that the widget is active. - \value State_AutoRaise Used to indicate if auto-raise appearance should be usd on a tool button. + \value State_AutoRaise Used to indicate if auto-raise appearance should be used on a tool button. \value State_Children Used to indicate if an item view branch has children. \value State_DownArrow Used to indicate if a down arrow should be visible on the widget. \value State_Editing Used to indicate if an editor is opened on the widget. diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 083a4a4f27..2c7dbf63be 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -1044,6 +1044,10 @@ void QCompleter::setModel(QAbstractItemModel *model) { Q_D(QCompleter); QAbstractItemModel *oldModel = d->proxy->sourceModel(); +#ifndef QT_NO_FILESYSTEMMODEL + if (qobject_cast<const QFileSystemModel *>(oldModel)) + setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel +#endif d->proxy->setSourceModel(model); if (d->popup) setPopup(d->popup); // set the model and make new connections diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 774f5a708d..5778d16456 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -757,8 +757,7 @@ bool QAbstractSpinBox::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) - d->updateHoverControl(he->pos()); + d->updateHoverControl(static_cast<const QHoverEvent *>(event)->pos()); break; case QEvent::ShortcutOverride: if (d->edit->event(event)) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 51e23ca7f9..af178ce8f5 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2108,9 +2108,9 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) if (lineEdit) { const QString newText = itemText(normalized); if (lineEdit->text() != newText) { - lineEdit->setText(newText); + lineEdit->setText(newText); // may cause lineEdit -> nullptr (QTBUG-54191) #ifndef QT_NO_COMPLETER - if (lineEdit->completer()) + if (lineEdit && lineEdit->completer()) lineEdit->completer()->setCompletionPrefix(newText); #endif } |