From c1af2ced2d816932e78793295595bc1612a4700c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 12 May 2014 11:34:00 +0200 Subject: [PATCH 01/61] Mac OS X: Fix crash in Harfbuzz-NG CoreText does not support multithreading, so we would get a crash in tst_qglthreads. So we disable multithreading for HB-NG. Task-number: QTBUG-38762 Change-Id: I0473037c16017ff77cbba9b11fc0b396775ef789 Reviewed-by: Konstantin Ritt --- src/3rdparty/harfbuzz-ng/src/config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h index cb68ab0e5b6..9abb5df7f19 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 From 650e214d3de9dbe0af1cfa1acbf1f1a9556884ab Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Mon, 12 May 2014 21:54:55 +0100 Subject: [PATCH 02/61] Fix the documentation on how to use -openssl-linked. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You set the environment /before/ you run configure. Change-Id: I6954656f892214f41b5f2ec4e3f4926eb5a9e247 Reviewed-by: Thiago Macieira Reviewed-by: Topi Reiniö --- src/network/doc/src/ssl.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc index e1bb1b9316c..77fbec99433 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} From f2619db30046c5b6a431a5048bcedc6b1d04688f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 12 May 2014 15:20:02 +0200 Subject: [PATCH 03/61] fix doc references to webkit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we can't derive the doc index paths from QMAKEMODULES, as the mkspecs dir may not live at the repo's top level. instead, explicitly announce the repo's top level build dirs in QTREPOS, and use that accordingly. Task-number: QTBUG-38862 Change-Id: I643ad2bf63c8fca0ffc44ce3457dbe8a16dcab07 Reviewed-by: Jerome Pasion Reviewed-by: Topi Reiniö --- mkspecs/features/qt_build_config.prf | 8 ++++++-- mkspecs/features/qt_docs.prf | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index b611e782f9f..0bf90cc297c 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -34,8 +34,12 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR !build_pass:!isEmpty(_QMAKE_SUPER_CACHE_):force_independent { # When doing a -prefix build of top-level qt5/qt.pro, we need to announce - # this repo's module pris' location to the other repos. - isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$shadowed($$dirname(_QMAKE_CONF_)) + # this repo's output dir to the other repos. + MODULE_BASE_OUTDIR = $$shadowed($$dirname(_QMAKE_CONF_)) + !contains(QTREPOS, $$MODULE_BASE_OUTDIR): \ + cache(QTREPOS, add super, MODULE_BASE_OUTDIR) + # This repo's module pris' location needs to be made known to qmake. + isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$MODULE_BASE_OUTDIR modpath = $$MODULE_QMAKE_OUTDIR/mkspecs/modules !contains(QMAKEMODULES, $$modpath): \ cache(QMAKEMODULES, add super, modpath) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index be3cd5273c0..8e63fa61a7a 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -23,8 +23,9 @@ QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR !build_online_docs: \ QDOC += -installdir $$[QT_INSTALL_DOCS] DOC_INDEXES = -for(qmod, QMAKEMODULES): \ - DOC_INDEXES += -indexdir $$section(qmod, /, 0, -3)/doc +for(qrep, QTREPOS): \ + exists($$qrep/doc): \ + DOC_INDEXES += -indexdir $$qrep/doc qtver.name = QT_VERSION qtver.value = $$VERSION isEmpty(qtver.value): qtver.value = $$MODULE_VERSION From b23e72a772a5abfdf9784ab80db9a4d620137515 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 12 May 2014 17:05:36 -0700 Subject: [PATCH 04/61] Fix stateful handling of invalid UTF-8 straddling buffer borders When a UTF-8 sequences is too short, QUtf8Functions::fromUtf8 returns EndOfString. If the decoder is stateful, we must save the state and then restart it when more data is supplied. The new stateful decoder (8dd47e34b9b96ac27a99cdcf10b8aec506882fc2) mishandled the Error case by advancing the src pointer by a negative number, thus causing a buffer overflow (the issue of the task). And it also did not handle the len == 0 case properly, though neither did the older decoder. Task-number: QTBUG-38939 Change-Id: Ie03d7c55a04e51ee838ccdb3a01e5b989d8e67aa Reviewed-by: Kai Koehne Reviewed-by: Lars Knoll --- src/corelib/codecs/qutfcodec.cpp | 44 +++++++-- .../codecs/qtextcodec/tst_qtextcodec.cpp | 96 +++++++++++++++++++ 2 files changed, 132 insertions(+), 8 deletions(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 072cda63aa5..c5f580e13d8 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -237,7 +237,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(const_cast(result.constData())); const uchar *src = reinterpret_cast(chars); const uchar *end = src + len; @@ -282,7 +295,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(const_cast(result.constData())); const uchar *src = reinterpret_cast(chars); const uchar *end = src + len; @@ -305,15 +329,17 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte const uchar *begin = &remainingCharsData[1]; res = QUtf8Functions::fromUtf8(remainingCharsData[0], dst, begin, static_cast(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; @@ -322,8 +348,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/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index 12b81ee7d44..54e8f8c3863 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -80,6 +80,9 @@ private slots: void utf8bom_data(); void utf8bom(); + void utf8stateful_data(); + void utf8stateful(); + void utfHeaders_data(); void utfHeaders(); @@ -1611,6 +1614,99 @@ void tst_QTextCodec::utf8bom() QCOMPARE(codec->toUnicode(data.constData(), data.length(), &state), result); } +void tst_QTextCodec::utf8stateful_data() +{ + QTest::addColumn("buffer1"); + QTest::addColumn("buffer2"); + QTest::addColumn("result"); // null QString indicates decoder error + + // valid buffer continuations + QTest::newRow("1of2+valid") << QByteArray("\xc2") << QByteArray("\xa0") << "\xc2\xa0"; + QTest::newRow("1of3+valid") << QByteArray("\xe0") << QByteArray("\xa0\x80") << "\xe0\xa0\x80"; + QTest::newRow("2of3+valid") << QByteArray("\xe0\xa0") << QByteArray("\x80") << "\xe0\xa0\x80"; + QTest::newRow("1of4+valid") << QByteArray("\360") << QByteArray("\220\210\203") << "\360\220\210\203"; + QTest::newRow("2of4+valid") << QByteArray("\360\220") << QByteArray("\210\203") << "\360\220\210\203"; + QTest::newRow("3of4+valid") << QByteArray("\360\220\210") << QByteArray("\203") << "\360\220\210\203"; + QTest::newRow("1ofBom+valid") << QByteArray("\xef") << QByteArray("\xbb\xbf") << ""; + QTest::newRow("2ofBom+valid") << QByteArray("\xef\xbb") << QByteArray("\xbf") << ""; + + // invalid continuation + QTest::newRow("1of2+invalid") << QByteArray("\xc2") << QByteArray("a") << QString(); + QTest::newRow("1of3+invalid") << QByteArray("\xe0") << QByteArray("a") << QString(); + QTest::newRow("2of3+invalid") << QByteArray("\xe0\xa0") << QByteArray("a") << QString(); + QTest::newRow("1of4+invalid") << QByteArray("\360") << QByteArray("a") << QString(); + QTest::newRow("2of4+invalid") << QByteArray("\360\220") << QByteArray("a") << QString(); + QTest::newRow("3of4+invalid") << QByteArray("\360\220\210") << QByteArray("a") << QString(); + + // invalid: sequence too short (the empty second buffer causes a state reset) + QTest::newRow("1of2+empty") << QByteArray("\xc2") << QByteArray() << QString(); + QTest::newRow("1of3+empty") << QByteArray("\xe0") << QByteArray() << QString(); + QTest::newRow("2of3+empty") << QByteArray("\xe0\xa0") << QByteArray() << QString(); + QTest::newRow("1of4+empty") << QByteArray("\360") << QByteArray() << QString(); + QTest::newRow("2of4+empty") << QByteArray("\360\220") << QByteArray() << QString(); + QTest::newRow("3of4+empty") << QByteArray("\360\220\210") << QByteArray() << QString(); + + // overlong sequence: + QTest::newRow("overlong-1of2") << QByteArray("\xc1") << QByteArray("\x81") << QString(); + QTest::newRow("overlong-1of3") << QByteArray("\xe0") << QByteArray("\x81\x81") << QString(); + QTest::newRow("overlong-2of3") << QByteArray("\xe0\x81") << QByteArray("\x81") << QString(); + QTest::newRow("overlong-1of4") << QByteArray("\xf0") << QByteArray("\x80\x81\x81") << QString(); + QTest::newRow("overlong-2of4") << QByteArray("\xf0\x80") << QByteArray("\x81\x81") << QString(); + QTest::newRow("overlong-3of4") << QByteArray("\xf0\x80\x81") << QByteArray("\x81") << QString(); + + // out of range: + // leading byte 0xF4 can produce codepoints above U+10FFFF, which aren't valid + QTest::newRow("outofrange1-1of4") << QByteArray("\xf4") << QByteArray("\x90\x80\x80") << QString(); + QTest::newRow("outofrange1-2of4") << QByteArray("\xf4\x90") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange1-3of4") << QByteArray("\xf4\x90\x80") << QByteArray("\x80") << QString(); + QTest::newRow("outofrange2-1of4") << QByteArray("\xf5") << QByteArray("\x90\x80\x80") << QString(); + QTest::newRow("outofrange2-2of4") << QByteArray("\xf5\x90") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange2-3of4") << QByteArray("\xf5\x90\x80") << QByteArray("\x80") << QString(); + QTest::newRow("outofrange-1of5") << QByteArray("\xf8") << QByteArray("\x88\x80\x80\x80") << QString(); + QTest::newRow("outofrange-2of5") << QByteArray("\xf8\x88") << QByteArray("\x80\x80\x80") << QString(); + QTest::newRow("outofrange-3of5") << QByteArray("\xf8\x88\x80") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange-4of5") << QByteArray("\xf8\x88\x80\x80") << QByteArray("\x80") << QString(); + QTest::newRow("outofrange-1of6") << QByteArray("\xfc") << QByteArray("\x84\x80\x80\x80\x80") << QString(); + QTest::newRow("outofrange-2of6") << QByteArray("\xfc\x84") << QByteArray("\x80\x80\x80\x80") << QString(); + QTest::newRow("outofrange-3of6") << QByteArray("\xfc\x84\x80") << QByteArray("\x80\x80\x80") << QString(); + QTest::newRow("outofrange-4of6") << QByteArray("\xfc\x84\x80\x80") << QByteArray("\x80\x80") << QString(); + QTest::newRow("outofrange-5of6") << QByteArray("\xfc\x84\x80\x80\x80") << QByteArray("\x80") << QString(); +} + +void tst_QTextCodec::utf8stateful() +{ + QFETCH(QByteArray, buffer1); + QFETCH(QByteArray, buffer2); + QFETCH(QString, result); + + QTextCodec *utf8codec = QTextCodec::codecForName("utf-8"); + QVERIFY(utf8codec); + + QTextCodec::ConverterState state; + memset(&state, 0, sizeof state); + + QString decoded1 = utf8codec->toUnicode(buffer1, buffer1.size(), &state); + if (result.isNull()) { + // the decoder may have found an early error (invalidChars > 0): + // if it has, remainingChars == 0; + // if it hasn't, then it must have a state + QVERIFY2((state.remainingChars == 0) != (state.invalidChars == 0), + "remainingChars = " + QByteArray::number(state.remainingChars) + + "; invalidChars = " + QByteArray::number(state.invalidChars)); + } else { + QVERIFY(state.remainingChars > 0); + QCOMPARE(state.invalidChars, 0); + } + + QString decoded2 = utf8codec->toUnicode(buffer2, buffer2.size(), &state); + QCOMPARE(state.remainingChars, 0); + if (result.isNull()) { + QVERIFY(state.invalidChars > 0); + } else { + QCOMPARE(decoded1 + decoded2, result); + } +} + void tst_QTextCodec::utfHeaders_data() { QTest::addColumn("codecName"); From 7cc175c9d69102c15486ac0506031cb6d09741d3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 12 May 2014 13:48:38 +0200 Subject: [PATCH 05/61] Assume unlabelled mouse buttons are default buttons This patch fixes legacy wheel scrolling for XInput2 drivers that fail to label mouse buttons correctly. Task-number: QTBUG-38937 Change-Id: I659890517e749dc0039489e0b7a8c38be1065d33 Reviewed-by: Erik Verbruggen Reviewed-by: Laszlo Agocs Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index efa1691780a..64cb33979b1 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(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; } From a8877f529dffa68a8c1339cd10c32e3b783bba66 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 12 May 2014 15:45:24 +0200 Subject: [PATCH 06/61] Scrolling devices should not override touch or tablet devices XISelectEvents override any earlier set event mask for the same device ids. This may cause touch devices to stop reporting touch events if they export scroll buttons or axis. The patch checks for each scrolling device if they are also a touch devices and includes the necessary bitmask if they are, and skips any devices also recognized as tablet devices as they already capture all relevant events. In addition tablet event handling will no longer block handling of wheel button events for scroll devices with the same device id. Task-number: QTBUG-38935 Change-Id: Ifd4657beb0a0cebffe89d3470ef2bd605eb3552e Reviewed-by: Laszlo Agocs --- .../platforms/xcb/qxcbconnection_xi2.cpp | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 64cb33979b1..eb7b220c436 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -248,6 +248,7 @@ void QXcbConnection::xi2Select(xcb_window_t window) } #endif // XCB_USE_XINPUT22 + QSet tabletDevices; #ifndef QT_NO_TABLETEVENT // For each tablet, select some additional event types. // Press, motion, etc. events must never be selected for _all_ devices @@ -255,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(&tabletBitMask); QVector 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()); } @@ -273,17 +278,30 @@ void QXcbConnection::xi2Select(xcb_window_t window) // Enable each scroll device if (!m_scrollingDevices.isEmpty()) { QVector xiEventMask(m_scrollingDevices.size()); - bitMask = XI_MotionMask; + unsigned int scrollBitMask = 0; + unsigned char *xiScrollBitMask = reinterpret_cast(&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 } @@ -657,13 +675,15 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) if (reinterpret_cast(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(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. From 9a747cb5b7866d440211aa1dc4e07dd4ff914c2c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 12 May 2014 13:52:29 -0700 Subject: [PATCH 07/61] Fix an off-by-4 error in qHash with CRC32 I tested only the 64-bit build. The 32-bit build was reading garbage past the end of the strings in some cases. Change-Id: If6d239754e16a17cc4e8bb71e2b7778429dfa7ba Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Lars Knoll --- src/corelib/tools/qhash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index a5d14a35358..ca645636e44 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(p)); + h = _mm_crc32_u32(h, *reinterpret_cast(p - 4)); p -= 4; len = e - p; # endif From 06e27c2a52a4bd98bc102de0875df9918166d130 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 7 May 2014 12:56:13 +0200 Subject: [PATCH 08/61] Accessibility Android: Fix crash for invalid interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When asked for an accessibility interface with invalid ID we still return an AccessibilityNodeInfo. But instead of setting that interfaces' ID to the invalid ID, rather return one with no ID set so it will simply fall back to the view. Task-number: QTBUG-38829 Change-Id: If66f5b1b42ba46949d94a547050c7a2cfc7ee9b7 Reviewed-by: Jan Arve Sæther --- .../android/accessibility/QtAccessibilityDelegate.java | 6 +++++- .../android/accessibility/QtNativeAccessibility.java | 2 +- .../platforms/android/androidjniaccessibility.cpp | 10 ++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) 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 669fbaab0da..70b02d8d049 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 b1cc82c065c..8a536239574 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/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index a38741cc91c..2c1701db830 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(); @@ -235,6 +235,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 +246,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}, }; From 87152d3c89e25a01dab4f1e5852e7da7abf4e0b6 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Mon, 12 May 2014 10:07:09 +0200 Subject: [PATCH 09/61] QNX: Fix tst_qfileinfo Change-Id: Ia97a0c661d675e4f5ba800c32f8368583d58ee20 Reviewed-by: Sergio Ahumada --- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 6c147d68c8d..8174cd942f2 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1073,10 +1073,8 @@ void tst_QFileInfo::fileTimes() #endif #if defined(Q_OS_WINCE) QEXPECT_FAIL("simple", "WinCE only stores date of access data, not the time", Continue); -#elif defined(Q_OS_BLACKBERRY) - QEXPECT_FAIL("simple", "Blackberry OS uses the noatime filesystem option", Continue); - QEXPECT_FAIL("longfile", "Blackberry OS uses the noatime filesystem option", Continue); - QEXPECT_FAIL("longfile absolutepath", "Blackberry OS uses the noatime filesystem option", Continue); +#elif defined(Q_OS_QNX) + QEXPECT_FAIL("", "QNX uses the noatime filesystem option", Continue); #endif QVERIFY(fileInfo.lastRead() > beforeRead); QVERIFY(fileInfo.lastModified() > beforeWrite); @@ -1511,8 +1509,7 @@ void tst_QFileInfo::isWritable() QVERIFY(fi.exists()); QVERIFY(!fi.isWritable()); #endif -#if defined (Q_OS_BLACKBERRY) - // The Blackberry filesystem is read-only +#if defined (Q_OS_QNX) // On QNX /etc is usually on a read-only filesystem QVERIFY(!QFileInfo("/etc/passwd").isWritable()); #elif defined (Q_OS_UNIX) && !defined(Q_OS_VXWORKS) // VxWorks does not have users/groups if (::getuid() == 0) From 4f83102df0389ee9ae4bb974bb2e48723f52dbea Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 13 May 2014 16:30:18 +0200 Subject: [PATCH 10/61] QNX: Make QDateTime "daylightTransitions" auto test pass Change-Id: I8c68d15806c6ec39e98dddda86823d9b4e3a3169 Reviewed-by: John Layt --- .../auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 8f9376f8b68..8559b8ab96e 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -2549,7 +2549,7 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(msecBefore.isValid()); QCOMPARE(msecBefore.date(), QDate(2012, 10, 28)); QCOMPARE(msecBefore.time(), QTime(2, 59, 59, 999)); -#if defined(Q_OS_MAC) || defined(Q_OS_WIN) +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) || defined(Q_OS_QNX) // Win and Mac uses SecondOccurrence here QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_MAC @@ -2571,7 +2571,7 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(afterTran.isValid()); QCOMPARE(afterTran.date(), QDate(2012, 10, 28)); QCOMPARE(afterTran.time(), QTime(2, 59, 59, 999)); -#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC) +#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_QNX) // Linux mktime bug uses last calculation QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_UNIX @@ -2629,7 +2629,7 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); QCOMPARE(test.time(), QTime(2, 0, 0)); -#ifndef Q_OS_MAC +#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) // Linux mktime bug uses last calculation QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_MAC @@ -2671,7 +2671,7 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); QCOMPARE(test.time(), QTime(2, 0, 0)); -#ifndef Q_OS_MAC +#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) // Linux mktime bug uses last calculation QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_MAC @@ -2713,7 +2713,7 @@ void tst_QDateTime::daylightTransitions() const QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); QCOMPARE(test.time(), QTime(2, 0, 0)); -#ifndef Q_OS_MAC +#if !defined(Q_OS_MAC) && !defined(Q_OS_QNX) // Linux mktime bug uses last calculation QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_MAC @@ -2778,12 +2778,12 @@ void tst_QDateTime::daylightTransitions() const test = test.addMSecs(msecsOneHour); QVERIFY(test.isValid()); QCOMPARE(test.date(), QDate(2012, 10, 28)); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) || defined(Q_OS_QNX) // Mac uses FirstOccurrence, Windows uses SecondOccurrence, Linux uses last calculation QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_WIN QCOMPARE(test.time(), QTime(3, 0, 0)); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) || defined(Q_OS_QNX) // Mac uses FirstOccurrence, Windows uses SecondOccurrence, Linux uses last calculation QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue); #endif // Q_OS_WIN From d16508a285a5423ae9a5034e969801bce74ffb98 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 12 May 2014 09:09:24 +0200 Subject: [PATCH 11/61] Fix crash when loading invalid font data in QRawFont When passing invalid data to QRawFont, we need to fail gracefully and mark the font as invalid, instead of crashing. This crashed because of different missing sanity checks in the Windows and FontConfig font databases. [ChangeLog][Text] Fixed crash when trying to load a font from invalid data. Task-number: QTBUG-37190 Change-Id: I62c81217ec7d873350b575c9d4ae8e6f0a939540 Reviewed-by: Michael Bruning Reviewed-by: Konstantin Ritt --- .../fontdatabases/fontconfig/qfontconfigdatabase.cpp | 3 +++ .../platforms/windows/qwindowsfontdatabase.cpp | 3 +++ tests/auto/gui/text/qrawfont/tst_qrawfont.cpp | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 17717dd53cb..b8da9726d56 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -660,6 +660,9 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr) QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { QFontEngineFT *engine = static_cast(QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference)); + if (engine == 0) + return 0; + QFontDef fontDef = engine->fontDef; QFontEngineFT::GlyphFormat format; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 940d75614c7..6d9f01da4e1 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(tagName.constData())); + if (m_fontData.size() < sizeof(OffsetSubTable) + sizeof(TableDirectory)) + return 0; + OffsetSubTable *offsetSubTable = reinterpret_cast(m_fontData.data()); TableDirectory *tableDirectory = reinterpret_cast(offsetSubTable + 1); diff --git a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp index ae6e4503011..20bfaf99dd7 100644 --- a/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/gui/text/qrawfont/tst_qrawfont.cpp @@ -99,6 +99,8 @@ private slots: void rawFontSetPixelSize(); void multipleRawFontsFromData(); + + void rawFontFromInvalidData(); private: QString testFont; QString testFontBoldItalic; @@ -939,6 +941,15 @@ void tst_QRawFont::multipleRawFontsFromData() || testFont.style() != (testFontBoldItalic.style())); } +void tst_QRawFont::rawFontFromInvalidData() +{ + QByteArray invalidData("foobar"); + QRawFont font; + font.loadFromData(invalidData, 10, QFont::PreferDefaultHinting); + + QVERIFY(!font.isValid()); +} + #endif // QT_NO_RAWFONT QTEST_MAIN(tst_QRawFont) From bf284c2bbdf783340a2f35350fd5ea690b3192b2 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 12 May 2014 15:35:49 +0300 Subject: [PATCH 12/61] Direct2D QPA: Fix check for cosmetic pen When checking whether a QPen should be treated as cosmetic we need to take into account the render hints set on the painter as well. Change-Id: I8200611af08000d2d1626d8ef97eb3f6dac4951c Reviewed-by: Risto Avila Reviewed-by: Andrew Knight --- .../platforms/direct2d/qwindowsdirect2dpaintengine.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index ca2dcf908d9..5a4157565ef 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: From 8df62598ac4ee3f90c7f4b80759a5fdbf23010ab Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 24 Apr 2014 11:55:55 +0200 Subject: [PATCH 13/61] qmacmime: add support for public.text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copying a URL from Safari to Qt app does not work. The reason is that it lies on the pasteboard as public.text, which we don't support. This patch will implement support for public.text. The UTI public.text is documented as text with an unspecified encoding. On iOS, this turns out to be UTF8 (which also matches [UIPasteboard generalPasteboard].string). Task-number: QTBUG-38551 Change-Id: I216dab206d3bff2dde99927ed7e5a3d85309f2a2 Reviewed-by: Tor Arne Vestbø --- src/platformsupport/clipboard/qmacmime.mm | 65 +++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 93d897503b6..af94589c08e 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -115,6 +115,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" @@ -343,6 +344,69 @@ QList QMacPasteboardMimePlainText::convertFromMime(const QString &, return ret; } +class QMacPasteboardMimePlainTextFallback : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimePlainTextFallback() : 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 data, QString flav); + QList convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimePlainTextFallback::convertorName() +{ + return QLatin1String("PlainText (public.text)"); +} + +QString QMacPasteboardMimePlainTextFallback::flavorFor(const QString &mime) +{ + if (mime == QLatin1String("text/plain")) + return QLatin1String("public.text"); + return QString(); +} + +QString QMacPasteboardMimePlainTextFallback::mimeFor(QString flav) +{ + if (flav == QLatin1String("public.text")) + return QLatin1String("text/plain"); + return QString(); +} + +bool QMacPasteboardMimePlainTextFallback::canConvert(const QString &mime, QString flav) +{ + return mime == mimeFor(flav); +} + +QVariant QMacPasteboardMimePlainTextFallback::convertToMime(const QString &mimetype, QList data, QString flavor) +{ + if (data.count() > 1) + 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(firstData.constData()), + firstData.size(), kCFStringEncodingUTF8, false)); + } else { + qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); + } + return QVariant(); +} + +QList QMacPasteboardMimePlainTextFallback::convertFromMime(const QString &, QVariant data, QString flavor) +{ + QList ret; + QString string = data.toString(); + if (flavor == QLatin1String("public.text")) + ret.append(string.toUtf8()); + return ret; +} + class QMacPasteboardMimeUnicodeText : public QMacInternalPasteboardMime { public: QMacPasteboardMimeUnicodeText() : QMacInternalPasteboardMime(MIME_ALL) { } @@ -696,6 +760,7 @@ void QMacInternalPasteboardMime::initializeMimeTypes() new QMacPasteboardMimeAny; //standard types that we wrap + new QMacPasteboardMimePlainTextFallback; new QMacPasteboardMimeUnicodeText; new QMacPasteboardMimePlainText; new QMacPasteboardMimeHTMLText; From 1b2614477f42825d95bbd7a4ebc6aa91fd82e1d9 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 13 May 2014 18:08:42 +0200 Subject: [PATCH 14/61] Fix accessibility auto test Prevent crash on platforms that don't support accessibility by skipping tests. Change-Id: I42ba44df3200e0abd62797c76a5c538fb1d2757c Reviewed-by: Frederik Gladhorn --- tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 54c56eb18be..8b033efa4ab 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -315,6 +315,8 @@ void tst_QAccessibility::initTestCase() { QTestAccessibility::initialize(); QPlatformIntegration *pfIntegration = QGuiApplicationPrivate::platformIntegration(); + if (!pfIntegration->accessibility()) + QSKIP("This platform does not support accessibility"); pfIntegration->accessibility()->setActive(true); } From 08117eee009f06d77bba489bd9513b5671e3d604 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 12 May 2014 08:24:06 +0200 Subject: [PATCH 15/61] Android: Support QFont::Courier style hint Android doesn't have a serif monospaced font, so for the courier style hint we at least need to fall back to something monospaced, which is "Droid Sans Mono" on Android. [ChangeLog][Android][Text] Fall back to Droid Sans Mono for QFont::Courier style hint. Task-number: QTBUG-37844 Change-Id: Ib42caf53a8fb7b9958e10a8f123cac928eee7069 Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/qandroidplatformfontdatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp index 7423e6c55a4..935caed4673 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]; From a968042f54aaa0155374f8a4140aaa1122f82949 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 14 May 2014 14:38:07 +0200 Subject: [PATCH 16/61] Restore fullscreen mode after keyboard is dismissed Showing the onscreen keyboard will also show the navigation soft buttons. We need to tell Android to re-enable immersive mode after the keyboard is hidden. Since we now do this in two places, refactor the logic. Task-number: QTBUG-36916 Change-Id: Ic69c28f41f5e8cf324d81f9bada3cb148dfb5306 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../qt5/android/QtActivityDelegate.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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 b396dfdfa1a..554c54d4a0c 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. } } } From 8e5e9d7987d0251fa61e24acbf6171879df3ae16 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Fri, 9 May 2014 14:53:06 +0200 Subject: [PATCH 17/61] QDoc: Added "QML Type" to HTML titles of QML type pages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -makes it more consistent with the C++ pages. -easier to read for the search engines. Change-Id: I172bdff04e0aa80ee58a903d112585992234d7d7 Reviewed-by: Topi Reiniö --- src/tools/qdoc/htmlgenerator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 641e59f018c..06097e85d57 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -1446,6 +1446,10 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) // Replace the marker with a QML code marker. marker = CodeMarker::markerForLanguage(QLatin1String("QML")); } + else if (dn->subType() == Node::QmlClass) { + fullTitle = fullTitle + " QML Type"; + htmlTitle = fullTitle; + } generateHeader(htmlTitle, dn, marker); /* From 5b4c0da9d0dbe219234feb85ba4cd6d94425d12b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 11 May 2014 11:54:54 -0700 Subject: [PATCH 18/61] Move the hex digits out of _q_toHex Avoids them being duplicated several times in QtCore Change-Id: Idee0168ed9d452a572ad46e2a14d2d4d3c7d2f7e Reviewed-by: Robin Burchell Reviewed-by: Olivier Goffart --- src/corelib/plugin/quuid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 183a16a7ada..ac66bd00cec 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 void _q_toHex(Char *&dst, Integral value) { - static const char digits[] = "0123456789abcdef"; - value = qToBigEndian(value); const char* p = reinterpret_cast(&value); From 2a9201c1e637562f5b6f6d3777af419c59f655cd Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 14 May 2014 13:56:08 +0200 Subject: [PATCH 19/61] Fix error when reading newlines Fix error 'operation priorities' identified by static analysis from http://www.viva64.com/en/b/0251/ '!=' operator's priority is higher than that of the '=' Change-Id: I2668171acb506992e3a15b113682ac04ba309532 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/io/qsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 321525ca189..63a0266948b 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) { From 1a93c2df1d171319b2fa26eafd94681e544e8092 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 13 May 2014 16:30:53 +0200 Subject: [PATCH 20/61] Disable compiler warnings for libqtharfbuzz-ng This 3rdparty code produces a lot of warnings especially with clang. Change-Id: I6f48410699e785d1b2e84b9a6d7b0ba8751179b0 Reviewed-by: Konstantin Ritt Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index bd0475fc057..246c763fd6d 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) From e26ed09102e2eb350eb072decbd670b7d515be45 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 15 May 2014 12:14:54 +0200 Subject: [PATCH 21/61] Revert "fix build for MSVC 2010" The condition in WinUser.h is _WIN32_WINNT >= 0x0602. The original #if was correct. This reverts commit 42d162addf82aa2064600219b9b3224836f676ac Change-Id: I7a3098ced143fba7b31b138cc7aaaf8f6920bef3 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qeventdispatcher_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 7debf0d7741..64ad2ff0d3f 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; } From 72558e810d9b3493dabfc936fa6c8bf3c3f3b49c Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 15 May 2014 19:00:15 +0200 Subject: [PATCH 22/61] Avoid setting unnecessary parameters in QOpenGLWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QOpenGLFramebufferObject sets the texture parameters already, do not set them again. Especially not GL_REPEAT, which is wrong and breaks on devices that do not support REPEAT on NPOT textures. What QOpenGLFramebufferObject does is just fine (it sets NEAREST/ NEAREST and CLAMP_TO_EDGE). This is important for WebEngine where the QWidget-based web view is using QOpenGLWidget. Change-Id: I264d30118ce7adf50f68f2c7b9a5599a406b4362 Reviewed-by: Jørgen Lind --- src/widgets/kernel/qopenglwidget.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index cbefb8a6bfa..307d0bb9098 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(); From fa3d264b0bd70afa15a22811be369dc8b65267e6 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 15 May 2014 15:57:01 +0200 Subject: [PATCH 23/61] QNX: Fix tst_selftest GRAPHICS_ROOT and TZ environment variables are needed in child processes in order to successfully run the auto test selftests. Change-Id: I7befabd535b4c47b1e75acbe3d6158d0d9b811b3 Reviewed-by: Friedemann Kleint --- tests/auto/testlib/selftests/tst_selftests.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 8167a96eaa2..9082561dc99 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -526,9 +526,11 @@ static QProcessEnvironment processEnvironment() const QProcessEnvironment systemEnvironment = QProcessEnvironment::systemEnvironment(); foreach (const QString &key, systemEnvironment.keys()) { const bool useVariable = key == QLatin1String("PATH") || key == QLatin1String("QT_QPA_PLATFORM") -#ifdef Q_OS_UNIX +#if defined(Q_OS_QNX) + || key == QLatin1String("GRAPHICS_ROOT") || key == QLatin1String("TZ") +#elif defined(Q_OS_UNIX) || key == QLatin1String("HOME") || key == QLatin1String("USER") // Required for X11 on openSUSE -# ifndef Q_OS_MAC +# if !defined(Q_OS_MAC) || key == QLatin1String("DISPLAY") || key == QLatin1String("XAUTHLOCALHOSTNAME") || key.startsWith(QLatin1String("XDG_")) # endif // !Q_OS_MAC From 514697893f5be4bbef18b1ae5c7b61531c689dbe Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 May 2014 15:03:34 +0200 Subject: [PATCH 24/61] qmacmime: add support for public.rtf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Application like Safari on iOS posts rtf to the pasteboard when copying html. With this converter added, you can then paste rtf as html into Qt Change-Id: I6b62bcc9cfc0b16a47d44bd8d74062226522526d Reviewed-by: Morten Johan Sørvig --- src/platformsupport/clipboard/qmacmime.mm | 88 +++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index af94589c08e..63675d7a32c 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -39,6 +39,13 @@ ** ****************************************************************************/ +#include +#if defined(Q_OS_IOS) +#import +#elif defined(Q_OS_OSX) +#import +#endif + #include "qmacmime_p.h" #include "qguiapplication.h" @@ -541,6 +548,86 @@ QList 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 data, QString flav); + QList 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 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 QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor) +{ + QList 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) { } @@ -763,6 +850,7 @@ void QMacInternalPasteboardMime::initializeMimeTypes() new QMacPasteboardMimePlainTextFallback; new QMacPasteboardMimeUnicodeText; new QMacPasteboardMimePlainText; + new QMacPasteboardMimeRtfText; new QMacPasteboardMimeHTMLText; new QMacPasteboardMimeFileUri; new QMacPasteboardMimeUrl; From 6388163df8f660ae38cb60e58afe9c9833b2512e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 28 Apr 2014 14:41:04 +0200 Subject: [PATCH 25/61] qmacmime: rename and move QMacPasteboardMimePlainText to the cocoa plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit com.apple.traditional-mac-plain-text is not in use on iOS according to Apples UTType reference. So we enable it only for OS X by moving it into the cocoa port. The order in which we instanciate convertors matters when the application is reading data from the pasteboard. But since QMacPasteboardMimePlainText should come before the other "text/plain" convertors on OS X, moving it to the cocoa port is safe as those convertors are instanciated after those in qmacmime. Change-Id: I76b9b14e5ce78f34e0f1ecbfee71e48a27a4687b Reviewed-by: Morten Johan Sørvig --- src/platformsupport/clipboard/qmacmime.mm | 62 ------------------- .../platforms/cocoa/qcocoamimetypes.mm | 62 +++++++++++++++++++ 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 63675d7a32c..27a490335bb 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -290,67 +290,6 @@ QList QMacPasteboardMimeTypeName::convertFromMime(const QString &, Q return ret; } -class QMacPasteboardMimePlainText : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimePlainText() : 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 data, QString flav); - QList convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimePlainText::convertorName() -{ - return QLatin1String("PlainText"); -} - -QString QMacPasteboardMimePlainText::flavorFor(const QString &mime) -{ - if (mime == QLatin1String("text/plain")) - return QLatin1String("com.apple.traditional-mac-plain-text"); - return QString(); -} - -QString QMacPasteboardMimePlainText::mimeFor(QString flav) -{ - if (flav == QLatin1String("com.apple.traditional-mac-plain-text")) - return QLatin1String("text/plain"); - return QString(); -} - -bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav) -{ - return flavorFor(mime) == flav; -} - -QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList 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")) { - return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault, - reinterpret_cast(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false)); - } else { - qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); - } - return ret; -} - -QList QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor) -{ - QList ret; - QString string = data.toString(); - if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) - ret.append(string.toLatin1()); - return ret; -} - class QMacPasteboardMimePlainTextFallback : public QMacInternalPasteboardMime { public: QMacPasteboardMimePlainTextFallback() : QMacInternalPasteboardMime(MIME_ALL) { } @@ -849,7 +788,6 @@ void QMacInternalPasteboardMime::initializeMimeTypes() //standard types that we wrap new QMacPasteboardMimePlainTextFallback; new QMacPasteboardMimeUnicodeText; - new QMacPasteboardMimePlainText; new QMacPasteboardMimeRtfText; new QMacPasteboardMimeHTMLText; new QMacPasteboardMimeFileUri; diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index 8151d314494..f6487095e70 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 data, QString flav); + QList 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 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(firstData.constData()), + firstData.size(), CFStringGetSystemEncoding(), false)); + } else { + qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); + } + return ret; +} + +QList QMacPasteboardMimeTraditionalMacPlainText::convertFromMime(const QString &, QVariant data, QString flavor) +{ + QList 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) { } @@ -204,6 +265,7 @@ QList QMacPasteboardMimeRtfText::convertFromMime(const QString &mime void QCocoaMimeTypes::initializeMimeTypes() { + new QMacPasteboardMimeTraditionalMacPlainText; new QMacPasteboardMimeTiff; new QMacPasteboardMimeRtfText; } From 986309cbf05f632605b72bdc7fe4affc6d348021 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 May 2014 15:15:07 +0200 Subject: [PATCH 26/61] cocoa: remove rtf converter from cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is now a modified rtf converter in qmacmime that can also write rtf back to the pasteboard, and that works on both OS X and iOS. So we can therefore remove the one from the cocoa port. Change-Id: Ieed04502752290d2f139f98cec69477ff1edbe4e Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoamimetypes.mm | 67 ------------------- 1 file changed, 67 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index f6487095e70..421d934fa78 100644 --- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -197,77 +197,10 @@ QList 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 data, QString flav); - QList 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 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 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 ret; - return ret; -} - void QCocoaMimeTypes::initializeMimeTypes() { new QMacPasteboardMimeTraditionalMacPlainText; new QMacPasteboardMimeTiff; - new QMacPasteboardMimeRtfText; } QT_END_NAMESPACE From 679cd99f3d43ac624ad2683f6d3b1b97b3b2cb0d Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 7 May 2014 16:06:22 +0200 Subject: [PATCH 27/61] Accessibility: Update ComboBox text on arrow keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use ValueChanged to notify of changes in the ComboBox. On Linux we need to update name and then send selection-changed for Orca. Task-number: QTBUG-36814 Change-Id: Icdd34adddeac532476a6dd910d1e8bd33bcd590b Reviewed-by: Jan Arve Sæther --- .../linuxaccessibility/atspiadaptor.cpp | 27 ++++++++++++++----- src/widgets/widgets/qcombobox.cpp | 12 ++++----- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index 1ccab0a859e..0fa1d962422 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/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 06258cb4a6e..f857f4eac01 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 } From 1248eddd1461d3fa6e87d1d3278016d102f47e18 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 8 May 2014 16:41:44 +0200 Subject: [PATCH 28/61] Accessibility Android: Fix states MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the bit flags as parameters to the JNI functions would fail since they'd always be cast to false instead of the c-style casts. This fixes checkboxes reporting themselves as checkable and their check state. Task-number: QTBUG-38831 Change-Id: I30ab63ceabbec4cc2fbda9475e05523d915087fe Reviewed-by: Jan Arve Sæther --- .../platforms/android/androidjniaccessibility.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index 2c1701db830..fa7e2594608 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -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 } } From 102cec7ec03822243d9cb99763a0c02f9a13351d Mon Sep 17 00:00:00 2001 From: Jorgen Lind Date: Fri, 16 May 2014 13:56:23 +0200 Subject: [PATCH 29/61] QOpenGLTextureBlitter fix allocating 4 times as much memory as needed and copying a lot of garbage. Change-Id: Idf1d23d06423a98ce503c9bcf9614b12dd1fb92a Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengltextureblitter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp index efe769badff..e6dbb706189 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"); From cfcbb957c7ee85decee3379d8876a7b4094ae501 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 16 May 2014 15:11:39 +0200 Subject: [PATCH 30/61] Call tzset() before localtime_r() as the docs say. Without it, one might run the risk of QDateTime::currentDateTime() returning an invalid QDateTime the first time after changing timezone. Change-Id: I3efb04d41e7fe4685f6cc5fb41b68424eb4b9eb8 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 801876629cf..d6f1d6c9423 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; From 518d874bc8cd43a6e87700be00c6f5132288bd35 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Thu, 8 May 2014 01:31:20 -0400 Subject: [PATCH 31/61] QMacStyle: Always draw status bar in active state if the window is main. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On OS X, most controls are drawn active or inactive based on their window's main state, NOT its key ("active" in Qt) state. Change-Id: If447d0a537bc594978f7202e7888ceacb54ec8fa Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index e165b8aa68a..8bc454a7952 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -3265,7 +3265,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 { @@ -3275,7 +3275,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); From 71006cf04c6a3d1f44efb3d59eb136f4f589bccf Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Wed, 7 May 2014 16:36:04 -0700 Subject: [PATCH 32/61] CoreWLan: wait for scan thread to finish If the scan thread is running when QCoreWlanEngine is destroyed it will access stale data and cause a crash. Task-number: QTBUG-36000 Change-Id: I8cc9e39a3f7d4736da39e8b31f6963db35318f19 Reviewed-by: Frederik Gladhorn Reviewed-by: Peter Hartmann --- src/plugins/bearer/corewlan/qcorewlanengine.mm | 2 ++ src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 2d8b9be092b..554ad26e51f 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 057aec54871..ba1cf332582 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]; From 43d4fecde59e6d317731ebabbe612a0752781ca8 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 15 May 2014 15:04:49 +0200 Subject: [PATCH 33/61] Fix auto test failure output on QNX On QNX mbstowcs does not ignore last parameter (max) when first (dest) is NULL. Set it to sufficiently large value to yield proper results on QNX. Other platforms (standard libraries) will ignore this value anyway. Change-Id: Ie4695254d45082e151a052bf16de684af3b1ba1e Reviewed-by: Thiago Macieira --- src/testlib/qtestresult.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 859f6743cd3..8eb1fa2d9c6 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -49,7 +49,6 @@ #include #include #include -#include 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 : "", expected, qMax(len1, len2) - len2 + 1, ":", val2 ? val2 : ""); } else - qsnprintf(msg, 1024, "%s", failureMsg); + qsnprintf(msg, maxMsgLen, "%s", failureMsg); delete [] val1; delete [] val2; From af16f88e970e3f6ceb32becca6b0e9baa61ae0e9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 16 May 2014 17:17:57 +0200 Subject: [PATCH 34/61] egl cursor: The sampler is a uniform not an attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ibae21653040f1d8dff2d2c0b7c1b2812d9e14551 Reviewed-by: Jørgen Lind --- src/platformsupport/eglconvenience/qeglplatformcursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index e99581183e4..b6293e60ec4 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) From ba28ca60f66c83a1caa5777d78ffac63e92dfec3 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 15 May 2014 13:09:31 +0200 Subject: [PATCH 35/61] Fix compilation on libxcb 1.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libxkbcommon-x11 uses xcb_discard_reply() function which was introduced in libxcb 1.6, this brakes the compilation in src/3rdparty/xkbcommon/src/x11/util.c when linking with libxcb 1.5 : linking ../../../../plugins/platforms/libqxcb.so .obj/util.o: In function `adopt_atoms': util.c:(.text+0x347): undefined reference to `xcb_discard_reply' collect2: error: ld returned 1 exit status We can use an alternative approach to discard uncollected replies and in addition add a fix for out-of-bounds error [1] [1] https://github.com/xkbcommon/libxkbcommon/commit/e3f751be660e28e48d1477660e99e5456c864296 Task-number: QTBUG-38952 Change-Id: Ide90f9a2e75fc79d2bab0b81adb282c8cc81c345 Reviewed-by: Jørgen Lind --- .../Fix-compilation-on-libxcb-1.5.patch | 19 +++++++++++++++++++ src/3rdparty/xkbcommon/src/x11/util.c | 8 ++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 src/3rdparty/xkbcommon/Fix-compilation-on-libxcb-1.5.patch 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 00000000000..691f142e5e0 --- /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 92ff2e630ec..7659c711a2c 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; } } From 35766fbe472c32afb7313a9e57d886f43cebcde7 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 14 May 2014 13:09:27 +0300 Subject: [PATCH 36/61] Direct2D QPA: Fix version check It turns out that the version we were testing against was more recent than basic Windows 7 SP1 + Platform Update. The direct2d version that combination produces without any other updates is 6.2.9200.16492, and it is sufficient for us. Change-Id: Ib9840647371e2bb5c71bf74486348444ed4b4c19 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../platforms/direct2d/qwindowsdirect2dintegration.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index 9833d50e6c3..b162ac63188 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() { From 58caefa13e7bcfac1baccee4d1e7a73bd6b48f19 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Fri, 9 May 2014 11:17:41 +0300 Subject: [PATCH 37/61] Direct2D QPA: Stroke using direct2d primitives Use native direct2d stroking instead of falling back to QPaintEngineEx::stroke which in turn calls the pure virtual QPaintEngineEx::fill which is reimplemented in QWindowsDirect2DPaintEngine. In some cases like arc stroking this is significantly faster (up to 3x in my measurements) and results in better visual quality. Change-Id: I1c86ff772ba591432ff6550c7c59704ace4f0e0f Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 78 ++++++++++++++++++- .../direct2d/qwindowsdirect2dpaintengine.h | 7 ++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 5a4157565ef..a838950c9e3 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -934,6 +934,33 @@ void QWindowsDirect2DPaintEngine::setState(QPainterState *s) transformChanged(); } +void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) +{ + Q_D(QWindowsDirect2DPaintEngine); + + ComPtr 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); @@ -943,7 +970,6 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br return; ensureBrush(brush); - if (emulationRequired(BrushEmulation)) { rasterFill(path, brush); return; @@ -961,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 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 fb9b7acec3b..c91a951ebe8 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; From 828656241bb69dc4c247796860963d88aa70ca5c Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 19 May 2014 13:30:28 +0300 Subject: [PATCH 38/61] Direct2D QPA: Use correct buffer size constant Change-Id: I2d8ec5faed959d6d642242b3e26ee0f185ee3d53 Reviewed-by: Friedemann Kleint --- .../platforms/direct2d/qwindowsdirect2dintegration.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index b162ac63188..0e38f9b12ad 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -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 info(versionInfoSize); From 1d7902a0caa77563d242e665e0a442e8afc6cf1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 15 May 2014 16:21:39 +0000 Subject: [PATCH 39/61] Fix crash in QNetworkAccessManager. Recreating QCoreApplication could cause a crash in QNetworkAccessManager constructor. That was caused by an invalid shutdown detection introduced in f273d6fbc02055ff3999adc0df76360ca0670435. Task-number: QTBUG-36897 Change-Id: Ib5bba773a2a4fcde690a3a93680aef551aae3a5b Reviewed-by: Peter Hartmann --- src/network/bearer/qnetworkconfigmanager.cpp | 14 +++- src/network/bearer/qnetworkconfigmanager_p.h | 2 +- tests/auto/network/bearer/bearer.pro | 1 + .../qnetworkconfigurationmanagerqappless.pro | 6 ++ ...t_qnetworkconfigurationmanagerqappless.cpp | 73 +++++++++++++++++++ 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/qnetworkconfigurationmanagerqappless.pro create mode 100644 tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp index 855ab4e4852..db1325d85b8 100644 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -57,6 +57,13 @@ QT_BEGIN_NAMESPACE static QBasicAtomicPointer 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 d0913a843a7..78b90b60a80 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/tests/auto/network/bearer/bearer.pro b/tests/auto/network/bearer/bearer.pro index 872a818e4ca..6ce922eaf80 100644 --- a/tests/auto/network/bearer/bearer.pro +++ b/tests/auto/network/bearer/bearer.pro @@ -2,5 +2,6 @@ TEMPLATE=subdirs SUBDIRS=\ qnetworkconfiguration \ qnetworkconfigurationmanager \ + qnetworkconfigurationmanagerqappless \ qnetworksession \ diff --git a/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/qnetworkconfigurationmanagerqappless.pro b/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/qnetworkconfigurationmanagerqappless.pro new file mode 100644 index 00000000000..ad080910d70 --- /dev/null +++ b/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/qnetworkconfigurationmanagerqappless.pro @@ -0,0 +1,6 @@ +CONFIG += testcase +TARGET = tst_qnetworkconfigurationmanagerqappless +SOURCES += tst_qnetworkconfigurationmanagerqappless.cpp +HEADERS += ../qbearertestcommon.h + +QT = core network testlib diff --git a/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp b/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp new file mode 100644 index 00000000000..eff2cb1642b --- /dev/null +++ b/tests/auto/network/bearer/qnetworkconfigurationmanagerqappless/tst_qnetworkconfigurationmanagerqappless.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +QT_USE_NAMESPACE + +class tst_QNetworkConfigurationManager : public QObject +{ + Q_OBJECT + +private slots: + void staticsInitialization(); +}; + +void tst_QNetworkConfigurationManager::staticsInitialization() +{ + // This code should not crash. The test was introduced as + // a fix for https://bugreports.qt-project.org/browse/QTBUG-36897 + for (int i = 0; i < 2; i++) + { + int argc = 1; + const char *testName = "tst_qnetworkconfigurationmanagerqappless"; + char **argv = const_cast(&testName); + QCoreApplication app(argc, argv); + QNetworkAccessManager qnam; + Q_UNUSED(app); + Q_UNUSED(qnam); + } + QVERIFY(true); +} + +QTEST_APPLESS_MAIN(tst_QNetworkConfigurationManager) +#include "tst_qnetworkconfigurationmanagerqappless.moc" From 6ef8eee8d42485ce3e1f6ef3bd60413d4bad7ecd Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 14 May 2014 18:36:26 +0200 Subject: [PATCH 40/61] Fix potential null pointer access Change-Id: I7516ce88b38609ab9851419566141ba93a59aed3 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index ead29556b74..18e62b26d4b 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -827,7 +827,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(); From ac10baa2a093a0769a04575f475db5081f64ce81 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 16 May 2014 12:03:16 +0200 Subject: [PATCH 41/61] CMake: Don't FATAL_ERROR if GL libraries can not be found. For Windows builds, the necessary libraries are not found in the sdk if the wrong environment is used, which is quite common. Task-number: QTBUG-34940 Change-Id: I7d844649790cbfacab3154a717d318fd570c4149 Reviewed-by: Brad King Reviewed-by: Stephen Kelly --- src/gui/Qt5GuiConfigExtras.cmake.in | 63 ++++++++++++++++------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in index 75a2385d57c..f9c327f938a 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}) + 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}\") + 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) From 043529c9dc609f3dc4bc6c79b7bc4d33ca3a3ba3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 May 2014 14:13:23 +0200 Subject: [PATCH 42/61] Windows QPA: Remove dependency on swprintf_s() pulled in via _com_error::ErrorMessage(). Task-number: QTBUG-35617 Change-Id: I0ad926ac564612ebd0eb38f16b3e69cbcd48e62f Reviewed-by: Joerg Bornemann --- .../platforms/windows/qwindowscontext.cpp | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 18e62b26d4b..f2f285f0f6f 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -692,6 +692,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. */ @@ -758,7 +779,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; From 802e50c86b1b195d07d149092c97188e65423ec7 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 18 May 2014 12:19:32 +0100 Subject: [PATCH 43/61] Avoid accessing the internals of the SSL_CIPHER struct. Avoid accessing the internals of the SSL_CIPHER struct since this has changed size etc. over time leading to binary incompatibilities. Task-number: QTBUG-32423 Task-number: QTBUG-23363 Change-Id: I8cb399484e3a62be7d511f4b8b22c876825c87d4 Reviewed-by: Peter Hartmann Reviewed-by: Daniel Molkentin --- src/network/ssl/qsslsocket_openssl.cpp | 4 +--- src/network/ssl/qsslsocket_openssl_symbols.cpp | 2 ++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 2ee69d35da8..0315749cb31 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -237,9 +237,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 01c0f6f8108..d4a4117b8bd 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -203,6 +203,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. @@ -725,6 +726,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 1e68fdd6c21..0f3d2673c2b 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -294,6 +294,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. From 49dc7d2b8c77975de864e46f08f6fb59bc44b03a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Apr 2014 16:57:31 -0700 Subject: [PATCH 44/61] Fix minor coding style issues in new code in QtCore Change-Id: I444daf8e81257f55746f9d32fbcb60a2e1b69444 Reviewed-by: Liang Qi Reviewed-by: Rafael Roquetto Reviewed-by: Lars Knoll --- src/corelib/kernel/qppsattribute.cpp | 7 +++---- src/corelib/kernel/qppsobject.cpp | 18 +++++++++--------- src/corelib/tools/qchar.h | 3 ++- src/corelib/tools/qstring.h | 3 ++- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/corelib/kernel/qppsattribute.cpp b/src/corelib/kernel/qppsattribute.cpp index f6745d2354b..93d7ae756e7 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 eb8e69baffb..1095ad51da4 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/tools/qchar.h b/src/corelib/tools/qchar.h index 1955758fca9..24c757f9f45 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/qstring.h b/src/corelib/tools/qstring.h index 359d0c49e52..3985bc76fea 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; From 199b2594ff08b8341126165f17bbef8af54351ec Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 11 May 2014 17:41:40 -0700 Subject: [PATCH 45/61] Make the use of -ffunction-sections more generic in Qt Move it from bootstrap.pro into qt_module.prf so it will apply to any other bootstrapped libraries, like libQmlDevTools. Variable called "SPLIT_SECTIONS" because -fdata-sections could be added in the future, if it proves to be a benefit. Change-Id: I3fbb004f111620a84e58e9112e9bce3afd95631e Reviewed-by: Oswald Buddenhagen --- mkspecs/common/gcc-base.conf | 2 ++ mkspecs/features/qt_module.prf | 2 ++ mkspecs/linux-icc/qmake.conf | 2 ++ mkspecs/macx-icc/qmake.conf | 2 ++ mkspecs/win32-g++/qmake.conf | 2 ++ src/tools/bootstrap/bootstrap.pro | 2 -- 6 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index 4326f919253..fcff502af67 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -47,6 +47,7 @@ QMAKE_CFLAGS_ISYSTEM = -isystem QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden QMAKE_CFLAGS_EXCEPTIONS_OFF += -fno-exceptions +QMAKE_CFLAGS_SPLIT_SECTIONS += -ffunction-sections QMAKE_CXXFLAGS += $$QMAKE_CFLAGS QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS @@ -60,6 +61,7 @@ QMAKE_CXXFLAGS_APP += $$QMAKE_CFLAGS_APP QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden QMAKE_CXXFLAGS_EXCEPTIONS_OFF += $$QMAKE_CFLAGS_EXCEPTIONS_OFF +QMAKE_CXXFLAGS_SPLIT_SECTIONS += $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_LFLAGS += QMAKE_LFLAGS_DEBUG += diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 5dac0250eaa..8bf4c92cdd2 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -29,6 +29,8 @@ host_build|staticlib: CONFIG += static host_build { QT -= gui # no host module will ever use gui + QMAKE_CFLAGS += $$QMAKE_CFLAGS_SPLIT_SECTIONS + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SPLIT_SECTIONS force_bootstrap { !build_pass: CONFIG += release contains(QT, core(-private)?|xml) { diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 1b71588b8c1..c0caca09fa4 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -23,6 +23,7 @@ QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB QMAKE_CFLAGS_YACC = QMAKE_CFLAGS_ISYSTEM = -isystem QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections QMAKE_CFLAGS_SSE2 += -xSSE2 QMAKE_CFLAGS_SSE3 += -xSSE3 @@ -44,6 +45,7 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD +QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS # Disabling exceptions disabled - workaround for QTBUG-36577 #QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions QMAKE_CXXFLAGS_CXX11 = -std=c++0x diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf index 0bbb1be4ee5..03dc58a65c9 100644 --- a/mkspecs/macx-icc/qmake.conf +++ b/mkspecs/macx-icc/qmake.conf @@ -22,6 +22,7 @@ QMAKE_CFLAGS_SHLIB = -fPIC -fno-jump-tables QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses QMAKE_CFLAGS_THREAD = +QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections QMAKE_CFLAGS_SSE2 += -xSSE2 QMAKE_CFLAGS_SSE3 += -xSSE3 @@ -51,6 +52,7 @@ QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_CXXFLAGS_CXX11 = -std=c++11 +QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_LINK = icpc QMAKE_LINK_SHLIB = icpc diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 830dde97e99..759ade93c17 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -32,6 +32,7 @@ QMAKE_CFLAGS_WARN_OFF = -w QMAKE_CFLAGS_RELEASE = -O2 QMAKE_CFLAGS_DEBUG = -g QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_SPLIT_SECTIONS = -ffunction-sections QMAKE_CFLAGS_SSE2 = -msse2 -mstackrealign QMAKE_CFLAGS_SSE3 = -msse3 QMAKE_CFLAGS_SSSE3 = -mssse3 @@ -56,6 +57,7 @@ QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions QMAKE_CXXFLAGS_CXX11 = -std=c++0x +QMAKE_CXXFLAGS_SPLIT_SECTIONS = $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_INCDIR = diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index fea4e2519f3..310ea317ac6 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -145,8 +145,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) From e91e502ab6424be12c3448431a65e7d617ab5571 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 11 May 2014 17:43:51 -0700 Subject: [PATCH 46/61] Make qmake also use -ffunction-sections This might lead to a smaller binary if we use --gc-sections too. Change-Id: I7e17b956a85ecefc3e187054848393d2855152b6 Reviewed-by: Oswald Buddenhagen --- configure | 6 ++++-- tools/configure/configureapp.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/configure b/configure index e7e4f4f59be..d4eb6d0dc0f 100755 --- a/configure +++ b/configure @@ -3662,8 +3662,8 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; echo "########################################################################" >> "$mkfile" EXTRA_OBJS= EXTRA_SRCS= - EXTRA_CFLAGS="\$(QMAKE_CFLAGS)" - EXTRA_CXXFLAGS="\$(QMAKE_CXXFLAGS)" + EXTRA_CFLAGS="\$(QMAKE_CFLAGS) \$(QMAKE_CFLAGS_SPLIT_SECTIONS)" + EXTRA_CXXFLAGS="\$(QMAKE_CXXFLAGS) \$(QMAKE_CXXFLAGS_SPLIT_SECTIONS)" EXTRA_LFLAGS="\$(QMAKE_LFLAGS)" if [ "$PLATFORM" = "irix-cc" ] || [ "$PLATFORM" = "irix-cc-64" ]; then @@ -3674,7 +3674,9 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; setBootstrapVariable QMAKE_CC CC "$CC_TRANSFORM" setBootstrapVariable QMAKE_CXX CXX "$CC_TRANSFORM" setBootstrapVariable QMAKE_CFLAGS + setBootstrapVariable QMAKE_CFLAGS_SPLIT_SECTIONS setBootstrapVariable QMAKE_CXXFLAGS + setBootstrapVariable QMAKE_CXXFLAGS_SPLIT_SECTIONS setBootstrapVariable QMAKE_LFLAGS if [ "$CFG_RELEASE_QMAKE" = "yes" ]; then diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 06f78b11167..0e3bbcd3fbc 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4039,8 +4039,8 @@ void Configure::buildQmake() stream << "QT_VERSION = " << dictionary["VERSION"] << endl; if (dictionary[ "QMAKESPEC" ] == QString("win32-g++")) { stream << "QMAKESPEC = $(SOURCE_PATH)\\mkspecs\\win32-g++" << endl - << "EXTRA_CFLAGS = -DUNICODE" << endl - << "EXTRA_CXXFLAGS = -DUNICODE" << endl + << "EXTRA_CFLAGS = -DUNICODE -ffunction-sections" << endl + << "EXTRA_CXXFLAGS = -DUNICODE -ffunction-sections" << endl << "QTOBJS = qfilesystemengine_win.o \\" << endl << " qfilesystemiterator_win.o \\" << endl << " qfsfileengine_win.o \\" << endl From 6315745770384490509cf471c6286a1ea32cb79e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 May 2014 11:27:06 -0700 Subject: [PATCH 47/61] Strip bootstrapped binaries of unused sections This matches the -ffunction-sections from bootstrap.pro, which tells the compiler to create a section for each function. The -gc-sections option tells the linker to drop what wasn't used (normally, it only drops entire files). Before (on Linux, built with -O3, no LTO): text data bss dec hex filename 1746385 7920 3750 1758055 1ad367 bin/moc 1444101 6664 1894 1452659 162a73 bin/rcc 4407725 1568 4896 4414189 435aed bin/qmake After: text data bss dec hex filename 1131655 6520 3494 1141669 116ba5 bin/moc 1027043 5480 1766 1034289 fc831 bin/rcc 3578489 1656 5313 3585458 36b5b2 bin/qmake Gain: 35% on moc, 28% on rcc, 19% on qmake Before (on OS X): __TEXT __DATA __OBJC others dec hex 1495040 12288 0 4294993008 4296500336 100176470 bin/moc 1265664 8192 0 4294983904 4296257760 10013b0e0 bin/rcc 5279744 81920 0 4297912320 4303273984 1007ec000 bin/qmake After: __TEXT __DATA __OBJC others dec hex 806912 8192 0 4294988132 4295803236 1000cc164 bin/moc 720896 8192 0 4294979764 4295708852 1000b50b4 bin/rcc 4841472 77824 0 4295580688 4300499984 100546c10 bin/qmake Gain: 46% on moc, 43% on rcc, 8% on qmake. Change-Id: Icc7cdc9fd6f5db15537b4adabaac7e7a27e539d4 Reviewed-by: Oswald Buddenhagen --- configure | 3 ++- mkspecs/common/linux.conf | 1 + mkspecs/common/mac.conf | 1 + mkspecs/features/qt_app.prf | 3 +++ mkspecs/win32-g++/qmake.conf | 1 + tools/configure/configureapp.cpp | 1 + 6 files changed, 9 insertions(+), 1 deletion(-) diff --git a/configure b/configure index d4eb6d0dc0f..d5c2b0801f0 100755 --- a/configure +++ b/configure @@ -3664,7 +3664,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_SRCS= EXTRA_CFLAGS="\$(QMAKE_CFLAGS) \$(QMAKE_CFLAGS_SPLIT_SECTIONS)" EXTRA_CXXFLAGS="\$(QMAKE_CXXFLAGS) \$(QMAKE_CXXFLAGS_SPLIT_SECTIONS)" - EXTRA_LFLAGS="\$(QMAKE_LFLAGS)" + EXTRA_LFLAGS="\$(QMAKE_LFLAGS) \$(QMAKE_LFLAGS_GCSECTIONS)" if [ "$PLATFORM" = "irix-cc" ] || [ "$PLATFORM" = "irix-cc-64" ]; then EXTRA_LFLAGS="$EXTRA_LFLAGS -lm" @@ -3678,6 +3678,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; setBootstrapVariable QMAKE_CXXFLAGS setBootstrapVariable QMAKE_CXXFLAGS_SPLIT_SECTIONS setBootstrapVariable QMAKE_LFLAGS + setBootstrapVariable QMAKE_LFLAGS_GCSECTIONS if [ "$CFG_RELEASE_QMAKE" = "yes" ]; then setBootstrapVariable QMAKE_CFLAGS_RELEASE diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf index 98e6cefabd8..e10ab71cd6e 100644 --- a/mkspecs/common/linux.conf +++ b/mkspecs/common/linux.conf @@ -6,6 +6,7 @@ QMAKE_PLATFORM += linux QMAKE_CFLAGS_THREAD += -D_REENTRANT QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD +QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections QMAKE_INCDIR = QMAKE_LIBDIR = diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index 44216653701..5f60549c70d 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -18,6 +18,7 @@ QMAKE_INCDIR_OPENGL = \ QMAKE_FIX_RPATH = install_name_tool -id QMAKE_LFLAGS_RPATH = +QMAKE_LFLAGS_GCSECTIONS = -Wl,-dead_strip QMAKE_LIBS_DYNLOAD = QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL diff --git a/mkspecs/features/qt_app.prf b/mkspecs/features/qt_app.prf index a4fcb7d484d..0f83fd7270e 100644 --- a/mkspecs/features/qt_app.prf +++ b/mkspecs/features/qt_app.prf @@ -16,6 +16,9 @@ DESTDIR = $$MODULE_BASE_OUTDIR/bin isEmpty(QMAKE_INFO_PLIST): CONFIG -= app_bundle +# This decreases the binary size for tools if statically linked +QMAKE_LFLAGS += $$QMAKE_LFLAGS_GCSECTIONS + host_build: QT -= gui # no host tool will ever use gui host_build:force_bootstrap { !build_pass: CONFIG += release diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 759ade93c17..d26ffb4e213 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -77,6 +77,7 @@ QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows QMAKE_LFLAGS_DLL = -shared QMAKE_LFLAGS_CXX11 = +QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections QMAKE_LINK_OBJECT_MAX = 10 QMAKE_LINK_OBJECT_SCRIPT = object_script QMAKE_PREFIX_STATICLIB = lib diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 0e3bbcd3fbc..b7565093f1e 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4041,6 +4041,7 @@ void Configure::buildQmake() stream << "QMAKESPEC = $(SOURCE_PATH)\\mkspecs\\win32-g++" << endl << "EXTRA_CFLAGS = -DUNICODE -ffunction-sections" << endl << "EXTRA_CXXFLAGS = -DUNICODE -ffunction-sections" << endl + << "EXTRA_LFLAGS = -Wl,--gc-sections" << endl << "QTOBJS = qfilesystemengine_win.o \\" << endl << " qfilesystemiterator_win.o \\" << endl << " qfsfileengine_win.o \\" << endl From b8f96418ed625b4acd0f2584d1d9bc065321677c Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 13 May 2014 11:14:32 +0200 Subject: [PATCH 48/61] Skip some qsavefile auto tests Some of the QSaveFile tests are not applicable with root privileges. Change-Id: I1a22906c0b14acf144f1849719152dfe9d79f426 Reviewed-by: David Faure --- .../auto/corelib/io/qsavefile/tst_qsavefile.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp index 04c083e653b..87bcfe572d9 100644 --- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp +++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp @@ -47,9 +47,8 @@ #include #include -#if defined(Q_OS_UNIX) -# include // for geteuid -# include +#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) +#include // for geteuid #endif #if defined(Q_OS_WIN) @@ -199,6 +198,10 @@ void tst_QSaveFile::transactionalWriteNoPermissionsOnDir_data() void tst_QSaveFile::transactionalWriteNoPermissionsOnDir() { #ifdef Q_OS_UNIX +#if !defined(Q_OS_VXWORKS) + if (::geteuid() == 0) + QSKIP("Test is not applicable with root privileges"); +#endif QFETCH(bool, directWriteFallback); QTemporaryDir dir; QVERIFY(dir.isValid()); @@ -253,6 +256,10 @@ void tst_QSaveFile::transactionalWriteNoPermissionsOnDir() void tst_QSaveFile::transactionalWriteNoPermissionsOnFile() { +#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) + if (::geteuid() == 0) + QSKIP("Test is not applicable with root privileges"); +#endif // Setup an existing but readonly file QTemporaryDir dir; QVERIFY(dir.isValid()); @@ -299,6 +306,10 @@ void tst_QSaveFile::transactionalWriteCanceled() void tst_QSaveFile::transactionalWriteErrorRenaming() { +#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) + if (::geteuid() == 0) + QSKIP("Test is not applicable with root privileges"); +#endif QTemporaryDir dir; QVERIFY(dir.isValid()); const QString targetFile = dir.path() + QString::fromLatin1("/outfile"); From 1ea0d59c4a068b9bddab1a5161cc51f050c4a55d Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 13 May 2014 10:20:48 +0200 Subject: [PATCH 49/61] Skip tst_QLockFile::noPermissions QLockFile "noPermissions" test is not applicable with root privileges. Change-Id: I5779da524f24d0f1b9ef519d654856a6200da6bf Reviewed-by: David Faure --- tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index fdb29b60d81..bd9e28beb5d 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -44,6 +44,9 @@ #include #include #include +#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) +#include +#endif class tst_QLockFile : public QObject { @@ -365,9 +368,12 @@ void tst_QLockFile::staleLockRace() void tst_QLockFile::noPermissions() { -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) // A readonly directory still allows us to create files, on Windows. QSKIP("No permission testing on Windows"); +#elif defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) + if (::geteuid() == 0) + QSKIP("Test is not applicable with root privileges"); #endif // Restore permissions so that the QTemporaryDir cleanup can happen class PermissionRestorer From 1243940f83a5c04cc0eb64a0d1679dab3b7164f1 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Fri, 16 May 2014 22:46:23 +0800 Subject: [PATCH 50/61] QDoc: Stop copying title string unnecessarily "htmlTitle" never diverges from "fullTitle". Change-Id: Id1ce9005311bd86aa9803836168a2bebae6db65d Reviewed-by: Martin Smith Reviewed-by: Jerome Pasion --- src/tools/qdoc/htmlgenerator.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 06097e85d57..407253ff649 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -1344,7 +1344,6 @@ void HtmlGenerator::generateCollisionPages() ncn->clearCurrentChild(); 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. @@ -1352,7 +1351,7 @@ void HtmlGenerator::generateCollisionPages() marker = CodeMarker::markerForLanguage(QLatin1String("QML")); } - generateHeader(htmlTitle, ncn, marker); + generateHeader(fullTitle, ncn, marker); if (!fullTitle.isEmpty()) out() << "

" << protectEnc(fullTitle) << "

\n"; @@ -1437,21 +1436,18 @@ void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) QList
sections; QList
::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"; - htmlTitle = fullTitle; } - 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. From 1b031630ded1fbb9a94642de1d720651a390a03b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 7 May 2014 16:38:06 +0200 Subject: [PATCH 51/61] fix too aggressive installation of helper libraries of course all helper libraries are built statically, so the criterion is not useful. what is interesting is whether the whole qt configuration is static, as that determines what will happen with the helper library when linking the final "actual" artifacts. Change-Id: I96980c645cb478b2f7a30688b49cb51bec8c9f08 Reviewed-by: Friedemann Kleint Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_helper_lib.prf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index 4af5bcaabb8..b2bb55bb1e6 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -20,8 +20,8 @@ contains(QT_CONFIG, build_all): CONFIG += build_all DESTDIR = $$MODULE_BASE_OUTDIR/lib DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin -# Static builds always need to be installed, as the convenience libraries -# are not linked to the final library in this case. -installed|static: load(qt_installs) +# In static builds of Qt, convenience libraries must be installed, +# as in this case they are not linked to the final library/plugin. +installed|contains(QT_CONFIG, static): load(qt_installs) TARGET = $$qtLibraryTarget($$TARGET) From 5283a6c87beac5a43f612786fefd6e43f2c70bf6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 19 May 2014 16:53:34 -0700 Subject: [PATCH 52/61] Disable hash seeding for bootstrapped tools Any bootstrapped tool is a development tool, by definition. So the effects of seeding the hash with a random number can cause the same source input to produce different binary results, which can throw some caching tools into disarray (like the Open Build System). There should be minimal fall out from the reduced protection against DoS. Since those are only development tools, "specially crafted" input implies the developer is DoS'ing him/herself. Note: the change to qhash.cpp applies to moc and rcc, which are always bootstrapped. Change-Id: I061ab52036e40627c0703f1bf881455cbf848f43 Reviewed-by: Oswald Buddenhagen Reviewed-by: hjk --- src/corelib/tools/qhash.cpp | 8 ++++---- src/tools/qdoc/main.cpp | 2 ++ src/tools/uic/main.cpp | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index ca645636e44..7200ea7993b 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -222,12 +222,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) @@ -254,17 +255,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(&seed); seed ^= seedPtr; #if QT_POINTER_SIZE == 8 seed ^= (seedPtr >> 32); #endif +#endif // QT_BOOTSTRAPPED return seed; } diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index 398d1884640..3d2ee409b07 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -542,6 +542,7 @@ static void processQdocconfFile(const QString &fileName) Generator::debugSegfault("qdoc finished!"); } +extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; QT_END_NAMESPACE int main(int argc, char **argv) @@ -549,6 +550,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 cb2bd430ff4..12b0ee67378 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -52,9 +52,12 @@ #include 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)); From bf50bf737b6198a64756ce96ff9852c36e6f3066 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 20 May 2014 12:51:37 +0200 Subject: [PATCH 53/61] iOS: don't report negative selection ranges for backspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt sometimes report that the selection anchor is placed before the cursor when querying it for current selection. We need to accomodate for this when reporting current selection back to iOS, since it expects the range to always be positive. When pressing backspace, iOS will select the letter that should be deleted, and then call "deleteBackwards". If holding down backspace for a while, it will start selecting whole words instead. Since we reported negative ranges during this process, it caused artifacts and stray letters to be drawn. Task-number: QTBUG-39073 Change-Id: Ida9518307adce915adf49160b541a2f88637a0da Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview_textinput.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm index 3f6c6d12568..79e3897013c 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 From 4be7cd09d670064728d3ea508b06bb85e3c71708 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 May 2014 10:09:50 +0200 Subject: [PATCH 54/61] xcode generator: don't modify or copy QMAKE_INFO_PLIST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the project has a custom Info.plist assigned to QMAKE_INFO_PLIST, we should leave it as-is without scanning and replacing contents inside it. Since we always copy the file to the build folder at qmake time, any later attempts to modify the source file will not have any effect. A better solution is to just reference the custom plist directly from the Xcode, without modifying it. This change will also stop unixmake2 from assigning the default plist to QMAKE_INFO_PLIST, since we need to know in the xcode generator if the variable was set in the project or not. Task-number: QTBUG-38260 Change-Id: I3c488b2960170c544d94f9db89d3ca95ee290bdd Reviewed-by: Tor Arne Vestbø --- qmake/generators/mac/pbuilder_pbx.cpp | 12 +++++++----- qmake/generators/unix/unixmake2.cpp | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index d44c2ca73fa..e1e373787c6 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -1390,9 +1390,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && project->isActiveConfig("lib_bundle"))) { QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), Option::output_dir, input_dir); - if (plist.isEmpty()) + if (!plist.isEmpty()) { + if (exists(plist)) + t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", plist) << ";\n"; + else + warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", plist.toLatin1().constData()); + } else { plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); - if (exists(plist)) { QFile plist_in_file(plist); if (plist_in_file.open(QIODevice::ReadOnly)) { QTextStream plist_in(&plist_in_file); @@ -1422,8 +1426,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";\n"; } } - } else { - warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", plist.toLatin1().constData()); } } diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index a28760015e0..d1e363626d8 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake application of the Qt Toolkit. @@ -732,6 +732,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //copy the plist QString info_plist = escapeFilePath(fileFixify(project->first("QMAKE_INFO_PLIST").toQString())), info_plist_out = escapeFilePath(project->first("QMAKE_INFO_PLIST_OUT").toQString()); + if (info_plist.isEmpty()) + info_plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); bundledFiles << info_plist_out; QString destdir = info_plist_out.section(Option::dir_sep, 0, -2); t << info_plist_out << ": \n\t"; @@ -1269,8 +1271,6 @@ void UnixMakefileGenerator::init2() if(plist.isEmpty()) plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); if(exists(Option::fixPathToLocalOS(plist))) { - if(project->isEmpty("QMAKE_INFO_PLIST")) - project->values("QMAKE_INFO_PLIST").append(plist); project->values("QMAKE_INFO_PLIST_OUT").append(project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Info.plist"); From 849f8f58ce8eb58b80ea6ffeda0a9ea77898e437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Sun, 18 May 2014 18:45:42 +0200 Subject: [PATCH 55/61] Android: Fix crash caused by unintentionally modification of env data. The data given to putenv(3) becomes a part of the environment, as described in SUSv2, so If the data is unintentionally modified or deleted the consequence can be fatal. In previous versions of Android, the putenv(3) implementation made a copy of the data, so this bug has gone unnoticed. Task-number: QTBUG-39042 Change-Id: I20559c848fded10eeae54c4700ba0f4669fe49fc Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../platforms/android/androidjnimain.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 2998762cc31..7ca4db710b5 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 envVars = QByteArray(nativeString).split('\t'); + env->ReleaseStringUTFChars(environmentString, nativeString); + foreach (const QByteArray &envVar, envVars) { + const QList 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'); From c045cb950b3610278b4257712eca88d4e3ecf9fd Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 20 May 2014 14:43:27 +0200 Subject: [PATCH 56/61] Socks5 socket engine test: Disable UDP over Socks test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... because it fails on the new network test server. The Socks5 tests in QUdpSocket have already been disabled by commit aa3eaf9d2ec4927df51e7d773a66f68ec5e4fce9 . Task-number: QTBUG-35490 Change-Id: Ib062adb422ff6e5538f14d15a266d79c3bb53956 Reviewed-by: Richard J. Moore Reviewed-by: Tony Sarajärvi --- .../tst_qsocks5socketengine.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp index ac391a1bcc7..4a324b883a4 100644 --- a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp +++ b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp @@ -570,16 +570,10 @@ void tst_QSocks5SocketEngine::udpTest() QVERIFY(udpSocket.state() == QAbstractSocket::UnconnectedState); // Bind #1 -#if defined(UBUNTU_ONEIRIC) && defined(__x86_64__) - { - bool bindSuccessful = udpSocket.bind(QHostAddress("0.0.0.0"), 0); - if (!bindSuccessful) - QEXPECT_FAIL("", "QTBUG-23380: Fails on some Ubuntu 11.10 x64 configurations", Abort); - QVERIFY(bindSuccessful); - } -#else - QVERIFY(udpSocket.bind(QHostAddress("0.0.0.0"), 0)); -#endif + bool bindSuccessful = udpSocket.bind(QHostAddress("0.0.0.0"), 0); + if (!bindSuccessful) + QEXPECT_FAIL("", "QTBUG-23380 / QTBUG-35490: Fails on some Ubuntu 11.10 x64 configurations and on new network test server", Abort); + QVERIFY(bindSuccessful); QVERIFY(udpSocket.state() == QAbstractSocket::BoundState); QVERIFY(udpSocket.localPort() != 0); From ff31090d07cbbb6f67d259438939e810a0baf67f Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Fri, 28 Mar 2014 11:15:16 +0100 Subject: [PATCH 57/61] Cocoa: Do not process ampersands in menus twice. When syncing between QAction and native NSMenuItems, the ampersands (mnemonics) were removed twice. This lead to double ampersands being removed instead of replace with single ones. Task-number: QTBUG-37933 Change-Id: If1d9cd247b467472647b22b38460b44b03f13d82 Reviewed-by: Liang Qi --- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 2 +- tests/auto/widgets/widgets/qmenu/qmenu.pro | 5 +- .../auto/widgets/widgets/qmenu/tst_qmenu.cpp | 23 ++++++++ .../widgets/widgets/qmenu/tst_qmenu_mac.mm | 59 +++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 9e748bff726..32692edde42 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/tests/auto/widgets/widgets/qmenu/qmenu.pro b/tests/auto/widgets/widgets/qmenu/qmenu.pro index 9efd0302bf1..7c1315afa82 100644 --- a/tests/auto/widgets/widgets/qmenu/qmenu.pro +++ b/tests/auto/widgets/widgets/qmenu/qmenu.pro @@ -2,4 +2,7 @@ CONFIG += testcase TARGET = tst_qmenu QT += widgets testlib SOURCES += tst_qmenu.cpp - +macx:{ + OBJECTIVE_SOURCES += tst_qmenu_mac.mm + LIBS += -lobjc +} diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index f7dff7bc57c..b4be24f0e01 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -116,6 +116,10 @@ private slots: void QTBUG30595_rtl_submenu(); void QTBUG20403_nested_popup_on_shortcut_trigger(); void QTBUG_10735_crashWithDialog(); +#ifdef Q_OS_MAC + void QTBUG_37933_ampersands_data(); + void QTBUG_37933_ampersands(); +#endif protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -1025,5 +1029,24 @@ void tst_QMenu::QTBUG_10735_crashWithDialog() menu.activateAction(0); } +#ifdef Q_OS_MAC +void tst_QMenu::QTBUG_37933_ampersands_data() +{ + QTest::addColumn("title"); + QTest::addColumn("visibleTitle"); + QTest::newRow("simple") << QString("Test") << QString("Test"); + QTest::newRow("ampersand") << QString("&Test") << QString("Test"); + QTest::newRow("double_ampersand") << QString("&Test && more") << QString("Test & more"); +} + +void tst_qmenu_QTBUG_37933_ampersands(); + +void tst_QMenu::QTBUG_37933_ampersands() +{ + // external in .mm file + tst_qmenu_QTBUG_37933_ampersands(); +} +#endif + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm b/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm new file mode 100644 index 00000000000..dd0597d1ae7 --- /dev/null +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu_mac.mm @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import + +#include +#include + +void tst_qmenu_QTBUG_37933_ampersands() +{ + QMenu m; + QFETCH(QString, title); + QFETCH(QString, visibleTitle); + m.addAction(title); + + NSMenu* nativeMenu = m.toNSMenu(); + Q_ASSERT(nativeMenu != 0); + NSMenuItem* item = [nativeMenu itemAtIndex:0]; + Q_ASSERT(item != 0); + QCOMPARE(QString::fromUtf8([[item title] UTF8String]), visibleTitle); +} From 2983cb9531d47e5826540ca79e3066a8ed0db30c Mon Sep 17 00:00:00 2001 From: Axel Rasmussen Date: Tue, 15 Apr 2014 22:53:36 -0600 Subject: [PATCH 58/61] Fix broken QPlainTextDocumentLayout after removing chars This fixes an issue where, if characters were removed from several blocks in a single edit, the document layout would end up being corrupted since the document layout manager wouldn't re-layout the proper number of text blocks. Task-number: QTBUG-30051 Change-Id: Idf3a6f567120e6a5dbebf1f65f685d374219328a Reviewed-by: Konstantin Ritt Reviewed-by: Pierre Rossi --- src/widgets/widgets/qplaintextedit.cpp | 5 ++- .../qplaintextedit/tst_qplaintextedit.cpp | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 6ed1aeff721..23c1e99231f 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; diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index 61eb390fd31..c47f7b1ff6c 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -154,6 +154,7 @@ private slots: void findBackwardWithRegExp(); void findWithRegExpReturnsFalseIfNoMoreResults(); #endif + void layoutAfterMultiLineRemove(); private: void createSelection(); @@ -1567,5 +1568,49 @@ void tst_QPlainTextEdit::findWithRegExpReturnsFalseIfNoMoreResults() } #endif +void tst_QPlainTextEdit::layoutAfterMultiLineRemove() +{ + ed->setVisible(true); // The widget must be visible to reproduce this bug. + + QString contents; + for (int i = 0; i < 5; ++i) + contents.append("\ttest\n"); + + ed->setPlainText(contents); + + /* + * Remove the tab from the beginning of lines 2-4, in an edit block. The + * edit block is required for the bug to be reproduced. + */ + + QTextCursor curs = ed->textCursor(); + curs.movePosition(QTextCursor::Start); + curs.movePosition(QTextCursor::NextBlock); + + curs.beginEditBlock(); + for (int i = 0; i < 3; ++i) { + curs.deleteChar(); + curs.movePosition(QTextCursor::NextBlock); + } + curs.endEditBlock(); + + /* + * Now, we're going to perform the following actions: + * + * - Move to the beginning of the document. + * - Move down three times - this should put us at the front of block 3. + * - Move to the end of the line. + * + * At this point, if the document layout is behaving correctly, we should + * still be positioned on block 3. Verify that this is the case. + */ + + curs.movePosition(QTextCursor::Start); + curs.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 3); + curs.movePosition(QTextCursor::EndOfLine); + + QCOMPARE(curs.blockNumber(), 3); +} + QTEST_MAIN(tst_QPlainTextEdit) #include "tst_qplaintextedit.moc" From 8bdf319c28ae7844f8cdbf0af26c8bfc78ea50cc Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Mon, 26 Aug 2013 11:07:15 +0300 Subject: [PATCH 59/61] Fix for bindvalue(int) memory allocation problem QSqlResult::bindValue(int index, ...) is increasing the memory usage when called multiple times for same index Task-number: QTBUG-33169 Change-Id: I4f26125f6bb994bb430dc054df5761b6ddf03075 Reviewed-by: Konstantin Ritt Reviewed-by: Mark Brand --- src/sql/kernel/qsqlresult.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 6959dc39f7e..09b8f8d8895 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& 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; From a82249a47b6fe8dd6729a6cf85349d6b3346d71a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 15 May 2014 22:52:13 +0200 Subject: [PATCH 60/61] Mark the missing QDnsLookup constructor as \internal Implementation will be added for Qt 5.4.0 as it cannot be done sooner. Change-Id: I4d2626416fae99339988cd994653ce7ec753f081 Reviewed-by: Richard J. Moore Reviewed-by: Thiago Macieira --- src/network/kernel/qdnslookup.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp index 97a402901e0..e111a190cb0 100644 --- a/src/network/kernel/qdnslookup.cpp +++ b/src/network/kernel/qdnslookup.cpp @@ -281,6 +281,11 @@ QDnsLookup::QDnsLookup(Type type, const QString &name, QObject *parent) d->type = type; } +/*! + \fn QDnsLookup::QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent) + \internal +*/ + /*! Destroys the QDnsLookup object. From 5d2939344eb8fbd3c2115f52a7a8d47365bdf820 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Thu, 8 May 2014 00:50:47 -0400 Subject: [PATCH 61/61] Trigger repaint of window when toggling unified toolbar on or off. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5204e5c65ae3cf84459cc62f587ecccd855e02f8 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +++ src/widgets/widgets/qmainwindow.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 60152b56b20..651fedb26ea 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/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 90cfb1d7cb3..358569a5e45 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(function))(window()->windowHandle(), set); + update(); } #endif