diff options
Diffstat (limited to 'src')
56 files changed, 597 insertions, 263 deletions
diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index bd0475fc05..246c763fd6 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -3,7 +3,7 @@ TARGET = qtharfbuzzng CONFIG += \ static \ hide_symbols \ - exceptions_off rtti_off + exceptions_off rtti_off warn_off load(qt_helper_lib) diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h index cb68ab0e5b..9abb5df7f1 100644 --- a/src/3rdparty/harfbuzz-ng/src/config.h +++ b/src/3rdparty/harfbuzz-ng/src/config.h @@ -4,7 +4,6 @@ #define HAVE_OT #define HAVE_ATEXIT -#define HB_NO_MT #define HB_NO_UNICODE_FUNCS #define HB_DISABLE_DEPRECATED diff --git a/src/3rdparty/xkbcommon/Fix-compilation-on-libxcb-1.5.patch b/src/3rdparty/xkbcommon/Fix-compilation-on-libxcb-1.5.patch new file mode 100644 index 0000000000..691f142e5e --- /dev/null +++ b/src/3rdparty/xkbcommon/Fix-compilation-on-libxcb-1.5.patch @@ -0,0 +1,19 @@ +diff --git a/src/3rdparty/xkbcommon/src/x11/util.c b/src/3rdparty/xkbcommon/src/x11/util.c +index 92ff2e6..7659c71 100644 +--- a/src/3rdparty/xkbcommon/src/x11/util.c ++++ b/src/3rdparty/xkbcommon/src/x11/util.c +@@ -198,8 +198,12 @@ adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn, + * sit there waiting. Sad. + */ + err_discard: +- for (size_t j = i + 1; j < stop; j++) +- xcb_discard_reply(conn, cookies[j].sequence); ++ for (size_t j = i + 1; j < stop; j++) { ++ if (from[j] != XCB_ATOM_NONE) { ++ reply = xcb_get_atom_name_reply(conn, cookies[j % SIZE], NULL); ++ free(reply); ++ } ++ } + return false; + } + } diff --git a/src/3rdparty/xkbcommon/src/x11/util.c b/src/3rdparty/xkbcommon/src/x11/util.c index 92ff2e630e..7659c711a2 100644 --- a/src/3rdparty/xkbcommon/src/x11/util.c +++ b/src/3rdparty/xkbcommon/src/x11/util.c @@ -198,8 +198,12 @@ adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn, * sit there waiting. Sad. */ err_discard: - for (size_t j = i + 1; j < stop; j++) - xcb_discard_reply(conn, cookies[j].sequence); + for (size_t j = i + 1; j < stop; j++) { + if (from[j] != XCB_ATOM_NONE) { + reply = xcb_get_atom_name_reply(conn, cookies[j % SIZE], NULL); + free(reply); + } + } return false; } } diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java index 669fbaab0d..70b02d8d04 100644 --- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java +++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java @@ -240,8 +240,12 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate node.setClassName(m_view.getClass().getName() + DEFAULT_CLASS_NAME); node.setPackageName(m_view.getContext().getPackageName()); + if (!QtNativeAccessibility.populateNode(virtualViewId, node)) + return node; + + // set only if valid, otherwise we return a node that is invalid and will crash when accessed node.setSource(m_view, virtualViewId); - QtNativeAccessibility.populateNode(virtualViewId, node); + if (TextUtils.isEmpty(node.getText()) && TextUtils.isEmpty(node.getContentDescription())) Log.w(TAG, "AccessibilityNodeInfo with empty contentDescription: " + virtualViewId); diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java index b1cc82c065..8a53623957 100644 --- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java +++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java @@ -54,5 +54,5 @@ class QtNativeAccessibility static native int hitTest(float x, float y); static native boolean clickAction(int objectId); - static native void populateNode(int objectId, AccessibilityNodeInfo node); + static native boolean populateNode(int objectId, AccessibilityNodeInfo node); } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index b396dfdfa1..554c54d4a0 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -170,6 +170,13 @@ public class QtActivityDelegate m_layout.requestLayout(); } + public void updateFullScreen() + { + if (m_fullScreen) { + m_fullScreen = false; + setFullScreen(true); + } + } // input method hints - must be kept in sync with QTDIR/src/corelib/global/qnamespace.h private final int ImhHiddenText = 0x1; @@ -213,6 +220,10 @@ public class QtActivityDelegate return false; m_keyboardIsVisible = visibility; QtNative.keyboardVisibilityChanged(m_keyboardIsVisible); + + if (visibility == false) + updateFullScreen(); // Hiding the keyboard clears the immersive mode, so we need to set it again. + return true; } public void resetSoftwareKeyboard() @@ -721,12 +732,7 @@ public class QtActivityDelegate QtNative.updateApplicationState(ApplicationActive); QtNative.clearLostActions(); QtNative.updateWindow(); - - if (m_fullScreen) { - // Suspending the app clears the immersive mode, so we need to set it again. - m_fullScreen = false; // Force the setFullScreen() call below to actually do something - setFullScreen(true); - } + updateFullScreen(); // Suspending the app clears the immersive mode, so we need to set it again. } } } diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index c0f26ad803..f16144771f 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -254,7 +254,20 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve QString QUtf8::convertToUnicode(const char *chars, int len) { - QString result(len + 1, Qt::Uninitialized); // worst case + // UTF-8 to UTF-16 always needs the exact same number of words or less: + // UTF-8 UTF-16 + // 1 byte 1 word + // 2 bytes 1 word + // 3 bytes 1 word + // 4 bytes 2 words (one surrogate pair) + // That is, we'll use the full buffer if the input is US-ASCII (1-byte UTF-8), + // half the buffer for U+0080-U+07FF text (e.g., Greek, Cyrillic, Arabic) or + // non-BMP text, and one third of the buffer for U+0800-U+FFFF text (e.g, CJK). + // + // The table holds for invalid sequences too: we'll insert one replacement char + // per invalid byte. + QString result(len, Qt::Uninitialized); + ushort *dst = reinterpret_cast<ushort *>(const_cast<QChar *>(result.constData())); const uchar *src = reinterpret_cast<const uchar *>(chars); const uchar *end = src + len; @@ -299,7 +312,18 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte int res; uchar ch = 0; - QString result(need + len + 1, Qt::Uninitialized); // worst case + // See above for buffer requirements for stateless decoding. However, that + // fails if the state is not empty. The following situations can add to the + // requirements: + // state contains chars starts with requirement + // 1 of 2 bytes valid continuation 0 + // 2 of 3 bytes same 0 + // 3 bytes of 4 same +1 (need to insert surrogate pair) + // 1 of 2 bytes invalid continuation +1 (need to insert replacement and restart) + // 2 of 3 bytes same +1 (same) + // 3 of 4 bytes same +1 (same) + QString result(need + len + 1, Qt::Uninitialized); + ushort *dst = reinterpret_cast<ushort *>(const_cast<QChar *>(result.constData())); const uchar *src = reinterpret_cast<const uchar *>(chars); const uchar *end = src + len; @@ -322,15 +346,17 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte const uchar *begin = &remainingCharsData[1]; res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(remainingCharsData[0], dst, begin, static_cast<const uchar *>(remainingCharsData) + remainingCharsCount + newCharsToCopy); - if (res == QUtf8BaseTraits::EndOfString) { + if (res == QUtf8BaseTraits::Error || (res == QUtf8BaseTraits::EndOfString && len == 0)) { + // special case for len == 0: + // if we were supplied an empty string, terminate the previous, unfinished sequence with error + ++invalid; + *dst++ = replacement; + } else if (res == QUtf8BaseTraits::EndOfString) { // if we got EndOfString again, then there were too few bytes in src; // copy to our state and return state->remainingChars = remainingCharsCount + newCharsToCopy; memcpy(&state->state_data[0], remainingCharsData, state->remainingChars); return QString(); - } else if (res == QUtf8BaseTraits::Error) { - ++invalid; - *dst++ = replacement; } else if (!headerdone && res >= 0) { // eat the UTF-8 BOM headerdone = true; @@ -339,8 +365,10 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte } // adjust src now that we have maybe consumed a few chars - //Q_ASSERT(res > remainingCharsCount) - src += res - remainingCharsCount; + if (res >= 0) { + Q_ASSERT(res > remainingCharsCount); + src += res - remainingCharsCount; + } } } diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 321525ca18..63a0266948 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1752,7 +1752,7 @@ bool QConfFileSettingsPrivate::readIniLine(const QByteArray &data, int &dataPos, if (i == lineStart + 1) { char ch; - while (i < dataLen && ((ch = data.at(i) != '\n') && ch != '\r')) + while (i < dataLen && (((ch = data.at(i)) != '\n') && ch != '\r')) ++i; lineStart = i; } else if (!inQuotes) { diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 7debf0d774..64ad2ff0d3 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -435,10 +435,10 @@ static inline UINT inputTimerMask() UINT result = QS_TIMER | QS_INPUT | QS_RAWINPUT; // QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of // QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8. -#if WINVER > 0x0602 +#if WINVER > 0x0601 if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) result &= ~(QS_TOUCH | QS_POINTER); -#endif // WINVER > 0x0602 +#endif // WINVER > 0x0601 return result; } diff --git a/src/corelib/kernel/qppsattribute.cpp b/src/corelib/kernel/qppsattribute.cpp index f6745d2354..93d7ae756e 100644 --- a/src/corelib/kernel/qppsattribute.cpp +++ b/src/corelib/kernel/qppsattribute.cpp @@ -127,8 +127,7 @@ QPpsAttribute QPpsAttributePrivate::createPpsAttribute(const QPpsAttributeMap &v // /////////////////////////// -QPpsAttribute::QPpsAttribute(): - d(new QPpsAttributePrivate()) +QPpsAttribute::QPpsAttribute() : d(new QPpsAttributePrivate()) { } @@ -136,7 +135,7 @@ QPpsAttribute::~QPpsAttribute() { } -QPpsAttribute::QPpsAttribute(const QPpsAttribute &other): d(other.d) +QPpsAttribute::QPpsAttribute(const QPpsAttribute &other) : d(other.d) { } @@ -147,7 +146,7 @@ QPpsAttribute &QPpsAttribute::operator=(const QPpsAttribute &other) } #ifdef Q_COMPILER_RVALUE_REFS -QPpsAttribute::QPpsAttribute(QPpsAttribute &&other): d(other.d) +QPpsAttribute::QPpsAttribute(QPpsAttribute &&other) : d(other.d) { other.d->type = QPpsAttribute::None; } diff --git a/src/corelib/kernel/qppsobject.cpp b/src/corelib/kernel/qppsobject.cpp index eb8e69baff..1095ad51da 100644 --- a/src/corelib/kernel/qppsobject.cpp +++ b/src/corelib/kernel/qppsobject.cpp @@ -94,12 +94,12 @@ Q_GLOBAL_STATIC(QPpsMaxSize, ppsMaxSize) // /////////////////////////////////////////////////////////////////////////////// -QPpsObjectPrivate::QPpsObjectPrivate(const QString &path) : - notifier(0), - path(path), - error(EOK), - fd(-1), - readyReadEnabled(true) +QPpsObjectPrivate::QPpsObjectPrivate(const QString &path) + : notifier(0), + path(path), + error(EOK), + fd(-1), + readyReadEnabled(true) { } @@ -490,9 +490,9 @@ void QPpsObjectPrivate::encodeObject(pps_encoder_t *encoder, const QVariantMap & // /////////////////////////////////////////////////////////////////////////////// -QPpsObject::QPpsObject(const QString &path, QObject *parent) : - QObject(parent), - d_ptr(new QPpsObjectPrivate(path)) +QPpsObject::QPpsObject(const QString &path, QObject *parent) + : QObject(parent), + d_ptr(new QPpsObjectPrivate(path)) { } diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 183a16a7ad..ac66bd00ce 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -50,11 +50,11 @@ #endif QT_BEGIN_NAMESPACE +static const char digits[] = "0123456789abcdef"; + template <class Char, class Integral> void _q_toHex(Char *&dst, Integral value) { - static const char digits[] = "0123456789abcdef"; - value = qToBigEndian(value); const char* p = reinterpret_cast<const char*>(&value); diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index 9ef4ee91c6..11969e12d3 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -353,7 +353,8 @@ public: inline Direction direction() const { return QChar::direction(ucs); } inline JoiningType joiningType() const { return QChar::joiningType(ucs); } #if QT_DEPRECATED_SINCE(5, 3) - QT_DEPRECATED inline Joining joining() const { + QT_DEPRECATED inline Joining joining() const + { switch (QChar::joiningType(ucs)) { case QChar::Joining_Causing: return QChar::Center; case QChar::Joining_Dual: return QChar::Dual; diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 801876629c..d6f1d6c942 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2405,6 +2405,9 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT local.tm_year = sysTime.wYear - 1900; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // localtime() is required to work as if tzset() was called before it. + // localtime_r() does not have this requirement, so make an explicit call. + qt_tzset(); // Use the reentrant version of localtime() where available // as is thread-safe and doesn't use a shared static data area tm *res = 0; diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 928707660b..e227a483c4 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -125,7 +125,7 @@ static uint crc32(const Char *ptr, size_t len, uint h) # else p += 4; for ( ; p <= e; p += 4) - h = _mm_crc32_u32(h, *reinterpret_cast<const uint *>(p)); + h = _mm_crc32_u32(h, *reinterpret_cast<const uint *>(p - 4)); p -= 4; len = e - p; # endif @@ -227,12 +227,13 @@ uint qHash(QLatin1String key, uint seed) Q_DECL_NOTHROW */ static uint qt_create_qhash_seed() { + uint seed = 0; + +#ifndef QT_BOOTSTRAPPED QByteArray envSeed = qgetenv("QT_HASH_SEED"); if (!envSeed.isNull()) return envSeed.toUInt(); - uint seed = 0; - #ifdef Q_OS_UNIX int randomfd = qt_safe_open("/dev/urandom", O_RDONLY); if (randomfd == -1) @@ -259,17 +260,16 @@ static uint qt_create_qhash_seed() seed ^= timestamp; seed ^= (timestamp >> 32); -#ifndef QT_BOOTSTRAPPED quint64 pid = QCoreApplication::applicationPid(); seed ^= pid; seed ^= (pid >> 32); -#endif // QT_BOOTSTRAPPED quintptr seedPtr = reinterpret_cast<quintptr>(&seed); seed ^= seedPtr; #if QT_POINTER_SIZE == 8 seed ^= (seedPtr >> 32); #endif +#endif // QT_BOOTSTRAPPED return seed; } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 359d0c49e5..3985bc76fe 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -949,7 +949,8 @@ public: QChar::Direction direction() const { return QChar(*this).direction(); } QChar::JoiningType joiningType() const { return QChar(*this).joiningType(); } #if QT_DEPRECATED_SINCE(5, 3) - QT_DEPRECATED QChar::Joining joining() const { + QT_DEPRECATED QChar::Joining joining() const + { switch (QChar(*this).joiningType()) { case QChar::Joining_Causing: return QChar::Center; case QChar::Joining_Dual: return QChar::Dual; diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in index 75a2385d57..f9c327f938 100644 --- a/src/gui/Qt5GuiConfigExtras.cmake.in +++ b/src/gui/Qt5GuiConfigExtras.cmake.in @@ -94,7 +94,7 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs) !!ENDIF foreach(_lib ${Libs}) string(REGEX REPLACE "[^_A-Za-z0-9]" "_" _cmake_lib_name ${_lib}) - if (NOT TARGET Qt5::Gui_${_cmake_lib_name}) + if (NOT TARGET Qt5::Gui_${_cmake_lib_name} AND NOT _Qt5Gui_${_cmake_lib_name}_LIBRARY_DONE) find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY ${_lib} !!IF !isEmpty(CROSS_COMPILE) PATHS \"${LibDir}\" @@ -106,42 +106,51 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs) !!IF mac set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}") !!ENDIF - if (NOT Qt5Gui_${_cmake_lib_name}_LIBRARY) - if (\"${ARGN}\" STREQUAL \"OPTIONAL\") - break() - else() - message(FATAL_ERROR \"Failed to find \\\"${_lib}\\\" in \\\"${LibDir}\\\" with CMAKE_CXX_LIBRARY_ARCHITECTURE \\\"${CMAKE_CXX_LIBRARY_ARCHITECTURE}\\\".\") - endif() - endif() - add_library(Qt5::Gui_${_cmake_lib_name} SHARED IMPORTED) - set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_${Name}_INCLUDE_DIRS}) - - set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - _qt5_Gui_check_file_exists(\"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") - set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") + if (WIN32 AND NOT Qt5Gui_${_cmake_lib_name}_LIBRARY) + # The above find_library call doesn't work for finding + # libraries in Windows SDK paths outside of the proper + # environment. Just add the library name to the result + # variable instead. + # We avoid doing this in the first case because Qt may be + # compiled with another set of GL libraries (such as coming + # from ANGLE). The point of these find calls is to try to + # find the same binaries as Qt is compiled with (as they are + # in the interface of QtGui), so an effort is made to do so + # above with paths known to qmake. + set(_Qt5Gui_${_cmake_lib_name}_LIBRARY_DONE TRUE) + unset(Qt5Gui_${_cmake_lib_name}_LIBRARY CACHE) + list(APPEND Qt5Gui_${Name}_LIBRARIES ${_lib}) + else() + add_library(Qt5::Gui_${_cmake_lib_name} SHARED IMPORTED) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_${Name}_INCLUDE_DIRS}) + + set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + _qt5_Gui_check_file_exists(\"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") !!IF !isEmpty(CMAKE_WINDOWS_BUILD) - set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") !!ENDIF - unset(Qt5Gui_${_cmake_lib_name}_LIBRARY CACHE) + unset(Qt5Gui_${_cmake_lib_name}_LIBRARY CACHE) - find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG ${_lib}d - PATHS \"${LibDir}\" + find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG ${_lib}d + PATHS \"${LibDir}\" !!IF !mac - NO_DEFAULT_PATH + NO_DEFAULT_PATH !!ENDIF - ) - if (Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG) - set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - _qt5_Gui_check_file_exists(\"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") - set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") + ) + if (Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + _qt5_Gui_check_file_exists(\"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") !!IF !isEmpty(CMAKE_WINDOWS_BUILD) - set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") !!ENDIF + endif() + unset(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG CACHE) + list(APPEND Qt5Gui_${Name}_LIBRARIES Qt5::Gui_${_cmake_lib_name}) endif() - unset(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG CACHE) endif() - list(APPEND Qt5Gui_${Name}_LIBRARIES Qt5::Gui_${_cmake_lib_name}) endforeach() if (NOT CMAKE_CROSSCOMPILING) foreach(_dir ${Qt5Gui_${Name}_INCLUDE_DIRS}) @@ -152,7 +161,7 @@ endmacro() !!IF !isEmpty(CMAKE_EGL_LIBS) -_qt5gui_find_extra_libs(EGL \"$$CMAKE_EGL_LIBS\" \"$$CMAKE_EGL_LIBDIR\" \"$$CMAKE_EGL_INCDIRS\" OPTIONAL) +_qt5gui_find_extra_libs(EGL \"$$CMAKE_EGL_LIBS\" \"$$CMAKE_EGL_LIBDIR\" \"$$CMAKE_EGL_INCDIRS\") !!ENDIF !!IF !isEmpty(CMAKE_OPENGL_LIBS) diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp index efe769badf..e6dbb70618 100644 --- a/src/gui/opengl/qopengltextureblitter.cpp +++ b/src/gui/opengl/qopengltextureblitter.cpp @@ -261,12 +261,12 @@ bool QOpenGLTextureBlitter::create() d->vertexBuffer.create(); d->vertexBuffer.bind(); - d->vertexBuffer.allocate(vertex_buffer_data, sizeof(vertex_buffer_data) * sizeof(vertex_buffer_data[0])); + d->vertexBuffer.allocate(vertex_buffer_data, sizeof(vertex_buffer_data)); d->vertexBuffer.release(); d->textureBuffer.create(); d->textureBuffer.bind(); - d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data) * sizeof(texture_buffer_data[0])); + d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data)); d->textureBuffer.release(); d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord"); diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp index 855ab4e485..db1325d85b 100644 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -57,6 +57,13 @@ QT_BEGIN_NAMESPACE static QBasicAtomicPointer<QNetworkConfigurationManagerPrivate> connManager_ptr; static QBasicAtomicInt appShutdown; +static void connManager_prepare() +{ + int shutdown = appShutdown.fetchAndStoreAcquire(0); + Q_ASSERT(shutdown == 0 || shutdown == 1); + Q_UNUSED(shutdown); +} + static void connManager_cleanup() { // this is not atomic or thread-safe! @@ -68,8 +75,9 @@ static void connManager_cleanup() cmp->cleanup(); } -void QNetworkConfigurationManagerPrivate::addPostRoutine() +void QNetworkConfigurationManagerPrivate::addPreAndPostRoutine() { + qAddPreRoutine(connManager_prepare); qAddPostRoutine(connManager_cleanup); } @@ -85,12 +93,12 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() if (QCoreApplicationPrivate::mainThread() == QThread::currentThread()) { // right thread or no main thread yet - ptr->addPostRoutine(); + ptr->addPreAndPostRoutine(); ptr->initialize(); } else { // wrong thread, we need to make the main thread do this QObject *obj = new QObject; - QObject::connect(obj, SIGNAL(destroyed()), ptr, SLOT(addPostRoutine()), Qt::DirectConnection); + QObject::connect(obj, SIGNAL(destroyed()), ptr, SLOT(addPreAndPostRoutine()), Qt::DirectConnection); ptr->initialize(); // this moves us to the right thread obj->moveToThread(QCoreApplicationPrivate::mainThread()); obj->deleteLater(); diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index d0913a843a..78b90b60a8 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -94,7 +94,7 @@ public: public Q_SLOTS: void updateConfigurations(); - static void addPostRoutine(); + static void addPreAndPostRoutine(); Q_SIGNALS: void configurationAdded(const QNetworkConfiguration &config); diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc index e1bb1b9316..77fbec9943 100644 --- a/src/network/doc/src/ssl.qdoc +++ b/src/network/doc/src/ssl.qdoc @@ -57,7 +57,7 @@ system: \code - ./configure -openssl-linked OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' + OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' ./configure -openssl-linked \endcode To disable SSL support in a Qt build, configure Qt with the \c{-no-openssl} diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp index 97a402901e..e111a190cb 100644 --- a/src/network/kernel/qdnslookup.cpp +++ b/src/network/kernel/qdnslookup.cpp @@ -282,6 +282,11 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, QObject *parent) } /*! + \fn QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent) + \internal +*/ + +/*! Destroys the QDnsLookup object. It is safe to delete a QDnsLookup object even if it is not finished, you diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 173d8eaa89..f869039687 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -238,9 +238,7 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *ciph ciph.d->encryptionMethod = descriptionList.at(4).mid(4); ciph.d->exportable = (descriptionList.size() > 6 && descriptionList.at(6) == QLatin1String("export")); - ciph.d->bits = cipher->strength_bits; - ciph.d->supportedBits = cipher->alg_bits; - + ciph.d->bits = q_SSL_CIPHER_get_bits(cipher, &ciph.d->supportedBits); } return ciph; } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index b75893d00f..ca692510c1 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -205,6 +205,7 @@ DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return) DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return) DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return) DEFINEFUNC3(char *, SSL_CIPHER_description, SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return) +DEFINEFUNC2(int, SSL_CIPHER_get_bits, SSL_CIPHER *a, a, int *b, b, return 0, return) DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return) #if OPENSSL_VERSION_NUMBER >= 0x00908000L // 0.9.8 broke SC and BC by changing this function's signature. @@ -736,6 +737,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(sk_pop_free) RESOLVEFUNC(sk_value) RESOLVEFUNC(SSL_CIPHER_description) + RESOLVEFUNC(SSL_CIPHER_get_bits) RESOLVEFUNC(SSL_CTX_check_private_key) RESOLVEFUNC(SSL_CTX_ctrl) RESOLVEFUNC(SSL_CTX_free) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 75e239237e..34c0040e56 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -296,6 +296,7 @@ char * q_sk_value(STACK *a, int b); int q_SSL_accept(SSL *a); int q_SSL_clear(SSL *a); char *q_SSL_CIPHER_description(SSL_CIPHER *a, char *b, int c); +int q_SSL_CIPHER_get_bits(SSL_CIPHER *a, int *b); int q_SSL_connect(SSL *a); #if OPENSSL_VERSION_NUMBER >= 0x00908000L // 0.9.8 broke SC and BC by changing this function's signature. diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 93d897503b..27a490335b 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -39,6 +39,13 @@ ** ****************************************************************************/ +#include <QtCore/qsystemdetection.h> +#if defined(Q_OS_IOS) +#import <UIKit/UIKit.h> +#elif defined(Q_OS_OSX) +#import <Cocoa/Cocoa.h> +#endif + #include "qmacmime_p.h" #include "qguiapplication.h" @@ -115,6 +122,7 @@ const QStringList& qt_mac_enabledDraggedTypes() \list \i public.utf8-plain-text - converts to "text/plain" \i public.utf16-plain-text - converts to "text/plain" + \i public.text - converts to "text/plain" \i public.html - converts to "text/html" \i public.url - converts to "text/uri-list" \i public.file-url - converts to "text/uri-list" @@ -282,9 +290,9 @@ QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, Q return ret; } -class QMacPasteboardMimePlainText : public QMacInternalPasteboardMime { +class QMacPasteboardMimePlainTextFallback : public QMacInternalPasteboardMime { public: - QMacPasteboardMimePlainText() : QMacInternalPasteboardMime(MIME_ALL) { } + QMacPasteboardMimePlainTextFallback() : QMacInternalPasteboardMime(MIME_ALL) { } QString convertorName(); QString flavorFor(const QString &mime); @@ -294,52 +302,54 @@ public: QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); }; -QString QMacPasteboardMimePlainText::convertorName() +QString QMacPasteboardMimePlainTextFallback::convertorName() { - return QLatin1String("PlainText"); + return QLatin1String("PlainText (public.text)"); } -QString QMacPasteboardMimePlainText::flavorFor(const QString &mime) +QString QMacPasteboardMimePlainTextFallback::flavorFor(const QString &mime) { if (mime == QLatin1String("text/plain")) - return QLatin1String("com.apple.traditional-mac-plain-text"); + return QLatin1String("public.text"); return QString(); } -QString QMacPasteboardMimePlainText::mimeFor(QString flav) +QString QMacPasteboardMimePlainTextFallback::mimeFor(QString flav) { - if (flav == QLatin1String("com.apple.traditional-mac-plain-text")) + if (flav == QLatin1String("public.text")) return QLatin1String("text/plain"); return QString(); } -bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav) +bool QMacPasteboardMimePlainTextFallback::canConvert(const QString &mime, QString flav) { - return flavorFor(mime) == flav; + return mime == mimeFor(flav); } -QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) +QVariant QMacPasteboardMimePlainTextFallback::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) { if (data.count() > 1) - qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data"); - const QByteArray &firstData = data.first(); - QVariant ret; - if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) { + qWarning("QMacPasteboardMimePlainTextFallback: Cannot handle multiple member data"); + + if (flavor == QLatin1String("public.text")) { + // Note that public.text is documented by Apple to have an undefined encoding. From + // testing it seems that utf8 is normally used, at least by Safari on iOS. + const QByteArray &firstData = data.first(); return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false)); + firstData.size(), kCFStringEncodingUTF8, false)); } else { qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); } - return ret; + return QVariant(); } -QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor) +QList<QByteArray> QMacPasteboardMimePlainTextFallback::convertFromMime(const QString &, QVariant data, QString flavor) { QList<QByteArray> ret; QString string = data.toString(); - if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) - ret.append(string.toLatin1()); + if (flavor == QLatin1String("public.text")) + ret.append(string.toUtf8()); return ret; } @@ -477,6 +487,86 @@ QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mim return ret; } +class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); + QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeRtfText::convertorName() +{ + return QLatin1String("Rtf"); +} + +QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime) +{ + if (mime == QLatin1String("text/html")) + return QLatin1String("public.rtf"); + return QString(); +} + +QString QMacPasteboardMimeRtfText::mimeFor(QString flav) +{ + if (flav == QLatin1String("public.rtf")) + return QLatin1String("text/html"); + return QString(); +} + +bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav) +{ +#if defined(Q_OS_IOS) + if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_7_0) + return false; +#endif + + return mime == mimeFor(flav); +} + +QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor) +{ + if (!canConvert(mimeType, flavor)) + return QVariant(); + if (data.count() > 1) + qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data"); + + // Read RTF into to NSAttributedString, then convert the string to HTML + NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.at(0).toNSData() + options:[NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute] + documentAttributes:nil + error:nil]; + + NSError *error; + NSRange range = NSMakeRange(0, [string length]); + NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSData *htmlData = [string dataFromRange:range documentAttributes:dict error:&error]; + return QByteArray::fromNSData(htmlData); +} + +QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor) +{ + QList<QByteArray> ret; + if (!canConvert(mime, flavor)) + return ret; + + NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.toByteArray().toNSData() + options:[NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute] + documentAttributes:nil + error:nil]; + + NSError *error; + NSRange range = NSMakeRange(0, [string length]); + NSDictionary *dict = [NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSData *rtfData = [string dataFromRange:range documentAttributes:dict error:&error]; + ret << QByteArray::fromNSData(rtfData); + return ret; +} + class QMacPasteboardMimeFileUri : public QMacInternalPasteboardMime { public: QMacPasteboardMimeFileUri() : QMacInternalPasteboardMime(MIME_ALL) { } @@ -696,8 +786,9 @@ void QMacInternalPasteboardMime::initializeMimeTypes() new QMacPasteboardMimeAny; //standard types that we wrap + new QMacPasteboardMimePlainTextFallback; new QMacPasteboardMimeUnicodeText; - new QMacPasteboardMimePlainText; + new QMacPasteboardMimeRtfText; new QMacPasteboardMimeHTMLText; new QMacPasteboardMimeFileUri; new QMacPasteboardMimeUrl; diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index e99581183e..b6293e60ec 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -171,7 +171,7 @@ void QEGLPlatformCursor::createShaderPrograms() m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry"); m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry"); - m_textureEntry = m_program->attributeLocation("texture"); + m_textureEntry = m_program->uniformLocation("texture"); } void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index a730993df7..0d1f9455e1 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -659,6 +659,9 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr) QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { QFontEngineFT *engine = static_cast<QFontEngineFT*>(QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference)); + if (engine == 0) + return 0; + QFontDef fontDef = engine->fontDef; QFontEngineFT::GlyphFormat format; diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index 1ccab0a859..0fa1d96242 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -1024,15 +1024,28 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event) case QAccessible::ValueChanged: { if (sendObject || sendObject_value_changed || sendObject_property_change_accessible_value) { QAccessibleInterface * iface = event->accessibleInterface(); - if (!iface || !iface->valueInterface()) { - qWarning() << "ValueChanged event from invalid accessible: " << iface; + if (!iface) { + qWarning() << "ValueChanged event from invalid accessible."; return; } - - QString path = pathForInterface(iface); - QVariantList args = packDBusSignalArguments(QLatin1String("accessible-value"), 0, 0, variantForPath(path)); - sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), - QLatin1String("PropertyChange"), args); + if (iface->valueInterface()) { + QString path = pathForInterface(iface); + QVariantList args = packDBusSignalArguments(QLatin1String("accessible-value"), 0, 0, variantForPath(path)); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("PropertyChange"), args); + } else if (iface->role() == QAccessible::ComboBox) { + // Combo Box with AT-SPI likes to be special + // It requires a name-change to update caches and then selection-changed + QString path = pathForInterface(iface); + QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path)); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("PropertyChange"), args1); + QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0)))); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("SelectionChanged"), args2); + } else { + qWarning() << "ValueChanged event and no ValueInterface or ComboBox: " << iface; + } } break; } diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 2d8b9be092..554ad26e51 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -419,6 +419,8 @@ QCoreWlanEngine::QCoreWlanEngine(QObject *parent) QCoreWlanEngine::~QCoreWlanEngine() { + scanThread->wait(5000); + while (!foundConfigurations.isEmpty()) delete foundConfigurations.takeFirst(); [listener remove]; diff --git a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm b/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm index 057aec5487..ba1cf33258 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm @@ -404,6 +404,8 @@ QCoreWlanEngine::QCoreWlanEngine(QObject *parent) QCoreWlanEngine::~QCoreWlanEngine() { + scanThread->wait(5000); + while (!foundConfigurations.isEmpty()) delete foundConfigurations.takeFirst(); [listener remove]; diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index a38741cc91..fa7e259460 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -170,7 +170,7 @@ if (!clazz) { \ jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \ if (!method) { \ __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ - return; \ + return false; \ } \ env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \ } @@ -190,12 +190,12 @@ if (!clazz) { \ return jdesc; } - static void populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node) + static bool populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node) { QAccessibleInterface *iface = interfaceFromId(objectId); if (!iface || !iface->isValid()) { __android_log_print(ANDROID_LOG_WARN, m_qtTag, "Accessibility: populateNode for Invalid ID"); - return; + return false; } QAccessible::State state = iface->state(); @@ -215,11 +215,10 @@ if (!clazz) { \ } CALL_METHOD(node, "setEnabled", "(Z)V", !state.disabled) - //CALL_METHOD(node, "setFocusable", "(Z)V", state.focusable) - CALL_METHOD(node, "setFocusable", "(Z)V", true) - //CALL_METHOD(node, "setFocused", "(Z)V", state.focused) - CALL_METHOD(node, "setCheckable", "(Z)V", state.checkable) - CALL_METHOD(node, "setChecked", "(Z)V", state.checked) + CALL_METHOD(node, "setFocusable", "(Z)V", (bool)state.focusable) + CALL_METHOD(node, "setFocused", "(Z)V", (bool)state.focused) + CALL_METHOD(node, "setCheckable", "(Z)V", (bool)state.checkable) + CALL_METHOD(node, "setChecked", "(Z)V", (bool)state.checked) CALL_METHOD(node, "setVisibleToUser", "(Z)V", !state.invisible) if (iface->actionInterface()) { @@ -227,7 +226,7 @@ if (!clazz) { \ bool clickable = actions.contains(QAccessibleActionInterface::pressAction()); bool toggle = actions.contains(QAccessibleActionInterface::toggleAction()); if (clickable || toggle) { - CALL_METHOD(node, "setClickable", "(Z)V", clickable) + CALL_METHOD(node, "setClickable", "(Z)V", (bool)clickable) CALL_METHOD(node, "addAction", "(I)V", 16) // ACTION_CLICK defined in AccessibilityNodeInfo } } @@ -235,6 +234,8 @@ if (!clazz) { \ jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size()); //CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc) CALL_METHOD(node, "setContentDescription", "(Ljava/lang/CharSequence;)V", jdesc) + + return true; } static JNINativeMethod methods[] = { @@ -244,7 +245,7 @@ if (!clazz) { \ {"descriptionForAccessibleObject", "(I)Ljava/lang/String;", (jstring)descriptionForAccessibleObject}, {"screenRect", "(I)Landroid/graphics/Rect;", (jobject)screenRect}, {"hitTest", "(FF)I", (void*)hitTest}, - {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)V", (void*)populateNode}, + {"populateNode", "(ILandroid/view/accessibility/AccessibilityNodeInfo;)Z", (void*)populateNode}, {"clickAction", "(I)Z", (void*)clickAction}, }; diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 2998762cc3..7ca4db710b 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -463,17 +463,19 @@ static void *startMainMethod(void */*data*/) static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring paramsString, jstring environmentString) { m_mainLibraryHnd = NULL; - const char *nativeString = env->GetStringUTFChars(environmentString, 0); - QByteArray string = nativeString; - env->ReleaseStringUTFChars(environmentString, nativeString); - m_applicationParams=string.split('\t'); - foreach (string, m_applicationParams) { - if (!string.isEmpty() && putenv(string.constData())) - qWarning() << "Can't set environment" << string; + { // Set env. vars + const char *nativeString = env->GetStringUTFChars(environmentString, 0); + const QList<QByteArray> envVars = QByteArray(nativeString).split('\t'); + env->ReleaseStringUTFChars(environmentString, nativeString); + foreach (const QByteArray &envVar, envVars) { + const QList<QByteArray> envVarPair = envVar.split('='); + if (envVarPair.size() == 2 && ::setenv(envVarPair[0], envVarPair[1], 1) != 0) + qWarning() << "Can't set environment" << envVarPair; + } } - nativeString = env->GetStringUTFChars(paramsString, 0); - string = nativeString; + const char *nativeString = env->GetStringUTFChars(paramsString, 0); + QByteArray string = nativeString; env->ReleaseStringUTFChars(paramsString, nativeString); m_applicationParams=string.split('\t'); diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp index 7423e6c55a..935caed467 100644 --- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp +++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp @@ -82,7 +82,7 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami Q_UNUSED(family); Q_UNUSED(style); - if (styleHint == QFont::Monospace) + if (styleHint == QFont::Monospace || styleHint == QFont::Courier) return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";") + m_fallbacks[script]; return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script]; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 9e748bff72..32692edde4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -119,7 +119,7 @@ QCocoaMenuItem::~QCocoaMenuItem() void QCocoaMenuItem::setText(const QString &text) { - m_text = qt_mac_removeAmpersandEscapes(text); + m_text = text; } void QCocoaMenuItem::setIcon(const QIcon &icon) diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index 8151d31449..421d934fa7 100644 --- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -45,6 +45,67 @@ QT_BEGIN_NAMESPACE +class QMacPasteboardMimeTraditionalMacPlainText : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimeTraditionalMacPlainText() : QMacInternalPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); + QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeTraditionalMacPlainText::convertorName() +{ + return QLatin1String("PlainText (traditional-mac-plain-text)"); +} + +QString QMacPasteboardMimeTraditionalMacPlainText::flavorFor(const QString &mime) +{ + if (mime == QLatin1String("text/plain")) + return QLatin1String("com.apple.traditional-mac-plain-text"); + return QString(); +} + +QString QMacPasteboardMimeTraditionalMacPlainText::mimeFor(QString flav) +{ + if (flav == QLatin1String("com.apple.traditional-mac-plain-text")) + return QLatin1String("text/plain"); + return QString(); +} + +bool QMacPasteboardMimeTraditionalMacPlainText::canConvert(const QString &mime, QString flav) +{ + return flavorFor(mime) == flav; +} + +QVariant QMacPasteboardMimeTraditionalMacPlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) +{ + if (data.count() > 1) + qWarning("QMacPasteboardMimeTraditionalMacPlainText: Cannot handle multiple member data"); + const QByteArray &firstData = data.first(); + QVariant ret; + if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) { + return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault, + reinterpret_cast<const UInt8 *>(firstData.constData()), + firstData.size(), CFStringGetSystemEncoding(), false)); + } else { + qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); + } + return ret; +} + +QList<QByteArray> QMacPasteboardMimeTraditionalMacPlainText::convertFromMime(const QString &, QVariant data, QString flavor) +{ + QList<QByteArray> ret; + QString string = data.toString(); + if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) + ret.append(string.toLatin1()); + return ret; +} + class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime { public: QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { } @@ -136,76 +197,10 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q return ret; } -// This handler is special: It supports converting public.rtf top text/html, -// but not the other way around. -class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeRtfText::convertorName() -{ - return QLatin1String("Rtf"); -} - -QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("text/html")) - return QLatin1String("public.rtf"); - return QString(); -} - -QString QMacPasteboardMimeRtfText::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.rtf")) - return QLatin1String("text/html"); - return QString(); -} - -bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav) -{ - return flavorFor(mime) == flav; -} - -QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor) -{ - if (!canConvert(mimeType, flavor)) - return QVariant(); - if (data.count() > 1) - qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data"); - - // Convert Rtf to Html. - NSAttributedString *string = [[NSAttributedString alloc] initWithRTF:data.at(0).toNSData() documentAttributes:NULL]; - NSError *error; - NSRange range = NSMakeRange(0,[string length]); - NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; - NSData *htmldata = [string dataFromRange:range documentAttributes:dict error:&error]; - [string release]; - return QByteArray::fromNSData(htmldata); -} - -QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor) -{ - Q_UNUSED(mime); - Q_UNUSED(data); - Q_UNUSED(flavor); - - qWarning("QMacPasteboardMimeRtfText: Conversion from Html to Rtf is not supported"); - QList<QByteArray> ret; - return ret; -} - void QCocoaMimeTypes::initializeMimeTypes() { + new QMacPasteboardMimeTraditionalMacPlainText; new QMacPasteboardMimeTiff; - new QMacPasteboardMimeRtfText; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 60152b56b2..651fedb26e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1620,6 +1620,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window) if (!m_drawContentBorderGradient) { [window setStyleMask:[window styleMask] & ~NSTexturedBackgroundWindowMask]; + [[[window contentView] superview] setNeedsDisplay:YES]; return; } @@ -1650,6 +1651,8 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window) [window setContentBorderThickness:effectiveBottomContentBorderThickness forEdge:NSMinYEdge]; [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge]; + + [[[window contentView] superview] setNeedsDisplay:YES]; } void QCocoaWindow::updateNSToolbar() diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 9833d50e6c..0e38f9b12a 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -80,12 +80,12 @@ private: {} public: - // 6.2.9200.16765 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update + // 6.2.9200.16492 corresponds to Direct2D 1.1 on Windows 7 SP1 with Platform Update enum { D2DMinVersionPart1 = 6, D2DMinVersionPart2 = 2, D2DMinVersionPart3 = 9200, - D2DMinVersionPart4 = 16765 + D2DMinVersionPart4 = 16492 }; static Direct2DVersion systemVersion() { @@ -93,8 +93,8 @@ public: TCHAR filename[bufSize]; UINT i = GetSystemDirectory(filename, bufSize); - if (i > 0 && i < MAX_PATH) { - if (_tcscat_s(filename, MAX_PATH, __TEXT("\\d2d1.dll")) == 0) { + if (i > 0 && i < bufSize) { + if (_tcscat_s(filename, bufSize, __TEXT("\\d2d1.dll")) == 0) { DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL); if (versionInfoSize) { QVector<BYTE> info(versionInfoSize); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index ca2dcf908d..a838950c9e 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -592,9 +592,13 @@ public: props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ props.dashOffset = newPen.dashOffset(); - props.transformType = qIsNull(newPen.widthF()) ? D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE - : newPen.isCosmetic() ? D2D1_STROKE_TRANSFORM_TYPE_FIXED - : D2D1_STROKE_TRANSFORM_TYPE_NORMAL; + + if (newPen.widthF() == 0) + props.transformType = D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE; + else if (qt_pen_is_cosmetic(newPen, q->state()->renderHints)) + props.transformType = D2D1_STROKE_TRANSFORM_TYPE_FIXED; + else + props.transformType = D2D1_STROKE_TRANSFORM_TYPE_NORMAL; switch (newPen.style()) { case Qt::SolidLine: @@ -930,6 +934,33 @@ void QWindowsDirect2DPaintEngine::setState(QPainterState *s) transformChanged(); } +void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) +{ + Q_D(QWindowsDirect2DPaintEngine); + + ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + if (!geometry) { + qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); + return; + } + + const QBrush &brush = state()->brush; + if (qbrush_style(brush) != Qt::NoBrush) { + if (emulationRequired(BrushEmulation)) + rasterFill(path, brush); + else + fill(geometry.Get(), brush); + } + + const QPen &pen = state()->pen; + if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) { + if (emulationRequired(PenEmulation)) + QPaintEngineEx::stroke(path, pen); + else + stroke(geometry.Get(), pen); + } +} + void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QWindowsDirect2DPaintEngine); @@ -939,7 +970,6 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br return; ensureBrush(brush); - if (emulationRequired(BrushEmulation)) { rasterFill(path, brush); return; @@ -957,6 +987,56 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get()); } +void QWindowsDirect2DPaintEngine::fill(ID2D1Geometry *geometry, const QBrush &brush) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillTag); + + ensureBrush(brush); + if (!d->brush.brush) + return; + + d->dc()->FillGeometry(geometry, d->brush.brush.Get()); +} + +void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pen) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillTag); + + if (path.isEmpty()) + return; + + ensurePen(pen); + if (emulationRequired(PenEmulation)) { + QPaintEngineEx::stroke(path, pen); + return; + } + + if (!d->pen.brush) + return; + + ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + if (!geometry) { + qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); + return; + } + + d->dc()->DrawGeometry(geometry.Get(), d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); +} + +void QWindowsDirect2DPaintEngine::stroke(ID2D1Geometry *geometry, const QPen &pen) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillTag); + + ensurePen(pen); + if (!d->pen.brush) + return; + + d->dc()->DrawGeometry(geometry, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); +} + void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QWindowsDirect2DPaintEngine); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index fb9b7acec3..c91a951ebe 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -68,7 +68,14 @@ public: void setState(QPainterState *s) Q_DECL_OVERRIDE; + void draw(const QVectorPath &path) Q_DECL_OVERRIDE; + void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE; + void fill(ID2D1Geometry *geometry, const QBrush &brush); + + void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE; + void stroke(ID2D1Geometry *geometry, const QPen &pen); + void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE; void clipEnabledChanged() Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm index 3f6c6d1256..79e3897013 100644 --- a/src/plugins/platforms/ios/quiview_textinput.mm +++ b/src/plugins/platforms/ios/quiview_textinput.mm @@ -253,7 +253,7 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables); - (UITextRange *)selectedTextRange { int cursorPos = [self imValue:Qt::ImCursorPosition].toInt(); int anchorPos = [self imValue:Qt::ImAnchorPosition].toInt(); - return [QUITextRange rangeWithNSRange:NSMakeRange(cursorPos, (anchorPos - cursorPos))]; + return [QUITextRange rangeWithNSRange:NSMakeRange(qMin(cursorPos, anchorPos), qAbs(anchorPos - cursorPos))]; } - (NSString *)textInRange:(UITextRange *)range diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 63615dd4bf..322bae10aa 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -741,6 +741,27 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, HWND_MESSAGE, NULL, (HINSTANCE)GetModuleHandle(0), NULL); } +#ifndef Q_OS_WINCE +// Re-engineered from the inline function _com_error::ErrorMessage(). +// We cannot use it directly since it uses swprintf_s(), which is not +// present in the MSVCRT.DLL found on Windows XP (QTBUG-35617). +static inline QString errorMessageFromComError(const _com_error &comError) +{ + TCHAR *message = Q_NULLPTR; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, comError.Error(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + message, 0, NULL); + if (message) { + const QString result = QString::fromWCharArray(message).trimmed(); + LocalFree((HLOCAL)message); + return result; + } + if (const WORD wCode = comError.WCode()) + return QStringLiteral("IDispatch error #") + QString::number(wCode); + return QStringLiteral("Unknown error 0x0") + QString::number(comError.Error(), 16); +} +#endif // !Q_OS_WINCE + /*! \brief Common COM error strings. */ @@ -807,7 +828,7 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) #ifndef Q_OS_WINCE _com_error error(hr); result += QByteArrayLiteral(" ("); - result += QString::fromWCharArray(error.ErrorMessage()).toLocal8Bit(); + result += errorMessageFromComError(error); result += ')'; #endif // !Q_OS_WINCE return result; @@ -876,7 +897,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, // TODO: Release/regrab mouse if a popup has mouse grab. return false; case QtWindows::DestroyEvent: - if (!platformWindow->testFlag(QWindowsWindow::WithinDestroy)) { + if (platformWindow && !platformWindow->testFlag(QWindowsWindow::WithinDestroy)) { qWarning() << "External WM_DESTROY received for " << platformWindow->window() << ", parent: " << platformWindow->window()->parent() << ", transient parent: " << platformWindow->window()->transientParent(); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 52825ebc6d..f081bbd307 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -165,6 +165,9 @@ namespace { Q_ASSERT(tagName.size() == 4); quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData())); + if (m_fontData.size() < sizeof(OffsetSubTable) + sizeof(TableDirectory)) + return 0; + OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data()); TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index efa1691780..eb7b220c43 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -148,15 +148,17 @@ void QXcbConnection::initializeXInput2() } case XIButtonClass: { XIButtonClassInfo *bci = reinterpret_cast<XIButtonClassInfo *>(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) { + if (bci->num_buttons >= 5) { + Atom label4 = bci->labels[3]; + Atom label5 = bci->labels[4]; + if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp) && (!label5 || qatom(label5) == QXcbAtom::ButtonWheelDown)) scrollingDevice.legacyOrientations |= Qt::Vertical; - } else if (buttonAtom == QXcbAtom::ButtonHorizWheelLeft - || buttonAtom == QXcbAtom::ButtonHorizWheelRight) { + } + if (bci->num_buttons >= 7) { + Atom label6 = bci->labels[5]; + Atom label7 = bci->labels[6]; + if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight)) scrollingDevice.legacyOrientations |= Qt::Horizontal; - } } break; } @@ -246,6 +248,7 @@ void QXcbConnection::xi2Select(xcb_window_t window) } #endif // XCB_USE_XINPUT22 + QSet<int> tabletDevices; #ifndef QT_NO_TABLETEVENT // For each tablet, select some additional event types. // Press, motion, etc. events must never be selected for _all_ devices @@ -253,15 +256,19 @@ void QXcbConnection::xi2Select(xcb_window_t window) // similar handlers useless and we have no intention to infect // all the pure xcb code with Xlib-based XI2. if (!m_tabletData.isEmpty()) { + unsigned int tabletBitMask = bitMask; + unsigned char *xiTabletBitMask = reinterpret_cast<unsigned char *>(&tabletBitMask); QVector<XIEventMask> xiEventMask(m_tabletData.count()); - bitMask |= XI_ButtonPressMask; - bitMask |= XI_ButtonReleaseMask; - bitMask |= XI_MotionMask; - bitMask |= XI_PropertyEventMask; + tabletBitMask |= XI_ButtonPressMask; + tabletBitMask |= XI_ButtonReleaseMask; + tabletBitMask |= XI_MotionMask; + tabletBitMask |= XI_PropertyEventMask; for (int i = 0; i < m_tabletData.count(); ++i) { - xiEventMask[i].deviceid = m_tabletData.at(i).deviceId; - xiEventMask[i].mask_len = sizeof(bitMask); - xiEventMask[i].mask = xiBitMask; + int deviceId = m_tabletData.at(i).deviceId; + tabletDevices.insert(deviceId); + xiEventMask[i].deviceid = deviceId; + xiEventMask[i].mask_len = sizeof(tabletBitMask); + xiEventMask[i].mask = xiTabletBitMask; } XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count()); } @@ -271,17 +278,30 @@ void QXcbConnection::xi2Select(xcb_window_t window) // Enable each scroll device if (!m_scrollingDevices.isEmpty()) { QVector<XIEventMask> xiEventMask(m_scrollingDevices.size()); - bitMask = XI_MotionMask; + unsigned int scrollBitMask = 0; + unsigned char *xiScrollBitMask = reinterpret_cast<unsigned char *>(&scrollBitMask); + scrollBitMask = XI_MotionMask; + scrollBitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; bitMask |= XI_ButtonReleaseMask; int i=0; Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) { + if (tabletDevices.contains(scrollingDevice.deviceId)) + continue; // All necessary events are already captured. xiEventMask[i].deviceid = scrollingDevice.deviceId; - xiEventMask[i].mask_len = sizeof(bitMask); - xiEventMask[i].mask = xiBitMask; + if (m_touchDevices.contains(scrollingDevice.deviceId)) { + xiEventMask[i].mask_len = sizeof(bitMask); + xiEventMask[i].mask = xiBitMask; + } else { + xiEventMask[i].mask_len = sizeof(scrollBitMask); + xiEventMask[i].mask = xiScrollBitMask; + } i++; } - XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size()); + XISelectEvents(xDisplay, window, xiEventMask.data(), i); } +#else + Q_UNUSED(xiBitMask); #endif } @@ -655,13 +675,15 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) if (reinterpret_cast<xXIDeviceEvent *>(event)->detail == 1) { // ignore the physical buttons on the stylus tabletData->down = true; xi2ReportTabletEvent(*tabletData, xiEvent); - } + } else + handled = false; break; case XI_ButtonRelease: // stylus up if (reinterpret_cast<xXIDeviceEvent *>(event)->detail == 1) { tabletData->down = false; xi2ReportTabletEvent(*tabletData, xiEvent); - } + } else + handled = false; break; case XI_Motion: // Report TabletMove only when the stylus is touching the tablet. diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 6959dc39f7..09b8f8d889 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -688,7 +688,9 @@ void QSqlResult::bindValue(int index, const QVariant& val, QSql::ParamType param { Q_D(QSqlResult); d->binds = PositionalBinding; - d->indexes[d->fieldSerial(index)].append(index); + QList<int>& indexes = d->indexes[d->fieldSerial(index)]; + if (!indexes.contains(index)) + indexes.append(index); if (d->values.count() <= index) d->values.resize(index + 1); d->values[index] = val; diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 859f6743cd..8eb1fa2d9c 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -49,7 +49,6 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <wchar.h> static const char *currentAppName = 0; @@ -257,10 +256,11 @@ bool QTestResult::compare(bool success, const char *failureMsg, QTEST_ASSERT(expected); QTEST_ASSERT(actual); - char msg[1024]; + const size_t maxMsgLen = 1024; + char msg[maxMsgLen]; if (QTestLog::verboseLevel() >= 2) { - qsnprintf(msg, 1024, "QCOMPARE(%s, %s)", actual, expected); + qsnprintf(msg, maxMsgLen, "QCOMPARE(%s, %s)", actual, expected); QTestLog::info(msg, file, line); } @@ -268,16 +268,17 @@ bool QTestResult::compare(bool success, const char *failureMsg, failureMsg = "Compared values are not the same"; if (success && QTest::expectFailMode) { - qsnprintf(msg, 1024, "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected); + qsnprintf(msg, maxMsgLen, + "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected); } else if (val1 || val2) { - size_t len1 = mbstowcs(NULL, actual, 0); - size_t len2 = mbstowcs(NULL, expected, 0); - qsnprintf(msg, 1024, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s", + size_t len1 = mbstowcs(NULL, actual, maxMsgLen); // Last parameter is not ignored on QNX + size_t len2 = mbstowcs(NULL, expected, maxMsgLen); // (result is never larger than this). + qsnprintf(msg, maxMsgLen, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s", failureMsg, actual, qMax(len1, len2) - len1 + 1, ":", val1 ? val1 : "<null>", expected, qMax(len1, len2) - len2 + 1, ":", val2 ? val2 : "<null>"); } else - qsnprintf(msg, 1024, "%s", failureMsg); + qsnprintf(msg, maxMsgLen, "%s", failureMsg); delete [] val1; delete [] val2; diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 630a8c985f..2b58bff8f3 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -146,8 +146,6 @@ macx { ../../corelib/io/qstandardpaths_win.cpp } -*-g++*: QMAKE_CXXFLAGS += -ffunction-sections - if(contains(QT_CONFIG, zlib)|cross_compile):include(../../3rdparty/zlib.pri) else:include(../../3rdparty/zlib_dependency.pri) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 775fc6a750..99e59f60a3 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -1354,7 +1354,6 @@ void HtmlGenerator::generateCollisionPages() beginSubPage(ncn, Generator::fileName(ncn)); QString fullTitle = ncn->fullTitle(); - QString htmlTitle = fullTitle; CodeMarker* marker = CodeMarker::markerForFileName(ncn->location().filePath()); if (ncn->isQmlNode()) { // Replace the marker with a QML code marker. @@ -1362,7 +1361,7 @@ void HtmlGenerator::generateCollisionPages() marker = CodeMarker::markerForLanguage(QLatin1String("QML")); } - generateHeader(htmlTitle, ncn, marker); + generateHeader(fullTitle, ncn, marker); if (!fullTitle.isEmpty()) out() << "<h1 class=\"title\">" << protectEnc(fullTitle) << "</h1>\n"; @@ -1447,17 +1446,18 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) QList<Section> sections; QList<Section>::const_iterator s; QString fullTitle = dn->fullTitle(); - QString htmlTitle = fullTitle; if (dn->subType() == Node::QmlBasicType) { fullTitle = "QML Basic Type: " + fullTitle; - htmlTitle = fullTitle; // Replace the marker with a QML code marker. marker = CodeMarker::markerForLanguage(QLatin1String("QML")); } + else if (dn->subType() == Node::QmlClass) { + fullTitle = fullTitle + " QML Type"; + } - generateHeader(htmlTitle, dn, marker); + generateHeader(fullTitle, dn, marker); /* Generate the TOC for the new doc format. Don't generate a TOC for the home page. diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index b67ba01f92..d1af5abf7b 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -551,6 +551,7 @@ static void processQdocconfFile(const QString &fileName) Generator::debug("qdoc finished!"); } +extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; QT_END_NAMESPACE int main(int argc, char **argv) @@ -558,6 +559,7 @@ int main(int argc, char **argv) QT_USE_NAMESPACE #ifndef QT_BOOTSTRAPPED + qt_qhash_seed.testAndSetRelaxed(-1, 0); // set the hash seed to 0 if it wasn't set yet QCoreApplication app(argc, argv); #endif diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp index cb2bd430ff..12b0ee6737 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -52,9 +52,12 @@ #include <qcommandlineparser.h> QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; int runUic(int argc, char *argv[]) { + qt_qhash_seed.testAndSetRelaxed(-1, 0); // set the hash seed to 0 if it wasn't set yet + QCoreApplication app(argc, argv); QCoreApplication::setApplicationVersion(QString::fromLatin1(QT_VERSION_STR)); diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index cbefb8a6bf..307d0bb909 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -170,12 +170,6 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *) d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio(), QOpenGLFramebufferObject::CombinedDepthStencil); d->fbo->bind(); QOpenGLFunctions *funcs = d->context.functions(); - funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture()); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - resizeGL(width(), height()); paintGL(); funcs->glFlush(); diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 252de5cd18..513848f7ab 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -3245,7 +3245,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai case PE_PanelStatusBar: { // Fill the status bar with the titlebar gradient. QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom()); - if (opt->state & QStyle::State_Active) { + if (w ? qt_macWindowMainWindow(w->window()) : (opt->state & QStyle::State_Active)) { linearGrad.setColorAt(0, titlebarGradientActiveBegin); linearGrad.setColorAt(1, titlebarGradientActiveEnd); } else { @@ -3255,7 +3255,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai p->fillRect(opt->rect, linearGrad); // Draw the black separator line at the top of the status bar. - if (opt->state & QStyle::State_Active) + if (w ? qt_macWindowMainWindow(w->window()) : (opt->state & QStyle::State_Active)) p->setPen(titlebarSeparatorLineActive); else p->setPen(titlebarSeparatorLineInactive); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 06258cb4a6..f857f4eac0 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1000,11 +1000,11 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn emit q->currentTextChanged(text); } q->update(); - } #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(q, QAccessible::NameChanged); + QAccessibleValueChangeEvent event(q, text); QAccessible::updateAccessibility(&event); #endif + } } void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end) @@ -1269,7 +1269,7 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) if (!lineEdit) emit q->currentTextChanged(text); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(q, QAccessible::NameChanged); + QAccessibleValueChangeEvent event(q, text); QAccessible::updateAccessibility(&event); #endif } @@ -2757,7 +2757,7 @@ void QComboBox::clear() Q_D(QComboBox); d->model->removeRows(0, d->model->rowCount(d->root), d->root); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(this, QAccessible::NameChanged); + QAccessibleValueChangeEvent event(this, QString()); QAccessible::updateAccessibility(&event); #endif } @@ -2771,7 +2771,7 @@ void QComboBox::clearEditText() if (d->lineEdit) d->lineEdit->clear(); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(this, QAccessible::NameChanged); + QAccessibleValueChangeEvent event(this, QString()); QAccessible::updateAccessibility(&event); #endif } @@ -2785,7 +2785,7 @@ void QComboBox::setEditText(const QString &text) if (d->lineEdit) d->lineEdit->setText(text); #ifndef QT_NO_ACCESSIBILITY - QAccessibleEvent event(this, QAccessible::NameChanged); + QAccessibleValueChangeEvent event(this, text); QAccessible::updateAccessibility(&event); #endif } diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 90cfb1d7cb..358569a5e4 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -1519,6 +1519,7 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) typedef void (*SetContentBorderEnabledFunction)(QWindow *window, bool enable); (reinterpret_cast<SetContentBorderEnabledFunction>(function))(window()->windowHandle(), set); + update(); } #endif diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index e41cb64463..df13085dee 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -284,14 +284,15 @@ void QPlainTextDocumentLayoutPrivate::relayout() /*! \reimp */ -void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, int charsAdded) +void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int charsAdded) { Q_D(QPlainTextDocumentLayout); QTextDocument *doc = document(); int newBlockCount = doc->blockCount(); + int charsChanged = qMax(charsRemoved, charsAdded); QTextBlock changeStartBlock = doc->findBlock(from); - QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsAdded - 1)); + QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsChanged - 1)); if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) { QTextBlock block = changeStartBlock; |