From bbcdccd6768f999a49717dfc78efd4bb9d880412 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 21:18:27 +0200 Subject: [PATCH 01/20] deprecate import_qpa_plugin and qpa_minimal_plugin they have been fully superseded by 4255ba40ab073afcf2a095b135883612859af4c2. Change-Id: If7ac14c8b7d3cf00fb0cb916036b62eb86c9cee0 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt.prf | 14 ++++++++------ src/gui/gui.pro | 3 +-- src/plugins/platforms/cocoa/cocoa.pro | 1 + src/plugins/platforms/direct2d/direct2d.pro | 1 + src/plugins/platforms/directfb/directfb.pro | 1 + src/plugins/platforms/eglfs/eglfs.pro | 1 + src/plugins/platforms/ios/ios.pro | 1 + src/plugins/platforms/kms/kms.pro | 1 + src/plugins/platforms/linuxfb/linuxfb.pro | 1 + src/plugins/platforms/minimal/minimal.pro | 1 + src/plugins/platforms/minimalegl/minimalegl.pro | 1 + src/plugins/platforms/offscreen/offscreen.pro | 1 + src/plugins/platforms/openwfd/openwf.pro | 1 + src/plugins/platforms/qnx/qnx.pro | 1 + src/plugins/platforms/windows/windows.pro | 1 + src/plugins/platforms/winrt/winrt.pro | 1 + src/plugins/platforms/xcb/xcb-plugin.pro | 1 + 17 files changed, 24 insertions(+), 8 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 418b124a85a..54423017ee4 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -163,6 +163,14 @@ contains(qt_module_deps, qml): \ } } +!import_qpa_plugin { + warning("CONFIG-=import_qpa_plugin is deprecated. Use QTPLUGIN.platforms=- instead.") + QTPLUGIN.platforms = - +} else: qpa_minimal_plugin { + warning("CONFIG+=qpa_minimal_plugin is deprecated. Use QTPLUGIN.platforms=qminimal instead.") + QTPLUGIN.platforms = qminimal +} + contains(TEMPLATE, .*app) { autoplugs = for (qtmod, qt_module_deps) { @@ -198,12 +206,6 @@ QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN contains(QT_CONFIG, static) { QT_PLUGIN_VERIFY += QTPLUGIN force_import_plugins|contains(TEMPLATE, .*app) { - needs_qpa_plugin:import_qpa_plugin { - qpa_minimal_plugin: \ - QTPLUGIN += qminimal - else: \ - QTPLUGIN += $$QT_DEFAULT_QPA_PLUGIN - } import_plugins:!isEmpty(QTPLUGIN) { IMPORT_FILE_CONT = \ "// This file is autogenerated by qmake. It imports static plugin classes for" \ diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 6af692984af..af84eb7342d 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -1,8 +1,7 @@ TARGET = QtGui QT = core-private -MODULE_CONFIG = needs_qpa_plugin -contains(QT_CONFIG, opengl.*):MODULE_CONFIG += opengl +contains(QT_CONFIG, opengl.*): MODULE_CONFIG = opengl DEFINES += QT_NO_USING_NAMESPACE diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index a60f4adc28a..1f9c0e051d7 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -2,6 +2,7 @@ TARGET = qcocoa PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) OBJECTIVE_SOURCES += main.mm \ diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 4f986b57d70..439d31fb56f 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -2,6 +2,7 @@ TARGET = qdirect2d PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT *= core-private diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index ec4a612b525..89d8d42ceae 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -2,6 +2,7 @@ TARGET = qdirectfb PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QDirectFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 8827f7680ce..3ebe05b35ef 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -2,6 +2,7 @@ TARGET = qeglfs PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) SOURCES += $$PWD/main.cpp diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index b7e074b95a2..ffc4ff9b125 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -2,6 +2,7 @@ TARGET = qios PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QIOSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro index 1b3678f13ab..baa87781536 100644 --- a/src/plugins/platforms/kms/kms.pro +++ b/src/plugins/platforms/kms/kms.pro @@ -2,6 +2,7 @@ TARGET = qkms PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QKmsIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro index 9e9f9b29b7d..389d45c29c4 100644 --- a/src/plugins/platforms/linuxfb/linuxfb.pro +++ b/src/plugins/platforms/linuxfb/linuxfb.pro @@ -2,6 +2,7 @@ TARGET = qlinuxfb PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QLinuxFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 3131b162320..3ed4d2cdde1 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -2,6 +2,7 @@ TARGET = qminimal PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro index 00c83eb1caf..e78dcb8bc50 100644 --- a/src/plugins/platforms/minimalegl/minimalegl.pro +++ b/src/plugins/platforms/minimalegl/minimalegl.pro @@ -2,6 +2,7 @@ TARGET = qminimalegl PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalEglIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index 5db5e32e65c..94eeac6accb 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -2,6 +2,7 @@ TARGET = qoffscreen PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QOffscreenIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro index 2dbcb282db7..38bac057bd4 100644 --- a/src/plugins/platforms/openwfd/openwf.pro +++ b/src/plugins/platforms/openwfd/openwf.pro @@ -2,6 +2,7 @@ TARGET = qopenwf PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QOpenWFDIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 04c6087cd11..856b7d2abea 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -161,4 +161,5 @@ include (../../../platformsupport/fontdatabases/fontdatabases.pri) PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QQnxIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 188bd7917c3..cc0373c0770 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -2,6 +2,7 @@ TARGET = qwindows PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWindowsIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT *= core-private diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 60c87bb61a3..0122bf94753 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -12,6 +12,7 @@ winphone { PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index 9e4e997f559..a52aaa4a2ef 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -2,6 +2,7 @@ TARGET = qxcb PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QXcbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private From cae970c68663c320bcce86160d44d857bfc68fd0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 21:19:07 +0200 Subject: [PATCH 02/20] doc fixes Change-Id: I77da456b89accd7fc363471fe8e370da17e2fdcc Reviewed-by: Leena Miettinen Reviewed-by: Joerg Bornemann --- src/corelib/doc/src/plugins-howto.qdoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc index 7565d610ccd..7fc4682fd48 100644 --- a/src/corelib/doc/src/plugins-howto.qdoc +++ b/src/corelib/doc/src/plugins-howto.qdoc @@ -234,7 +234,7 @@ application is to compile it into a dynamic library that is shipped separately, and detected and loaded at runtime. - Plugins can be linked statically against your application. If you + Plugins can be linked statically into your application. If you build the static version of Qt, this is the only option for including Qt's predefined plugins. Using static plugins makes the deployment less error-prone, but has the disadvantage that no @@ -253,7 +253,8 @@ \row \li \c qico \li Image formats \li ICO \row \li \c qsvg \li Image formats \li SVG \row \li \c qtiff \li Image formats \li TIFF - \row \li \c qsqldb2 \li SQL driver \li IBM DB2 \row \li \c qsqlibase \li SQL driver \li Borland InterBase + \row \li \c qsqldb2 \li SQL driver \li IBM DB2 + \row \li \c qsqlibase \li SQL driver \li Borland InterBase \row \li \c qsqlite \li SQL driver \li SQLite version 3 \row \li \c qsqlite2 \li SQL driver \li SQLite version 2 \row \li \c qsqlmysql \li SQL driver \li MySQL @@ -263,7 +264,7 @@ \row \li \c qsqltds \li SQL driver \li Sybase Adaptive Server (TDS) \endtable - To link statically against those plugins, you need to add + To link those plugins statically, you need to add the required plugins to your build using \c QTPLUGIN. Q_IMPORT_PLUGIN() macros are also needed in application code, but those are automatically generated by qmake and added to From f56ef579ba5b1d3adda060fa9c0707e37f9f1baa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Apr 2014 11:18:17 -0700 Subject: [PATCH 03/20] Restore handling of BOMs in QString::fromUtf8 8dd47e34b9b96ac27a99cdcf10b8aec506882fc2 removed the handling of the BOMs but did not document it. This brings the behavior back and adds a unit test so we don't break it again. Discussed-on: http://lists.qt-project.org/pipermail/development/2014-April/016532.html Change-Id: Ifb7a9a6e5a494622f46b8ab435e1d168b862d952 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- src/corelib/codecs/qutfcodec.cpp | 44 ++++++++++++------- .../corelib/tools/qstring/tst_qstring.cpp | 8 ++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 54312601e4e..072cda63aa5 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE enum { Endian = 0, Data = 1 }; +static const uchar utf8bom[] = { 0xef, 0xbb, 0xbf }; + #if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2) static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const ushort *&src, const ushort *end) { @@ -187,9 +189,9 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve int invalid = 0; if (state && !(state->flags & QTextCodec::IgnoreHeader)) { // append UTF-8 BOM - *cursor++ = 0xef; - *cursor++ = 0xbb; - *cursor++ = 0xbf; + *cursor++ = utf8bom[0]; + *cursor++ = utf8bom[1]; + *cursor++ = utf8bom[2]; } const ushort *nextAscii = src; @@ -240,19 +242,31 @@ QString QUtf8::convertToUnicode(const char *chars, int len) const uchar *src = reinterpret_cast(chars); const uchar *end = src + len; - while (src < end) { - const uchar *nextAscii = end; - if (simdDecodeAscii(dst, nextAscii, src, end)) - break; + // attempt to do a full decoding in SIMD + const uchar *nextAscii = end; + if (!simdDecodeAscii(dst, nextAscii, src, end)) { + // at least one non-ASCII entry + // check if we failed to decode the UTF-8 BOM; if so, skip it + if (Q_UNLIKELY(src == reinterpret_cast(chars)) + && end - src >= 3 + && Q_UNLIKELY(src[0] == utf8bom[0] && src[1] == utf8bom[1] && src[2] == utf8bom[2])) { + src += 3; + } - do { - uchar b = *src++; - int res = QUtf8Functions::fromUtf8(b, dst, src, end); - if (res < 0) { - // decoding error - *dst++ = QChar::ReplacementCharacter; - } - } while (src < nextAscii); + while (src < end) { + nextAscii = end; + if (simdDecodeAscii(dst, nextAscii, src, end)) + break; + + do { + uchar b = *src++; + int res = QUtf8Functions::fromUtf8(b, dst, src, end); + if (res < 0) { + // decoding error + *dst++ = QChar::ReplacementCharacter; + } + } while (src < nextAscii); + } } result.truncate(dst - reinterpret_cast(result.constData())); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index d9d6b985b72..95d377b1765 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -3619,6 +3619,14 @@ void tst_QString::fromUtf8_data() str += " some "; QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9; + // test that QString::fromUtf8 suppresses an initial BOM, but not a ZWNBSP + str = "hello"; + QByteArray bom("\357\273\277"); + QTest::newRow("bom0") << bom << QString() << 3; + QTest::newRow("bom1") << bom + "hello" << str << -1; + QTest::newRow("bom+zwnbsp0") << bom + bom << QString(QChar(0xfeff)) << -1; + QTest::newRow("bom+zwnbsp1") << bom + "hello" + bom << str + QChar(0xfeff) << -1; + str = "hello"; str += QChar::ReplacementCharacter; str += QChar(0x68); From bbf37b61d00a6470349b728a4e6982a359e0931c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 4 Apr 2014 10:34:15 -0700 Subject: [PATCH 04/20] Document QString's UTF-8 conversion behaviors We haven't handled the Unicode non-characters specially since Qt 5.2 (since commit 9327bc87c3abf58bb471693b5448cd78e3db1b46), so this part of the documentation was stale. Since Qt 5.3 (since 8dd47e34b9b96ac27a99cdcf10b8aec506882fc2), QString will insert one replacement character for each byte that can't be decoded properly. [ChangeLog][Important Behavior Changes][UTF-8 decoding] The QString UTF-8 decoder changed behavior slightly: when it encounters invalid sequences, it will insert one replacement character per byte that is invalid, instead of one replacement character for the whole invalid length. Change-Id: Ia4ec78afded9445bbe937311d6be80f71bd1a55f Reviewed-by: Richard J. Moore Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- src/corelib/tools/qstring.cpp | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 79365b11b1b..aac9c493c35 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4331,14 +4331,6 @@ QByteArray QString::toLocal8Bit_helper(const QChar *data, int size) UTF-8 is a Unicode codec and can represent all characters in a Unicode string like QString. - However, in the Unicode range, there are certain codepoints that are not - considered characters. The Unicode standard reserves the last two - codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, - U+2FFFE, etc.), as well as 32 codepoints in the range U+FDD0..U+FDEF, - inclusive, as non-characters. If any of those appear in the string, they - may be discarded and will not appear in the UTF-8 representation, or they - may be replaced by one or more replacement characters. - \sa fromUtf8(), toLatin1(), toLocal8Bit(), QTextCodec */ @@ -4493,10 +4485,10 @@ QString QString::fromLocal8Bit_helper(const char *str, int size) sequences, non-characters, overlong sequences or surrogate codepoints encoded into UTF-8. - Non-characters are codepoints that the Unicode standard reserves and must - not be used in text interchange. They are the last two codepoints in each - Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, etc.), as well - as 32 codepoints in the range U+FDD0..U+FDEF, inclusive. + This function can be used to process incoming data incrementally as long as + all UTF-8 characters are terminated within the incoming data. Any + unterminated characters at the end of the string will be replaced or + suppressed. In order to do stateful decoding, please use \l QTextDecoder. \sa toUtf8(), fromLatin1(), fromLocal8Bit() */ @@ -9517,14 +9509,6 @@ QByteArray QStringRef::toLocal8Bit() const UTF-8 is a Unicode codec and can represent all characters in a Unicode string like QString. - However, in the Unicode range, there are certain codepoints that are not - considered characters. The Unicode standard reserves the last two - codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, - U+2FFFE, etc.), as well as 16 codepoints in the range U+FDD0..U+FDDF, - inclusive, as non-characters. If any of those appear in the string, they - may be discarded and will not appear in the UTF-8 representation, or they - may be replaced by one or more replacement characters. - \sa toLatin1(), toLocal8Bit(), QTextCodec */ QByteArray QStringRef::toUtf8() const From 2b88e9973b4c0a49be184b092481288180840372 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Apr 2014 16:09:16 -0700 Subject: [PATCH 05/20] Update the changelog for 5.3.0 Change-Id: Ic678258dc37d271daa4ee6a871907ca15db2ffde Reviewed-by: Lars Knoll --- dist/changes-5.3.0 | 465 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 459 insertions(+), 6 deletions(-) diff --git a/dist/changes-5.3.0 b/dist/changes-5.3.0 index cb2c3608f05..ae837fc023e 100644 --- a/dist/changes-5.3.0 +++ b/dist/changes-5.3.0 @@ -15,6 +15,50 @@ corresponding to tasks in the Qt Bug Tracker: Each of these identifiers can be entered in the bug tracker to obtain more information about a particular change. +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - SIMD support in CPUs: + * [QTBUG-30440] Qt no longer checks for support for the Neon FPU on + ARM platforms at runtime. Code optimized for Neon must be enabled + unconditionally at compile time by ensuring the compiler supports + Neon. You may need to edit your mkspec for that. + + * Qt now automatically generates code for processors supporting SSE2 + on i386 platforms. To disable this, pass the -no-sse2 option during + Qt configuration. Since this feature has been present on CPUs for + 10 years and since Qt no longer checks for runtime support for + SSE2, we strongly encourage users to leave the default setting on + for best performance. + - For Linux distributions that must retain support for CPUs without + SSE2, we recommend doing two builds of Qt and installing the + SSE2-enabled libraries in the LIBDIR/sse2 directory (specially + QtGui, QtQml and QtQuick libraries). Tools, plugins, and examples + are not affected. + - See discussion on the Qt development mailing list: + http://lists.qt-project.org/pipermail/development/2013-November/014085.html + + - SSL and security: + * The default set of ciphers used by QSslSocket has been changed to + exclude ciphers that are using key lengths smaller than 128 + bits. These ciphers are still available and can be enabled by + applications if required. + * [QTBUG-20666] Support for DH and ECDH key exchange cipher suites + when acting as an SSL server has been made possible. This change + means the you can now implement servers that offer forward-secrecy + using Qt. + * Running Qt applications that are setuid is no longer allowed by + default. If you really need to do this then you can call + QCoreApplication::setSetuidAllowed(true) before creating the + QCoreApplication instance. + + - UTF-8 decoding: + * The QString and QTextCodec UTF-8 decoder changed behavior slightly: + when it encounters invalid sequences, it will insert one + replacement character per byte that is invalid, instead of one + replacement character for the whole invalid length. + **************************************************************************** * Platform deprecation notice * **************************************************************************** @@ -24,17 +68,125 @@ information about a particular change. not tested, and most likely has issues that are not fully documented. **************************************************************************** -* Library * +* General * **************************************************************************** -QtWidgets ---------- + - Support for the following platforms has been removed, due to lack of + interest in updating support: INTEGRITY, VxWorks, Solaris on UltraSPARC + (with the Sun Studio compiler suite), AIX on POWER processors (with IBM + Visual Age compiler suite). + - Builtin command-line options such as -reverse, -session, -style + -etc. now all support double dash, e.g. --reverse, --session, + --style... + +**************************************************************************** +* Library * +**************************************************************************** QtCore ------ - Added QSignalBlocker, a RAII-style wrapper around QObject::blockSignals(). + - QLibraryInfo provides information on how Qt was built. + - Added class QMarginsF to support handling margins with floating-point + values. + + - Atomic support: + * Added more operations to the atomic classes, including operator T(), + operator=(T), operator++, operator--. For the QAtomicInteger, + bit-manipulation operations are also provided, both in operator and in + fetchAndXxxYyyyyy modes. + + - Event loop: + * [QTBUG-36611] QCoreApplication::hasPendingEvents and + QAbstractEventDispatcher::hasPendingEvents are now deprecated. Please + refer to the documentation for more information. + + - Logging: + * It is now possible for the qCDebug macros to be used in a printf + style. + * All qCDebug categories are enabled by default, except for Qt's own + categories. + * The logging framework can now be configured with an .ini file. + * Q_LOGGING_CATEGORY and Q_DECLARE_LOGGING_CATEGORY now return a const + object. + + - QByteArray: + * Added NSData/CDataRef converters for QByteArray. + + - QChar: + * Added JoiningType enum and joiningType() method that deprecates the + old QChar::Joining enum and joining() method. + + - QFileSelector: + * [QTBUG-35073] The identifier for OS X has been changed back to + 'osx' from 'mac', and 'mac' and 'darwin' have now been added as + selectors for Darwin OS (which is the base of both OS X and iOS). + + - QHash/QSet: + * Added qHash overloads for float, double and long double. + + - QJsonArray: + * Added convenience methods to QJsonArray for appending QJsonValues + + - QJsonValue: + * Added constructor to QJsonValue for const char * + * QJsonValue::fromVariant() will now convert single-precision Floats + into Doubles instead of Strings + + - QMargins: + * Added missing addition and subtraction operators. + + - QProcess: + * [QTBUG-26136] Added processId() to QProcess. This function will, + unlike pid(), return the actual process identifier on both Windows + and Unix. + + - QRect: + * Added QMargins subtraction operator. + + - QSettings: + * [QTBUG-9824][QTBUG-21062][QTBUG-22745] QSettings now returns the + correct value for isWritable() when using SystemScope settings. + + - QSortFilterProxyModel: + * [QTBUG-30662] Fixed sorting when a previously empty proxy model + becomes populated because of a change in the filter. + + - QStandardPaths: + * [QTBUG-34631] Added QStandardPaths implementation for Android. + + - QString: + * Added QLatin1String overload of contains() + * QString::toUcs4 now does not return invalid UCS-4 code units belonging + to the surrogate range (U+D800 to U+DFFF) when the QString contains + malformed UTF-16 data. Instead, U+FFFD is returned in place of the + malformed subsequence. + + - QTextCodec: + * Encoding a QString in UTF-32 will now replace malformed UTF-16 + subsequences in the string with the Unicode replacement character + (U+FFFD). + + - QVarLengthArray: + * Added the indexOf, lastIndexOf and contains functions to + QVarLengthArray. These functions make the class more similar to + QVector. + + - Windows: + * [QTBUG-35194] Now QStandardPaths::DownloadLocation returns the proper + path for Windows Vista and up + +QtDBus +------ + + - QtDBus adaptors now include the PropertiesChanged signal in + introspection data + + - QDBusServer: + * Added method to QDBusServer to allow anonymous client connections, + even if the connecting client is not authenticated as a user. QtGui ----- @@ -42,12 +194,313 @@ QtGui - Added setSwapInterval() to QSurfaceFormat. Platforms that support setting the swap interval are now defaulting to the value of 1, meaning vsync is enabled. + - [QTBUG-35220] Reading bmp images with alpha channel is now supported + - [QTBUG-36394] The main Embedded Linux platform plugins (eglfs, linuxfb, + kms) are changed to behave identically with regards to terminal keyboard + input: it is turned off by default on all of these platforms. If this + feature is not desired, it can be disabled by setting the environment + variable QT_QPA_ENABLE_TERMINAL_KEYBOARD. + - [QTBUG-36374] Mouse hotplugging is now fully supported in eglfs when + running on Embedded Linux systems with libudev support enabled. + - [QTBUG-36603] Windows Accessibility now handles the disabled state of + widgets correctly. + - Accessibility on Linux now reports the active state correctly. + - [QTBUG-36483] Qt builds on Windows can now be configured for dynamic + loading of the OpenGL implementation. This can be requested by passing + -opengl dynamic to configure. In this mode no modules will link to + opengl32.dll or Angle's libegl/libglesv2. Instead, QtGui will + dynamically choose between desktop and Angle during the first GL/EGL/WGL + call. This allows deploying applications with a single set of Qt + libraries with the ability of transparently falling back to Angle in + case the opengl32.dll is not suitable, due to missing graphics drivers + for example. + - Added class QPageLayout to support handling page layouts including the + page size, orientation and margins. + - [QTBUG-28813][QTBUG-29930][QTBUG-35836] Fixed regression in + arabic text rendering. + - [QTBUG-37332] GLES3 and desktop OpenGL are now fully supported with + EGL + - [QTBUG-36993] Native (that is, not distance field based) text + rendering is now functional on OpenGL 3.2+ core profiles too. + + - Accessibility: + * [QTBUG-37204] Implemented text attributes to enable VoiceOver to read + QTextEdit and QPlainTextEdit. + * Assistive apps such as VoiceOver can now set the focus on widgets + and controls. + + - QColor: + * Exported highly optimized methods for premultiply and unpremultiply of + QRgb values. + + - QFont: + * Added qHash overload for this class. + + - QGuiApplication: + * Restored support for -title command line argument on X11 and added + -qwindowtitle on all platforms. + + - QImage: + * Added rvalue-qualified overloads for mirrored(), rgbSwapped() and + convertToFormat(), allowing in-place conversion in some cases + + - QOpenGLFramebufferObject: + * [QTBUG-35881] Added takeTexture() for retrieving and detaching the + texture from the framebuffer object. + + - QPageSize: + * Added new QPageSize class to implement Adobe Postscript PPD standard + page sizes. This class supports the standard page sizes, names and + keys from the PPD standard, and provides convenient size and rect + conversion methods. + + - QPagedPaintDevice: + * [QTBUG-27685][QTBUG-25744] Paged paint devices such as QPrinter and + QPdfWriter now support all Postscript standard page sizes. + + - QPdfWriter: + * The QPdfWriter now supports setting the PDF orientation, layout and + resolution by using QPageSize and QPageLayout. + + - QTextLayout: + * [QTBUG-18060] Fixed visual cursor movement in bidirectional text. + + - QWindow: + * QWindow::icon() now defaults to the application icon, which can be set + with QGuiApplication::setWindowIcon(). + +QtNetwork +--------- + + - [QTBUG-18714] Added support for the SPDY protocol (version 3.0). + + - QNetworkReply: + * [QTBUG-30880] Added more (specific) HTTP status codes to NetworkError + enum. + + - QSslConfiguration: + * [QTBUG-33208] Added support for the Next Protocol Negotiation (NPN) + TLS extension. + +QtPrintSupport +-------------- + + - [QTBUG-29663] Made the Qt buildsystem automatically include the + necessary plugins so that static applications can print. + - CUPS 1.4 is now required for print support on Linux and other *nix + platforms. + + - QPrintPreviewDialog: + * [QTBUG-36561] Fixed initialization of QPrintPreviewDialog's image + resources for static builds. + + - QPrinter: + * QPrinter can now use QPageSize and QPageLayout in the public api to + control the page layout for a print job. + + - QPrinterInfo: + * [QTBUG-35248] Added new public api for isRemote(), state(), + defaultPageSize(), supportedPageSizes(), supportsCustomPageSizes(), + minimumPhysicalPageSize(), maximumPhysicalPageSize(), + supportedResolutions(), availablePrinterNames(), and + defaultPrinterName(). The use of availablePrinters() is discouraged + due to performance concerns. QtSql ----- - QSqlQuery::isNull(field) now correctly returns true for "no such field". - QSqlQuery::isNull(fieldname) is a new overload. - - QSQLITE: Empty database name now opens in-memory database. - - QSqlError: Now handles alphanumeric error codes. Used by QPSQL. - Old numeric code is deprecated. + - [QTBUG-12186] Fixed the order of values with positional binding in a + QSqlQuery + + - QSQLITE: + * Creating temporary databases is now possible + * Empty database name now opens in-memory database. + + - QSqlError + * Now handles alphanumeric error codes. Used by QPSQL. Old numeric + code is deprecated. + +QtTest +------ + + - Added test duration to xml output. When running tests with xml output a + new tag of the form + is added to each test function and the test as a + whole. + - Added a CSV logging mode that is suitable for importing benchmark + results into spreadsheets. This can be enabled by the -csv option on the + command-line. The CSV logging mode will not print test failures, debug + messages, warnings, etc. + - QtTest now prints an escaped version of QStrings that failed to compare + with QCOMPARE. That is, instead of converting non-printable characters + to question marks, QtTest will print the Unicode representation of the + character in question. + + - Windows: + * [QTBUG-35743] Use correct UTF-8 encoding for XML test results on + platforms with different console encoding. + +QtWidgets +--------- + + - Accessibility: + * Fixed QTextEdit not reporting newlines to accessibility frameworks and + add editable text interface. + + - QAbstractSpinBox: + * [QTBUG-5142] QSpinBox and QDoubleSpinBox widgets can now show the + group (thousands) separators. + + - QColorDialog: + * Ensured QColorDialog::DontUseNativeDialog is respected when showing + the dialog. + + - QDateEdit: + * [QTBUG-36692] Fixed incorrect appearance on OS X of QDateEdit with + calendarPopup enabled. + + - QDrag + * Fixed Drag and Drop driven by touch-synthesized mouse events on + Windows. + + - QListView: + * [QTBUG-4714] Fixed QListView ignoring the grid size for word + wrapping in icon mode + + - QMdiSubWindow: + * [QTBUG-9933][QTBUG-27274] Fixed setWindowFlags() for QMdiSubWindow. + + - QMenu: + * [QTBUG-20094] Enabled sloppy submenu mouse navigation. + * [QTBUG-36142] QMenu now correctly uses text color set by style + sheet for menu items on Windows. + * [QTBUG-36218] Fixed position of menu gutter on Windows when using a + custom widget action. + + - QPlainTextEdit: + * Added find method overload using QRegExp + + - QSpinBox: + * [QTBUG-3032] Fixed keyboard selection with multiple-character strings. + + - QScrollArea: + * [QTBUG-36314] The setting for click position is now respected on OS X. + + - QTextDocument: + * [QTBUG-33336] Added support for empty inline elements in block tags. + + - QTextEdit: + * Added find method overload using QRegExp + + - QWidget: + * [QTBUG-25831] Restored the Qt 4 behavior in the sequence of events + that are delivered to widget windows and their children when a + mouse double click happens: the second MouseButtonPress event from + Qt 5.0-5.2 is no longer sent. + * [QTBUG-33716] QWidgets embedded in QGraphicsProxyWidget are no longer + sent close events when the app is closed on OS X. + * [QTBUG-36178] Fixed an issue where stay-on-top widgets would cover + their own children on OS X. + + - QWizard: + * [QTBUG-7484] Added NoCancelButtonOnLastPage option. + * [QTBUG-36192] Fixed frame when using Vista style/MSVC2012. + + - Text support: + * [QTBUG-36444] Fixed off-by-one in the height of text background. + + - Windows: + * [QTBUG-21371][QTBUG-4397] QWidget::restoreGeometry() now restores + maximized/full screen widgets to the correct screen. + +**************************************************************************** +* Compiler Specific Changes * +**************************************************************************** + + - Variadic macros are now enabled more liberally for gcc, clang, icc. If + you have warnings (because you e.g. compile with -pedantic), disable + them by -Wno-variadic-macros. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - [QTBUG-34781] Fixed regression in "make install" on library projects on + Android so they can be used inside subdirs projects again. + - [QTBUG-36074] Fixed crash on populating large combo boxes or menus. + - [QTBUG-36528] Fixed QDir::entryList() for assets scheme to no longer + skip the first file in the directory. + - [QTBUG-30652] It is now possible to define a splash screen which will be + visible until the first window is created. + - [QTBUG-33704] Sped up first time directory listing in assets by using + pregenerated entry list. + - [QTBUG-37738] Fixed font merging problem which caused e.g. missing + glyphs for Arabic numerals. + - [QTBUG-36025] Fixed a memory leak in the clipboard + + - Fonts: + * [QTBUG-36789] Fixed support for Arabic text. + +Linux +----- + + - Systems with systemd may now pass -journald to configure to send + logging output to journald. Logging will still be sent to stderr for + interactive applications (run from a tty) or with QT_NO_JOURNALD_LOG + set to a non-empty value. + +OS X +---- + + - [QTBUG-18980][QTBUG-38246] Use CoreText text shaping engine for + support of complex scripts. If required, the shaping engine used in + previous versions can be preferred by configuring Qt with + -no-harfbuzz. Alternatively, the QT_HARFBUZZ environment variable + could be set to "old". + +Windows +------- + + - Introduced experimental direct2d platform plugin for Windows. This + plugin shares most code with the current windows plugin, but + substitutes a direct2d-based paint engine for window backing stores + and pixmaps. + + - QtWidgets / QFileDialog: + * Handled the case of having trailing spaces in a filename correctly so + if the filename ends up being empty that the parent path is used + instead. + + - Windows Embedded: + * Fixed building issue when configuring Qt with -qtlibinfix + +X11 / XCB +--------- + + - Qt now supports XInput2 smooth scrolling events + +**************************************************************************** +* Tools * +**************************************************************************** + +moc +--- + + - [QTBUG-33668] Fixed passing -D of a macro defined to something more + complex than a single identifier. + + - QTBUG-36128: + * [QTBUG-36128] Fixed sign conversion warning in generated file. + +qdbus +----- + + - [QTBUG-36524] Fixed a bug that caused the qdbus tool to crash when + trying to display remote interfaces that had complex types without a + matching base Qt type. + From cafa3848e2315d851a338c9821fb4cb47db511be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 23 Apr 2014 14:29:03 +0200 Subject: [PATCH 06/20] QOpenGLFunctions: Compile on Mac OS 10.6 The 10.6 OpenGL headers have "GLenum" as the type for the 3rd argument. The OpenGL standard has "Glint", which is also what Qt expects. Work around this by casting the pointer type. Task-id: QTBUG-38406 Change-Id: I6d820f41e0d14cbc2d50d91997b6c40b626b159f Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglfunctions.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index af536fa9273..85b893e434a 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -3282,7 +3282,11 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) StencilFunc = ::glStencilFunc; StencilMask = ::glStencilMask; StencilOp = ::glStencilOp; - TexImage2D = ::glTexImage2D; +#if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + TexImage2D = reinterpret_cast(glTexImage2D); +#else + TexImage2D = glTexImage2D; +#endif TexParameterf = ::glTexParameterf; TexParameterfv = ::glTexParameterfv; TexParameteri = ::glTexParameteri; From e57b521d950575a96d54e6944ab153a9505e51f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 6 Mar 2014 13:01:20 -0800 Subject: [PATCH 07/20] Deprecate setSharable in Qt containers The ability to set a container to be unsharable has very little use and it costs us an extra conditional for every refcount up and possibly down. This change is a no-op for current Qt 5. It shuffles a few things around just so Qt can compile if you define QT_NO_UNSHARABLE_CONTAINERS. That is done to ease the fixing of the code in Qt 6 and to make my life easier: I'll keep that defined in my local Qt build so I can catch any misuses of this deprecated API. The newly deprecated methods are not marked QT_DEPRECATED because the bootstrapped tools wouldn't build -- they're built with QT_NO_DEPRECATED defined, which causes build errors. [ChangeLog][QtCore] The setSharable() and isSharable() functions in Qt containers has been deprecated and will be removed in Qt 6. New applications should not use this feature, while old applications that may be using this (undocumented) feature should port away from it. Discussed-on: http://lists.qt-project.org/pipermail/development/2014-February/015724.html Change-Id: I789771743dcaed6a43eccd99382f8b3ffa61e479 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/global/qglobal.h | 3 + src/corelib/tools/qarraydata.cpp | 13 +- src/corelib/tools/qarraydata.h | 4 + src/corelib/tools/qarraydatapointer.h | 4 + src/corelib/tools/qcontiguouscache.h | 2 + src/corelib/tools/qhash.h | 2 + src/corelib/tools/qlinkedlist.h | 2 + src/corelib/tools/qlist.h | 2 + src/corelib/tools/qmap.h | 2 + src/corelib/tools/qrefcount.h | 18 ++- src/corelib/tools/qset.h | 2 + src/corelib/tools/qvector.h | 14 +- .../corelib/tools/qarraydata/simplevector.h | 3 +- .../tools/qarraydata/tst_qarraydata.cpp | 44 ++++++- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 4 +- .../tools/qlinkedlist/tst_qlinkedlist.cpp | 6 +- tests/auto/corelib/tools/qlist/tst_qlist.cpp | 8 +- tests/auto/corelib/tools/qmap/tst_qmap.cpp | 8 +- .../corelib/tools/qvector/tst_qvector.cpp | 121 ++++++++++++------ 19 files changed, 199 insertions(+), 63 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index fba8b019e7b..391466448f5 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -58,7 +58,10 @@ #if !defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_CONFIGURE) #include #include +#endif #define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE)) +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +# define QT_NO_UNSHARABLE_CONTAINERS #endif /* These two macros makes it possible to turn the builtin line expander into a diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 825b3289c7b..12736d5c2e6 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -75,10 +75,13 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, && !(alignment & (alignment - 1))); // Don't allocate empty headers - if (!(options & RawData) && !capacity) - return !(options & Unsharable) - ? const_cast(&qt_array_empty) - : const_cast(&qt_array_unsharable_empty); + if (!(options & RawData) && !capacity) { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + if (options & Unsharable) + return const_cast(&qt_array_unsharable_empty); +#endif + return const_cast(&qt_array_empty); + } size_t headerSize = sizeof(QArrayData); @@ -118,8 +121,10 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize, && !(alignment & (alignment - 1))); Q_UNUSED(objectSize) Q_UNUSED(alignment) +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (data == &qt_array_unsharable_empty) return; +#endif Q_ASSERT_X(!data->ref.isStatic(), "QArrayData::deallocate", "Static data can not be deleted"); ::free(data); diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index ffb2b8765e3..10a9e355428 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -80,7 +80,9 @@ struct Q_CORE_EXPORT QArrayData enum AllocationOption { CapacityReserved = 0x1, +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Unsharable = 0x2, +#endif RawData = 0x4, Grow = 0x8, @@ -99,8 +101,10 @@ struct Q_CORE_EXPORT QArrayData AllocationOptions detachFlags() const { AllocationOptions result; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (!ref.isSharable()) result |= Unsharable; +#endif if (capacityReserved) result |= CapacityReserved; return result; diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 533f7a306f8..2245106ec0e 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -134,6 +134,7 @@ public: return (!d->isMutable() || d->ref.isShared()); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) void setSharable(bool sharable) { if (needsDetach()) { @@ -147,6 +148,9 @@ public: } } + bool isSharable() const { return d->isSharable(); } +#endif + void swap(QArrayDataPointer &other) { qSwap(d, other.d); diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index d601ddb8191..e05ef33aa2f 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -104,7 +104,9 @@ public: inline void detach() { if (d->ref.load() != 1) detach_helper(); } inline bool isDetached() const { return d->ref.load() == 1; } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } +#endif QContiguousCache &operator=(const QContiguousCache &other); #ifdef Q_COMPILER_RVALUE_REFS diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 40e501355cd..f68b02be2c5 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -330,7 +330,9 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; } +#endif inline bool isSharedWith(const QHash &other) const { return d == other.d; } void clear(); diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index bdacdbcd265..3377d1bbc30 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -106,7 +106,9 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper2(this->e); } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; } +#endif inline bool isSharedWith(const QLinkedList &other) const { return d == other.d; } inline bool isEmpty() const { return d->size == 0; } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 3a0d01aa8db..9e4ba70908a 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -146,6 +146,7 @@ public: } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -155,6 +156,7 @@ public: if (d != &QListData::shared_null) d->ref.setSharable(sharable); } +#endif inline bool isSharedWith(const QList &other) const { return d == other.d; } inline bool isEmpty() const { return p.isEmpty(); } diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 487039ccfba..76f8bd6f179 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -377,6 +377,7 @@ public: inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -386,6 +387,7 @@ public: // Don't call on shared_null d->ref.setSharable(sharable); } +#endif inline bool isSharedWith(const QMap &other) const { return d == other.d; } void clear(); diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h index 84314b1fcc6..3a8f0f3982e 100644 --- a/src/corelib/tools/qrefcount.h +++ b/src/corelib/tools/qrefcount.h @@ -55,8 +55,10 @@ class RefCount public: inline bool ref() Q_DECL_NOTHROW { int count = atomic.load(); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; +#endif if (count != -1) // !isStatic atomic.ref(); return true; @@ -64,13 +66,16 @@ public: inline bool deref() Q_DECL_NOTHROW { int count = atomic.load(); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; +#endif if (count == -1) // isStatic return true; return atomic.deref(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) bool setSharable(bool sharable) Q_DECL_NOTHROW { Q_ASSERT(!isShared()); @@ -80,17 +85,18 @@ public: return atomic.testAndSetRelaxed(1, 0); } - bool isStatic() const Q_DECL_NOTHROW - { - // Persistent object, never deleted - return atomic.load() == -1; - } - bool isSharable() const Q_DECL_NOTHROW { // Sharable === Shared ownership. return atomic.load() != 0; } +#endif + + bool isStatic() const Q_DECL_NOTHROW + { + // Persistent object, never deleted + return atomic.load() == -1; + } bool isShared() const Q_DECL_NOTHROW { diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index ad2f91b983b..0cc704b6cfc 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -91,7 +91,9 @@ public: inline void detach() { q_hash.detach(); } inline bool isDetached() const { return q_hash.isDetached(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { q_hash.setSharable(sharable); } +#endif inline void clear() { q_hash.clear(); } diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index b0be98c2966..6f7c534085d 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -107,6 +107,7 @@ public: inline void detach(); inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -122,6 +123,7 @@ public: } Q_ASSERT(d->ref.isSharable() == sharable); } +#endif inline bool isSharedWith(const QVector &other) const { return d == other.d; } @@ -329,10 +331,12 @@ template void QVector::detach() { if (!isDetached()) { - if (d->alloc) - reallocData(d->size, int(d->alloc)); - else +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + if (!d->alloc) d = Data::unsharableEmpty(); + else +#endif + reallocData(d->size, int(d->alloc)); } Q_ASSERT(isDetached()); } @@ -484,7 +488,9 @@ void QVector::reallocData(const int asize, const int aalloc, QArrayData::Allo x = Data::allocate(aalloc, options); Q_CHECK_PTR(x); // aalloc is bigger then 0 so it is not [un]sharedEmpty +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable)); +#endif Q_ASSERT(!x->ref.isStatic()); x->size = asize; @@ -550,7 +556,9 @@ void QVector::reallocData(const int asize, const int aalloc, QArrayData::Allo Q_ASSERT(d->data()); Q_ASSERT(uint(d->size) <= d->alloc); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(d != Data::unsharableEmpty()); +#endif Q_ASSERT(aalloc ? d != Data::sharedNull() : d == Data::sharedNull()); Q_ASSERT(d->alloc >= uint(aalloc)); Q_ASSERT(d->size == asize); diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 40917c0172b..af0ced130ce 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -101,9 +101,10 @@ public: bool isStatic() const { return d->ref.isStatic(); } bool isShared() const { return d->ref.isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) bool isSharable() const { return d->ref.isSharable(); } - void setSharable(bool sharable) { d.setSharable(sharable); } +#endif size_t size() const { return d->size; } size_t capacity() const { return d->alloc; } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 60b807a7bc1..35ec0ef0195 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -52,7 +52,9 @@ struct SharedNullVerifier { Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(QArrayData::shared_null[0].ref.isSharable()); +#endif } }; @@ -107,7 +109,9 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(!array.ref.isStatic()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); +#endif QVERIFY(array.ref.ref()); QCOMPARE(array.ref.atomic.load(), 2); @@ -127,6 +131,7 @@ void tst_QArrayData::referenceCounting() // Now would be a good time to free/release allocated data } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { // Reference counting initialized to 0 (non-sharable) QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 }; @@ -145,6 +150,7 @@ void tst_QArrayData::referenceCounting() // Free/release data } +#endif { // Reference counting initialized to -1 (static read-only data) @@ -153,13 +159,16 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.isStatic()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); +#endif QVERIFY(array.ref.ref()); QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.deref()); QCOMPARE(array.ref.atomic.load(), -1); + } } @@ -169,16 +178,19 @@ void tst_QArrayData::sharedNullEmpty() QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0); QVERIFY(null->ref.isStatic()); - QVERIFY(null->ref.isSharable()); QVERIFY(null->ref.isShared()); QVERIFY(empty->ref.isStatic()); - QVERIFY(empty->ref.isSharable()); QVERIFY(empty->ref.isShared()); QCOMPARE(null->ref.atomic.load(), -1); QCOMPARE(empty->ref.atomic.load(), -1); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + QVERIFY(null->ref.isSharable()); + QVERIFY(empty->ref.isSharable()); +#endif + QVERIFY(null->ref.ref()); QVERIFY(empty->ref.ref()); @@ -305,6 +317,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v7.isShared()); QVERIFY(!v8.isShared()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(v1.isSharable()); QVERIFY(v2.isSharable()); QVERIFY(v3.isSharable()); @@ -313,6 +326,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v6.isSharable()); QVERIFY(v7.isSharable()); QVERIFY(v8.isSharable()); +#endif QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); @@ -496,6 +510,7 @@ void tst_QArrayData::simpleVector() for (int i = 0; i < 120; ++i) QCOMPARE(v1[i], v8[i % 10]); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { v7.setSharable(true); QVERIFY(v7.isSharable()); @@ -558,6 +573,7 @@ void tst_QArrayData::simpleVector() QVERIFY(null.isEmpty()); QVERIFY(empty.isEmpty()); } +#endif } Q_DECLARE_METATYPE(SimpleVector) @@ -648,7 +664,7 @@ void tst_QArrayData::allocate_data() QTest::addColumn("alignment"); QTest::addColumn("allocateOptions"); QTest::addColumn("isCapacityReserved"); - QTest::addColumn("isSharable"); + QTest::addColumn("isSharable"); // ### Qt6: remove QTest::addColumn("commonEmpty"); struct { @@ -662,10 +678,12 @@ void tst_QArrayData::allocate_data() }; QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0); - QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); - QVERIFY(shared_empty); + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); QVERIFY(unsharable_empty); +#endif struct { char const *description; @@ -676,10 +694,12 @@ void tst_QArrayData::allocate_data() } options[] = { { "Default", QArrayData::Default, false, true, shared_empty }, { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty }, +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { "Reserved | Unsharable", QArrayData::CapacityReserved | QArrayData::Unsharable, true, false, unsharable_empty }, { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty }, +#endif { "Grow", QArrayData::Grow, false, true, shared_empty } }; @@ -700,7 +720,6 @@ void tst_QArrayData::allocate() QFETCH(size_t, alignment); QFETCH(QArrayData::AllocationOptions, allocateOptions); QFETCH(bool, isCapacityReserved); - QFETCH(bool, isSharable); QFETCH(const QArrayData *, commonEmpty); // Minimum alignment that can be requested is that of QArrayData. @@ -725,7 +744,10 @@ void tst_QArrayData::allocate() else QCOMPARE(data->alloc, uint(capacity)); QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + QFETCH(bool, isSharable); QCOMPARE(data->ref.isSharable(), isSharable); +#endif // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. @@ -1302,6 +1324,7 @@ static inline bool arrayIsFilledWith(const QArrayDataPointer &array, void tst_QArrayData::setSharable_data() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QTest::addColumn >("array"); QTest::addColumn("size"); QTest::addColumn("capacity"); @@ -1342,10 +1365,12 @@ void tst_QArrayData::setSharable_data() QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2; QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3; QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3; +#endif } void tst_QArrayData::setSharable() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QFETCH(QArrayDataPointer, array); QFETCH(size_t, size); QFETCH(size_t, capacity); @@ -1424,6 +1449,7 @@ void tst_QArrayData::setSharable() QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved)); QVERIFY(array->ref.isSharable()); +#endif } struct ResetOnDtor @@ -1474,6 +1500,7 @@ void fromRawData_impl() QVERIFY((const T *)raw.constBegin() != array); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { // Immutable, unsharable SimpleVector raw = SimpleVector::fromRawData(array, @@ -1502,6 +1529,7 @@ void fromRawData_impl() QCOMPARE(raw.back(), T(11)); QVERIFY((const T *)raw.constBegin() != array); } +#endif } void tst_QArrayData::fromRawData_data() @@ -1558,7 +1586,9 @@ void tst_QArrayData::literals() QVERIFY(v.isStatic()); #endif +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); +#endif QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd()); for (int i = 0; i < 10; ++i) @@ -1607,7 +1637,9 @@ void tst_QArrayData::variadicLiterals() QVERIFY(v.isStatic()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); +#endif QCOMPARE((const int *)(v.constBegin() + v.size()), (const int *)v.constEnd()); for (int i = 0; i < 7; ++i) diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 73f8973245c..9c96aaf78d7 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -1217,12 +1217,14 @@ void tst_QHash::noNeedlessRehashes() void tst_QHash::const_shared_null() { + QHash hash2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QHash hash1; hash1.setSharable(false); QVERIFY(hash1.isDetached()); - QHash hash2; hash2.setSharable(true); +#endif QVERIFY(!hash2.isDetached()); } diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp index 49b32d5534e..9e47e9c6d64 100644 --- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp +++ b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp @@ -1018,12 +1018,14 @@ void tst_QLinkedList::initializeList() const template void tst_QLinkedList::constSharedNull() const { + QLinkedList list2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QLinkedList list1; list1.setSharable(false); QVERIFY(list1.isDetached()); - QLinkedList list2; list2.setSharable(true); +#endif QVERIFY(!list2.isDetached()); } @@ -1049,6 +1051,7 @@ void tst_QLinkedList::constSharedNullComplex() const void tst_QLinkedList::setSharableInt() const { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QLinkedList orglist; orglist << 0 << 1 << 2 << 3 << 4 << 5; int size = 6; @@ -1094,6 +1097,7 @@ void tst_QLinkedList::setSharableInt() const } QCOMPARE(list.size(), size); +#endif } QTEST_APPLESS_MAIN(tst_QLinkedList) diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index d77cc4a37cb..b368359c62b 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -1522,12 +1522,14 @@ void tst_QList::initializeList() const template void tst_QList::constSharedNull() const { + QList list2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QList list1; list1.setSharable(false); QVERIFY(list1.isDetached()); - QList list2; list2.setSharable(true); +#endif QVERIFY(!list2.isDetached()); } @@ -1553,16 +1555,19 @@ void tst_QList::constSharedNullComplex() const template void generateSetSharableData() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QTest::addColumn >("list"); QTest::addColumn("size"); QTest::newRow("null") << QList() << 0; QTest::newRow("non-empty") << (QList() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5; +#endif } template void runSetSharableTest() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QFETCH(QList, list); QFETCH(int, size); @@ -1602,6 +1607,7 @@ void runSetSharableTest() QCOMPARE(int(list[i]), i); QCOMPARE(list.size(), size); +#endif } void tst_QList::setSharableInt_data() const diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index e812e5a337a..00e669c1d8e 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -984,12 +984,14 @@ void tst_QMap::qmultimap_specific() void tst_QMap::const_shared_null() { + QMap map2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QMap map1; map1.setSharable(false); QVERIFY(map1.isDetached()); - QMap map2; map2.setSharable(true); +#endif QVERIFY(!map2.isDetached()); } @@ -1046,6 +1048,7 @@ const T &const_(const T &t) void tst_QMap::setSharable() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QMap map; map.insert(1, "um"); @@ -1095,6 +1098,7 @@ void tst_QMap::setSharable() QVERIFY(!map.isDetached()); QVERIFY(copy.isSharedWith(map)); } +#endif } void tst_QMap::insert() @@ -1204,7 +1208,6 @@ void tst_QMap::initializerList() void tst_QMap::testInsertWithHint() { QMap map; - map.setSharable(false); // Check with end hint(); map.insert(map.constEnd(), 3, 1); // size == 1 @@ -1268,7 +1271,6 @@ void tst_QMap::testInsertWithHint() void tst_QMap::testInsertMultiWithHint() { QMap map; - map.setSharable(false); typedef QMap::const_iterator cite; // Hack since we define QT_STRICT_ITERATORS map.insertMulti(cite(map.end()), 64, 65); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index c9545c8eb48..f1efbf08125 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -265,12 +265,15 @@ private slots: void initializeListCustom(); void const_shared_null(); +#if 1 + // ### Qt6 remove this section void setSharableInt_data(); void setSharableInt(); void setSharableMovable_data(); void setSharableMovable(); void setSharableCustom_data(); void setSharableCustom(); +#endif void detachInt() const; void detachMovable() const; @@ -393,6 +396,14 @@ void tst_QVector::copyConstructor() const QVector v2(v1); QCOMPARE(v1, v2); } + { + QVector v1; + v1 << value1 << value2 << value3 << value4; + QVector v2(v1); + QCOMPARE(v1, v2); + } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v1; v1.setSharable(false); @@ -400,12 +411,6 @@ void tst_QVector::copyConstructor() const QVERIFY(!v1.isSharedWith(v2)); QCOMPARE(v1, v2); } - { - QVector v1; - v1 << value1 << value2 << value3 << value4; - QVector v2(v1); - QCOMPARE(v1, v2); - } { QVector v1; v1 << value1 << value2 << value3 << value4; @@ -414,6 +419,7 @@ void tst_QVector::copyConstructor() const QVERIFY(!v1.isSharedWith(v2)); QCOMPARE(v1, v2); } +#endif } void tst_QVector::copyConstructorInt() const @@ -514,6 +520,8 @@ void tst_QVector::append() const QVERIFY(v.size() == 3); QCOMPARE(v.at(v.size() - 1), SimpleValue::at(0)); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v(2); v.reserve(12); @@ -522,6 +530,7 @@ void tst_QVector::append() const QVERIFY(v.size() == 3); QCOMPARE(v.last(), SimpleValue::at(0)); } +#endif } void tst_QVector::appendInt() const @@ -819,12 +828,15 @@ void tst_QVector::eraseEmpty() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v; v.setSharable(false); v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#endif } void tst_QVector::eraseEmptyInt() const @@ -855,6 +867,8 @@ void tst_QVector::eraseEmptyReserved() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v; v.reserve(10); @@ -862,6 +876,7 @@ void tst_QVector::eraseEmptyReserved() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#endif } void tst_QVector::eraseEmptyReservedInt() const @@ -968,6 +983,8 @@ void tst_QVector::erase(bool shared) const if (shared) QCOMPARE(SimpleValue::vector(12), *svc.copy); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v = SimpleValue::vector(10); SharedVectorChecker svc(v, shared); @@ -980,6 +997,7 @@ void tst_QVector::erase(bool shared) const if (shared) QCOMPARE(SimpleValue::vector(10), *svc.copy); } +#endif } void tst_QVector::eraseInt() const @@ -1052,6 +1070,8 @@ template void tst_QVector::eraseReserved() const v.erase(v.begin() + 1, v.end() - 1); QCOMPARE(v.size(), 2); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v(10); v.reserve(16); @@ -1061,6 +1081,7 @@ template void tst_QVector::eraseReserved() const v.erase(v.begin(), v.end() - 1); QCOMPARE(v.size(), 1); } +#endif } void tst_QVector::eraseReservedInt() const @@ -1512,6 +1533,14 @@ void tst_QVector::resizePOD_data() const QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector nullNotShared; QVector emptyNotShared(0, 5); QVector emptyReservedNotShared; @@ -1530,16 +1559,12 @@ void tst_QVector::resizePOD_data() const nonEmptyNotShared.setSharable(false); nonEmptyReservedNotShared.setSharable(false); - QTest::newRow("null") << null << 10; - QTest::newRow("empty") << empty << 10; - QTest::newRow("emptyReserved") << emptyReserved << 10; - QTest::newRow("nonEmpty") << nonEmpty << 10; - QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; QTest::newRow("nullNotShared") << nullNotShared << 10; QTest::newRow("emptyNotShared") << emptyNotShared << 10; QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +#endif } void tst_QVector::resizePOD() const @@ -1583,6 +1608,14 @@ void tst_QVector::resizeComplexMovable_data() const QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector nullNotShared; QVector emptyNotShared(0, 'Q'); QVector emptyReservedNotShared; @@ -1601,16 +1634,12 @@ void tst_QVector::resizeComplexMovable_data() const nonEmptyNotShared.setSharable(false); nonEmptyReservedNotShared.setSharable(false); - QTest::newRow("null") << null << 10; - QTest::newRow("empty") << empty << 10; - QTest::newRow("emptyReserved") << emptyReserved << 10; - QTest::newRow("nonEmpty") << nonEmpty << 10; - QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; QTest::newRow("nullNotShared") << nullNotShared << 10; QTest::newRow("emptyNotShared") << emptyNotShared << 10; QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +#endif } void tst_QVector::resizeComplexMovable() const @@ -1658,6 +1687,14 @@ void tst_QVector::resizeComplex_data() const QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector nullNotShared; QVector emptyNotShared(0, '0'); QVector emptyReservedNotShared; @@ -1676,16 +1713,12 @@ void tst_QVector::resizeComplex_data() const nonEmptyNotShared.setSharable(false); nonEmptyReservedNotShared.setSharable(false); - QTest::newRow("null") << null << 10; - QTest::newRow("empty") << empty << 10; - QTest::newRow("emptyReserved") << emptyReserved << 10; - QTest::newRow("nonEmpty") << nonEmpty << 10; - QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; QTest::newRow("nullNotShared") << nullNotShared << 10; QTest::newRow("emptyNotShared") << emptyNotShared << 10; QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +#endif } void tst_QVector::resizeComplex() const @@ -2070,15 +2103,20 @@ void tst_QVector::initializeListCustom() void tst_QVector::const_shared_null() { + QVector v2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector v1; v1.setSharable(false); QVERIFY(v1.isDetached()); - QVector v2; v2.setSharable(true); +#endif QVERIFY(!v2.isDetached()); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +// ### Qt6 remove this section template void tst_QVector::setSharable_data() const { @@ -2109,21 +2147,6 @@ void tst_QVector::setSharable_data() const QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true; } -void tst_QVector::setSharableInt_data() -{ - setSharable_data(); -} - -void tst_QVector::setSharableMovable_data() -{ - setSharable_data(); -} - -void tst_QVector::setSharableCustom_data() -{ - setSharable_data(); -} - template void tst_QVector::setSharable() const { @@ -2185,6 +2208,30 @@ void tst_QVector::setSharable() const .arg(vector.capacity()) .arg(capacity))); } +#else +template void tst_QVector::setSharable_data() const +{ +} + +template void tst_QVector::setSharable() const +{ +} +#endif + +void tst_QVector::setSharableInt_data() +{ + setSharable_data(); +} + +void tst_QVector::setSharableMovable_data() +{ + setSharable_data(); +} + +void tst_QVector::setSharableCustom_data() +{ + setSharable_data(); +} void tst_QVector::setSharableInt() { From eb1325047f2697d24e93ebaf924900affc876bc1 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 24 Apr 2014 15:33:27 +0200 Subject: [PATCH 08/20] Don't crash on broken GIF images Broken GIF images could set invalid width and height values inside the image, leading to Qt creating a null QImage for it. In that case we need to abort decoding the image and return an error. Initial patch by Rich Moore. Task-number: QTBUG-38367 Change-Id: Id82a4036f478bd6e49c402d6598f57e7e5bb5e1e Security-advisory: CVE-2014-0190 Reviewed-by: Richard J. Moore --- src/gui/image/qgifhandler.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index eeb62af4e55..19b838240f1 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -359,6 +359,13 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, memset(bits, 0, image->byteCount()); } + // Check if the previous attempt to create the image failed. If it + // did then the image is broken and we should give up. + if (image->isNull()) { + state = Error; + return -1; + } + disposePrevious(image); disposed = false; From d29a750c0cc423bf65171338eeaa767f272d4ef0 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 24 Apr 2014 17:52:29 +0200 Subject: [PATCH 09/20] QAbstractSocket: enable read notification for unbuffered sockets This restores behavior for UDP sockets as it was in 5.2.1. Change 13c246ee119fdb10d91f509b968a221d4fc1d8ba introduced a behavioral change / regression in that respect. Task-number: QTBUG-37489 Change-Id: I8f0b26d763dd66ea6edcc343e91ff5c9c7bdc0f2 Reviewed-by: Richard J. Moore --- src/network/socket/qabstractsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 1ceec717c6e..b8f76f8d4f2 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -748,7 +748,7 @@ bool QAbstractSocketPrivate::canReadNotification() return true; } - if (isBuffered && socketEngine) + if ((isBuffered || socketType != QAbstractSocket::TcpSocket) && socketEngine) socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable()); // reset the read socket notifier state if we reentered inside the From 7e071cebaa731b3f635ef515627985e27726aba1 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 3 Apr 2014 15:36:27 +0200 Subject: [PATCH 10/20] Android input method fixes for SwiftKey Try to conform to the input method protocol in the way that SwiftKey expects (and the way that the stock android components actually do). * Refactor cursor position logic * fix getExtractedText() so it includes preedit text * ignore the hintMaxChars parameter to getExtractedText(), since it looks like everybody else does * fix setComposingRegion when preedit is active * track the start of the preedit and the preedit cursor position, since the Qt input method query does not give us this information Change-Id: I2ed8797abacd97ca749ca152fab2a2d5446ef603 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../android/qandroidinputcontext.cpp | 184 ++++++++++++++---- .../platforms/android/qandroidinputcontext.h | 2 + 2 files changed, 144 insertions(+), 42 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 02fda19d760..e255a49ac7f 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2012 BogDan Vatra ** Contact: http://www.qt-project.org/legal ** @@ -338,7 +339,7 @@ static JNINativeMethod methods[] = { QAndroidInputContext::QAndroidInputContext() - : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0) + : QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0) { QtAndroid::AttachedJNIEnv env; if (!env.jniEnv) @@ -431,9 +432,24 @@ QAndroidInputContext *QAndroidInputContext::androidInputContext() return m_androidInputContext; } +// cursor position getter that also works with editors that have not been updated to the new API +static inline int getAbsoluteCursorPosition(const QSharedPointer &query) +{ + QVariant absolutePos = query->value(Qt::ImAbsolutePosition); + return absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); +} + +// position of the start of the current block +static inline int getBlockPosition(const QSharedPointer &query) +{ + QVariant absolutePos = query->value(Qt::ImAbsolutePosition); + return absolutePos.isValid() ? absolutePos.toInt() - query->value(Qt::ImCursorPosition).toInt() : 0; +} + void QAndroidInputContext::reset() { clear(); + m_batchEditNestingLevel = 0; if (qGuiApp->focusObject()) QtAndroidInput::resetSoftwareKeyboard(); else @@ -449,13 +465,20 @@ void QAndroidInputContext::updateCursorPosition() { QSharedPointer query = focusObjectInputMethodQuery(); if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) { - // make sure it also works with editors that have not been updated to the new API - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); + const int cursorPos = getAbsoluteCursorPosition(query); const int composeLength = m_composingText.length(); - const int composeStart = composeLength ? cursorPos : -1; - QtAndroidInput::updateSelection(cursorPos + composeLength, cursorPos + composeLength, //empty selection - composeStart, composeStart + composeLength); // pre-edit text + + //Q_ASSERT(m_composingText.isEmpty() == (m_composingTextStart == -1)); + if (m_composingText.isEmpty() != (m_composingTextStart == -1)) + qWarning() << "Input method out of sync" << m_composingText << m_composingTextStart; + + + // Qt's idea of the cursor position is the start of the preedit area, so we have to maintain our own preedit cursor pos + int realCursorPosition = cursorPos; + if (!m_composingText.isEmpty()) + realCursorPosition = m_composingCursor; + QtAndroidInput::updateSelection(realCursorPosition, realCursorPosition, //empty selection + m_composingTextStart, m_composingTextStart + composeLength); // pre-edit text } } @@ -529,6 +552,7 @@ bool QAndroidInputContext::isComposing() const void QAndroidInputContext::clear() { m_composingText.clear(); + m_composingTextStart = -1; m_extractedText.clear(); } @@ -569,8 +593,18 @@ jboolean QAndroidInputContext::endBatchEdit() jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/) { + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_FALSE; + + + const int cursorPos = getAbsoluteCursorPosition(query); m_composingText = text; - return finishComposingText(); + m_composingTextStart = cursorPos; + m_composingCursor = cursorPos + text.length(); + finishComposingText(); + //### move cursor to newCursorPosition and call updateCursorPosition() + return JNI_TRUE; } jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint rightLength) @@ -580,6 +614,7 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right return JNI_TRUE; m_composingText.clear(); + m_composingTextStart = -1; QInputMethodEvent event; event.setCommitString(QString(), -leftLength, leftLength+rightLength); @@ -617,7 +652,9 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/) return res; } -const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/) + + +const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint /*hintMaxChars*/, jint /*hintMaxLines*/, jint /*flags*/) { // Note to self: "if the GET_EXTRACTED_TEXT_MONITOR flag is set, you should be calling // updateExtractedText(View, int, ExtractedText) whenever you call @@ -628,28 +665,37 @@ const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedTex return m_extractedText; int localPos = query->value(Qt::ImCursorPosition).toInt(); //position before pre-edit text relative to the current block - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - int blockPos = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; // position of the start of the current block - QString blockText = query->value(Qt::ImSurroundingText).toString() + m_composingText; + int blockPos = getBlockPosition(query); + QString blockText = query->value(Qt::ImSurroundingText).toString(); int composeLength = m_composingText.length(); + if (composeLength > 0) { + //Qt doesn't give us the preedit text, so we have to insert it at the correct position + int localComposePos = m_composingTextStart - blockPos; + blockText = blockText.left(localComposePos) + m_composingText + blockText.mid(localComposePos); + } + int cpos = localPos + composeLength; //actual cursor pos relative to the current block int localOffset = 0; // start of extracted text relative to the current block - if (hintMaxChars) { - if (cpos > hintMaxChars) - localOffset = cpos - hintMaxChars; - m_extractedText.text = blockText.mid(localOffset, hintMaxChars); - } - m_extractedText.startOffset = blockPos + localOffset; // "The offset in the overall text at which the extracted text starts." + // It is documented that we should try to return hintMaxChars + // characters, but that's not what the standard Android controls do, and + // there are input methods out there that (surprise) seem to depend on + // what happens in reality rather than what's documented. + + m_extractedText.text = blockText; + m_extractedText.startOffset = blockPos + localOffset; const QString &selection = query->value(Qt::ImCurrentSelection).toString(); const int selLen = selection.length(); if (selLen) { m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt() - localOffset; m_extractedText.selectionEnd = m_extractedText.selectionStart + selLen; - } else { + } else if (composeLength > 0) { + m_extractedText.selectionStart = m_composingCursor - m_extractedText.startOffset; + m_extractedText.selectionEnd = m_composingCursor - m_extractedText.startOffset; + } else { m_extractedText.selectionStart = cpos - localOffset; m_extractedText.selectionEnd = cpos - localOffset; } @@ -668,6 +714,7 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/) QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/) { + //### the preedit text could theoretically be after the cursor QVariant textAfter = queryFocusObjectThreadSafe(Qt::ImTextAfterCursor, QVariant(length)); if (textAfter.isValid()) { return textAfter.toString().left(length); @@ -703,15 +750,34 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/) if (!text.length()) return text; - const int wordLeftPos = cursorPos - length; - return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos) + m_composingText; + //### the preedit text does not need to be immediately before the cursor + if (cursorPos <= length) + return text.left(cursorPos) + m_composingText; + else + return text.mid(cursorPos - length, length) + m_composingText; } +/* + Android docs say that this function should remove the current preedit text + if any, and replace it with the given text. Any selected text should be + removed. The cursor is then moved to newCursorPosition. If > 0, this is + relative to the end of the text - 1; if <= 0, this is relative to the start + of the text. + */ + jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition) { + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_FALSE; + + const int cursorPos = getAbsoluteCursorPosition(query); if (newCursorPosition > 0) newCursorPosition += text.length() - 1; + m_composingText = text; + m_composingTextStart = text.isEmpty() ? -1 : cursorPos; + m_composingCursor = cursorPos + newCursorPosition; QList attributes; attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, newCursorPosition, @@ -726,23 +792,26 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur QInputMethodEvent event(m_composingText, attributes); sendInputMethodEvent(&event); - QSharedPointer query = focusObjectInputMethodQuery(); - if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) { - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); - const int preeditLength = text.length(); - QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, -1, -1); - } + updateCursorPosition(); return JNI_TRUE; } // Android docs say: // * start may be after end, same meaning as if swapped -// * this function must not trigger updateSelection +// * this function should not trigger updateSelection // * if start == end then we should stop composing jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) { + // Qt will not include the current preedit text in the query results, and interprets all + // parameters relative to the text excluding the preedit. The simplest solution is therefore to + // tell Qt that we commit the text before we set the new region. This may cause a little flicker, but is + // much more robust than trying to keep the two different world views in sync + + bool wasComposing = !m_composingText.isEmpty(); + if (wasComposing) + finishComposingText(); + QSharedPointer query = focusObjectInputMethodQuery(); if (query.isNull()) return JNI_FALSE; @@ -757,19 +826,23 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) Therefore, the length of the region is end - start */ + int length = end - start; int localPos = query->value(Qt::ImCursorPosition).toInt(); - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; + int blockPosition = getBlockPosition(query); int localStart = start - blockPosition; // Qt uses position inside block + int currentCursor = wasComposing ? m_composingCursor : blockPosition + localPos; bool updateSelectionWasBlocked = m_blockUpdateSelection; m_blockUpdateSelection = true; QString text = query->value(Qt::ImSurroundingText).toString(); - m_composingText = text.mid(localStart, length); - //in the Qt text controls, the cursor position is the start of the preedit + m_composingText = text.mid(localStart, length); + m_composingTextStart = start; + m_composingCursor = currentCursor; + + //in the Qt text controls, the preedit is defined relative to the cursor position int relativeStart = localStart - localPos; QList attributes; @@ -781,13 +854,22 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) QVariant(underlined))); // Keep the cursor position unchanged (don't move to end of preedit) - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, localPos - localStart, length, QVariant())); + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, currentCursor - start, 1, QVariant())); QInputMethodEvent event(m_composingText, attributes); event.setCommitString(QString(), relativeStart, length); sendInputMethodEvent(&event); m_blockUpdateSelection = updateSelectionWasBlocked; + +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + QSharedPointer query2 = focusObjectInputMethodQuery(); + if (!query2.isNull()) { + qDebug() << "Setting. Prev local cpos:" << localPos << "block pos:" <value(Qt::ImCursorPosition).toInt(); - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; + int blockPosition = getBlockPosition(query); + int localCursorPos = start - blockPosition; QList attributes; - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, - start - blockPosition, - end - start, - QVariant())); + if (!m_composingText.isEmpty() && start == end) { + // not actually changing the selection; just moving the + // preedit cursor + int localOldPos = query->value(Qt::ImCursorPosition).toInt(); + int pos = localCursorPos - localOldPos; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, pos, 1, QVariant())); - QInputMethodEvent event(QString(), attributes); + //but we have to tell Qt about the compose text all over again + + // Show compose text underlined + QTextCharFormat underlined; + underlined.setFontUnderline(true); + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, m_composingText.length(), + QVariant(underlined))); + m_composingCursor = start; + + } else { + // actually changing the selection + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, + localCursorPos, + end - start, + QVariant())); + } + QInputMethodEvent event(m_composingText, attributes); sendInputMethodEvent(&event); + updateCursorPosition(); return JNI_TRUE; } diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h index 3ce141ae152..a467e4849ef 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -134,6 +134,8 @@ private slots: private: ExtractedText m_extractedText; QString m_composingText; + int m_composingTextStart; + int m_composingCursor; QMetaObject::Connection m_updateCursorPosConnection; bool m_blockUpdateSelection; int m_batchEditNestingLevel; From 06fef71775c187de690dc54749956bad62cda2f5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 15:43:29 +0200 Subject: [PATCH 11/20] document new QTPLUGIN magic Change-Id: Ia12f55a3e6bd670cb95c21c8f896b0451dd63693 Reviewed-by: Fawzi Mohamed Reviewed-by: Leena Miettinen Reviewed-by: Oswald Buddenhagen --- qmake/doc/src/qmake-manual.qdoc | 10 +++++ .../snippets/code/doc_src_plugins-howto.pro | 4 +- src/corelib/doc/src/plugins-howto.qdoc | 43 +++++++++++++------ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 91629ec9ddc..94fe02dc707 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2133,6 +2133,16 @@ linked with an application so that they are available as built-in resources. + qmake automatically adds the plugins that are typically needed + by the used Qt modules (see \c QT). + The defaults are tuned towards an optimal out-of-the-box experience. + See \l{Static Plugins} for a list of available plugins, and ways + to override the automatic linking. + + This variable currently has no effect when linking against a + shared/dynamic build of Qt, or when linking libraries. + It may be used for deployment of dynamic plugins at a later time. + \target QT_VERSION_variable \section1 QT_VERSION diff --git a/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro b/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro index 5eb9604ed73..dc75c1d9d76 100644 --- a/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro +++ b/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro @@ -43,7 +43,7 @@ CONFIG += release #! [3] #! [4] -CONFIG += qpa_minimal_plugin +QTPLUGIN.platforms = qminimal #! [4] #! [5] @@ -53,7 +53,7 @@ QTPLUGIN += qjpeg \ #! [5] #! [6] -CONFIG -= import_qpa_plugin +QTPLUGIN.platforms = - #! [6] #! [7] diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc index 7fc4682fd48..7dc0d01ccef 100644 --- a/src/corelib/doc/src/plugins-howto.qdoc +++ b/src/corelib/doc/src/plugins-howto.qdoc @@ -266,20 +266,46 @@ To link those plugins statically, you need to add the required plugins to your build using \c QTPLUGIN. - Q_IMPORT_PLUGIN() macros are also needed in application code, - but those are automatically generated by qmake and added to - your application project. In the \c .pro file for your application, you need the following entry: \snippet code/doc_src_plugins-howto.pro 5 + qmake automatically adds the plugins to QTPLUGIN that are typically + needed by the used Qt modules (see \c QT), while more specialized + plugins need to be added manually. + The default list of automatically added plugins can be overridden + per type. + For example, to link the minimal plugin instead of the default Qt + platform adaptation plugin, use: + + \snippet code/doc_src_plugins-howto.pro 4 + + If you want neither the default nor the minimal QPA plugin to be + linked automatically, use: + + \snippet code/doc_src_plugins-howto.pro 6 + + The defaults are tuned towards an optimal out-of-the-box experience, + but may unnecessarily bloat the application. + It is recommended to inspect the linker command line built by qmake + and eliminate unnecessary plugins. + + \section2 Details of Linking Static Plugins + + To cause static plugins actually being linked and instantiated, + Q_IMPORT_PLUGIN() macros are also needed in application code, + but those are automatically generated by qmake and added to + your application project. + If you do not want all plugins added to QTPLUGIN to be automatically linked, remove \c import_plugins from the \c CONFIG variable: \snippet code/doc_src_plugins-howto.pro 7 + \section2 Creating Static Plugins + It is also possible to create your own static plugins, by following these steps: @@ -298,17 +324,6 @@ to make sure that the \c{QT_STATICPLUGIN} preprocessor macro is defined. - The default Qt platform adaptation plugin is automatically added to QTPLUGIN - in static builds. If you want to add the minimal plugin instead, add \c qpa_minimal_plugin - to \c CONFIG: - - \snippet code/doc_src_plugins-howto.pro 4 - - If you want neither the default nor the minimal QPA plugin to be linked automatically, - remove \c import_qpa_plugin from \c CONFIG: - - \snippet code/doc_src_plugins-howto.pro 6 - \section1 Deploying and Debugging Plugins The \l{Deploying Plugins} document covers the process of deploying From a162a3cbbc3c27b42c86f870aba051a408f04ed4 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 23 Apr 2014 16:26:26 +0200 Subject: [PATCH 12/20] Android: Add "unversioned_libname" configuration On Android, there's a limitation set on the names of the libraries you deploy that they must start with "lib" and end with ".so", so Android apps will link against and deploy with the unversioned libQt5FooBar.so libraries. When cross-compiling on Windows however, due to the lack of symbolic links, the only installed library used to be the main library target "libQt5FooBar.so.X.Y.Z" (for version X.Y.Z.) This has been worked around in packaging, but breaks building add-on modules on top of Qt, and is clearly wrong. This patch introduces a new "unversioned_libname" configuration in qmake which is currently only supported for the Unix makefile generator and only enabled for Android builds. When it is enabled, only the unversioned library "libQt5FooBar.so" will be created. Task-number: QTBUG-38347 Change-Id: Ia8897ca7a23a62e2a526d0e02854899b02eb19dc Reviewed-by: Oswald Buddenhagen --- mkspecs/android-g++/qmake.conf | 2 +- qmake/generators/unix/unixmake.cpp | 4 +- qmake/generators/unix/unixmake2.cpp | 70 +++++++++++++++++++---------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 44624fcca52..c9497edfad9 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -3,7 +3,7 @@ MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = android QMAKE_COMPILER = gcc -CONFIG += android_install unversioned_soname android_deployment_settings +CONFIG += android_install unversioned_soname unversioned_libname android_deployment_settings include(../common/linux.conf) include(../common/gcc-base-unix.conf) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 4c3df4efe8f..5ea47cc8674 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -749,7 +749,9 @@ UnixMakefileGenerator::defaultInstall(const QString &t) target = "$(QMAKE_TARGET)"; } else if(project->first("TEMPLATE") == "lib") { if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) { - if(!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin")) { + if (!project->isActiveConfig("staticlib") + && !project->isActiveConfig("plugin") + && !project->isActiveConfig("unversioned_libname")) { if(project->isEmpty("QMAKE_HPUX_SHLIB")) { links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)"; } else { diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 6e08c138edb..a28760015e0 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -234,14 +234,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_BUNDLE")) { t << "TARGETD = " << escapeFilePath(var("TARGET_x.y")) << endl; t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; - } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { - t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; - t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; - t << "TARGET1 = " << escapeFilePath(var("TARGET_x")) << endl; - t << "TARGET2 = " << escapeFilePath(var("TARGET_x.y")) << endl; - } else { - t << "TARGETD = " << escapeFilePath(var("TARGET_x")) << endl; + } else if (!project->isActiveConfig("unversioned_libname")) { t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; + if (project->isEmpty("QMAKE_HPUX_SHLIB")) { + t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; + t << "TARGET1 = " << escapeFilePath(var("TARGET_x")) << endl; + t << "TARGET2 = " << escapeFilePath(var("TARGET_x.y")) << endl; + } else { + t << "TARGETD = " << escapeFilePath(var("TARGET_x")) << endl; + } } } writeExtraCompilerVariables(t); @@ -574,22 +575,36 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { - t << "\n\t" - << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)\n\t" - << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; - t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); - if(!destdir.isEmpty()) + t << "\n\t"; + + if (!project->isActiveConfig("unversioned_libname")) + t << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)"; + else + t << "-$(DEL_FILE) $(TARGET)"; + + t << "\n\t" << var("QMAKE_LINK_SHLIB_CMD"); + + if (!project->isActiveConfig("unversioned_libname")) { + t << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); + } + if (!destdir.isEmpty()) { t << "\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t" - << "-$(MOVE) $(TARGET) " << destdir << " \n\t" - << "-$(MOVE) $(TARGET0) " << destdir << " \n\t" - << "-$(MOVE) $(TARGET1) " << destdir << " \n\t" - << "-$(MOVE) $(TARGET2) " << destdir << " \n\t"; + << "-$(MOVE) $(TARGET) " << destdir << " "; + + if (!project->isActiveConfig("unversioned_libname")) { + t << "\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t" + << "-$(MOVE) $(TARGET0) " << destdir << " \n\t" + << "-$(MOVE) $(TARGET1) " << destdir << " \n\t" + << "-$(MOVE) $(TARGET2) " << destdir << " "; + } + } if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; @@ -924,8 +939,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty() && !project->isActiveConfig("plugin")) { t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n"; - t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " - << destdir << "$(TARGET2) $(TARGETA)\n"; + if (!project->isActiveConfig("unversioned_libname")) { + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " + << destdir << "$(TARGET2) $(TARGETA)\n"; + } else { + t << "\t-$(DEL_FILE) $(TARGETA)\n"; + } } else { t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n"; } @@ -1165,7 +1184,10 @@ void UnixMakefileGenerator::init2() project->first("VER_MIN") + "." + project->first("VER_PAT")); } - project->values("TARGET") = project->values("TARGET_x.y.z"); + if (project->isActiveConfig("unversioned_libname")) + project->values("TARGET") = project->values("TARGET_"); + else + project->values("TARGET") = project->values("TARGET_x.y.z"); } if(project->isEmpty("QMAKE_LN_SHLIB")) project->values("QMAKE_LN_SHLIB").append("ln -s"); From c0825cbfc0c568542a9e4c09e23d42eb76a5a706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 24 Apr 2014 14:34:34 +0200 Subject: [PATCH 13/20] Cocoa: Make Qt::Tool windows hide on deactivate This is a regression from 5.1. Task-number: QTBUG-37706 Change-Id: Ib28eead869dde37ded37397a89a94b67fb150cca Reviewed-by: Gabriel de Dietrich Reviewed-by: Liang Qi --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5def64ee0a6..60152b56b20 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1375,7 +1375,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() qPlatformWindow:this]; if ((type & Qt::Popup) == Qt::Popup) [window setHasShadow:YES]; - [window setHidesOnDeactivate: NO]; + + [window setHidesOnDeactivate:(type & Qt::Tool) == Qt::Tool]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { From 89ecac46075e51c8125a96bb98e99d39f546dacd Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Apr 2014 15:12:46 +0200 Subject: [PATCH 14/20] QSqlError: Mark deprecated functiond with QT_DEPRECATED And move the default argument from the deprecated constructor to the new one Also make sure that the error number is consistent across the two constructor Change-Id: I3721266b39ab493f0add35b2d1f892b2f6094992 Reviewed-by: Lars Knoll --- src/sql/kernel/qsqlerror.cpp | 5 +++-- src/sql/kernel/qsqlerror.h | 16 +++++++--------- .../sql/kernel/qsqlerror/tst_qsqlerror.cpp | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/sql/kernel/qsqlerror.cpp b/src/sql/kernel/qsqlerror.cpp index 1763722e8ac..1979e5d1f58 100644 --- a/src/sql/kernel/qsqlerror.cpp +++ b/src/sql/kernel/qsqlerror.cpp @@ -107,7 +107,8 @@ QSqlError::QSqlError(const QString& driverText, const QString& databaseText, Err d->driverError = driverText; d->databaseError = databaseText; d->errorType = type; - d->errorCode = QString::number(number); + if (number != -1) + d->errorCode = QString::number(number); } #endif @@ -287,7 +288,7 @@ void QSqlError::setType(ErrorType type) #if QT_DEPRECATED_SINCE(5, 3) int QSqlError::number() const { - return d->errorCode.toInt(); + return d->errorCode.isEmpty() ? -1 : d->errorCode.toInt(); } #endif diff --git a/src/sql/kernel/qsqlerror.h b/src/sql/kernel/qsqlerror.h index 4e27ab03ae8..679e0f9e3cb 100644 --- a/src/sql/kernel/qsqlerror.h +++ b/src/sql/kernel/qsqlerror.h @@ -60,15 +60,13 @@ public: UnknownError }; #if QT_DEPRECATED_SINCE(5, 3) - QSqlError( const QString& driverText = QString(), - const QString& databaseText = QString(), - ErrorType type = NoError, - int number = -1); + QT_DEPRECATED QSqlError(const QString &driverText, const QString &databaseText, + ErrorType type, int number); #endif - QSqlError(const QString &driverText, - const QString &databaseText, - ErrorType type, - const QString &errorCode); + QSqlError(const QString &driverText = QString(), + const QString &databaseText = QString(), + ErrorType type = NoError, + const QString &errorCode = QString()); QSqlError(const QSqlError& other); QSqlError& operator=(const QSqlError& other); bool operator==(const QSqlError& other) const; @@ -79,7 +77,7 @@ public: QString databaseText() const; ErrorType type() const; #if QT_DEPRECATED_SINCE(5, 3) - int number() const; + QT_DEPRECATED int number() const; #endif QString nativeErrorCode() const; QString text() const; diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp index 9763e3e7e6b..847453b3ed4 100644 --- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp +++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp @@ -102,6 +102,7 @@ void tst_QSqlError::construction() QCOMPARE(obj1.databaseText(), QString("databasetext")); QCOMPARE(obj1.type(), QSqlError::UnknownError); QCOMPARE(obj1.number(), 123); + QCOMPARE(obj1.nativeErrorCode(), QStringLiteral("123")); QVERIFY(obj1.isValid()); QSqlError obj2(obj1); @@ -109,6 +110,7 @@ void tst_QSqlError::construction() QCOMPARE(obj2.databaseText(), obj1.databaseText()); QCOMPARE(obj2.type(), obj1.type()); QCOMPARE(obj2.number(), obj1.number()); + QCOMPARE(obj2.nativeErrorCode(), obj1.nativeErrorCode()); QVERIFY(obj2.isValid()); QSqlError obj3 = obj2; @@ -116,10 +118,16 @@ void tst_QSqlError::construction() QCOMPARE(obj3.databaseText(), obj2.databaseText()); QCOMPARE(obj3.type(), obj2.type()); QCOMPARE(obj3.number(), obj2.number()); + QCOMPARE(obj3.nativeErrorCode(), obj2.nativeErrorCode()); QVERIFY(obj3.isValid()); QSqlError obj4; QVERIFY(!obj4.isValid()); + QCOMPARE(obj4.driverText(), QString()); + QCOMPARE(obj4.databaseText(), QString()); + QCOMPARE(obj4.type(), QSqlError::NoError); + QCOMPARE(obj4.number(), -1); + QCOMPARE(obj4.nativeErrorCode(), QString()); QSqlError obj5(QStringLiteral("drivertext"), QStringLiteral("databasetext"), QSqlError::UnknownError, QStringLiteral("123")); @@ -138,6 +146,16 @@ void tst_QSqlError::construction() QCOMPARE(obj6.number(), 0); QCOMPARE(obj6.nativeErrorCode(), QStringLiteral("Err123")); QVERIFY(obj6.isValid()); + + // Default constructed object as constructed before Qt 5.3 + QSqlError obj7(QString(), QString(), QSqlError::NoError, -1); + QVERIFY(!obj7.isValid()); + QCOMPARE(obj7.driverText(), QString()); + QCOMPARE(obj7.databaseText(), QString()); + QCOMPARE(obj7.type(), QSqlError::NoError); + QCOMPARE(obj7.number(), -1); + QCOMPARE(obj7.nativeErrorCode(), QString()); + } void tst_QSqlError::operators() From 58bb42dc2c338338b7b6079993ace3d55c2e1d7e Mon Sep 17 00:00:00 2001 From: John Layt Date: Wed, 16 Apr 2014 15:56:13 +0200 Subject: [PATCH 15/20] QPrintEngine - Fix alpha engine state sync Move the copy of the paint engine to after the engine state has been synced, otherwise the transform is incorrectly applied after the new page. Task-number: QTBUG-38329 Change-Id: I2e134889b3ef10f6e3dce42edac2a58e78c66c30 Reviewed-by: Michael Bruning Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw Reviewed-by: Lars Knoll --- src/printsupport/kernel/qpaintengine_alpha.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index 7d4dc181114..ddfa918b90f 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -345,8 +345,8 @@ void QAlphaPaintEngine::flushAndInit(bool init) d->m_picpainter->setFont(painter()->font()); d->m_picpainter->setOpacity(painter()->opacity()); d->m_picpainter->setTransform(painter()->combinedTransform()); - *d->m_picpainter->d_func()->state = *painter()->d_func()->state; d->m_picengine->syncState(); + *d->m_picpainter->d_func()->state = *painter()->d_func()->state; } } From c1625ef8237cff4d313a07ac7091a50c9444a106 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 23 Apr 2014 08:54:12 +0300 Subject: [PATCH 16/20] Fix vcxproj generation on Windows Phone f412f2b5 refactored the platform tool set retrieval, but made the call too early to choose the right tool set on Windows Phone. This fixes the call so that it does not depend on the WinPhone member variable, and also makes it forward-compatible with Windows Phone 8.1. Task-number: QTBUG-38516 Change-Id: Ide91563f5c7f909c4d1a258adc29af6c94595dc9 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_vcproj.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index ac258e2841b..2bd3301e16c 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -397,8 +397,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return envVar; QString suffix; - if (vcProject.Configuration.WinPhone) - suffix = "_wp80"; + if (project->isActiveConfig("winphone")) + suffix = '_' + project->first("WINTARGET_VER").toQString().toLower(); else if (project->first("QMAKE_TARGET_OS") == "xp") suffix = "_xp"; From 93c6976a394275d5fdad6266512925f6c7c94911 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Apr 2014 16:45:55 -0700 Subject: [PATCH 17/20] Un-export QSignalBlocker: it's all inline Change-Id: I0fb5a30eebd9edba853b7e4bd74cc7e9b06da486 Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart --- src/corelib/kernel/qobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index ee6ef23139c..a54690606a3 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -549,7 +549,7 @@ template inline const char * qobject_interface_iid() Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *); #endif -class Q_CORE_EXPORT QSignalBlocker +class QSignalBlocker { public: inline explicit QSignalBlocker(QObject *o); From f9d323279a0b3928acf40d56d84e9e5cc2cb7ee9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 24 Apr 2014 17:11:23 +0200 Subject: [PATCH 18/20] Rename new QOpenGLContext APIs isES() becomes isOpenGLES(). The library type enums are changed DesktopGL -> LibGL and GLES2 -> LibGLES. This removes the now unnecessary version number, the confusing "desktop" term and provides better readability. The old function/values are kept until the related qtdeclarative changes are integrated. Task-number: QTBUG-38564 Change-Id: Ibb0a1209985f1ce4bb9451f9b7b093c2b68a6505 Reviewed-by: Sean Harmer --- src/gui/kernel/qopenglcontext.cpp | 16 +++++----- src/gui/kernel/qopenglcontext.h | 12 +++++-- src/gui/kernel/qplatformintegration.cpp | 4 +-- src/gui/opengl/qopenglengineshadermanager.cpp | 2 +- src/gui/opengl/qopenglframebufferobject.cpp | 14 ++++---- src/gui/opengl/qopenglframebufferobject_p.h | 2 +- src/gui/opengl/qopenglfunctions.cpp | 8 ++--- src/gui/opengl/qopenglpaintengine.cpp | 8 ++--- src/gui/opengl/qopenglshaderprogram.cpp | 10 +++--- src/gui/opengl/qopengltexture.cpp | 32 +++++++++---------- src/gui/opengl/qopengltextureglyphcache.cpp | 6 ++-- src/gui/opengl/qopengltexturehelper.cpp | 6 ++-- src/gui/opengl/qopengltimerquery.cpp | 2 +- src/gui/opengl/qopenglvertexarrayobject.cpp | 4 +-- src/gui/painting/qplatformbackingstore.cpp | 2 +- .../qglengineshadermanager.cpp | 2 +- .../qpaintengineex_opengl2.cpp | 10 +++--- .../qtextureglyphcache_gl.cpp | 4 +-- src/opengl/qgl.cpp | 26 +++++++-------- src/opengl/qgl_qpa.cpp | 2 +- src/opengl/qglframebufferobject.cpp | 14 ++++---- src/opengl/qglframebufferobject_p.h | 2 +- src/opengl/qglfunctions.cpp | 2 +- src/opengl/qglpixelbuffer.cpp | 6 ++-- src/opengl/qglshaderprogram.cpp | 12 +++---- .../eglconvenience/qeglconvenience.cpp | 4 +-- .../platforms/windows/qwindowsintegration.cpp | 6 ++-- .../windows/qwindowsnativeinterface.cpp | 4 +-- .../platforms/windows/qwindowswindow.cpp | 2 +- tests/auto/opengl/qgl/tst_qgl.cpp | 12 +++---- .../opengl/qglfunctions/tst_qglfunctions.cpp | 2 +- .../auto/opengl/qglthreads/tst_qglthreads.cpp | 2 +- .../widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 2 +- 33 files changed, 124 insertions(+), 118 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index dbca05037b9..1af5c09fd2c 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -364,7 +364,7 @@ int QOpenGLContextPrivate::maxTextureSize() funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); #ifndef QT_OPENGL_ES - if (!q->isES()) { + if (!q->isOpenGLES()) { GLenum proxy = GL_PROXY_TEXTURE_2D; GLint size; @@ -676,7 +676,7 @@ QOpenGLFunctions *QOpenGLContext::functions() const QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const { #ifndef QT_OPENGL_ES_2 - if (isES()) { + if (isOpenGLES()) { qWarning("versionFunctions: Not supported on OpenGL ES"); return 0; } @@ -1036,8 +1036,8 @@ void *QOpenGLContext::openGLModuleHandle() \enum QOpenGLContext::OpenGLModuleType This enum defines the type of the underlying OpenGL implementation. - \value DesktopGL Desktop OpenGL - \value GLES2 OpenGL ES 2.0 or higher + \value LibGL OpenGL + \value LibGLES OpenGL ES 2.0 or higher \since 5.3 */ @@ -1052,7 +1052,7 @@ void *QOpenGLContext::openGLModuleHandle() \note A desktop OpenGL implementation may be capable of creating ES-compatible contexts too. Therefore in most cases it is more appropriate to check QSurfaceFormat::renderableType() or using the - the convenience function isES(). + the convenience function isOpenGLES(). \note This function requires that the QGuiApplication instance is already created. @@ -1064,9 +1064,9 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType() Q_ASSERT(qGuiApp); return QGuiApplicationPrivate::instance()->platformIntegration()->openGLModuleType(); #elif defined(QT_OPENGL_ES_2) - return GLES2; + return LibGLES; #else - return DesktopGL; + return LibGL; #endif } @@ -1080,7 +1080,7 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType() \since 5.3 */ -bool QOpenGLContext::isES() const +bool QOpenGLContext::isOpenGLES() const { return format().renderableType() == QSurfaceFormat::OpenGLES; } diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index fce983f9756..c422d008c18 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -195,13 +195,19 @@ public: static void *openGLModuleHandle(); enum OpenGLModuleType { - DesktopGL, - GLES2 + LibGL, + LibGLES, + + // ### + DesktopGL = LibGL, + GLES2 = LibGLES }; static OpenGLModuleType openGLModuleType(); - bool isES() const; + bool isOpenGLES() const; + + bool isES() const { return isOpenGLES(); } // ### Q_SIGNALS: void aboutToBeDestroyed(); diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index a6e0d4705b3..da192a8e256 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -491,14 +491,14 @@ void QPlatformIntegration::sync() a desktop OpenGL implementation may be capable of creating OpenGL ES-compatible contexts too. - \sa QOpenGLContext::openGLModuleType(), QOpenGLContext::isES() + \sa QOpenGLContext::openGLModuleType(), QOpenGLContext::isOpenGLES() \since 5.3 */ QOpenGLContext::OpenGLModuleType QPlatformIntegration::openGLModuleType() { qWarning("This plugin does not support dynamic OpenGL loading!"); - return QOpenGLContext::DesktopGL; + return QOpenGLContext::LibGL; } #endif diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp index a1215acb7e6..1c4231b79fa 100644 --- a/src/gui/opengl/qopenglengineshadermanager.cpp +++ b/src/gui/opengl/qopenglengineshadermanager.cpp @@ -164,7 +164,7 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context) code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader; code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader; - if (context->isES()) + if (context->isOpenGLES()) code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES; else code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop; diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 92a7330d6c9..cc829df9500 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -590,7 +590,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) { - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -602,7 +602,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen GL_DEPTH_COMPONENT, size.width(), size.height()); } } else { - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -631,7 +631,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen #ifdef QT_OPENGL_ES GLenum storage = GL_STENCIL_INDEX8; #else - GLenum storage = ctx->isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; + GLenum storage = ctx->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) @@ -773,7 +773,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar Q_D(QOpenGLFramebufferObject); d->init(this, size, NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -793,7 +793,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum Q_D(QOpenGLFramebufferObject); d->init(this, QSize(width, height), NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -850,7 +850,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, QSize(width, height), attachment, target, internal_format); } @@ -877,7 +877,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, size, attachment, target, internal_format); } diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h index bd830b38e98..7a653bc16d1 100644 --- a/src/gui/opengl/qopenglframebufferobject_p.h +++ b/src/gui/opengl/qopenglframebufferobject_p.h @@ -74,7 +74,7 @@ public: // context, so we need a fallback just to be safe, even though in pratice there // will usually be a context current. QOpenGLContext *ctx = QOpenGLContext::currentContext(); - const bool isES = ctx ? ctx->isES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL; + const bool isES = ctx ? ctx->isOpenGLES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL; internal_format = isES ? GL_RGBA : GL_RGBA8; #else internal_format = GL_RGBA; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 85b893e434a..bcb38ce7f1d 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -256,7 +256,7 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context) static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { // OpenGL ES 2 int features = QOpenGLFunctions::Multitexture | QOpenGLFunctions::Shaders | @@ -367,7 +367,7 @@ static int qt_gl_resolve_extensions() if (extensionMatcher.match("GL_ARB_pixel_buffer_object")) extensions |= QOpenGLExtensions::PixelBufferObject; - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (format.majorVersion() >= 2) extensions |= QOpenGLExtensions::GenerateMipmap; if (extensionMatcher.match("GL_OES_mapbuffer")) @@ -2415,7 +2415,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveClearColor(GLclampf red, GLclampf g static void QOPENGLF_APIENTRY qopenglfResolveClearDepthf(GLclampf depth) { - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { RESOLVE_FUNC_VOID(0, ClearDepthf)(depth); } else { RESOLVE_FUNC_VOID(0, ClearDepth)((GLdouble) depth); @@ -2464,7 +2464,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveDepthMask(GLboolean flag) static void QOPENGLF_APIENTRY qopenglfResolveDepthRangef(GLclampf zNear, GLclampf zFar) { - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { RESOLVE_FUNC_VOID(0, DepthRangef)(zNear, zFar); } else { RESOLVE_FUNC_VOID(0, DepthRange)((GLdouble) zNear, (GLdouble) zFar); diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index f160b340e0a..81a0d82c99f 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -221,7 +221,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); GLuint wrapMode = GL_REPEAT; - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, // we emulate GL_REPEAT by only taking the fractional part of the texture coords // in the qopenglslTextureBrushSrcFragmentShader program. @@ -598,7 +598,7 @@ void QOpenGL2PaintEngineExPrivate::resetGLState() setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { // gl_Color, corresponding to vertex attribute 3, may have been changed float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; funcs.glVertexAttrib4fv(3, color); @@ -1333,7 +1333,7 @@ void QOpenGL2PaintEngineEx::renderHintsChanged() state()->renderHintsChanged = true; #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGL2PaintEngineEx); if ((state()->renderHints & QPainter::Antialiasing) || (state()->renderHints & QPainter::HighQualityAntialiasing)) @@ -2011,7 +2011,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheFormat = QFontEngine::Format_A8; #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { d->funcs.glDisable(GL_MULTISAMPLE); d->glyphCacheFormat = QFontEngine::Format_A32; d->multisamplingAlwaysEnabled = false; diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index bfde2704461..c4862945bb1 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -176,7 +176,7 @@ public: #endif { #ifndef QT_OPENGL_ES_2 - if (!ctx->isES()) { + if (!ctx->isOpenGLES()) { QSurfaceFormat f = ctx->format(); // Geometry shaders require OpenGL >= 3.2 @@ -445,7 +445,7 @@ bool QOpenGLShader::compileSourceCode(const char *source) #ifdef QOpenGL_REDEFINE_HIGHP if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers - && QOpenGLContext::currentContext()->isES()) { + && QOpenGLContext::currentContext()->isOpenGLES()) { src.append(redefineHighp); srclen.append(GLint(sizeof(redefineHighp) - 1)); } @@ -674,7 +674,7 @@ bool QOpenGLShaderProgram::init() #ifndef QT_OPENGL_ES_2 // Resolve OpenGL 4 functions for tessellation shader support QSurfaceFormat format = context->format(); - if (!context->isES() + if (!context->isOpenGLES() && format.version() >= qMakePair(4, 0)) { d->tessellationFuncs = context->versionFunctions(); d->tessellationFuncs->initializeOpenGLFunctions(); @@ -3280,7 +3280,7 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context) #ifndef QT_OPENGL_ES_2 // Geometry shaders require OpenGL 3.2 or newer QSurfaceFormat format = context->format(); - return (!context->isES()) + return (!context->isOpenGLES()) && (format.version() >= qMakePair(3, 2)); #else // No geometry shader support in OpenGL ES2 @@ -3288,7 +3288,7 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context) #endif } else if (type == TessellationControl || type == TessellationEvaluation) { #if !defined(QT_OPENGL_ES_2) - return (!context->isES()) + return (!context->isOpenGLES()) && (format.version() >= qMakePair(4, 0)); #else // No tessellation shader support in OpenGL ES2 diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 078274eabd3..445e3ed64ea 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2432,7 +2432,7 @@ bool QOpenGLTexture::hasFeature(Feature feature) bool supported = false; #if !defined(QT_OPENGL_ES_2) - if (!ctx->isES()) { + if (!ctx->isOpenGLES()) { switch (feature) { case ImmutableMultisampleStorage: case TextureBuffer: @@ -2489,7 +2489,7 @@ bool QOpenGLTexture::hasFeature(Feature feature) } } - if (ctx->isES()) + if (ctx->isOpenGLES()) #endif { switch (feature) { @@ -2524,7 +2524,7 @@ bool QOpenGLTexture::hasFeature(Feature feature) void QOpenGLTexture::setMipBaseLevel(int baseLevel) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->textureId); @@ -2561,7 +2561,7 @@ int QOpenGLTexture::mipBaseLevel() const void QOpenGLTexture::setMipMaxLevel(int maxLevel) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->textureId); @@ -2598,7 +2598,7 @@ int QOpenGLTexture::mipMaxLevel() const void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->textureId); @@ -2708,7 +2708,7 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel) void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value) { #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -2737,7 +2737,7 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g, SwizzleValue b, SwizzleValue a) { #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -2786,7 +2786,7 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode) { #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -2977,7 +2977,7 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire void QOpenGLTexture::setBorderColor(QColor color) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3007,7 +3007,7 @@ void QOpenGLTexture::setBorderColor(QColor color) void QOpenGLTexture::setBorderColor(float r, float g, float b, float a) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3040,7 +3040,7 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a) void QOpenGLTexture::setBorderColor(int r, int g, int b, int a) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3075,7 +3075,7 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a) void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3187,7 +3187,7 @@ void QOpenGLTexture::borderColor(unsigned int *border) const void QOpenGLTexture::setMinimumLevelOfDetail(float value) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3224,7 +3224,7 @@ float QOpenGLTexture::minimumLevelOfDetail() const void QOpenGLTexture::setMaximumLevelOfDetail(float value) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3260,7 +3260,7 @@ float QOpenGLTexture::maximumLevelOfDetail() const void QOpenGLTexture::setLevelOfDetailRange(float min, float max) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3302,7 +3302,7 @@ QPair QOpenGLTexture::levelOfDetailRange() const void QOpenGLTexture::setLevelofDetailBias(float bias) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index 3287bbb9721..ac88d9d3a59 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -369,7 +369,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed || mask.format() == QImage::Format_ARGB32_Premultiplied #else || (mask.format() == QImage::Format_ARGB32_Premultiplied - && ctx->isES()) + && ctx->isOpenGLES()) #endif ) { for (int y = 0; y < maskHeight; ++y) { @@ -387,7 +387,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed src[x] = qRgba(r, g, b, avg); // swizzle the bits to accommodate for the GL_RGBA upload. #if Q_BYTE_ORDER != Q_BIG_ENDIAN - if (ctx->isES()) + if (ctx->isOpenGLES()) #endif src[x] = ARGB2RGBA(src[x]); } @@ -400,7 +400,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed #ifdef QT_OPENGL_ES_2 GLenum fmt = GL_RGBA; #else - GLenum fmt = ctx->isES() ? GL_RGBA : GL_BGRA; + GLenum fmt = ctx->isOpenGLES() ? GL_RGBA : GL_BGRA; #endif // QT_OPENGL_ES_2 #if Q_BYTE_ORDER == Q_BIG_ENDIAN diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 1d31fb56053..27aece8ecad 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) { // Resolve EXT_direct_state_access entry points if present - if (!context->isES() + if (!context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) { TextureParameteriEXT = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT"))); TextureParameterivEXT = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT"))); @@ -121,7 +121,7 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) } // Some DSA functions are part of NV_texture_multisample instead - if (!context->isES() + if (!context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) { TextureImage3DMultisampleNV = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureImage3DMultisampleNV"))); TextureImage2DMultisampleNV = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureImage2DMultisampleNV"))); @@ -190,7 +190,7 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) TexSubImage1D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexSubImage1D"))); #endif - if (context->isES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) { + if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) { TexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES"))); TexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES"))); CompressedTexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES"))); diff --git a/src/gui/opengl/qopengltimerquery.cpp b/src/gui/opengl/qopengltimerquery.cpp index 908a9cee079..5159ec58fc7 100644 --- a/src/gui/opengl/qopengltimerquery.cpp +++ b/src/gui/opengl/qopengltimerquery.cpp @@ -135,7 +135,7 @@ bool QOpenGLTimerQueryPrivate::create() return false; } - if (context->isES()) { + if (context->isOpenGLES()) { qWarning("QOpenGLTimerQuery: Not supported on OpenGL ES"); return false; } diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 9dfd5b2a6f3..5ebfc9a9c82 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -60,7 +60,7 @@ public: QVertexArrayObjectHelper(QOpenGLContext *context) { Q_ASSERT(context); - if (context->isES()) { + if (context->isOpenGLES()) { GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); @@ -159,7 +159,7 @@ bool QOpenGLVertexArrayObjectPrivate::create() context = ctx; QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { vaoFuncs.helper = new QVertexArrayObjectHelper(ctx); vaoFuncsType = OES; diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 6425aa065e0..5b6c4bb83d9 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -314,7 +314,7 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu funcs->glGenTextures(1, &d_ptr->textureId); funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index f266318ba66..19e453e7838 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -163,7 +163,7 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; - if (!context->contextHandle()->isES()) + if (!context->contextHandle()->isOpenGLES()) code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop; else code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2b49e4d2d18..78c4b23665e 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -539,7 +539,7 @@ void QGL2PaintEngineEx::beginNativePainting() d->funcs.glDisableVertexAttribArray(i); #ifndef QT_OPENGL_ES_2 - if (!d->ctx->contextHandle()->isES()) { + if (!d->ctx->contextHandle()->isOpenGLES()) { const QGLContext *ctx = d->ctx; const QGLFormat &fmt = d->device->format(); if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) @@ -597,7 +597,7 @@ void QGL2PaintEngineExPrivate::resetGLState() ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); #ifndef QT_OPENGL_ES_2 - if (!ctx->contextHandle()->isES()) { + if (!ctx->contextHandle()->isOpenGLES()) { // gl_Color, corresponding to vertex attribute 3, may have been changed float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; funcs.glVertexAttrib4fv(3, color); @@ -1364,7 +1364,7 @@ void QGL2PaintEngineEx::renderHintsChanged() state()->renderHintsChanged = true; #if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isES()) { + if (!d->ctx->contextHandle()->isOpenGLES()) { if ((state()->renderHints & QPainter::Antialiasing) || (state()->renderHints & QPainter::HighQualityAntialiasing)) glEnable(GL_MULTISAMPLE); @@ -2040,14 +2040,14 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_SCISSOR_TEST); #if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isES()) + if (!d->ctx->contextHandle()->isOpenGLES()) glDisable(GL_MULTISAMPLE); #endif d->glyphCacheFormat = QFontEngine::Format_A8; #if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isES()) { + if (!d->ctx->contextHandle()->isOpenGLES()) { d->glyphCacheFormat = QFontEngine::Format_A32; d->multisamplingAlwaysEnabled = false; } else { diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index b1e289254f4..f1da50a6b9d 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -319,7 +319,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub uchar g = src[x] >> 8; uchar b = src[x]; quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. - if (ctx->contextHandle()->isES()) { + if (ctx->contextHandle()->isOpenGLES()) { // swizzle the bits to accommodate for the GL_RGBA upload. src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); } else { @@ -333,7 +333,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub if (mask.format() == QImage::Format_RGB32) { GLenum format = GL_RGBA; #if !defined(QT_OPENGL_ES_2) - if (!ctx->contextHandle()->isES()) + if (!ctx->contextHandle()->isOpenGLES()) format = GL_BGRA; #endif glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits()); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3cfdcc549c1..ae70072c4d7 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1700,7 +1700,7 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp int w = size.width(); int h = size.height(); #ifndef QT_OPENGL_ES - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { //### glGetTexImage not in GL ES 2.0, need to do something else here! glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); } @@ -2285,7 +2285,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); QOpenGLContext *ctx = QOpenGLContext::currentContext(); - bool genMipmap = !ctx->isES(); + bool genMipmap = !ctx->isOpenGLES(); if (glFormat.directRendering() && (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap)) && target == GL_TEXTURE_2D @@ -2427,7 +2427,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G printf(" - did byte swapping (%d ms)\n", time.elapsed()); #endif } - if (ctx->isES()) { + if (ctx->isOpenGLES()) { // OpenGL/ES requires that the internal and external formats be // identical. internalFormat = externalFormat; @@ -2440,7 +2440,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G const QImage &constRef = img; // to avoid detach in bits()... glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, pixel_type, constRef.bits()); - if (genMipmap && ctx->isES()) + if (genMipmap && ctx->isOpenGLES()) q->functions()->glGenerateMipmap(target); #ifndef QT_NO_DEBUG GLenum error = glGetError(); @@ -2524,7 +2524,7 @@ int QGLContextPrivate::maxTextureSize() #ifndef QT_OPENGL_ES Q_Q(QGLContext); - if (!q->contextHandle()->isES()) { + if (!q->contextHandle()->isOpenGLES()) { GLenum proxy = GL_PROXY_TEXTURE_2D; GLint size; @@ -2702,7 +2702,7 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex Q_UNUSED(textureHeight); Q_UNUSED(textureTarget); #else - if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isES()) { + if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isOpenGLES()) { if (textureWidth == -1 || textureHeight == -1) { glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); @@ -2769,7 +2769,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text #endif #ifndef QT_OPENGL_ES_2 - if (!contextHandle()->isES()) { + if (!contextHandle()->isOpenGLES()) { #ifdef QT_OPENGL_ES if (textureTarget != GL_TEXTURE_2D) { qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); @@ -2831,7 +2831,7 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text Q_UNUSED(textureId); Q_UNUSED(textureTarget); #else - if (!contextHandle()->isES()) { + if (!contextHandle()->isOpenGLES()) { const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); @@ -4135,7 +4135,7 @@ void QGLWidget::glDraw() return; makeCurrent(); #ifndef QT_OPENGL_ES - if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isES()) + if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isOpenGLES()) glDrawBuffer(GL_FRONT); #endif QSize readback_target_size = d->glcx->d_ptr->readback_target_size; @@ -4180,7 +4180,7 @@ void QGLWidget::qglColor(const QColor& c) const #else Q_D(const QGLWidget); const QGLContext *ctx = QGLContext::currentContext(); - if (ctx && !ctx->contextHandle()->isES()) { + if (ctx && !ctx->contextHandle()->isOpenGLES()) { if (ctx->format().rgba()) glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? @@ -4212,7 +4212,7 @@ void QGLWidget::qglClearColor(const QColor& c) const #else Q_D(const QGLWidget); const QGLContext *ctx = QGLContext::currentContext(); - if (ctx && !ctx->contextHandle()->isES()) { + if (ctx && !ctx->contextHandle()->isOpenGLES()) { if (ctx->format().rgba()) glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? @@ -4387,7 +4387,7 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) { #ifndef QT_OPENGL_ES Q_D(QGLWidget); - if (!d->glcx->contextHandle()->isES()) { + if (!d->glcx->contextHandle()->isOpenGLES()) { Q_D(QGLWidget); if (str.isEmpty() || !isValid()) return; @@ -4477,7 +4477,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con { #ifndef QT_OPENGL_ES Q_D(QGLWidget); - if (!d->glcx->contextHandle()->isES()) { + if (!d->glcx->contextHandle()->isOpenGLES()) { Q_D(QGLWidget); if (str.isEmpty() || !isValid()) return; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 10e6ffde460..61d295f1731 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -326,7 +326,7 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) d->context = new QOpenGLContext; #if !defined(QT_OPENGL_ES) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { // On desktop, request latest released version QSurfaceFormat format; #if defined(Q_OS_MAC) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index bd8bc2f64ac..419055f1a3b 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -595,7 +595,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else - if (ctx->contextHandle()->isES()) { + if (ctx->contextHandle()->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -617,7 +617,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, size.width(), size.height()); } #else - if (ctx->contextHandle()->isES()) { + if (ctx->contextHandle()->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -647,7 +647,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, #ifdef QT_OPENGL_ES GLenum storage = GL_STENCIL_INDEX8; #else - GLenum storage = ctx->contextHandle()->isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; + GLenum storage = ctx->contextHandle()->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) @@ -849,7 +849,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) Q_D(QGLFramebufferObject); d->init(this, size, NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -869,7 +869,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) Q_D(QGLFramebufferObject); d->init(this, QSize(width, height), NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -926,7 +926,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, QSize(width, height), attachment, target, internal_format); } @@ -953,7 +953,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, size, attachment, target, internal_format); } diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h index 0edce5da2f1..1aefa0b4420 100644 --- a/src/opengl/qglframebufferobject_p.h +++ b/src/opengl/qglframebufferobject_p.h @@ -72,7 +72,7 @@ public: { #ifndef QT_OPENGL_ES_2 QOpenGLContext *ctx = QOpenGLContext::currentContext(); - const bool isES = ctx ? ctx->isES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL; + const bool isES = ctx ? ctx->isOpenGLES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL; internal_format = isES ? GL_RGBA : GL_RGBA8; #else internal_format = GL_RGBA; diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 42b3b47f7fd..5ad842bad4d 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -223,7 +223,7 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { // OpenGL ES 2 int features = QGLFunctions::Multitexture | QGLFunctions::Shaders | diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 32b18bfda4d..12b26e5381f 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -361,7 +361,7 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const glBindTexture(GL_TEXTURE_2D, texture_id); #ifndef QT_OPENGL_ES - GLenum format = ctx->isES() ? GL_RGBA : GL_RGBA8; + GLenum format = ctx->isOpenGLES() ? GL_RGBA : GL_RGBA8; glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0); #else glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); @@ -488,7 +488,7 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target) { Q_D(QGLPixelBuffer); #ifndef QT_OPENGL_ES - GLenum format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + GLenum format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; return d->qctx->bindTexture(image, target, GLint(format)); #else return d->qctx->bindTexture(image, target, GL_RGBA); @@ -507,7 +507,7 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target) { Q_D(QGLPixelBuffer); #ifndef QT_OPENGL_ES - GLenum format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + GLenum format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; return d->qctx->bindTexture(pixmap, target, GLint(format)); #else return d->qctx->bindTexture(pixmap, target, GL_RGBA); diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 65f217edf2d..6173ad12885 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -248,7 +248,7 @@ bool QGLShaderPrivate::create() shader = glfuncs->glCreateShader(GL_VERTEX_SHADER); #if !defined(QT_OPENGL_ES_2) else if (shaderType == QGLShader::Geometry - && !context->contextHandle()->isES()) + && !context->contextHandle()->isOpenGLES()) shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT); #endif else @@ -430,14 +430,14 @@ bool QGLShader::compileSourceCode(const char *source) srclen.append(GLint(headerLen)); } #ifdef QGL_DEFINE_QUALIFIERS - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { src.append(qualifierDefines); srclen.append(GLint(sizeof(qualifierDefines) - 1)); } #endif #ifdef QGL_REDEFINE_HIGHP if (d->shaderType == Fragment - && QOpenGLContext::currentContext()->isES()) { + && QOpenGLContext::currentContext()->isOpenGLES()) { src.append(redefineHighp); srclen.append(GLint(sizeof(redefineHighp) - 1)); } @@ -568,7 +568,7 @@ public: void initializeGeometryShaderFunctions() { QOpenGLContext *context = QOpenGLContext::currentContext(); - if (!context->isES()) { + if (!context->isOpenGLES()) { glProgramParameteri = (type_glProgramParameteri) context->getProcAddress("glProgramParameteri"); @@ -936,7 +936,7 @@ bool QGLShaderProgram::link() #if !defined(QT_OPENGL_ES_2) // Set up the geometry shader parameters - if (!QOpenGLContext::currentContext()->isES() + if (!QOpenGLContext::currentContext()->isOpenGLES() && d->glfuncs->glProgramParameteri) { foreach (QGLShader *shader, d->shaders) { if (shader->shaderType() & QGLShader::Geometry) { @@ -3074,7 +3074,7 @@ int QGLShaderProgram::maxGeometryOutputVertices() const { GLint n = 0; #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) + if (!QOpenGLContext::currentContext()->isOpenGLES()) glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); #endif return n; diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index e6624fb9ff4..75789db153b 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -242,7 +242,7 @@ EGLConfig QEglConfigChooser::chooseConfig() #ifdef EGL_VERSION_1_4 case QSurfaceFormat::DefaultRenderableType: #ifndef QT_NO_OPENGL - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) configureAttributes.append(EGL_OPENGL_BIT); else #endif // QT_NO_OPENGL @@ -366,7 +366,7 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, format.setRenderableType(QSurfaceFormat::OpenGL); else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType #ifndef QT_NO_OPENGL - && QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL + && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL #endif && (renderableType & EGL_OPENGL_BIT)) format.setRenderableType(QSurfaceFormat::OpenGL); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index de346632869..78bf8335267 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -243,7 +243,7 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co return true; case ThreadedOpenGL: #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - return QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL + return QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true; # else return true; @@ -308,7 +308,7 @@ QPlatformOpenGLContext { qCDebug(lcQpaGl) << __FUNCTION__ << context->format(); #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) { if (d->m_staticEGLContext.isNull()) { QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create(); if (!staticContext) @@ -319,7 +319,7 @@ QPlatformOpenGLContext } #endif #if !defined(QT_OPENGL_ES_2) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { if (d->m_staticOpenGLContext.isNull()) d->m_staticOpenGLContext = QSharedPointer(QOpenGLStaticContext::create()); diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 7e15be1d196..06c0122bbba 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -125,7 +125,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour return 0; } #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) { QWindowsEGLContext *windowsEglContext = static_cast(context->handle()); if (resource == QByteArrayLiteral("eglDisplay")) return windowsEglContext->eglDisplay(); @@ -136,7 +136,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour } #endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC #if !defined(QT_OPENGL_ES_2) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { QWindowsGLContext *windowsContext = static_cast(context->handle()); if (resource == QByteArrayLiteral("renderingContext")) return windowsContext->renderingContext(); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ee9bf9936c7..a6b7d194325 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -880,7 +880,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->surfaceType() == QWindow::OpenGLSurface) { setFlag(OpenGLSurface); #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) setFlag(OpenGL_ES2); #endif } diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 5831b33974f..ba2528d3cfe 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -754,7 +754,7 @@ void tst_QGL::openGLVersionCheck() #elif defined(QT_OPENGL_ES_2) QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); #else - if (QOpenGLContext::currentContext()->isES()) + if (QOpenGLContext::currentContext()->isOpenGLES()) QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); else QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1); @@ -1552,7 +1552,7 @@ void tst_QGL::fboFormat() #ifdef QT_OPENGL_ES_2 GL_RGBA; #else - QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL ? GL_RGBA : GL_RGBA8; + QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8; #endif QCOMPARE(int(format1.internalTextureFormat()), expectedFormat); @@ -1629,7 +1629,7 @@ void tst_QGL::fboFormat() #ifdef QT_OPENGL_ES_2 GL_RGBA #else - QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL ? GL_RGBA : GL_RGBA8 + QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8 #endif ); QVERIFY(!(format1c == format3c)); @@ -1642,7 +1642,7 @@ void tst_QGL::fboFormat() #ifdef QT_OPENGL_ES_2 GL_RGBA #else - QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL ? GL_RGBA : GL_RGBA8 + QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8 #endif ); QVERIFY(!(format1c == format4c)); @@ -2417,10 +2417,10 @@ void tst_QGL::extensions() QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Shaders)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Buffers)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Multisample)); - QVERIFY(!ctx->isES() || allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); + QVERIFY(!ctx->isOpenGLES() || allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::NPOTTextures) && allFeatures.testFlag(QOpenGLFunctions::NPOTTextureRepeat)); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { QVERIFY(!allFeatures.testFlag(QOpenGLFunctions::FixedFunctionPipeline)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); } diff --git a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp index cdd820cf5b8..2f09d847729 100644 --- a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp +++ b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp @@ -96,7 +96,7 @@ void tst_QGLFunctions::features() funcs.initializeGLFunctions(); // Validate the features against what we expect for this platform. - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { #if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) QGLFunctions::OpenGLFeatures allFeatures = (QGLFunctions::Multitexture | diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp index 999761e3f02..70e3a3b62ae 100644 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp @@ -339,7 +339,7 @@ static inline float qrandom() { return (rand() % 100) / 100.f; } void renderAScene(int w, int h) { - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { QGLFunctions funcs(QGLContext::currentContext()); Q_UNUSED(w); Q_UNUSED(h); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index ba9652a1700..bc2e4caacd2 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -2598,7 +2598,7 @@ void tst_QMdiArea::nativeSubWindows() if (platformName != QLatin1String("xcb") && platformName != QLatin1String("windows")) QSKIP(qPrintable(QString::fromLatin1("nativeSubWindows() does not work on this platform (%1).").arg(platformName))); #if defined(Q_OS_WIN) && !defined(QT_NO_OPENGL) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) QSKIP("nativeSubWindows() does not work with ANGLE on Windows, QTBUG-28545."); #endif { // Add native widgets after show. From 55d1aa3121063fcb41f8f4500c4319b64ca8ee67 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 24 Apr 2014 14:53:50 +0200 Subject: [PATCH 19/20] Use runtime detection of XInput 2.1 to disable legacy wheel events Ensure we fall back to using wheel button events if xinput 2.1 scroll events are not available. Handles lack of xinput 2.1 support in the server or in the input devices drivers. Task-number: QTBUG-38169 Change-Id: Ie4ad9069f648d0ab02d8f9540ed01ad58fd9e9d8 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection.cpp | 13 ++++++ src/plugins/platforms/xcb/qxcbconnection.h | 10 +++- .../platforms/xcb/qxcbconnection_xi2.cpp | 46 ++++++++++++++++++- src/plugins/platforms/xcb/qxcbwindow.cpp | 18 ++++---- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index f5f6c712c5d..e3b81c2b40c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1791,6 +1791,19 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub return true; } +bool QXcbConnection::xi2GetButtonState(void *event, int buttonNum) +{ + xXIDeviceEvent *xideviceevent = static_cast(event); + unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1]; + + for (int i = 0; i < (xideviceevent->buttons_len * 4); i++) { + if (buttonNum < 8) + return (buttonsMaskAddr[i] & (1 << buttonNum)); + buttonNum -= 8; + } + return false; +} + // Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: // - "pad0" became "extension" // - "pad1" and "pad" became "pad0" diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 13a0280baf9..1933b89a190 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -402,6 +402,12 @@ public: #elif defined(XCB_USE_XINPUT2) void xi2Select(xcb_window_t window); #endif +#ifdef XCB_USE_XINPUT21 + bool isUsingXInput21() { return m_xi2Enabled && m_xi2Minor >= 1; } +#else + bool isUsingXInput21() { return false; } +#endif + void sync(); void flush() { xcb_flush(m_connection); } @@ -511,11 +517,12 @@ private: QVector m_tabletData; #endif struct ScrollingDevice { - ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0) { } + ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } int deviceId; int verticalIndex, horizontalIndex; double verticalIncrement, horizontalIncrement; Qt::Orientations orientations; + Qt::Orientations legacyOrientations; QPointF lastScrollPosition; }; void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice); @@ -525,6 +532,7 @@ private: #if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO) static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value); static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode); + static bool xi2GetButtonState(void *event, int buttonNum); #endif xcb_connection_t *m_connection; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index d7b3c75aee9..831ccba6f66 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -134,7 +134,6 @@ void QXcbConnection::initializeXInput2() #ifdef XCB_USE_XINPUT21 case XIScrollClass: { XIScrollClassInfo *sci = reinterpret_cast(devices[i].classes[c]); - scrollingDevice.deviceId = devices[i].deviceid; if (sci->scroll_type == XIScrollTypeVertical) { scrollingDevice.orientations |= Qt::Vertical; scrollingDevice.verticalIndex = sci->number; @@ -147,6 +146,20 @@ void QXcbConnection::initializeXInput2() } break; } + case XIButtonClass: { + XIButtonClassInfo *bci = reinterpret_cast(devices[i].classes[c]); + for (int i=0; i < bci->num_buttons; ++i) { + const int buttonAtom = qatom(bci->labels[i]); + if (buttonAtom == QXcbAtom::ButtonWheelUp + || buttonAtom == QXcbAtom::ButtonWheelDown) { + scrollingDevice.legacyOrientations |= Qt::Vertical; + } else if (buttonAtom == QXcbAtom::ButtonHorizWheelLeft + || buttonAtom == QXcbAtom::ButtonHorizWheelRight) { + scrollingDevice.legacyOrientations |= Qt::Horizontal; + } + } + break; + } #endif default: break; @@ -170,7 +183,10 @@ void QXcbConnection::initializeXInput2() #endif // QT_NO_TABLETEVENT #ifdef XCB_USE_XINPUT21 - if (scrollingDevice.orientations) { + if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) { + scrollingDevice.deviceId = devices[i].deviceid; + // Only use legacy wheel button events when we don't have real scroll valuators. + scrollingDevice.legacyOrientations &= ~scrollingDevice.orientations; m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice); if (Q_UNLIKELY(debug_xinput_devices)) qDebug() << " it's a scrolling device"; @@ -256,6 +272,7 @@ void QXcbConnection::xi2Select(xcb_window_t window) if (!m_scrollingDevices.isEmpty()) { QVector xiEventMask(m_scrollingDevices.size()); bitMask = XI_MotionMask; + bitMask |= XI_ButtonReleaseMask; int i=0; Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) { xiEventMask[i].deviceid = scrollingDevice.deviceId; @@ -595,6 +612,31 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers); } } + } else if (xiEvent->evtype == XI_ButtonRelease) { + xXIDeviceEvent* xiDeviceEvent = reinterpret_cast(event); + if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) { + QPoint angleDelta; + if (scrollingDevice.legacyOrientations & Qt::Vertical) { + if (xi2GetButtonState(xiDeviceEvent, 4)) + angleDelta.setY(120); + else if (xi2GetButtonState(xiDeviceEvent, 5)) + angleDelta.setY(-120); + } + if (scrollingDevice.legacyOrientations & Qt::Horizontal) { + if (xi2GetButtonState(xiDeviceEvent, 6)) + angleDelta.setX(120); + if (xi2GetButtonState(xiDeviceEvent, 7)) + angleDelta.setX(-120); + } + if (!angleDelta.isNull()) { + QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y)); + QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y)); + Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods); + if (modifiers & Qt::AltModifier) + std::swap(angleDelta.rx(), angleDelta.ry()); + QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, QPoint(), angleDelta, modifiers); + } + } } #else Q_UNUSED(event); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index ad7e99bd498..386bf16c166 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1705,16 +1705,16 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); if (isWheel) { -#ifndef XCB_USE_XINPUT21 - // Logic borrowed from qapplication_x11.cpp - int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); - bool hor = (((event->detail == 4 || event->detail == 5) - && (modifiers & Qt::AltModifier)) - || (event->detail == 6 || event->detail == 7)); + if (!connection()->isUsingXInput21()) { + // Logic borrowed from qapplication_x11.cpp + int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); + bool hor = (((event->detail == 4 || event->detail == 5) + && (modifiers & Qt::AltModifier)) + || (event->detail == 6 || event->detail == 7)); - QWindowSystemInterface::handleWheelEvent(window(), event->time, - local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); -#endif + QWindowSystemInterface::handleWheelEvent(window(), event->time, + local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); + } return; } From 079f2bf5d8a4221b821ec8062affe2efaa9668a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 23 Apr 2014 11:32:44 +0200 Subject: [PATCH 20/20] Cocoa: Fix crash on Combobox popup close. Regression caused by 0be1c4899c. The calls to handleCloseEvent/flushWindowSystemEvents may result in popup window deletion and a stale/null pointer access. Get the window type before closing it. Task-number: QTBUG-38418 Change-Id: I212a56979e0248076e1eb5bf9ede1ff0d424e041 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 93462e7ea17..4065b57e467 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -637,9 +637,9 @@ static QTouchDevice *touchDevice = 0; return [super mouseDown:theEvent]; m_sendUpAsRightButton = false; if (m_platformWindow->m_activePopupWindow) { + Qt::WindowType type = m_platformWindow->m_activePopupWindow->type(); QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow); QWindowSystemInterface::flushWindowSystemEvents(); - Qt::WindowType type = m_platformWindow->m_activePopupWindow->type(); m_platformWindow->m_activePopupWindow = 0; // Consume the mouse event when closing the popup, except for tool tips // were it's expected that the event is processed normally.