diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-03-15 01:00:11 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-03-15 01:00:11 +0100 |
commit | 8264e495fa9220c101a8a913701a0b8834a6d58b (patch) | |
tree | 069aa1d3efab926991c1edfc5b69a3d9e58dcfba /src | |
parent | 80f52812f2651e6d427bb3dd2e338b60fb25d48b (diff) | |
parent | 8eb3944dac81b8c51d7bac7784204d457551b50c (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Change-Id: I8b5a10d897a926078895ae41f48cdbd2474902b8
Diffstat (limited to 'src')
27 files changed, 231 insertions, 164 deletions
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 9143e04d45..ebf9864b15 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -48,9 +48,7 @@ #include <errno.h> -#if QT_CONFIG(getentropy) -# include <sys/random.h> -#elif !defined(Q_OS_BSD4) && !defined(Q_OS_WIN) +#if !QT_CONFIG(getentropy) && !defined(Q_OS_BSD4) && !defined(Q_OS_WIN) # include "qdeadlinetimer.h" # include "qhashfunctions.h" diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index d043b3aea5..06eacf5455 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -750,13 +750,47 @@ QString QDir::filePath(const QString &fileName) const QString QDir::absoluteFilePath(const QString &fileName) const { const QDirPrivate* d = d_ptr.constData(); - if (isAbsolutePath(fileName)) + // Don't trust our own isAbsolutePath(); Q_OS_WIN needs a drive. + if (QFileSystemEntry(fileName).isAbsolute()) return fileName; d->resolveAbsoluteEntry(); const QString absoluteDirPath = d->absoluteDirEntry.filePath(); if (fileName.isEmpty()) return absoluteDirPath; +#ifdef Q_OS_WIN + // Handle the "absolute except for drive" case (i.e. \blah not c:\blah): + int size = absoluteDirPath.length(); + if ((fileName.startsWith(QLatin1Char('/')) + || fileName.startsWith(QLatin1Char('\\'))) + && size > 1) { + // Combine absoluteDirPath's drive with fileName + int drive = 2; // length of drive prefix + if (Q_UNLIKELY(absoluteDirPath.at(1).unicode() != ':')) { + // Presumably, absoluteDirPath is an UNC path; use its //server/share + // part as "drive" - it's as sane a thing as we can do. + for (int i = 2; i-- > 0; ) { // Scan two "path fragments": + while (drive < size && absoluteDirPath.at(drive).unicode() == '/') + drive++; + if (drive >= size) { + qWarning("Base directory starts with neither a drive nor a UNC share: %s", + qPrintable(QDir::toNativeSeparators(absoluteDirPath))); + return QString(); + } + while (drive < size && absoluteDirPath.at(drive).unicode() != '/') + drive++; + } + // We'll append fileName, which starts with a slash; so omit trailing slash: + if (absoluteDirPath.at(drive).unicode() == '/') + drive--; + } else if (!absoluteDirPath.at(0).isLetter()) { + qWarning("Base directory's drive is not a letter: %s", + qPrintable(QDir::toNativeSeparators(absoluteDirPath))); + return QString(); + } + return absoluteDirPath.leftRef(drive) % fileName; + } +#endif // Q_OS_WIN if (!absoluteDirPath.endsWith(QLatin1Char('/'))) return absoluteDirPath % QLatin1Char('/') % fileName; return absoluteDirPath % fileName; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 2a42ad42f9..5cc3a5937e 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -91,26 +91,35 @@ extern "C" NSString *NSTemporaryDirectory(); # include <sys/syscall.h> # include <sys/sendfile.h> # include <linux/fs.h> +# include <linux/stat.h> // in case linux/fs.h is too old and doesn't define it: #ifndef FICLONE # define FICLONE _IOW(0x94, 9, int) #endif -# if !QT_CONFIG(renameat2) && defined(SYS_renameat2) +# if defined(Q_OS_ANDROID) +// renameat2() and statx() are disabled on Android because quite a few systems +// come with sandboxes that kill applications that make system calls outside a +// whitelist and several Android vendors can't be bothered to update the list. +# undef SYS_renameat2 +# undef SYS_statx +# undef STATX_BASIC_STATS +# else +# if !QT_CONFIG(renameat2) && defined(SYS_renameat2) static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags) { return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); } -# endif +# endif -# if !QT_CONFIG(statx) && defined(SYS_statx) && QT_HAS_INCLUDE(<linux/stat.h>) -# include <linux/stat.h> +# if !QT_CONFIG(statx) && defined(SYS_statx) static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf) { return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); } -# endif +# endif +# endif // !Q_OS_ANDROID #endif -#ifndef STATX_BASIC_STATS -struct statx { mode_t stx_mode; }; +#ifndef STATX_ALL +struct statx { mode_t stx_mode; }; // dummy #endif QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 04c9a9bcba..712e8bbcab 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -599,7 +599,7 @@ void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *liste jobject QtAndroidPrivate::callOnBindListener(jobject intent) { QMutexLocker lock(g_onBindListenerMutex); - if (g_onBindListener) + if (*g_onBindListener) return (*g_onBindListener)->onBind(intent); return nullptr; } diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 96299b9eaf..f77831c703 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3896,7 +3896,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) \sa setValue(), value() */ -/*! \fn static inline QVariant fromStdVariant(const std::variant<T, Types...> &value) +/*! \fn template<typename... Types> QVariant QVariant::fromStdVariant(const std::variant<Types...> &value) \since 5.11 Returns a QVariant with the type and value of the active variant of \a value. If diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index b515dfa099..1dc4b56e9b 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -359,7 +359,7 @@ class Q_CORE_EXPORT QVariant static inline QVariant fromValue(const T &value) { return qVariantFromValue(value); } -#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L +#if defined(Q_CLANG_QDOC) || (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L) template<typename... Types> static inline QVariant fromStdVariant(const std::variant<Types...> &value) { diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 4ae4e687a0..7b0e691127 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -4409,7 +4409,6 @@ QByteArray &QByteArray::setRawData(const char *data, uint size) } else { d->offset = sizeof(QByteArrayData); d->size = 0; - *d->data() = 0; } } return *this; diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index cf3d712421..c3a264f1e8 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -222,6 +222,9 @@ void QOpenGLWindowPrivate::initialize() if (context) return; + if (!q->handle()) + qWarning("Attempted to initialize QOpenGLWindow without a platform window"); + context.reset(new QOpenGLContext); context->setShareContext(shareContext); context->setFormat(q->requestedFormat()); diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index e5cd0be519..1b964ba913 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -251,7 +251,7 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt: { Q_ASSERT(window); if (oldState < Qt::WindowNoState) - oldState = window->windowState(); + oldState = window->windowStates(); QWindowSystemInterfacePrivate::WindowStateChangedEvent *e = new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowStates(oldState)); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index ed9d00f4a7..efd9b0c146 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5489,6 +5489,8 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL // nothing } else if (coverage == 255) { *dst = src; + } else if (!colorProfile) { + *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage); } else { if (*dst >= 0xff000000) { grayBlendPixel(dst, coverage, srcLinear, colorProfile); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index f7578a3c57..33fde8c61a 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2341,8 +2341,12 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) { QRectF targetBounds = s->matrix.mapRect(r); - bool exceedsPrecision = targetBounds.width() > 0x7fff - || targetBounds.height() > 0x7fff; + bool exceedsPrecision = r.width() > 0x7fff + || r.height() > 0x7fff + || targetBounds.width() > 0x7fff + || targetBounds.height() > 0x7fff + || s->matrix.m11() >= 512 + || s->matrix.m22() >= 512; if (!exceedsPrecision && d->canUseFastImageBlending(d->rasterBuffer->compositionMode, img)) { if (s->matrix.type() > QTransform::TxScale) { @@ -4639,9 +4643,13 @@ void QSpanData::setupMatrix(const QTransform &matrix, int bilin) bilinear = bilin; const bool affine = inv.isAffine(); + const qreal f1 = m11 * m11 + m21 * m21; + const qreal f2 = m12 * m12 + m22 * m22; fast_matrix = affine - && m11 * m11 + m21 * m21 < 1e4 - && m12 * m12 + m22 * m22 < 1e4 + && f1 < 1e4 + && f2 < 1e4 + && f1 > (1.0 / 65536) + && f2 > (1.0 / 65536) && qAbs(dx) < 1e4 && qAbs(dy) < 1e4; diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index e0c705f97e..116a6693c4 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -876,12 +876,12 @@ void QSslConfiguration::setDiffieHellmanParameters(const QSslDiffieHellmanParame Returns the backend-specific configuration. - Only options set by addBackendConfig() or setBackendConfig() will be + Only options set by addBackendConfiguration() or setBackendConfiguration() will be returned. The internal standard configuration of the backend is not reported. - \sa setBackendConfigOption(), setBackendConfig() + \sa setBackendConfigurationOption(), setBackendConfiguration() */ -QMap<QByteArray, QVariant> QSslConfiguration::backendConfig() const +QMap<QByteArray, QVariant> QSslConfiguration::backendConfiguration() const { return d->backendConfig; } @@ -902,9 +902,9 @@ QMap<QByteArray, QVariant> QSslConfiguration::backendConfig() const configuration. Using the backend-specific configuration to set a general configuration option again will overwrite the general configuration option. - \sa backendConfig(), setBackendConfig() + \sa backendConfiguration(), setBackendConfiguration() */ -void QSslConfiguration::setBackendConfigOption(const QByteArray &name, const QVariant &value) +void QSslConfiguration::setBackendConfigurationOption(const QByteArray &name, const QVariant &value) { d->backendConfig[name] = value; } @@ -914,13 +914,13 @@ void QSslConfiguration::setBackendConfigOption(const QByteArray &name, const QVa Sets or clears the backend-specific configuration. - Without a \a backendConfig parameter this function will clear the + Without a \a backendConfiguration parameter this function will clear the backend-specific configuration. More information about the supported - options is available in the documentation of addBackendConfig(). + options is available in the documentation of addBackendConfiguration(). - \sa backendConfig(), setBackendConfigOption() + \sa backendConfiguration(), setBackendConfigurationOption() */ -void QSslConfiguration::setBackendConfig(const QMap<QByteArray, QVariant> &backendConfig) +void QSslConfiguration::setBackendConfiguration(const QMap<QByteArray, QVariant> &backendConfig) { d->backendConfig = backendConfig; } diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index b3264126dd..a5561d9828 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -150,9 +150,9 @@ public: QSslDiffieHellmanParameters diffieHellmanParameters() const; void setDiffieHellmanParameters(const QSslDiffieHellmanParameters &dhparams); - QMap<QByteArray, QVariant> backendConfig() const; - void setBackendConfigOption(const QByteArray &name, const QVariant &value); - void setBackendConfig(const QMap<QByteArray, QVariant> &backendConfig = QMap<QByteArray, QVariant>()); + QMap<QByteArray, QVariant> backendConfiguration() const; + void setBackendConfigurationOption(const QByteArray &name, const QVariant &value); + void setBackendConfiguration(const QMap<QByteArray, QVariant> &backendConfig = QMap<QByteArray, QVariant>()); static QSslConfiguration defaultConfiguration(); static void setDefaultConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 386c280659..41b759364b 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -245,7 +245,7 @@ QString QSslContext::errorString() const // static void QSslContext::applyBackendConfig(QSslContext *sslContext) { - if (sslContext->sslConfiguration.backendConfig().isEmpty()) + if (sslContext->sslConfiguration.backendConfiguration().isEmpty()) return; #if OPENSSL_VERSION_NUMBER >= 0x10002000L @@ -255,7 +255,7 @@ void QSslContext::applyBackendConfig(QSslContext *sslContext) q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx); q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE); - const auto &backendConfig = sslContext->sslConfiguration.backendConfig(); + const auto &backendConfig = sslContext->sslConfiguration.backendConfiguration(); for (auto i = backendConfig.constBegin(); i != backendConfig.constEnd(); ++i) { if (!i.value().canConvert(QMetaType::QByteArray)) { sslContext->errorCode = QSslError::UnspecifiedError; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 833d676192..4273904c12 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -922,7 +922,7 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration) d->configuration.peerVerifyDepth = configuration.peerVerifyDepth(); d->configuration.peerVerifyMode = configuration.peerVerifyMode(); d->configuration.protocol = configuration.protocol(); - d->configuration.backendConfig = configuration.backendConfig(); + d->configuration.backendConfig = configuration.backendConfiguration(); d->configuration.sslOptions = configuration.d->sslOptions; d->configuration.sslSession = configuration.sessionTicket(); d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint(); diff --git a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp index de369e0b00..aa7bb102c6 100644 --- a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp +++ b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp @@ -134,6 +134,7 @@ messageDebugEntries[] = { {WM_XBUTTONUP, "WM_XBUTTONUP", true}, {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK", true}, {WM_MOUSEHWHEEL, "WM_MOUSEHWHEEL", true}, + {WM_GETOBJECT, "WM_GETOBJECT", true}, {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true}, {WM_INPUTLANGCHANGE, "WM_INPUTLANGCHANGE", true}, {WM_IME_NOTIFY, "WM_IME_NOTIFY", true}, @@ -162,6 +163,7 @@ messageDebugEntries[] = { {WM_GETMINMAXINFO, "WM_GETMINMAXINFO", true}, {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING", true}, {WM_NCCREATE, "WM_NCCREATE", true}, + {WM_NCDESTROY, "WM_NCDESTROY", true}, {WM_NCCALCSIZE, "WM_NCCALCSIZE", true}, {WM_NCACTIVATE, "WM_NCACTIVATE", true}, {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE", true}, @@ -180,7 +182,9 @@ messageDebugEntries[] = { {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN", true}, {WM_DISPLAYCHANGE, "WM_DISPLAYCHANGE", true}, {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true}, - {WM_THEMECHANGED, "WM_THEMECHANGED", true} + {WM_THEMECHANGED, "WM_THEMECHANGED", true}, + {0x90, "WM_UAHDESTROYWINDOW", true}, + {0x272, "WM_UNREGISTER_WINDOW_SERVICES", true} }; static inline const MessageDebugEntry *messageDebugEntry(UINT msg) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 85d213ad46..bbaaf43ebb 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -507,6 +507,8 @@ static void addExtraFallbacks(QStringList *fallbackList) // add Apple Symbols to cover those too. if (!fallbackList->contains(QStringLiteral("Apple Symbols"))) fallbackList->append(QStringLiteral("Apple Symbols")); +#else + Q_UNUSED(fallbackList) #endif } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 3d0dbd7b1a..20d6e6e8d4 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1364,9 +1364,10 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow); if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) { if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) { - qCDebug(lcQpaEvents) << "EVENT: hwd=" << hwnd << eventName << hex << "msg=0x" << message - << "et=0x" << et << dec << "wp=" << int(wParam) << "at" - << GET_X_LPARAM(lParam) << GET_Y_LPARAM(lParam) << "handled=" << handled; + qCDebug(lcQpaEvents).nospace() << "EVENT: hwd=" << hwnd << ' ' << eventName + << " msg=0x" << hex << message << " et=0x" << et << dec << " wp=" + << int(wParam) << " at " << GET_X_LPARAM(lParam) << ',' + << GET_Y_LPARAM(lParam) << " handled=" << handled; } } if (!handled) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 159e1250d0..9fff4b5e42 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1077,6 +1077,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, */ const char *QWindowsWindow::embeddedNativeParentHandleProperty = "_q_embedded_native_parent_handle"; +const char *QWindowsWindow::hasBorderInFullScreenProperty = "_q_has_border_in_fullscreen"; QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) : QWindowsBaseWindow(aWindow), @@ -1106,7 +1107,6 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) updateDropSite(window()->isTopLevel()); registerTouchWindow(); - setWindowState(aWindow->windowStates()); const qreal opacity = qt_window_private(aWindow)->opacity; if (!qFuzzyCompare(opacity, qreal(1.0))) setOpacity(opacity); @@ -1115,6 +1115,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->isTopLevel()) setWindowIcon(aWindow->icon()); + if (aWindow->property(hasBorderInFullScreenProperty).toBool()) + setFlag(HasBorderInFullScreen); clearFlag(WithinCreate); } @@ -1133,9 +1135,11 @@ void QWindowsWindow::initialize() QWindowCreationContextPtr creationContext = QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr()); + QWindow *w = window(); + setWindowState(w->windowStates()); + // Trigger geometry change (unless it has a special state in which case setWindowState() // will send the message) and screen change signals of QWindow. - QWindow *w = window(); if (w->type() != Qt::Desktop) { const Qt::WindowState state = w->windowState(); if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen @@ -2662,15 +2666,26 @@ void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool 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); + window->setProperty(hasBorderInFullScreenProperty, QVariant(border)); } void QWindowsWindow::setHasBorderInFullScreen(bool border) { + if (testFlag(HasBorderInFullScreen) == border) + return; if (border) setFlag(HasBorderInFullScreen); else clearFlag(HasBorderInFullScreen); + // Directly apply the flag in case we are fullscreen. + if (m_windowState == Qt::WindowFullScreen) { + LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE); + if (border) + style |= WS_BORDER; + else + style &= ~WS_BORDER; + SetWindowLongPtr(handle(), GWL_STYLE, style); + } } QString QWindowsWindow::formatWindowTitle(const QString &title) diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 8d29b871bf..fe2518e329 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -340,6 +340,7 @@ public: static QString formatWindowTitle(const QString &title); static const char *embeddedNativeParentHandleProperty; + static const char *hasBorderInFullScreenProperty; private: inline void show_sys() const; diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 6ae52d9fd3..70d1757af4 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -74,7 +74,9 @@ class QXcbShmImage : public QXcbObject { public: QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format); - ~QXcbShmImage() { destroy(); } + ~QXcbShmImage() { destroy(true); } + + void resize(const QSize &size); void flushScrolledRegion(bool clientSideScroll); @@ -95,14 +97,18 @@ private: void createShmSegment(size_t segmentSize); void destroyShmSegment(size_t segmentSize); - void destroy(); + void create(const QSize &size, const xcb_format_t *fmt, QImage::Format format); + void destroy(bool destroyShm); void ensureGC(xcb_drawable_t dst); void shmPutImage(xcb_drawable_t drawable, const QRegion ®ion, const QPoint &offset = QPoint()); void flushPixmap(const QRegion ®ion, bool fullRegion = false); void setClip(const QRegion ®ion); + xcb_window_t m_screen_root; + xcb_shm_segment_info_t m_shm_info; + size_t m_segmentSize; xcb_image_t *m_xcb_image; @@ -171,6 +177,8 @@ static inline size_t imageDataSize(const xcb_image_t *image) QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format) : QXcbObject(screen->connection()) + , m_screen_root(screen->screen()->root) + , m_segmentSize(0) , m_graphics_buffer(nullptr) , m_gc(0) , m_gc_drawable(0) @@ -180,6 +188,27 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI const xcb_format_t *fmt = connection()->formatForDepth(depth); Q_ASSERT(fmt); + m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; + if (!m_hasAlpha) + format = qt_maybeAlphaVersionWithSameDepth(format); + + memset(&m_shm_info, 0, sizeof m_shm_info); + create(size, fmt, format); +} + +void QXcbShmImage::resize(const QSize &size) +{ + xcb_format_t fmt; + fmt.depth = m_xcb_image->depth; + fmt.bits_per_pixel = m_xcb_image->bpp; + fmt.scanline_pad = m_xcb_image->scanline_pad; + memset(fmt.pad0, 0, sizeof(fmt.pad0)); + destroy(false); + create(size, &fmt, m_qimage.format()); +} + +void QXcbShmImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format) +{ m_xcb_image = xcb_image_create(size.width(), size.height(), XCB_IMAGE_FORMAT_Z_PIXMAP, fmt->scanline_pad, @@ -192,14 +221,16 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI if (!segmentSize) return; - createShmSegment(segmentSize); + if (hasShm() && m_segmentSize > 0 && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize)) + destroyShmSegment(m_segmentSize); + if (!hasShm() && connection()->hasShm()) + { + qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for" << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel; + createShmSegment(segmentSize); + } m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize); - m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; - if (!m_hasAlpha) - format = qt_maybeAlphaVersionWithSameDepth(format); - m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage); @@ -207,10 +238,36 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI xcb_create_pixmap(xcb_connection(), m_xcb_image->depth, m_xcb_pixmap, - screen->screen()->root, + m_screen_root, m_xcb_image->width, m_xcb_image->height); } +void QXcbShmImage::destroy(bool destroyShm) +{ + if (m_xcb_image->data) { + if (m_shm_info.shmaddr) { + if (destroyShm) + destroyShmSegment(m_segmentSize); + } else { + free(m_xcb_image->data); + } + } + + xcb_image_destroy(m_xcb_image); + + if (m_gc) { + xcb_free_gc(xcb_connection(), m_gc); + m_gc = 0; + } + m_gc_drawable = 0; + + delete m_graphics_buffer; + m_graphics_buffer = nullptr; + + xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); + m_xcb_pixmap = 0; +} + void QXcbShmImage::flushScrolledRegion(bool clientSideScroll) { if (m_clientSideScroll == clientSideScroll) @@ -261,10 +318,8 @@ void QXcbShmImage::flushScrolledRegion(bool clientSideScroll) void QXcbShmImage::createShmSegment(size_t segmentSize) { - m_shm_info.shmaddr = nullptr; - - if (!connection()->hasShm()) - return; + Q_ASSERT(connection()->hasShm()); + Q_ASSERT(m_segmentSize == 0); #ifdef XCB_USE_SHM_FD if (connection()->hasShmFd()) { @@ -302,6 +357,8 @@ void QXcbShmImage::createShmSegment(size_t segmentSize) close(fds[0]); m_shm_info.shmseg = seg; m_shm_info.shmaddr = static_cast<quint8 *>(addr); + + m_segmentSize = segmentSize; } else #endif { @@ -338,6 +395,8 @@ void QXcbShmImage::createShmSegment(size_t segmentSize) m_shm_info.shmseg = seg; m_shm_info.shmid = id; // unused m_shm_info.shmaddr = static_cast<quint8 *>(addr); + + m_segmentSize = segmentSize; } } @@ -350,6 +409,7 @@ void QXcbShmImage::destroyShmSegment(size_t segmentSize) xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie); if (error) connection()->printXcbError("QXcbShmImage: xcb_shm_detach() failed with error", error); + m_shm_info.shmseg = 0; #ifdef XCB_USE_SHM_FD if (connection()->hasShmFd()) { @@ -364,7 +424,11 @@ void QXcbShmImage::destroyShmSegment(size_t segmentSize) qWarning("QXcbShmImage: shmdt() failed (%d: %s) for %p", errno, strerror(errno), m_shm_info.shmaddr); } + m_shm_info.shmid = 0; // unused } + m_shm_info.shmaddr = nullptr; + + m_segmentSize = 0; } extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); @@ -413,26 +477,6 @@ bool QXcbShmImage::scroll(const QRegion &area, int dx, int dy) return true; } -void QXcbShmImage::destroy() -{ - if (m_xcb_image->data) { - if (m_shm_info.shmaddr) - destroyShmSegment(imageDataSize(m_xcb_image)); - else - free(m_xcb_image->data); - } - - xcb_image_destroy(m_xcb_image); - - if (m_gc) - xcb_free_gc(xcb_connection(), m_gc); - delete m_graphics_buffer; - m_graphics_buffer = nullptr; - - xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); - m_xcb_pixmap = 0; -} - void QXcbShmImage::ensureGC(xcb_drawable_t dst) { if (m_gc_drawable != dst) { @@ -805,7 +849,6 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) if (m_image && size == m_image->size()) return; - QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle()); QPlatformWindow *pw = window()->handle(); if (!pw) { window()->create(); @@ -813,8 +856,13 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) } QXcbWindow* win = static_cast<QXcbWindow *>(pw); - delete m_image; - m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); + if (m_image) { + m_image->resize(size); + } else { + QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle()); + m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); + } + // Slow path for bgr888 VNC: Create an additional image, paint into that and // swap R and B while copying to m_image after each paint. if (win->imageNeedsRgbSwap()) { diff --git a/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp b/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp index 04abd707e1..6c5e1389cf 100644 --- a/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp +++ b/src/plugins/platformthemes/flatpak/qflatpaktheme.cpp @@ -95,41 +95,25 @@ QFlatpakTheme::QFlatpakTheme() QPlatformMenuItem* QFlatpakTheme::createPlatformMenuItem() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformMenuItem(); - - return QPlatformTheme::createPlatformMenuItem(); + return d->baseTheme->createPlatformMenuItem(); } QPlatformMenu* QFlatpakTheme::createPlatformMenu() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformMenu(); - - return QPlatformTheme::createPlatformMenu(); + return d->baseTheme->createPlatformMenu(); } QPlatformMenuBar* QFlatpakTheme::createPlatformMenuBar() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformMenuBar(); - - return QFlatpakTheme::createPlatformMenuBar(); + return d->baseTheme->createPlatformMenuBar(); } void QFlatpakTheme::showPlatformMenuBar() { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->showPlatformMenuBar(); - - return QFlatpakTheme::showPlatformMenuBar(); + return d->baseTheme->showPlatformMenuBar(); } bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const @@ -139,10 +123,7 @@ bool QFlatpakTheme::usePlatformNativeDialog(DialogType type) const if (type == FileDialog) return true; - if (d->baseTheme) - return d->baseTheme->usePlatformNativeDialog(type); - - return QFlatpakTheme::usePlatformNativeDialog(type); + return d->baseTheme->usePlatformNativeDialog(type); } QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type) const @@ -152,103 +133,64 @@ QPlatformDialogHelper* QFlatpakTheme::createPlatformDialogHelper(DialogType type if (type == FileDialog) return new QFlatpakFileDialog; - if (d->baseTheme) - return d->baseTheme->createPlatformDialogHelper(type); - - return QFlatpakTheme::createPlatformDialogHelper(type); + return d->baseTheme->createPlatformDialogHelper(type); } #ifndef QT_NO_SYSTEMTRAYICON QPlatformSystemTrayIcon* QFlatpakTheme::createPlatformSystemTrayIcon() const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createPlatformSystemTrayIcon(); - - return QPlatformTheme::createPlatformSystemTrayIcon(); + return d->baseTheme->createPlatformSystemTrayIcon(); } #endif const QPalette *QFlatpakTheme::palette(Palette type) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->palette(type); - - return QPlatformTheme::palette(type); + return d->baseTheme->palette(type); } const QFont* QFlatpakTheme::font(Font type) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->font(type); - - return QPlatformTheme::font(type); + return d->baseTheme->font(type); } QVariant QFlatpakTheme::themeHint(ThemeHint hint) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->themeHint(hint); - - return QPlatformTheme::themeHint(hint); + return d->baseTheme->themeHint(hint); } QPixmap QFlatpakTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->standardPixmap(sp, size); - - return QPlatformTheme::standardPixmap(sp, size); + return d->baseTheme->standardPixmap(sp, size); } QIcon QFlatpakTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->fileIcon(fileInfo, iconOptions); - - return QPlatformTheme::fileIcon(fileInfo, iconOptions); + return d->baseTheme->fileIcon(fileInfo, iconOptions); } QIconEngine * QFlatpakTheme::createIconEngine(const QString &iconName) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->createIconEngine(iconName); - - return QPlatformTheme::createIconEngine(iconName); + return d->baseTheme->createIconEngine(iconName); } QList<QKeySequence> QFlatpakTheme::keyBindings(QKeySequence::StandardKey key) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->keyBindings(key); - - return QPlatformTheme::keyBindings(key); + return d->baseTheme->keyBindings(key); } QString QFlatpakTheme::standardButtonText(int button) const { Q_D(const QFlatpakTheme); - - if (d->baseTheme) - return d->baseTheme->standardButtonText(button); - - return QPlatformTheme::standardButtonText(button); + return d->baseTheme->standardButtonText(button); } QT_END_NAMESPACE diff --git a/src/widgets/doc/images/graphicsflowlayout.png b/src/widgets/doc/images/graphicsflowlayout.png Binary files differnew file mode 100644 index 0000000000..ea70e102c3 --- /dev/null +++ b/src/widgets/doc/images/graphicsflowlayout.png diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index b7048d1616..00e9ff7400 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1175,9 +1175,10 @@ bool QHeaderView::sectionsMovable() const */ /*! - \since 5.10 + \property QHeaderView::firstSectionMovable + \brief Whether the first column can be moved by the user - If \a movable is true, the first column can be moved by the user. + This property controls whether the first column can be moved by the user. In a QTreeView, the first column holds the tree structure and is therefore non-movable by default, even after setSectionsMovable(true). @@ -1186,8 +1187,11 @@ bool QHeaderView::sectionsMovable() const In such a scenario, it is recommended to call QTreeView::setRootIsDecorated(false) as well. - This method has no effect unless setSectionsMovable(true) is called as well. + Setting it to true has no effect unless setSectionsMovable(true) is called + as well. + \sa setSectionsMovable() + \since 5.11 */ void QHeaderView::setFirstSectionMovable(bool movable) { @@ -1195,13 +1199,7 @@ void QHeaderView::setFirstSectionMovable(bool movable) d->allowUserMoveOfSection0 = movable; } -/*! - \since 5.10 - - Returns \c true if the first column can be moved by the user, - when this header is used in a QTreeView. -*/ -bool QHeaderView::firstSectionMovable() const +bool QHeaderView::isFirstSectionMovable() const { Q_D(const QHeaderView); return d->allowUserMoveOfSection0; diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h index c09081cd80..7e950add1f 100644 --- a/src/widgets/itemviews/qheaderview.h +++ b/src/widgets/itemviews/qheaderview.h @@ -53,6 +53,7 @@ class QStyleOptionHeader; class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView { Q_OBJECT + Q_PROPERTY(bool firstSectionMovable READ isFirstSectionMovable WRITE setFirstSectionMovable) Q_PROPERTY(bool showSortIndicator READ isSortIndicatorShown WRITE setSortIndicatorShown) Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections) Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection) @@ -119,7 +120,7 @@ public: inline QT_DEPRECATED bool isMovable() const { return sectionsMovable(); } #endif void setFirstSectionMovable(bool movable); - bool firstSectionMovable() const; + bool isFirstSectionMovable() const; void setSectionsClickable(bool clickable); bool sectionsClickable() const; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 4cf52f994a..39540cf898 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -113,8 +113,10 @@ static void initResources() { Q_INIT_RESOURCE(qstyle); - Q_INIT_RESOURCE(qmessagebox); +#if QT_CONFIG(messagebox) + Q_INIT_RESOURCE(qmessagebox); +#endif } QT_BEGIN_NAMESPACE diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 138733476f..923245c53c 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5457,11 +5457,11 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP setSystemClip(pdev->paintEngine(), pdev->devicePixelRatioF(), rgn.translated(offset)); QPainter p(pdev); p.translate(offset); - context.painter = context.sharedPainter = &p; + context.painter = &p; graphicsEffect->draw(&p); setSystemClip(pdev->paintEngine(), 1, QRegion()); } else { - context.painter = context.sharedPainter = sharedPainter; + context.painter = sharedPainter; if (sharedPainter->worldTransform() != sourced->lastEffectTransform) { sourced->invalidateCache(); sourced->lastEffectTransform = sharedPainter->worldTransform(); |