diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-15 08:09:50 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-02-15 08:09:50 +0100 |
commit | 80bf4bfe3df425962192118d4357acc144f6aef8 (patch) | |
tree | 79e4b6a00d6bf68be62fe157878f38dcd782a475 | |
parent | ac8a3b948da1980bc59bae3fc76d20b5b45662a0 (diff) | |
parent | 8c2b4266002736da499d169a0da187e5cdc5381a (diff) |
Merge remote-tracking branch 'origin/5.6.0' into 5.6
Change-Id: I0b190005377a23a91da3563428e223b8a3b18333
58 files changed, 339 insertions, 132 deletions
@@ -2854,7 +2854,7 @@ if [ -z "$PLATFORM" ]; then PLATFORM=ultrix-g++ ;; FreeBSD:*) - PLATFORM=freebsd-g++ + PLATFORM=freebsd-clang PLATFORM_NOTES=" - Also available for FreeBSD: freebsd-icc " diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index e543ea65e6..bb28af975f 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -194,7 +194,7 @@ equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_support android: CONFIG += qt_android_deps no_linker_version_script !header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { - verscript = $$OUT_PWD/$${TARGET}.version + verscript = $${TARGET}.version QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript internal_module { @@ -219,16 +219,20 @@ android: CONFIG += qt_android_deps no_linker_version_script } # Add a post-processing step to replace the @FILE:filename@ - verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $${verscript}.in > $@ - verscriptprocess.target = $$verscript + verscript_in = $${verscript}.in + verscriptprocess.name = linker version script ${QMAKE_FILE_BASE} + verscriptprocess.input = verscript_in + verscriptprocess.CONFIG += no_link target_predeps for(header, SYNCQT.PRIVATE_HEADER_FILES): \ verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header - verscriptprocess.depends += $${verscript}.in - QMAKE_EXTRA_TARGETS += verscriptprocess - PRE_TARGETDEPS += $$verscript - verscript = $${verscript}.in + verscriptprocess.output = $$verscript + verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@ + silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands + QMAKE_EXTRA_COMPILERS += verscriptprocess + + verscript = $$verscript_in } - write_file($$verscript, verscript_content)|error("Aborting.") + write_file($$OUT_PWD/$$verscript, verscript_content)|error("Aborting.") unset(current) unset(previous) unset(verscript) diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index 7a38ff8f38..1f04c8b0d7 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -49,9 +49,15 @@ for(resource, RESOURCES) { for(file, $${resource}.files) { abs_path = $$absolute_path($$file, $$_PRO_FILE_PWD_) - alias = $$relative_path($$abs_path, $$abs_base) - resource_file_content += \ - "<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$abs_path)</file>" + files = $$files($$abs_path/*, true) + isEmpty(files): \ + files = $$abs_path + for (file, files) { + exists($$file/*): next() # exclude directories + alias = $$relative_path($$file, $$abs_base) + resource_file_content += \ + "<file alias=\"$$xml_escape($$alias)\">$$xml_escape($$file)</file>" + } } resource_file_content += \ diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/freebsd-clang/qmake.conf index 9d9815a7b3..7f18bbb721 100644 --- a/mkspecs/unsupported/freebsd-clang/qmake.conf +++ b/mkspecs/freebsd-clang/qmake.conf @@ -30,7 +30,7 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../../common/gcc-base-unix.conf) -include(../../common/clang.conf) +include(../common/gcc-base-unix.conf) +include(../common/clang.conf) load(qt_config) diff --git a/mkspecs/freebsd-g++/qplatformdefs.h b/mkspecs/freebsd-clang/qplatformdefs.h index 3a39b79c41..3a39b79c41 100644 --- a/mkspecs/freebsd-g++/qplatformdefs.h +++ b/mkspecs/freebsd-clang/qplatformdefs.h diff --git a/mkspecs/freebsd-g++/qmake.conf b/mkspecs/unsupported/freebsd-g++/qmake.conf index 282b6bdfa7..527a94870c 100644 --- a/mkspecs/freebsd-g++/qmake.conf +++ b/mkspecs/unsupported/freebsd-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = freebsd bsd -include(../common/unix.conf) +include(../../common/unix.conf) QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE @@ -29,6 +29,6 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../common/gcc-base-unix.conf) -include(../common/g++-unix.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) load(qt_config) diff --git a/mkspecs/unsupported/freebsd-clang/qplatformdefs.h b/mkspecs/unsupported/freebsd-g++/qplatformdefs.h index 68a886ed89..b52be38b4e 100644 --- a/mkspecs/unsupported/freebsd-clang/qplatformdefs.h +++ b/mkspecs/unsupported/freebsd-g++/qplatformdefs.h @@ -31,4 +31,4 @@ ** ****************************************************************************/ -#include "../../freebsd-g++/qplatformdefs.h" +#include "../../freebsd-clang/qplatformdefs.h" diff --git a/mkspecs/freebsd-g++46/qmake.conf b/mkspecs/unsupported/freebsd-g++46/qmake.conf index b930fca78b..11041dee3d 100644 --- a/mkspecs/freebsd-g++46/qmake.conf +++ b/mkspecs/unsupported/freebsd-g++46/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = freebsd bsd -include(../common/unix.conf) +include(../../common/unix.conf) QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE @@ -29,8 +29,8 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../common/gcc-base-unix.conf) -include(../common/g++-unix.conf) +include(../../common/gcc-base-unix.conf) +include(../../common/g++-unix.conf) # Redefined here because g++-base.conf sets QMAKE_CC and QMAKE_CXX # to gcc and g++, respectively. diff --git a/mkspecs/freebsd-g++46/qplatformdefs.h b/mkspecs/unsupported/freebsd-g++46/qplatformdefs.h index 48dc4d64fb..b52be38b4e 100644 --- a/mkspecs/freebsd-g++46/qplatformdefs.h +++ b/mkspecs/unsupported/freebsd-g++46/qplatformdefs.h @@ -31,4 +31,4 @@ ** ****************************************************************************/ -#include "../freebsd-g++/qplatformdefs.h" +#include "../../freebsd-clang/qplatformdefs.h" diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 5cd0bde87b..ab3f29e2c7 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -27,6 +27,10 @@ ANDROID_PERMISSIONS = \ android.permission.INTERNET \ android.permission.WRITE_EXTERNAL_STORAGE +# QtCore can't be compiled with -Wl,-no-undefined because it uses the "environ" +# variable and on FreeBSD, this variable is in the final executable itself +freebsd: QMAKE_LFLAGS_NOUNDEF = + load(qt_module) load(qfeatures) diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h index d6b4a65600..953f669501 100644 --- a/src/corelib/global/qversiontagging.h +++ b/src/corelib/global/qversiontagging.h @@ -59,11 +59,7 @@ QT_BEGIN_NAMESPACE #elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID) # if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL)) # if defined(Q_PROCESSOR_X86_64) // x86-64 or x32 -# if defined(__code_model_large__) -# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" -# else -# define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOTPCREL\n" -# endif +# define QT_VERSION_TAG_RELOC(sym) ".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # else // x86 # define QT_VERSION_TAG_RELOC(sym) ".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(sym)) "@GOT\n" # endif diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 1a14500bd4..b3df139743 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -935,9 +935,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) { Q_ASSERT(notifier); - int sockfd = notifier->socket(); - int type = notifier->type(); #ifndef QT_NO_DEBUG + int sockfd = notifier->socket(); if (sockfd < 0) { qWarning("QSocketNotifier: Internal error"); return; @@ -946,8 +945,16 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) return; } #endif + doUnregisterSocketNotifier(notifier); +} +void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier) +{ Q_D(QEventDispatcherWin32); + int type = notifier->type(); + int sockfd = notifier->socket(); + Q_ASSERT(sockfd >= 0); + QSFDict::iterator it = d->active_fd.find(sockfd); if (it != d->active_fd.end()) { QSockFd &sd = it.value(); @@ -1203,11 +1210,11 @@ void QEventDispatcherWin32::closingDown() // clean up any socketnotifiers while (!d->sn_read.isEmpty()) - unregisterSocketNotifier((*(d->sn_read.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_read.begin()))->obj); while (!d->sn_write.isEmpty()) - unregisterSocketNotifier((*(d->sn_write.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_write.begin()))->obj); while (!d->sn_except.isEmpty()) - unregisterSocketNotifier((*(d->sn_except.begin()))->obj); + doUnregisterSocketNotifier((*(d->sn_except.begin()))->obj); Q_ASSERT(d->active_fd.isEmpty()); // clean up any timers diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 9a53e06730..222562dfce 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -103,6 +103,7 @@ public: protected: QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent = 0); virtual void sendPostedEvents(); + void doUnregisterSocketNotifier(QSocketNotifier *notifier); private: friend LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index 6a0900cf3f..bc81135d7a 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -36,7 +36,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qatomic.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index bd98cb326c..70b100d018 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -55,7 +55,7 @@ QT_END_NAMESPACE #include <new> #include <QtCore/qatomic.h> #include <QtCore/qobject.h> // for qobject_cast -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/dbus/qdbusabstractinterface.h b/src/dbus/qdbusabstractinterface.h index 5336dfba38..16071df956 100644 --- a/src/dbus/qdbusabstractinterface.h +++ b/src/dbus/qdbusabstractinterface.h @@ -43,6 +43,10 @@ #include <QtDBus/qdbusextratypes.h> #include <QtDBus/qdbusconnection.h> +#ifdef interface +#undef interface +#endif + #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 0f2d799b92..7f44272bc3 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -54,6 +54,10 @@ #include <algorithm> +#ifdef interface +#undef interface +#endif + #ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE diff --git a/src/dbus/qdbusextratypes.h b/src/dbus/qdbusextratypes.h index 8495b3a320..adbc371fdf 100644 --- a/src/dbus/qdbusextratypes.h +++ b/src/dbus/qdbusextratypes.h @@ -39,7 +39,7 @@ #include <QtCore/qvariant.h> #include <QtCore/qstring.h> #include <QtDBus/qdbusmacros.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index ebf42b0b06..cd448613d6 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -63,6 +63,9 @@ #include "qdbusthreaddebug_p.h" #include <algorithm> +#ifdef interface +#undef interface +#endif #ifndef QT_NO_DBUS diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index ef12b23caa..27bab10196 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -294,7 +294,7 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int if (depth != 32) { ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; - if (ncols > 256) // sanity check - don't run out of mem if color table is broken + if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken return false; image.setColorCount(ncols); } diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index f9ad6c0ac0..0c0653e8ab 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -189,6 +189,12 @@ inline QImage::Format qt_alphaVersion(QImage::Format format) return QImage::Format_ARGB32_Premultiplied; } +inline QImage::Format qt_maybeAlphaVersionWithSameDepth(QImage::Format format) +{ + const QImage::Format toFormat = qt_alphaVersion(format); + return qt_depthForFormat(format) == qt_depthForFormat(toFormat) ? toFormat : format; +} + inline QImage::Format qt_alphaVersionForPainting(QImage::Format format) { QImage::Format toFormat = qt_alphaVersion(format); diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 9e33787f53..fac3ae420d 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -47,6 +47,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qmargins.h> +#include <QtCore/qmath.h> #include <QtCore/qrect.h> #include <QtCore/qvector.h> #include <QtCore/qloggingcategory.h> @@ -382,6 +383,24 @@ inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow * return pointRegion; } +// When mapping expose events to Qt rects: round top/left towards the origin and +// bottom/right away from the origin, making sure that we cover the whole window. +inline QRegion fromNativeLocalExposedRegion(const QRegion &pixelRegion, const QWindow *window) +{ + if (!QHighDpiScaling::isActive()) + return pixelRegion; + + const qreal scaleFactor = QHighDpiScaling::factor(window); + QRegion pointRegion; + foreach (const QRect &rect, pixelRegion.rects()) { + const QPointF topLeftP = QPointF(rect.topLeft()) / scaleFactor; + const QPointF bottomRightP = QPointF(rect.bottomRight()) / scaleFactor; + pointRegion += QRect(QPoint(qFloor(topLeftP.x()), qFloor(topLeftP.y())), + QPoint(qCeil(bottomRightP.x()), qCeil(bottomRightP.y()))); + } + return pointRegion; +} + inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) @@ -498,6 +517,8 @@ namespace QHighDpi { template <typename T> inline T fromNativeLocalRegion(const T &value, ...) { return value; } template <typename T> inline + T fromNativeLocalExposedRegion(const T &value, ...) { return value; } + template <typename T> inline T toNativeLocalRegion(const T &value, ...) { return value; } template <typename T> inline diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 841967a545..a658f24ac5 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -54,7 +54,7 @@ #include <QtGui/qopengl.h> #include <QtGui/qopenglversionfunctions.h> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index a9dcb8bb7d..e10ddf22a7 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -582,7 +582,8 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw) void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion) { - QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw)); + QWindowSystemInterfacePrivate::ExposeEvent *e = + new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalExposedRegion(region, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -868,7 +869,7 @@ Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::Keybo QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } -Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) { #ifndef QT_NO_SHORTCUT diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h index a5d5677938..695fc76052 100644 --- a/src/gui/opengl/qopenglversionfunctions.h +++ b/src/gui/opengl/qopenglversionfunctions.h @@ -47,7 +47,7 @@ #ifndef QT_NO_OPENGL -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/qhash.h> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8a5a6d4fcf..c39675b0b6 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -106,7 +106,8 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *win, const QPoint &off } #endif - d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset); + d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, win), + QHighDpi::toNativeLocalPosition(offset, win)); } /*! diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 8e40eb6dff..33d5e76e52 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -263,12 +263,14 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, QOpenGLTextureBlitter *blitter, const QPoint &offset) { + const QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + return; + QRect rectInWindow = textures->geometry(idx); // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust rectInWindow.translate(-offset); - QRect clipRect = textures->clipRect(idx); - if (clipRect.isEmpty()) - clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); @@ -514,7 +516,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu if (needsConversion) image = image.convertToFormat(QImage::Format_RGBA8888); + // The image provided by the backingstore may have a stride larger than width * 4, for + // instance on platforms that manually implement client-side decorations. + static const int bytesPerPixel = 4; + const int strideInPixels = image.bytesPerLine() / bytesPerPixel; + const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3; + QOpenGLFunctions *funcs = ctx->functions(); + + if (hasUnpackRowLength) { + funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels); + } else if (strideInPixels != image.width()) { + // No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically + // hit with QtWayland which is rarely used in combination with a ES2.0-only GL + // implementation. Therefore, accept the performance hit and do a copy. + image = image.copy(); + } + if (resized) { if (d_ptr->textureId) funcs->glDeleteTextures(1, &d_ptr->textureId); @@ -536,11 +554,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu QRect imageRect = image.rect(); QRect rect = dirtyRegion.boundingRect() & imageRect; - if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { - funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); + if (hasUnpackRowLength) { funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, - image.constScanLine(rect.y()) + rect.x() * 4); - funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + image.constScanLine(rect.y()) + rect.x() * bytesPerPixel); } else { // if the rect is wide enough it's cheaper to just // extend it instead of doing an image copy @@ -562,6 +578,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu } } + if (hasUnpackRowLength) + funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + return d_ptr->textureId; } #endif // QT_NO_OPENGL diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 4dd2ee35b1..de5bec6f93 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1255,7 +1255,7 @@ QFixed QFontEngineFT::xHeight() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->sxHeight) { lockFace(); - QFixed answer = QFixed(os2->sxHeight*freetype->face->size->metrics.y_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1267,7 +1267,7 @@ QFixed QFontEngineFT::averageCharWidth() const TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); if (os2 && os2->xAvgCharWidth) { lockFace(); - QFixed answer = QFixed(os2->xAvgCharWidth*freetype->face->size->metrics.x_ppem)/freetype->face->units_per_EM; + QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize(); unlockFace(); return answer; } @@ -1295,7 +1295,7 @@ void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) c kerning_pairs_loaded = true; lockFace(); if (freetype->face->size->metrics.x_ppem != 0) { - QFixed scalingFactor(freetype->face->units_per_EM/freetype->face->size->metrics.x_ppem); + QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem); unlockFace(); const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor); } else { diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index dfb6c9c471..eb51447105 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1072,8 +1072,8 @@ QTextCursor::QTextCursor(const QTextBlock &block) /*! \internal */ -QTextCursor::QTextCursor(QTextDocumentPrivate &p, int pos) - : d(new QTextCursorPrivate(&p)) +QTextCursor::QTextCursor(QTextDocumentPrivate *p, int pos) + : d(new QTextCursorPrivate(p)) { d->adjusted_anchor = d->anchor = d->position = pos; diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index c5462b2936..d42d7a1a70 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -61,6 +61,8 @@ class Q_GUI_EXPORT QTextCursor public: QTextCursor(); explicit QTextCursor(QTextDocument *document); + QTextCursor(QTextDocumentPrivate *p, int pos); + explicit QTextCursor(QTextCursorPrivate *d); explicit QTextCursor(QTextFrame *frame); explicit QTextCursor(const QTextBlock &block); QTextCursor(const QTextCursor &cursor); @@ -219,9 +221,6 @@ public: QTextDocument *document() const; private: - QTextCursor(QTextDocumentPrivate &p, int pos); - explicit QTextCursor(QTextCursorPrivate *d); - QSharedDataPointer<QTextCursorPrivate> d; friend class QTextCursorPrivate; friend class QTextDocumentPrivate; diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 983ff13742..d3cb52d94f 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -101,7 +101,7 @@ public: void aboutToRemoveCell(int from, int to); static QTextCursor fromPosition(QTextDocumentPrivate *d, int pos) - { return QTextCursor(*d, pos); } + { return QTextCursor(d, pos); } QTextDocumentPrivate *priv; qreal x; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index e5dcfb2e55..587844c1dd 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1704,7 +1704,7 @@ bool QTextDocumentPrivate::ensureMaximumBlockCount() beginEditBlock(); const int blocksToRemove = blocks.numNodes() - maximumBlockCount; - QTextCursor cursor(*this, 0); + QTextCursor cursor(this, 0); cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, blocksToRemove); unreachableCharacterCount += cursor.selectionEnd() - cursor.selectionStart(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 65650504ac..9e2a23a7f7 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1058,12 +1058,15 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const QVector<quint32> indexes = oldGlyphRun.glyphIndexes(); QVector<QPointF> positions = oldGlyphRun.positions(); + QRectF boundingRect = oldGlyphRun.boundingRect(); indexes += glyphRun.glyphIndexes(); positions += glyphRun.positions(); + boundingRect = boundingRect.united(glyphRun.boundingRect()); oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setPositions(positions); + oldGlyphRun.setBoundingRect(boundingRect); } else { glyphRunHash[key] = glyphRun; } diff --git a/src/network/ssl/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h index 5716e3447d..c57453d41f 100644 --- a/src/network/ssl/qsslellipticcurve.h +++ b/src/network/ssl/qsslellipticcurve.h @@ -37,7 +37,7 @@ #include <QtCore/QtGlobal> #include <QtCore/QString> #include <QtCore/QMetaType> -#if QT_DEPRECATED_SINCE(5, 5) +#if QT_DEPRECATED_SINCE(5, 6) #include <QtCore/QHash> #endif #include <QtCore/qhashfunctions.h> diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 2e386532e2..c65d69e842 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE It is up to the platform plugin to manage the lifetime of the compositor (instance(), destroy()), set the correct destination - context and window as early as possible (setTargetWindow()), + context and window as early as possible (setTarget()), register the composited windows as they are shown, activated, raised and lowered (addWindow(), moveToTop(), etc.), and to schedule repaints (update()). @@ -177,11 +177,11 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) { - const QRect rectInWindow = textures->geometry(idx); - QRect clipRect = textures->clipRect(idx); + const QRect clipRect = textures->clipRect(idx); if (clipRect.isEmpty()) - clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + return; + const QRect rectInWindow = textures->geometry(idx); const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index fee3146f04..8ec5d20e05 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -34,6 +34,7 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QWindow> #include <QtGui/QPainter> +#include <QtGui/QOffscreenSurface> #include <qpa/qplatformbackingstore.h> #include <private/qwindow_p.h> @@ -82,13 +83,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore() { if (m_bsTexture) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); + // With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is + // made current before destroying backingstores. That is however not the case for + // windows with regular widgets only. + QScopedPointer<QOffscreenSurface> tempSurface; + if (!ctx) { + ctx = QOpenGLCompositor::instance()->context(); + tempSurface.reset(new QOffscreenSurface); + tempSurface->setFormat(ctx->format()); + tempSurface->create(); + ctx->makeCurrent(tempSurface.data()); + } + if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup()) glDeleteTextures(1, &m_bsTexture); else qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context"); + + if (tempSurface) + ctx->doneCurrent(); } - delete m_textures; + delete m_textures; // this does not actually own any GL resources } QPaintDevice *QOpenGLCompositorBackingStore::paintDevice() @@ -158,16 +174,15 @@ void QOpenGLCompositorBackingStore::updateTexture() void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { - // Called for ordinary raster windows. This is rare since RasterGLSurface - // support is claimed which leads to having all QWidget windows marked as - // RasterGLSurface instead of just Raster. These go through - // compositeAndFlush() instead of this function. + // Called for ordinary raster windows. Q_UNUSED(region); Q_UNUSED(offset); QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + Q_ASSERT(dstCtx); + QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; @@ -184,7 +199,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi QPlatformTextureList *textures, QOpenGLContext *context, bool translucentBackground) { - // QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top. + // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top. Q_UNUSED(region); Q_UNUSED(offset); @@ -193,6 +208,12 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow + + // The compositor's context and the context to which QOpenGLWidget/QQuickWidget + // textures belong are not the same. They share resources, though. + Q_ASSERT(context->shareGroup() == dstCtx->shareGroup()); + QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; @@ -254,6 +275,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta if (m_bsTexture) { glDeleteTextures(1, &m_bsTexture); m_bsTexture = 0; + m_bsTextureContext = Q_NULLPTR; } } diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 97dde16a2b..d2bb3c9cfd 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -51,7 +51,7 @@ QCocoaAccessibility::~QCocoaAccessibility() void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) { - if (!isActive() || !event->accessibleInterface()) + if (!isActive() || !event->accessibleInterface() || !event->accessibleInterface()->isValid()) return; QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()]; if (!element) { diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 608a7583c0..081bf927d9 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -120,7 +120,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (!element) { QAccessibleInterface *iface = QAccessible::accessibleInterface(anId); Q_ASSERT(iface); - if (!iface) + if (!iface || !iface->isValid()) return nil; element = [[self alloc] initWithId:anId]; cache->insertElement(anId, element); @@ -172,7 +172,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of static NSArray *defaultAttributes = nil; QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return defaultAttributes; if (defaultAttributes == nil) { @@ -226,7 +226,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)parentElement { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nil; if (QWindow *window = iface->window()) { @@ -259,7 +259,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)accessibilityAttributeValue:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -336,9 +336,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { - int line = -1; - int position = text->cursorPosition(); - convertLineOffset(text, &line, &position); + int line = 0; // true for all single line edits + if (iface->state().multiLine) { + int position = text->cursorPosition(); + convertLineOffset(text, &line, &position); + } return [NSNumber numberWithInt: line]; } return nil; @@ -354,7 +356,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSArray *)accessibilityParameterizedAttributeNames { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -379,7 +381,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) { + if (!iface || !iface->isValid()) { qWarning() << "Called attribute on invalid object: " << axid; return nil; } @@ -446,7 +448,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return NO; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { @@ -465,7 +467,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return; if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { if (QAccessibleActionInterface *action = iface->actionInterface()) @@ -494,7 +496,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSArray *)accessibilityActionNames { NSMutableArray * nsActions = [NSMutableArray new]; QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nsActions; const QStringList &supportedActionNames = QAccessibleBridgeUtils::effectiveActionNames(iface); @@ -509,7 +511,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSString *)accessibilityActionDescription:(NSString *)action { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - if (!iface) + if (!iface || !iface->isValid()) return nil; // FIXME is that the right return type?? QString qtAction = QCocoaAccessible::translateAction(action, iface); QString description; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 9dc013ba4d..4c1b190b9c 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -126,7 +126,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); if ([mSavePanel respondsToSelector:@selector(setLevel:)]) [mSavePanel setLevel:NSModalPanelWindowLevel]; - [mSavePanel setDelegate:self]; + mReturnCode = -1; mHelper = helper; mNameFilterDropDownList = new QStringList(mOptions->nameFilters()); @@ -147,7 +147,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); [self createTextField]; [self createAccessory]; [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil]; - + // -setAccessoryView: can result in -panel:directoryDidChange: + // resetting our mCurrentDir, set the delegate + // here to make sure it gets the correct value. + [mSavePanel setDelegate:self]; if (mOptions->isLabelExplicitlySet(QFileDialogOptions::Accept)) [mSavePanel setPrompt:[self strip:options->labelText(QFileDialogOptions::Accept)]]; diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 2086ce56e2..35b27cba0b 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -188,11 +188,8 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display(); - QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); + QPlatformOpenGLContext *share = context->shareHandle(); QVariant nativeHandle = context->nativeHandle(); QEglFSContext *ctx; diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 8301be8c17..84856831c3 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -138,6 +138,14 @@ void QEglFSWindow::create() if (!context->create()) qFatal("EGLFS: Failed to create compositing context"); compositor->setTarget(context, window()); + // If there is a "root" window into which raster and QOpenGLWidget content is + // composited, all other contexts must share with its context. + if (!qt_gl_global_share_context()) { + qt_gl_set_global_share_context(context); + // What we set up here is in effect equivalent to the application setting + // AA_ShareOpenGLContexts. Set the attribute to be fully consistent. + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + } } } diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index a6b1d0af26..af9d2a5969 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -155,7 +155,7 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) if (QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha) m_alphaNeedsFill = true; else // upgrade but here we know app painting does not rely on alpha hence no need to fill - format = qt_alphaVersionForPainting(format); + format = qt_maybeAlphaVersionWithSameDepth(format); QWindowsNativeImage *oldwni = m_image.data(); QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 71491595a4..a7de0e1783 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -759,12 +759,17 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph transform.m21 = matrix.m21(); transform.m22 = matrix.m22(); + DWRITE_RENDERING_MODE renderMode = + fontDef.hintingPreference == QFont::PreferNoHinting + ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC + : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL; + IDWriteGlyphRunAnalysis *glyphAnalysis = NULL; HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis( &glyphRun, 1.0f, &transform, - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, + renderMode, DWRITE_MEASURING_MODE_NATURAL, 0.0, 0.0, &glyphAnalysis diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index bc77df566e..882a7a6913 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -49,6 +49,7 @@ #include <QOffscreenSurface> #include <QOpenGLContext> #include <QtPlatformSupport/private/qeglconvenience_p.h> +#include <QtPlatformSupport/private/qeglpbuffer_p.h> QT_BEGIN_NAMESPACE @@ -148,14 +149,17 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface) Q_D(QWinRTEGLContext); Q_ASSERT(windowSurface->surface()->supportsOpenGL()); - if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen) - return false; + EGLSurface surface; + if (windowSurface->surface()->surfaceClass() == QSurface::Window) { + QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); + if (window->eglSurface() == EGL_NO_SURFACE) + window->createEglSurface(g->eglDisplay, d->eglConfig); - QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface); - if (window->eglSurface() == EGL_NO_SURFACE) - window->createEglSurface(g->eglDisplay, d->eglConfig); + surface = window->eglSurface(); + } else { // Offscreen + surface = static_cast<QEGLPbuffer *>(windowSurface)->pbuffer(); + } - EGLSurface surface = window->eglSurface(); if (surface == EGL_NO_SURFACE) return false; @@ -346,4 +350,9 @@ QFunctionPointer QWinRTEGLContext::getProcAddress(const QByteArray &procName) return eglGetProcAddress(procName.constData()); } +EGLDisplay QWinRTEGLContext::display() +{ + return g->eglDisplay; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index 31a2124b03..49b289cd79 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -38,6 +38,7 @@ #define QWINDOWSEGLCONTEXT_H #include <qpa/qplatformopenglcontext.h> +#include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -57,6 +58,7 @@ public: QSurfaceFormat format() const Q_DECL_OVERRIDE; QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; + static EGLDisplay display(); private: QScopedPointer<QWinRTEGLContextPrivate> d_ptr; Q_DECLARE_PRIVATE(QWinRTEGLContext) diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 2281bf56cc..9dac667ce5 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -45,12 +45,17 @@ #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" -#include <QtGui/QSurface> +#include <QtGui/QOffscreenSurface> #include <QtGui/QOpenGLContext> -#include <qfunctions_winrt.h> +#include <QtGui/QSurface> +#include <QtPlatformSupport/private/qeglpbuffer_p.h> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformwindow.h> #include <qpa/qplatformoffscreensurface.h> +#include <qfunctions_winrt.h> + #include <functional> #include <wrl.h> #include <windows.ui.xaml.h> @@ -385,11 +390,20 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *) QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { - // This is only used for shutdown of applications. - // In case we do not return an empty surface the scenegraph will try - // to create a new native window during application exit causing crashes - // or assertions. - return new QPlatformOffscreenSurface(surface); + QEGLPbuffer *pbuffer = nullptr; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([&pbuffer, surface]() { + pbuffer = new QEGLPbuffer(QWinRTEGLContext::display(), surface->requestedFormat(), surface); + return S_OK; + }); + if (hr == UI_E_WINDOW_CLOSED) { + // This is only used for shutdown of applications. + // In case we do not return an empty surface the scenegraph will try + // to create a new native window during application exit causing crashes + // or assertions. + return new QPlatformOffscreenSurface(surface); + } + + return pbuffer; } diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index bec94c1e51..034879c478 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -133,6 +133,15 @@ QWinRTWindow::QWinRTWindow(QWindow *window) hr = d->swapChainPanel.As(&d->uiElement); Q_ASSERT_SUCCEEDED(hr); + ComPtr<Xaml::IFrameworkElement> frameworkElement; + hr = d->swapChainPanel.As(&frameworkElement); + Q_ASSERT_SUCCEEDED(hr); + const QSizeF size = QSizeF(d->screen->geometry().size()) / d->screen->scaleFactor(); + hr = frameworkElement->put_Width(size.width()); + Q_ASSERT_SUCCEEDED(hr); + hr = frameworkElement->put_Height(size.height()); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<IDependencyObject> canvas = d->screen->canvas(); ComPtr<IPanel> panel; hr = canvas.As(&panel); diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index c34bea0242..3b04c59e28 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -179,7 +179,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; if (!m_hasAlpha) - format = qt_alphaVersionForPainting(format); + 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); diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index aa117ed7de..f80a72e2df 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); -Q_GUI_EXPORT bool qt_handleShortcutEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); +Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1); namespace QTest { @@ -93,7 +93,7 @@ namespace QTest if (action == Shortcut) { int timestamp = 0; - qt_handleShortcutEvent(window, timestamp, code, modifier, text, repeat); + qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat); return; } @@ -174,7 +174,7 @@ namespace QTest QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat); QSpontaneKeyEvent::setSpontaneous(&a); - if (press && qt_handleShortcutEvent(widget, a.timestamp(), code, modifier, text, repeat)) + if (press && qt_sendShortcutOverrideEvent(widget, a.timestamp(), code, modifier, text, repeat)) return; if (!qApp->notify(widget, &a)) QTest::qWarn("Keyboard event not accepted by receiving widget"); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 5e6563b0be..bfa1d69fa8 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1059,6 +1059,31 @@ static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra) return false; } +bool QWidgetBackingStore::syncAllowed() +{ +#ifndef QT_NO_OPENGL + QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData(); + if (textureListWatcher && !textureListWatcher->isLocked()) { + textureListWatcher->deleteLater(); + textureListWatcher = 0; + } else if (!tlwExtra->widgetTextures.isEmpty()) { + bool skipSync = false; + foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) { + if (tl->isLocked()) { + if (!textureListWatcher) + textureListWatcher = new QPlatformTextureListWatcher(this); + if (!textureListWatcher->isLocked()) + textureListWatcher->watch(tl); + skipSync = true; + } + } + if (skipSync) // cannot compose due to widget textures being in use + return false; + } +#endif + return true; +} + /*! Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store. @@ -1089,7 +1114,8 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg else markDirtyOnScreen(exposedRegion, exposedWidget, QPoint()); - doSync(); + if (syncAllowed()) + doSync(); } /*! @@ -1115,27 +1141,8 @@ void QWidgetBackingStore::sync() return; } -#ifndef QT_NO_OPENGL - if (textureListWatcher && !textureListWatcher->isLocked()) { - textureListWatcher->deleteLater(); - textureListWatcher = 0; - } else if (!tlwExtra->widgetTextures.isEmpty()) { - bool skipSync = false; - foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) { - if (tl->isLocked()) { - if (!textureListWatcher) - textureListWatcher = new QPlatformTextureListWatcher(this); - if (!textureListWatcher->isLocked()) - textureListWatcher->watch(tl); - skipSync = true; - } - } - if (skipSync) // cannot compose due to widget textures being in use - return; - } -#endif - - doSync(); + if (syncAllowed()) + doSync(); } void QWidgetBackingStore::doSync() diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index c45e60ef6e..564dc7f245 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -164,6 +164,8 @@ private: void updateLists(QWidget *widget); + bool syncAllowed(); + inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) { if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) { diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 6f8d97e028..0de0fe21f2 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -708,7 +708,6 @@ void QWidgetWindow::handleCloseEvent(QCloseEvent *event) { bool is_closing = m_widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); event->setAccepted(is_closing); - QWindow::event(event); // Call QWindow QCloseEvent handler. } #ifndef QT_NO_WHEELEVENT diff --git a/tests/auto/gui/image/qimagereader/images/corrupt_clut.bmp b/tests/auto/gui/image/qimagereader/images/corrupt_clut.bmp Binary files differnew file mode 100644 index 0000000000..aeb063fce5 --- /dev/null +++ b/tests/auto/gui/image/qimagereader/images/corrupt_clut.bmp diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 86dd8c4daf..ff15dc5b6d 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -1482,6 +1482,7 @@ void tst_QImageReader::readCorruptImage_data() QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("") << QByteArray("gif"); QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("") << QByteArray("png"); QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("") << QByteArray("bmp"); + QTest::newRow("corrupt bmp (clut)") << QString("corrupt_clut.bmp") << true << QString("") << QByteArray("bmp"); QTest::newRow("corrupt xpm (colors)") << QString("corrupt-colors.xpm") << true << QString("QImage: XPM color specification is missing: bla9an.n#x") << QByteArray("xpm"); diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index 5506c96221..78cb06986f 100644 --- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp +++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp @@ -70,6 +70,7 @@ private slots: void setRawDataAndGetAsVector(); void boundingRect(); void mixedScripts(); + void multiLineBoundingRect(); private: int m_testFontId; @@ -735,6 +736,34 @@ void tst_QGlyphRun::mixedScripts() QCOMPARE(glyphRuns.size(), 2); } +void tst_QGlyphRun::multiLineBoundingRect() +{ + QTextLayout layout; + layout.setText("Foo Bar"); + layout.beginLayout(); + + QTextLine line = layout.createLine(); + line.setNumColumns(4); + line.setPosition(QPointF(0, 0)); + + line = layout.createLine(); + line.setPosition(QPointF(0, 10)); + + layout.endLayout(); + + QCOMPARE(layout.lineCount(), 2); + + QList<QGlyphRun> firstLineGlyphRuns = layout.lineAt(0).glyphRuns(); + QList<QGlyphRun> allGlyphRuns = layout.glyphRuns(); + QCOMPARE(firstLineGlyphRuns.size(), 1); + QCOMPARE(allGlyphRuns.size(), 1); + + QGlyphRun firstLineGlyphRun = firstLineGlyphRuns.first(); + QGlyphRun allGlyphRun = allGlyphRuns.first(); + + QVERIFY(firstLineGlyphRun.boundingRect().height() < allGlyphRun.boundingRect().height()); +} + #endif // QT_NO_RAWFONT QTEST_MAIN(tst_QGlyphRun) diff --git a/tests/manual/qopenglwidget/openglwidget/main.cpp b/tests/manual/qopenglwidget/openglwidget/main.cpp index a56cea1dfe..3844ca3d0f 100644 --- a/tests/manual/qopenglwidget/openglwidget/main.cpp +++ b/tests/manual/qopenglwidget/openglwidget/main.cpp @@ -181,6 +181,13 @@ int main(int argc, char *argv[]) glw3->setObjectName("GL widget in scroll area (possibly native)"); glw3->setFormat(format); glw3->setFixedSize(600, 600); + OpenGLWidget *glw3child = new OpenGLWidget(0); + const float glw3ClearColor[] = { 0.5f, 0.2f, 0.8f }; + glw3child->setClearColor(glw3ClearColor); + glw3child->setObjectName("Child widget of GL Widget in scroll area"); + glw3child->setFormat(format); + glw3child->setParent(glw3); + glw3child->setGeometry(500, 500, 100, 100); // lower right corner of parent QScrollArea *sa = new QScrollArea; sa->setWidget(glw3); sa->setMinimumSize(100, 100); diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp index 4d2463b84d..95e2b31405 100644 --- a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp +++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp @@ -78,6 +78,8 @@ public: int m_interval; QVector3D m_rotAxis; + + float clearColor[3]; }; @@ -85,6 +87,7 @@ OpenGLWidget::OpenGLWidget(int interval, const QVector3D &rotAxis, QWidget *pare : QOpenGLWidget(parent) { d.reset(new OpenGLWidgetPrivate(this)); + d->clearColor[0] = d->clearColor[1] = d->clearColor[2] = 0.0f; d->m_interval = interval; d->m_rotAxis = rotAxis; if (interval > 0) { @@ -151,7 +154,7 @@ void OpenGLWidgetPrivate::render() const qreal retinaScale = q->devicePixelRatio(); glViewport(0, 0, width() * retinaScale, height() * retinaScale); - glClearColor(0.0, 0.0, 0.0, 1.0); + glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f); glClear(GL_COLOR_BUFFER_BIT); m_program->bind(); @@ -194,3 +197,10 @@ void OpenGLWidgetPrivate::render() if (m_interval <= 0) q->update(); } + +void OpenGLWidget::setClearColor(const float *c) +{ + d->clearColor[0] = c[0]; + d->clearColor[1] = c[1]; + d->clearColor[2] = c[2]; +} diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.h b/tests/manual/qopenglwidget/openglwidget/openglwidget.h index a1d5490845..1b9a66d877 100644 --- a/tests/manual/qopenglwidget/openglwidget/openglwidget.h +++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.h @@ -49,6 +49,8 @@ public: void resizeGL(int w, int h); void paintGL(); + void setClearColor(const float *c); + private: QScopedPointer<OpenGLWidgetPrivate> d; }; |