From a9cbddf4739f3cfabd38367b5f872fe2c1a3814c Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 9 Apr 2014 13:26:57 +0200 Subject: [PATCH 001/180] Cocoa: Post event to "show()" a modal window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way we were doing it, we may have interferred with other events in the CFRunLoop source and call processEvents() at the wrong moment or for the wrong reason. By using a posted event, we make the notification channel unambiguous. This ammends ff3dcc49c4a1912189091e35e87cb61af2f62d47. Task-number: QTBUG-38214 Change-Id: I94f7e89cf4c9803289749394f85119cba62ef0e7 Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoaeventdispatcher.h | 3 ++- .../platforms/cocoa/qcocoaeventdispatcher.mm | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 0274ed82012..de6c6585e9d 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -134,6 +134,8 @@ class QCocoaEventDispatcher : public QAbstractEventDispatcher void interrupt(); void flush(); + bool event(QEvent *); + friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; @@ -163,7 +165,6 @@ class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate // The following variables help organizing modal sessions: QStack cocoaModalSessionStack; bool currentExecIsNSAppRun; - bool modalSessionOnNSAppRun; bool nsAppRunCalledByQt; bool cleanupModalSessionsNeeded; uint processEventsCalled; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 495a54cac4f..e0ce9f96486 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -734,13 +734,25 @@ static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal) updateChildrenWorksWhenModal(); currentModalSessionCached = 0; if (currentExecIsNSAppRun) { - modalSessionOnNSAppRun = true; - q->wakeUp(); + QEvent *e = new QEvent(QEvent::User); + qApp->postEvent(q, e, Qt::HighEventPriority); } else { q->interrupt(); } } +bool QCocoaEventDispatcher::event(QEvent *e) +{ + Q_D(QCocoaEventDispatcher); + + if (e->type() == QEvent::User) { + d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents); + return true; + } + + return QObject::event(e); +} + void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) { Q_Q(QCocoaEventDispatcher); @@ -777,7 +789,6 @@ static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal) runLoopTimerRef(0), blockSendPostedEvents(false), currentExecIsNSAppRun(false), - modalSessionOnNSAppRun(false), nsAppRunCalledByQt(false), cleanupModalSessionsNeeded(false), processEventsCalled(0), @@ -908,14 +919,6 @@ void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *even // processEvents() was called "manually," ignore this source for now d->maybeCancelWaitForMoreEvents(); return; - } else if (d->modalSessionOnNSAppRun) { - // We're about to spawn the 1st modal session on top of the main runloop. - // Instead of calling processPostedEvents(), which would need us stop - // NSApp, we just re-enter processEvents(). This is equivalent to calling - // QDialog::exec() except that it's done in a non-blocking way. - d->modalSessionOnNSAppRun = false; - d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents); - return; } d->processPostedEvents(); d->maybeCancelWaitForMoreEvents(); From 20c4b797a162e5b13abafe183773019ea874811f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 4 Mar 2014 10:21:29 +0100 Subject: [PATCH 002/180] Doc: document obsolete QApplication::setGraphicsSystem() Change-Id: I5a87564d2dbfa5e739d1ca40db480e8e0c1b7fdf Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qapplication.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ed376fe923b..d90e2f51638 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -335,6 +335,15 @@ QApplicationPrivate::~QApplicationPrivate() See setColorSpec() for full details. */ +/*! + \fn QApplication::setGraphicsSystem(const QString &) + \obsolete + + This call has no effect. + + Use the QPA framework instead. +*/ + /*! \fn QWidget *QApplication::topLevelAt(const QPoint &point) From 9216bfbcb18c61429b6cdbe7ecf2e9e16c9cdaf7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 3 Mar 2014 19:29:19 +0100 Subject: [PATCH 003/180] Doc: document QTimeZone::swap() Change-Id: I80d55df65546b671772ed93cb852e88ee040114a Reviewed-by: Sze Howe Koh Reviewed-by: Lars Knoll --- src/corelib/tools/qtimezone.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index b30caf4289a..e17ff2b249e 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -417,6 +417,13 @@ QTimeZone::~QTimeZone() { } +/*! + \fn QTimeZone::swap(QTimeZone &other) + + Swaps this time zone instance with \a other. This function is very + fast and never fails. +*/ + /*! Assignment operator, assign \a other to this. */ From 0be1c4899c15221bf265713e714f5301bfa909d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 11 Apr 2014 15:11:09 +0200 Subject: [PATCH 004/180] Cocoa: Don't consume events when closing tool tips With change acebf677 we treat Qt::ToolTip similar to Qt::Popup and close them on a mouse click on the parent window. This mouse click is not forwarded to the standard mouse event handler. Add an exception for Qt::ToolTip. Task-number: QTBUG-38267 Change-Id: Ie3121f651a6ccc2427040e61db4f63967467604d Reviewed-by: Eike Ziller Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 0b9683a3efb..93462e7ea17 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -639,8 +639,12 @@ - (void)mouseDown:(NSEvent *)theEvent if (m_platformWindow->m_activePopupWindow) { QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow); QWindowSystemInterface::flushWindowSystemEvents(); + Qt::WindowType type = m_platformWindow->m_activePopupWindow->type(); m_platformWindow->m_activePopupWindow = 0; - return; + // Consume the mouse event when closing the popup, except for tool tips + // were it's expected that the event is processed normally. + if (type != Qt::ToolTip) + return; } if ([self hasMarkedText]) { NSInputManager* inputManager = [NSInputManager currentInputManager]; From 3a4bd21db55a6c08ad0a8e09be0699085c7c4b59 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 9 Apr 2014 07:27:21 +0200 Subject: [PATCH 005/180] docs: Q_CLASSINFO is used in a couple more places besides ActiveQt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I000f538dc11477224efbf2edc91873822eb9fef2 Reviewed-by: Jerome Pasion Reviewed-by: Topi Reiniö --- src/corelib/doc/qtcore.qdocconf | 2 +- src/corelib/kernel/qobject.cpp | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 18342d01381..c8eb15a7f77 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -26,7 +26,7 @@ qhp.QtCore.subprojects.classes.sortPages = true tagfile = ../../../doc/qtcore/qtcore.tags -depends += qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake +depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtqml qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake headerdirs += .. diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 01bedb4a3a9..0a504657a3f 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4063,18 +4063,21 @@ QDebug operator<<(QDebug dbg, const QObject *o) { \macro Q_CLASSINFO(Name, Value) \relates QObject - This macro associates extra information to the class, which is - available using QObject::metaObject(). Except for the ActiveQt - extension, Qt doesn't use this information. + This macro associates extra information to the class, which is available + using QObject::metaObject(). Qt makes only limited use of this feature, in + the \l{Active Qt}, \l{Qt D-Bus} and \l{Qt QML} modules. - The extra information takes the form of a \a Name string and a \a - Value literal string. + The extra information takes the form of a \a Name string and a \a Value + literal string. Example: \snippet code/src_corelib_kernel_qobject.cpp 35 \sa QMetaObject::classInfo() + \sa QAxFactory + \sa {Using Qt D-Bus Adaptors} + \sa {Extending QML - Default Property Example} */ /*! From ef77c16cb00ef3788e58da8b35cb91eaf2eaa591 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 10 Apr 2014 13:50:01 +0300 Subject: [PATCH 006/180] Make HarfBuzz-NG the default shaper on Mac For AAT shaping support, we need either the pre-QPA shaping trick or the new HarfBuzz on Mac; prefer the latter. Disable some test cases aimed to test the HB-old behavior; enable ones that should guarantee shaping-unaware behavior. [ChangeLog][OS X] Use CoreText text shaping engine for support of complex scripts. If required, the shaping engine used in previous versions can be preferred by configuring Qt with -no-harfbuzz. Alternatively, the QT_HARFBUZZ environment variable could be set to "old". Task-number: QTBUG-18980 (relates) Task-number: QTBUG-38246 Change-Id: Iee6fe4f5bc047e77259182b8585385c5febd02b3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- configure | 4 +- src/gui/text/qtextengine.cpp | 2 + .../gui/text/qtextlayout/tst_qtextlayout.cpp | 44 ++++++------------- .../tst_qtextscriptengine.cpp | 16 +++++++ 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/configure b/configure index 89c2318d827..a1b006b4ea8 100755 --- a/configure +++ b/configure @@ -616,7 +616,7 @@ CFG_EGL=auto CFG_EGL_X=auto CFG_FONTCONFIG=auto CFG_FREETYPE=auto -CFG_HARFBUZZ=no +CFG_HARFBUZZ=auto CFG_SQL_AVAILABLE= QT_ALL_BUILD_PARTS=" libs tools examples tests " QT_DEFAULT_BUILD_PARTS="libs tools examples" @@ -5233,8 +5233,8 @@ if [ "$CFG_FREETYPE" = "auto" ]; then fi # harfbuzz support -[ "$XPLATFORM_MINGW" = "yes" ] && [ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=no [ "$XPLATFORM_MAC" = "yes" ] && [ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=yes +[ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=no # disable auto-detection on non-Mac for now if [ "$CFG_HARFBUZZ" = "auto" ]; then if compileTest unix/harfbuzz "HarfBuzz"; then CFG_HARFBUZZ=system diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 35950c709bd..967ba24fcf7 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1556,8 +1556,10 @@ void QTextEngine::itemize() const #ifdef QT_ENABLE_HARFBUZZ_NG analysis = scriptAnalysis.data(); if (useHarfbuzzNG) { + // ### pretend HB-old behavior for now for (int i = 0; i < length; ++i) { switch (analysis[i].script) { + case QChar::Script_Latin: case QChar::Script_Han: case QChar::Script_Hiragana: case QChar::Script_Katakana: diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index 56d6711dc6b..d0482d77e2b 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -309,9 +309,6 @@ void tst_QTextLayout::simpleBoundingRect() void tst_QTextLayout::threeLineBoundingRect() { -#if defined(Q_OS_MAC) - QSKIP("QTestFontEngine on the mac does not support logclusters at the moment"); -#endif /* stricter check. break text into three lines */ QString firstWord("hello"); @@ -430,9 +427,6 @@ void tst_QTextLayout::forcedBreaks() void tst_QTextLayout::breakAny() { -#if defined(Q_OS_MAC) - QSKIP("QTestFontEngine on the mac does not support logclusters at the moment"); -#endif QString text = "ABCD"; QTextLayout layout(text, testFont); @@ -473,9 +467,6 @@ void tst_QTextLayout::breakAny() void tst_QTextLayout::noWrap() { -#if defined(Q_OS_MAC) - QSKIP("QTestFontEngine on the mac does not support logclusters at the moment"); -#endif QString text = "AB CD"; QTextLayout layout(text, testFont); @@ -1048,9 +1039,6 @@ void tst_QTextLayout::charWordStopOnLineSeparator() void tst_QTextLayout::xToCursorAtEndOfLine() { -#if defined(Q_OS_MAC) - QSKIP("QTestFontEngine on the mac does not support logclusters at the moment"); -#endif QString text = "FirstLine SecondLine"; text.replace('\n', QChar::LineSeparator); @@ -1112,9 +1100,6 @@ void tst_QTextLayout::graphemeBoundaryForSurrogatePairs() void tst_QTextLayout::tabStops() { -#if defined(Q_OS_MAC) - QSKIP("QTestFontEngine on the mac does not support logclusters at the moment"); -#endif QString txt("Hello there\tworld"); QTextLayout layout(txt, testFont); layout.beginLayout(); @@ -1931,13 +1916,16 @@ void tst_QTextLayout::textWithSurrogates_qtbug15679() void tst_QTextLayout::textWidthWithStackedTextEngine() { QString text = QString::fromUtf8("คลิก ถัดไป เพื่อดำเนินการต่อ"); + QTextLayout layout(text); layout.setCacheEnabled(true); layout.beginLayout(); QTextLine line = layout.createLine(); layout.endLayout(); - QFontMetricsF fm(layout.font()); - QCOMPARE(line.naturalTextWidth(), fm.width(text)); + + QStackTextEngine layout2(text, layout.font()); + + QVERIFY(layout2.width(0, text.size()).toReal() >= line.naturalTextWidth()); } void tst_QTextLayout::textWidthWithLineSeparator() @@ -1958,27 +1946,24 @@ void tst_QTextLayout::textWidthWithLineSeparator() void tst_QTextLayout::cursorInLigatureWithMultipleLines() { -#if !defined(Q_OS_MAC) - QSKIP("This test can only be run on Mac"); -#endif QTextLayout layout("first line finish", QFont("Times", 20)); layout.setCacheEnabled(true); layout.beginLayout(); QTextLine line = layout.createLine(); - line.setLineWidth(70); - line = layout.createLine(); + line.setNumColumns(10); + QTextLine line2 = layout.createLine(); layout.endLayout(); - // The second line will be "finish", with "fi" as a ligature - QEXPECT_FAIL("", "QTBUG-26403", Abort); - QVERIFY(line.cursorToX(0) != line.cursorToX(1)); + // The second line will be "finish" + QCOMPARE(layout.text().mid(line2.textStart(), line2.textLength()), QString::fromLatin1("finish")); + + QVERIFY(line.cursorToX(1) != line.cursorToX(0)); + QCOMPARE(line2.cursorToX(line2.textStart()), line.cursorToX(0)); + QCOMPARE(line2.cursorToX(line2.textStart() + 1), line.cursorToX(1)); } void tst_QTextLayout::xToCursorForLigatures() { -#if !defined(Q_OS_MAC) - QSKIP("This test can only be run on Mac"); -#endif QTextLayout layout("fi", QFont("Times", 20)); layout.setCacheEnabled(true); layout.beginLayout(); @@ -2001,9 +1986,6 @@ void tst_QTextLayout::xToCursorForLigatures() void tst_QTextLayout::cursorInNonStopChars() { -#if defined(Q_OS_MAC) - QSKIP("This test can not be run on Mac"); -#endif QTextLayout layout(QString::fromUtf8("\xE0\xA4\xA4\xE0\xA5\x8D\xE0\xA4\xA8")); layout.setCacheEnabled(true); layout.beginLayout(); diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index c4db6696950..5dfb0255104 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1105,6 +1105,9 @@ void tst_QTextScriptEngine::mirroredChars() void tst_QTextScriptEngine::controlInSyllable_qtbug14204() { +#ifdef Q_OS_MAC + QSKIP("Result differs for HarfBuzz-NG, skip test."); +#endif QFontDatabase db; if (!db.families().contains(QStringLiteral("Aparajita"))) QSKIP("couldn't find 'Aparajita' font"); @@ -1143,6 +1146,10 @@ void tst_QTextScriptEngine::combiningMarks_qtbug15675_data() QTest::addColumn("font"); QTest::addColumn("string"); +#ifdef Q_OS_MAC + QSKIP("Result differs for HarfBuzz-NG, skip test."); +#endif + bool hasTests = false; QStringList families; @@ -1274,13 +1281,22 @@ void tst_QTextScriptEngine::thaiWithZWJ() QCOMPARE(logClusters[i], ushort(i)); for (int i = 0; i < 10; i++) QCOMPARE(logClusters[i+7], ushort(0)); +#ifndef Q_OS_MAC + // ### Result differs for HarfBuzz-NG QCOMPARE(logClusters[17], ushort(1)); +#endif // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them. // The current implementation hides them, so we test for that. // The only characters that we should be hiding are the ZWJ and ZWNJ characters in position 1 and 3. const QGlyphLayout glyphLayout = e->layoutData->glyphLayout; for (int i = 0; i < 18; i++) { +#ifdef Q_OS_MAC + // ### Result differs for HarfBuzz-NG + if (i == 17) + QCOMPARE(glyphLayout.advances[i].toInt(), 0); + else +#endif if (i == 1 || i == 3) QCOMPARE(glyphLayout.advances[i].toInt(), 0); else From 0ec07b68ad34e135451dd5291732bf73d297ba0c Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 10 Apr 2014 13:50:53 +0300 Subject: [PATCH 007/180] Improve the Unicode script itemization implementation Make it closer to the Unicode specs (UAX#24): * Common now inherits the preceding character's script, if any; * In a combining character sequence, if the base character is of Common script, the entire sequence is treated like if it were of the first non-Inherited, non-Common script in the sequence. See http://www.unicode.org/reports/tr24/tr24-21.html for more details. [ChangeLog][QtGui] Fixed regression in arabic text rendering. Task-number: QTBUG-28813 Task-number: QTBUG-29930 (related) Task-number: QTBUG-35836 Change-Id: Id85761965b08ca94c674d5f3613fe58b82b2ce9c Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Ahmed Saidi --- src/corelib/tools/qunicodetools.cpp | 38 +++++++++++++++++-- src/gui/text/qtextengine.cpp | 17 +-------- .../tst_qtextscriptengine.cpp | 22 ++++------- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp index fac795051af..fc36d07a4ac 100644 --- a/src/corelib/tools/qunicodetools.cpp +++ b/src/corelib/tools/qunicodetools.cpp @@ -667,7 +667,7 @@ Q_CORE_EXPORT void initCharAttributes(const ushort *string, int length, // ---------------------------------------------------------------------------- // -// The Unicode script property. See http://www.unicode.org/reports/tr24/ (some very old version) +// The Unicode script property. See http://www.unicode.org/reports/tr24/tr24-21.html // // ---------------------------------------------------------------------------- @@ -689,15 +689,36 @@ Q_CORE_EXPORT void initScripts(const ushort *string, int length, uchar *scripts) const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4); - if (Q_LIKELY(prop->script == script || prop->script == QChar::Script_Inherited)) + if (Q_LIKELY(prop->script == script || prop->script <= QChar::Script_Inherited)) continue; // Never break between a combining mark (gc= Mc, Mn or Me) and its base character. // Thus, a combining mark — whatever its script property value is — should inherit // the script property value of its base character. static const int test = (FLAG(QChar::Mark_NonSpacing) | FLAG(QChar::Mark_SpacingCombining) | FLAG(QChar::Mark_Enclosing)); - if (Q_UNLIKELY(FLAG(prop->category) & test)) - continue; + if (Q_UNLIKELY(FLAG(prop->category) & test)) { + // In cases where the base character itself has the Common script property value, + // and it is followed by one or more combining marks with a specific script property value, + // it may be even better for processing to let the base acquire the script property value + // from the first mark. This approach can be generalized by treating all the characters + // of a combining character sequence as having the script property value + // of the first non-Inherited, non-Common character in the sequence if there is one, + // and otherwise treating all the characters as having the Common script property value. + if (Q_LIKELY(script > QChar::Script_Common || prop->script <= QChar::Script_Common)) + continue; + + script = QChar::Script(prop->script); + } + + if (Q_LIKELY(script != QChar::Script_Common)) { + // override preceding Common-s + while (sor > 0 && scripts[sor - 1] == QChar::Script_Common) + --sor; + } else { + // see if we are inheriting preceding run + if (sor > 0) + script = scripts[sor - 1]; + } while (sor < eor) scripts[sor++] = script; @@ -705,6 +726,15 @@ Q_CORE_EXPORT void initScripts(const ushort *string, int length, uchar *scripts) script = prop->script; } eor = length; + if (Q_LIKELY(script != QChar::Script_Common)) { + // override preceding Common-s + while (sor > 0 && scripts[sor - 1] == QChar::Script_Common) + --sor; + } else { + // see if we are inheriting preceding run + if (sor > 0) + script = scripts[sor - 1]; + } while (sor < eor) scripts[sor++] = script; } diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 967ba24fcf7..34788dc4dc9 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -122,20 +122,9 @@ class Itemizer { return; const int end = start + length; for (int i = start + 1; i < end; ++i) { - // According to the unicode spec we should be treating characters in the Common script - // (punctuation, spaces, etc) as being the same script as the surrounding text for the - // purpose of splitting up text. This is important because, for example, a fullstop - // (0x2E) can be used to indicate an abbreviation and so must be treated as part of a - // word. Thus it must be passed along with the word in languages that have to calculate - // word breaks. For example the thai word "ครม." has no word breaks but the word "ครม" - // does. - // Unfortuntely because we split up the strings for both wordwrapping and for setting - // the font and because Japanese and Chinese are also aliases of the script "Common", - // doing this would break too many things. So instead we only pass the full stop - // along, and nothing else. if (m_analysis[i].bidiLevel == m_analysis[start].bidiLevel && m_analysis[i].flags == m_analysis[start].flags - && (m_analysis[i].script == m_analysis[start].script || m_string[i] == QLatin1Char('.')) + && m_analysis[i].script == m_analysis[start].script && m_analysis[i].flags < QScriptAnalysis::SpaceTabOrObject && i - start < MaxItemLength) continue; @@ -1515,26 +1504,22 @@ void QTextEngine::itemize() const while (uc < e) { switch (*uc) { case QChar::ObjectReplacementCharacter: - analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::Object; break; case QChar::LineSeparator: if (analysis->bidiLevel % 2) --analysis->bidiLevel; - analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::LineOrParagraphSeparator; if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) *const_cast(uc) = 0x21B5; // visual line separator break; case QChar::Tabulation: - analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::Tab; analysis->bidiLevel = control.baseLevel(); break; case QChar::Space: case QChar::Nbsp: if (option.flags() & QTextOption::ShowTabsAndSpaces) { - analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::Space; analysis->bidiLevel = control.baseLevel(); break; diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index 5dfb0255104..74eb58670b5 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1258,29 +1258,21 @@ void tst_QTextScriptEngine::thaiWithZWJ() QTextLayout layout(s, font); QTextEngine *e = layout.engine(); e->itemize(); - QCOMPARE(e->layoutData->items.size(), 11); + QCOMPARE(e->layoutData->items.size(), 3); for (int item = 0; item < e->layoutData->items.size(); ++item) e->shape(item); - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(7)); // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script - QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Common: The smart quotes cannot be handled by thai, so should be a separate item - QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[3].num_glyphs, ushort(1)); // Common: Ellipsis - QCOMPARE(e->layoutData->items[4].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[5].num_glyphs, ushort(1)); // Common: Smart quote - QCOMPARE(e->layoutData->items[6].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[7].num_glyphs, ushort(1)); // Common: \xA0 = non-breaking space. Could be useful to have in thai, but not currently implemented - QCOMPARE(e->layoutData->items[8].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[9].num_glyphs, ushort(1)); // Japanese: Kanji for tree - QCOMPARE(e->layoutData->items[10].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(15)); // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script + QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Han: Kanji for tree + QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type //A quick sanity check - check all the characters are individual clusters unsigned short *logClusters = e->layoutData->logClustersPtr; - for (int i = 0; i < 7; i++) + for (int i = 0; i <= 14; i++) QCOMPARE(logClusters[i], ushort(i)); - for (int i = 0; i < 10; i++) - QCOMPARE(logClusters[i+7], ushort(0)); + QCOMPARE(logClusters[15], ushort(0)); + QCOMPARE(logClusters[16], ushort(0)); #ifndef Q_OS_MAC // ### Result differs for HarfBuzz-NG QCOMPARE(logClusters[17], ushort(1)); From 6977700bed929c7f1a20192d07a06abc2fdca278 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 10 Apr 2014 15:51:56 +0200 Subject: [PATCH 008/180] Disable threaded rendering if Mesa is used Mesa and xcb show some bad interaction which leads to frequent crashed on multithreaded access. Also, the selective approach to blacklisting only specific chipsets isn't feasible, given the resources available. The client glx vendor string is used to identify mesa instead of the server GL vendor and/or renderer string as that is much more reliable. Task-number: QTBUG-38221 Change-Id: I2d8c037aa4fd9c38eb9537452a5e7e62f72a081d Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qglxintegration.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index c183deb3b82..f78d3bcc4ef 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -449,12 +449,32 @@ bool QGLXContext::m_supportsThreading = true; // binary search. static const char *qglx_threadedgl_blacklist_renderer[] = { "Chromium", // QTBUG-32225 (initialization fails) - "Mesa DRI Intel(R) Sandybridge Mobile", // QTBUG-34492 (flickering in fullscreen) 0 }; +// This disables threaded rendering on anything using mesa, e.g. +// - nvidia/nouveau +// - amd/gallium +// - intel +// - some software opengl implementations +// +// The client glx vendor string is used to identify those setups as that seems to show the least +// variance between the bad configurations. It's always "Mesa Project and SGI". There are some +// configurations which don't use mesa and which can do threaded rendering (amd and nvidia chips +// with their own proprietary drivers). +// +// This, of course, is very broad and disables threaded rendering on a lot of devices which would +// be able to use it. However, the bugs listed below don't follow any easily recognizable pattern +// and we should rather be safe. +// +// http://cgit.freedesktop.org/xcb/libxcb/commit/?id=be0fe56c3bcad5124dcc6c47a2fad01acd16f71a will +// fix some of the issues. Basically, the proprietary drivers seem to have a way of working around +// a fundamental flaw with multithreaded access to xcb, but mesa doesn't. The blacklist should be +// reevaluated once that patch is released in some version of xcb. static const char *qglx_threadedgl_blacklist_vendor[] = { - "nouveau", // QTCREATORBUG-10875 (crash in creator) + "Mesa Project and SGI", // QTCREATORBUG-10875 (crash in creator) + // QTBUG-34492 (flickering in fullscreen) + // QTBUG-38221 0 }; @@ -502,9 +522,9 @@ void QGLXContext::queryDummyContext() } } - if (const char *vendor = (const char *) glGetString(GL_VENDOR)) { + if (glxvendor) { for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) { - if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) { + if (strstr(glxvendor, qglx_threadedgl_blacklist_vendor[i]) != 0) { m_supportsThreading = false; break; } From ff9afeed512e20e0fe19b4583c89df3802064b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Thu, 10 Apr 2014 16:28:33 +0100 Subject: [PATCH 009/180] Fix build against older OpenSSL. The declaration of q_SSL_ctrl is ifdefed, so ifdef it's usage too. Change-Id: I99a53af6f4f24ed991d39ab89f18e03b8f38c617 Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket_openssl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 1b3928fdfb2..f9f7d0b35de 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1438,8 +1438,10 @@ void QSslSocketBackendPrivate::continueHandshake() if (readBufferMaxSize) plainSocket->setReadBufferSize(readBufferMaxSize); +#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL)) configuration.peerSessionShared = true; +#endif #ifdef QT_DECRYPT_SSL_TRAFFIC if (ssl->session && ssl->s3) { From f946a1d0c16aec03364ef02f9f1708830bab0d79 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Apr 2014 14:09:28 +0200 Subject: [PATCH 010/180] check qmake/make exit code instead of looking for an executable it's a bit braindead to look whether we managed to build an executable if we can simply use the exit codes of qmake and make to test for success. the windows equivalent is already doing that. this also allows us to do tests that can fail despite building an executable, or not build one in the first place. Change-Id: Ib69f9d005309d55a790dd3d89db1ee913e45b26b Reviewed-by: Wolfgang Bremer Reviewed-by: Thiago Macieira --- config.tests/unix/compile.test | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test index 22064b85e91..f99237cb50c 100755 --- a/config.tests/unix/compile.test +++ b/config.tests/unix/compile.test @@ -69,15 +69,11 @@ rm -f "$EXE" "${EXE}.exe" set -- "$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" if [ "$VERBOSE" = "yes" ]; then - OUTDIR=$OUTDIR "$@" - $MAKE + OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes else - OUTDIR=$OUTDIR "$@" >/dev/null 2>&1 - $MAKE >/dev/null 2>&1 + OUTDIR=$OUTDIR "$@" >/dev/null 2>&1 && $MAKE >/dev/null 2>&1 && SUCCESS=yes fi -( [ -f "$EXE" ] || [ -f "${EXE}.exe" ] ) && SUCCESS=yes - # done if [ "$SUCCESS" != "yes" ]; then [ "$VERBOSE" = "yes" ] && echo "$DESCRIPTION disabled." From 865c181fbd4f34d6ecfbe5d2ced4dc36c02fc5fb Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Fri, 11 Apr 2014 13:30:03 +0200 Subject: [PATCH 011/180] Make objcopy config test cross platform functional This removes the old objcopy.test script and adds a cross platform qmake project for auto detection. Change-Id: Icc7c40d72fb0ff751d214b7351e20652f7b15945 Reviewed-by: Oswald Buddenhagen --- config.tests/unix/objcopy.test | 29 ----------------- config.tests/unix/objcopy/objcopy.cpp | 45 +++++++++++++++++++++++++++ config.tests/unix/objcopy/objcopy.pro | 10 ++++++ configure | 18 ++++++----- 4 files changed, 65 insertions(+), 37 deletions(-) delete mode 100755 config.tests/unix/objcopy.test create mode 100644 config.tests/unix/objcopy/objcopy.cpp create mode 100644 config.tests/unix/objcopy/objcopy.pro diff --git a/config.tests/unix/objcopy.test b/config.tests/unix/objcopy.test deleted file mode 100755 index 9eb6e22ab08..00000000000 --- a/config.tests/unix/objcopy.test +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -TEST_PATH=`dirname "$0"` -SEP_DEBUG_SUPPORT=no -COMPILER=$1 -QMAKE_OBJCOPY=$2 -VERBOSE=$3 - -if [ -n "$QMAKE_OBJCOPY" ]; then - echo "int main() { return 0; }" > objcopy_test.cpp - if $TEST_PATH/which.test "$QMAKE_OBJCOPY" >/dev/null 2>&1 && $COMPILER $SYSROOT_FLAG -g -o objcopy_test objcopy_test.cpp >/dev/null 2>&1; then - "$QMAKE_OBJCOPY" --only-keep-debug objcopy_test objcopy_test.debug >/dev/null 2>&1 \ - && "$QMAKE_OBJCOPY" --strip-debug objcopy_test >/dev/null 2>&1 \ - && "$QMAKE_OBJCOPY" --add-gnu-debuglink=objcopy_test.debug objcopy_test >/dev/null 2>&1 \ - && SEP_DEBUG_SUPPORT=yes - fi - rm -f objcopy_test objcopy_test.debug objcopy_test.cpp -else - [ "$VERBOSE" = "yes" ] && echo "Separate debug info check skipped, QMAKE_OBJCOPY is unset."; -fi - -# done -if [ "$SEP_DEBUG_SUPPORT" != "yes" ]; then - [ "$VERBOSE" = "yes" ] && echo "Separate debug info support disabled." - exit 0 -else - [ "$VERBOSE" = "yes" ] && echo "Separate debug info support enabled." - exit 1 -fi diff --git a/config.tests/unix/objcopy/objcopy.cpp b/config.tests/unix/objcopy/objcopy.cpp new file mode 100644 index 00000000000..66b261bd6db --- /dev/null +++ b/config.tests/unix/objcopy/objcopy.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the config.tests 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$ +** +****************************************************************************/ + +int main() +{ + return 0; +} diff --git a/config.tests/unix/objcopy/objcopy.pro b/config.tests/unix/objcopy/objcopy.pro new file mode 100644 index 00000000000..d2f9c738f6b --- /dev/null +++ b/config.tests/unix/objcopy/objcopy.pro @@ -0,0 +1,10 @@ +SOURCES = objcopy.cpp +CONFIG -= qt + +all.depends += only_keep_debug strip_debug add_gnu_debuglink + +only_keep_debug.commands = $$QMAKE_OBJCOPY --only-keep-debug objcopy objcopy.debug +strip_debug.commands = $$QMAKE_OBJCOPY --strip-debug objcopy +add_gnu_debuglink.commands = $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopy.debug objcopy + +QMAKE_EXTRA_TARGETS += all only_keep_debug strip_debug add_gnu_debuglink diff --git a/configure b/configure index 89c2318d827..67a5a4b537a 100755 --- a/configure +++ b/configure @@ -3178,7 +3178,7 @@ if [ "$CFG_PRECOMPILE" = "auto" ]; then fi fi -# auto-detect support for separate debug info in objcopy +# sanity-check for separate debug info if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then if [ "$CFG_SHARED" = "no" ]; then echo "ERROR: -separate-debug-info is incompatible with -static" @@ -3188,13 +3188,6 @@ if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then echo "ERROR: -separate-debug-info needs -debug, -debug-and-release, or -force-debug-info" exit 1 fi - TEST_OBJCOPY=`getXQMakeConf QMAKE_OBJCOPY` - COMPILER_WITH_FLAGS="$TEST_COMPILER $TEST_COMPILER_CXXFLAGS" - if "$unixtests/objcopy.test" "$COMPILER_WITH_FLAGS" "$TEST_OBJCOPY" "$OPT_VERBOSE"; then - echo "ERROR: -separate-debug-info was requested but this binutils does not support it." - echo "Re-run configure with -v for more information" - exit 1 - fi fi # auto-detect -fvisibility support @@ -3936,6 +3929,15 @@ fi # functionality tests #------------------------------------------------------------------------------- +# Detect objcopy support +if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then + if ! compileTest unix/objcopy "objcopy"; then + echo "ERROR: -separate-debug-info was requested but this binutils does not support it." + echo "Re-run configure with -v for more information" + exit 1 + fi +fi + # Detect C++11 support if [ "$CFG_CXX11" != "no" ]; then # Configure detects compiler features based on cross compiler, so we need From ba5e0d48b427da092b104d4fc8fec02ed078ec4d Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Wed, 9 Apr 2014 10:17:20 +0200 Subject: [PATCH 012/180] Adding support for -separate-debug-info on win32 There is no valid reason why separate debug info support is missing from the win32 configure app. It can be used with proper cross compilation tool chains. Change-Id: I5cf5fba24abc3b515f893a3f5b799a0644fd3218 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index d149511218e..cff3f1bf0c4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -164,6 +164,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "GUI" ] = "yes"; dictionary[ "RTTI" ] = "yes"; dictionary[ "STRIP" ] = "yes"; + dictionary[ "SEPARATE_DEBUG_INFO" ] = "no"; dictionary[ "SSE2" ] = "auto"; dictionary[ "SSE3" ] = "auto"; dictionary[ "SSSE3" ] = "auto"; @@ -445,6 +446,10 @@ void Configure::parseCmdLine() dictionary[ "BUILDALL" ] = "yes"; else if (configCmdLine.at(i) == "-force-debug-info") dictionary[ "FORCEDEBUGINFO" ] = "yes"; + else if (configCmdLine.at(i) == "-no-separate-debug-info") + dictionary[ "SEPARATE_DEBUG_INFO" ] = "no"; + else if (configCmdLine.at(i) == "-separate-debug-info") + dictionary[ "SEPARATE_DEBUG_INFO" ] = "yes"; else if (configCmdLine.at(i) == "-compile-examples") { dictionary[ "COMPILE_EXAMPLES" ] = "yes"; @@ -1765,7 +1770,8 @@ bool Configure::displayHelp() desc("BUILD", "debug", "-debug", "Compile and link Qt with debugging turned on."); desc("BUILDALL", "yes", "-debug-and-release", "Compile and link two Qt libraries, with and without debugging turned on.\n"); - desc("FORCEDEBUGINFO", "yes","-force-debug-info", "Create symbol files for release builds.\n"); + desc("FORCEDEBUGINFO", "yes","-force-debug-info", "Create symbol files for release builds."); + desc("SEPARATE_DEBUG_INFO", "yes","-separate-debug-info", "Strip debug information into a separate file.\n"); desc("BUILDDEV", "yes", "-developer-build", "Compile and link Qt with Qt developer options (including auto-tests exporting)\n"); @@ -2165,6 +2171,9 @@ bool Configure::checkAvailability(const QString &part) if (part == "STYLE_WINDOWSXP") available = (platform() == WINDOWS) && findFile("uxtheme.h"); + else if (part == "OBJCOPY") + available = tryCompileProject("unix/objcopy"); + else if (part == "ZLIB") available = findFile("zlib.h"); @@ -2489,6 +2498,21 @@ bool Configure::verifyConfiguration() dictionary["C++11"] = "auto"; } + if (dictionary["SEPARATE_DEBUG_INFO"] == "yes") { + if (dictionary[ "SHARED" ] == "no") { + cout << "ERROR: -separate-debug-info is incompatible with -static" << endl << endl; + dictionary[ "DONE" ] = "error"; + } else if (dictionary[ "BUILD" ] != "debug" + && dictionary[ "BUILDALL" ] == "no" + && dictionary[ "FORCEDEBUGINFO" ] == "no") { + cout << "ERROR: -separate-debug-info needs -debug, -debug-and-release, or -force-debug-info" << endl << endl; + dictionary[ "DONE" ] = "error"; + } else if (dictionary["SEPARATE_DEBUG_INFO"] == "yes" && !checkAvailability("OBJCOPY")) { + cout << "ERROR: -separate-debug-info was requested but this binutils does not support it." << endl; + dictionary[ "DONE" ] = "error"; + } + } + if (dictionary["SQL_SQLITE_LIB"] == "no" && dictionary["SQL_SQLITE"] != "no") { cout << "WARNING: Configure could not detect the presence of a system SQLite3 lib." << endl << "Configure will therefore continue with the SQLite3 lib bundled with Qt." << endl; @@ -2752,6 +2776,8 @@ void Configure::generateOutputVars() if (dictionary[ "BUILDALL" ] == "yes") { qtConfig += "build_all"; } + if (dictionary[ "SEPARATE_DEBUG_INFO" ] == "yes") + qtConfig += "separate_debug_info"; if (dictionary[ "FORCEDEBUGINFO" ] == "yes") qmakeConfig += "force_debug_info"; qmakeConfig += dictionary[ "BUILD" ]; From 53a5dd28c728fba49b01adbcaba610d12cfcde4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 8 Apr 2014 10:18:18 +0200 Subject: [PATCH 013/180] Handle parent is None from query_tree_reply in QxcbWindow::frameMargins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit None is a valid return value for parent in xcb_query_tree_reply_t. If that is used as the new parent the next call to xcb_query_tree_unchecked will fail with a BadWindow error. Change-Id: Iafe29b223ca65c86ecfd40fe51e67d4bd7abc1ce Reviewed-by: Jørgen Lind Reviewed-by: Uli Schlachter --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 5a2002f1d4f..193e75c1d66 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -554,7 +554,7 @@ QMargins QXcbWindow::frameMargins() const xcb_query_tree_reply_t *reply = xcb_query_tree_reply(xcb_connection(), cookie, NULL); if (reply) { - if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1) { + if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1 || reply->parent == XCB_WINDOW_NONE) { foundRoot = true; } else { window = parent; From 7549ef883addd9c17990c895c10e8daeff076944 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Fri, 4 Apr 2014 22:34:25 +0800 Subject: [PATCH 014/180] Doc: Remove QX11EmbedContainer/QX11EmbedWidget snippets - These classes no longer exist in Qt 5 - These snippets are not actually used in current docs Change-Id: I155e70b09933417c8ce1b14d033fb1c17a1c32db Reviewed-by: Jerome Pasion --- doc/src/snippets/qx11embedcontainer/main.cpp | 67 -------------------- doc/src/snippets/qx11embedwidget/main.cpp | 61 ------------------ 2 files changed, 128 deletions(-) delete mode 100644 doc/src/snippets/qx11embedcontainer/main.cpp delete mode 100644 doc/src/snippets/qx11embedwidget/main.cpp diff --git a/doc/src/snippets/qx11embedcontainer/main.cpp b/doc/src/snippets/qx11embedcontainer/main.cpp deleted file mode 100644 index 97d6f11385b..00000000000 --- a/doc/src/snippets/qx11embedcontainer/main.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -//! [0] -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - if (app.arguments().count() != 2) { - qFatal("Error - expected executable path as argument"); - return 1; - } - - QX11EmbedContainer container; - container.show(); - - QProcess process(&container); - QString executable(app.arguments()[1]); - QStringList arguments; - arguments << QString::number(container.winId()); - process.start(executable, arguments); - - int status = app.exec(); - process.close(); - return status; -} -//! [0] diff --git a/doc/src/snippets/qx11embedwidget/main.cpp b/doc/src/snippets/qx11embedwidget/main.cpp deleted file mode 100644 index 77b45c1da36..00000000000 --- a/doc/src/snippets/qx11embedwidget/main.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "embedwidget.h" - -//! [0] -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - if (app.arguments().count() != 2) { - qFatal("Error - expected window id as argument"); - return 1; - } - - QString windowId(app.arguments()[1]); - EmbedWidget window; - window.embedInto(windowId.toULong()); - window.show(); - - return app.exec(); -} -//! [0] From ff34070709dd16a66d3b3e9b1f919e77d33698e5 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 12:07:02 +0200 Subject: [PATCH 015/180] QNX: Fix QTreeView autotest The style is dpi dependent. I.e. on high dpi displays the pixel size of sections and rows of a QTreeView will be larger. Change-Id: I7477bfdd641d4db67973cafef5147f026f72c111 Reviewed-by: Bernd Weimer Reviewed-by: Sergio Ahumada --- tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 05799149408..77690cc27aa 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -2488,7 +2488,7 @@ void tst_QTreeView::extendedSelection_data() QTest::addColumn("selectedCount"); QTest::newRow("select") << QPoint(10, 10) << 2; - QTest::newRow("unselect") << QPoint(10, 150) << 0; + QTest::newRow("unselect") << QPoint(10, 300) << 0; } void tst_QTreeView::extendedSelection() @@ -2499,7 +2499,7 @@ void tst_QTreeView::extendedSelection() QStandardItemModel model(5, 2); QWidget topLevel; QTreeView view(&topLevel); - view.resize(qMax(mousePressPos.x() * 2, 200), qMax(mousePressPos.y() * 2, 200)); + view.resize(qMax(mousePressPos.x() * 2, 300), qMax(mousePressPos.y() * 2, 350)); view.setModel(&model); view.setSelectionMode(QAbstractItemView::ExtendedSelection); topLevel.show(); From bfb25c03523757d66974189e54dda97962206ef9 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 15:09:42 +0200 Subject: [PATCH 016/180] Restrict QFontComboBox's popup width to screen width Change-Id: I5a92308beb2f245d9f031918bb8154757316ef56 Reviewed-by: Marc Mutz --- src/widgets/widgets/qfontcombobox.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index 2bbf3730dbc..40ca73904cc 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -546,8 +547,10 @@ bool QFontComboBox::event(QEvent *e) { if (e->type() == QEvent::Resize) { QListView *lview = qobject_cast(view()); - if (lview) - lview->window()->setFixedWidth(width() * 5 / 3); + if (lview) { + setFixedWidth(qMin(width() * 5 / 3, + QApplication::desktop()->availableGeometry(lview).width())); + } } return QComboBox::event(e); } From 9cae7b5ee2ef5ee764acb8c44f6f28a73aea8b0d Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 11:48:47 +0200 Subject: [PATCH 017/180] QNX: Fix QWizard autotest In "task177022_setFixedSize" show was replaced with showNormal because on QNX and some other platforms show translates to a showFullScreen. For BlackBerry the test is skipped because the first top level window is always forced into fullscreen mode. Change-Id: I9df37c6bc47b47cbad4a1623b3eafa723abc6714 Reviewed-by: Bernd Weimer Reviewed-by: Sergio Ahumada --- tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index 4c07b48c007..a932a2e8592 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -2605,6 +2605,9 @@ void tst_QWizard::task161658_alignments() void tst_QWizard::task177022_setFixedSize() { +#ifdef Q_OS_BLACKBERRY + QSKIP("Window is forced fullscreen"); +#endif int width = 300; int height = 200; QWizard wiz; @@ -2622,7 +2625,7 @@ void tst_QWizard::task177022_setFixedSize() QCOMPARE(wiz.maximumWidth(), width); QCOMPARE(wiz.maximumHeight(), height); - wiz.show(); + wiz.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&wiz)); QCOMPARE(wiz.size(), QSize(width, height)); From bf2fa58c02c3e215069bea15d10fd7547034fc3d Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 11:39:05 +0200 Subject: [PATCH 018/180] QNX: Fix QGuiApplication autotests On QNX a window can only be activated if it has either a egl surface or a raster backingstore. Change-Id: If075093e39f1553eb8b25e35f7d372b1b15aa8af Reviewed-by: Sergio Ahumada --- .../qguiapplication/tst_qguiapplication.cpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 6ef9957fa16..e551d999590 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -48,6 +48,10 @@ #include #include +#if defined(Q_OS_QNX) +#include +#endif + #include #include "tst_qcoreapplication.h" @@ -124,6 +128,9 @@ void tst_QGuiApplication::focusObject() const QRect screenGeometry = QGuiApplication::primaryScreen()->availableVirtualGeometry(); DummyWindow window1; +#if defined(Q_OS_QNX) + window1.setSurfaceType(QSurface::OpenGLSurface); +#endif window1.resize(windowSize, windowSize); window1.setTitle(QStringLiteral("focusObject:window1")); window1.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing)); @@ -134,6 +141,15 @@ void tst_QGuiApplication::focusObject() window1.show(); +#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store + // and then post the window in order for screen to show the window + QOpenGLContext context; + context.create(); + context.makeCurrent(&window1); + QTest::qWaitForWindowExposed(&window1); // Buffer swap only succeeds with exposed window + context.swapBuffers(&window1); +#endif + QSignalSpy spy(&app, SIGNAL(focusObjectChanged(QObject*))); @@ -279,15 +295,35 @@ void tst_QGuiApplication::changeFocusWindow() // focus is changed between FocusAboutToChange and FocusChanged FocusChangeWindow window1; +#if defined(Q_OS_QNX) + window1.setSurfaceType(QSurface::OpenGLSurface); +#endif window1.resize(windowSize, windowSize); window1.setFramePosition(QPoint(screenGeometry.left() + spacing, screenGeometry.top() + spacing)); window1.setTitle(QStringLiteral("changeFocusWindow:window1")); window1.show(); +#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store + // and then post the window in order for screen to show the window + QOpenGLContext context; + context.create(); + context.makeCurrent(&window1); + QTest::qWaitForWindowExposed(&window1); // Buffer swap only succeeds with exposed window + context.swapBuffers(&window1); +#endif FocusChangeWindow window2; +#if defined(Q_OS_QNX) + window2.setSurfaceType(QSurface::OpenGLSurface); +#endif window2.resize(windowSize, windowSize); window2.setFramePosition(QPoint(screenGeometry.left() + 2 * spacing + windowSize, screenGeometry.top() + spacing)); window2.setTitle(QStringLiteral("changeFocusWindow:window2")); window2.show(); +#if defined(Q_OS_QNX) // We either need to create a eglSurface or a create a backing store + // and then post the window in order for screen to show the window + context.makeCurrent(&window2); + QTest::qWaitForWindowExposed(&window2); // Buffer swap only succeeds with exposed window + context.swapBuffers(&window2); +#endif QVERIFY(QTest::qWaitForWindowExposed(&window1)); QVERIFY(QTest::qWaitForWindowExposed(&window2)); window1.requestActivate(); From 571c16555bba86043b744c9aba963ed3269c5658 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 9 Apr 2014 17:36:02 +0200 Subject: [PATCH 019/180] QNX: Fix QMdiArea autotests Change-Id: I1c4b0bbe4984182c217ee97957e2f21f43caf116 Reviewed-by: Sergio Ahumada Reviewed-by: Bernd Weimer --- tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index ba9652a1700..27a2a456e70 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -1007,7 +1007,7 @@ void tst_QMdiArea::activeSubWindow() qApp->setActiveWindow(&mainWindow); QCOMPARE(mdiArea->activeSubWindow(), subWindow); -#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) +#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) && !defined(Q_OS_QNX) qApp->setActiveWindow(0); QVERIFY(!mdiArea->activeSubWindow()); #endif @@ -1088,7 +1088,7 @@ void tst_QMdiArea::currentSubWindow() QVERIFY(mdiArea.activeSubWindow()); QVERIFY(mdiArea.currentSubWindow()); -#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) +#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) && !defined(Q_OS_QNX) qApp->setActiveWindow(0); QVERIFY(!mdiArea.activeSubWindow()); QVERIFY(mdiArea.currentSubWindow()); @@ -1701,7 +1701,7 @@ void tst_QMdiArea::tileSubWindows() qApp->processEvents(); QTRY_COMPARE(workspace.size(), QSize(350, 150)); - const QSize minSize(300, 100); + const QSize minSize(600, 130); foreach (QMdiSubWindow *subWindow, workspace.subWindowList()) subWindow->setMinimumSize(minSize); @@ -1908,6 +1908,9 @@ void tst_QMdiArea::dontMaximizeSubWindowOnActivation() for (int i = 0; i < 5; ++i) { QMdiSubWindow *window = mdiArea.addSubWindow(new QWidget); window->show(); +#if defined Q_OS_QNX + QEXPECT_FAIL("", "QTBUG-38231", Abort); +#endif QVERIFY(window->isMaximized()); qApp->processEvents(); } From 38aba919ac7eac6633dcb63ddc8f11807545ffca Mon Sep 17 00:00:00 2001 From: jkobus Date: Mon, 14 Apr 2014 13:17:12 +0200 Subject: [PATCH 020/180] Fix documentation of QRegExp Change-Id: I6c9083941eb791eb34ce982986e3e04ac5a765ad Reviewed-by: Leena Miettinen --- src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp | 2 +- src/corelib/tools/qregexp.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp index 779fbaa723d..530819a173c 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregexp.cpp @@ -77,7 +77,7 @@ QRegExp mark("\\b" // word boundary QRegExp rx("^\\d\\d?$"); // match integers 0 to 99 rx.indexIn("123"); // returns -1 (no match) rx.indexIn("-6"); // returns -1 (no match) -rx.indexIn("6"); // returns 0 (matched as position 0) +rx.indexIn("6"); // returns 0 (matched at position 0) //! [4] diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index cadf2da0192..fbcd271f1d3 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -388,7 +388,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from, Note: Quantifiers are normally "greedy". They always match as much text as they can. For example, \b{0+} matches the first zero it finds and all the consecutive zeros after the first zero. Applied - to '20005', it matches'2\underline{000}5'. Quantifiers can be made + to '20005', it matches '2\underline{000}5'. Quantifiers can be made non-greedy, see setMinimal(). \target capturing parentheses @@ -678,7 +678,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from, QRegExp can match case insensitively using setCaseSensitivity(), and can use non-greedy matching, see setMinimal(). By default QRegExp uses full regexps but this can be changed with - setWildcard(). Searching can be forward with indexIn() or backward + setPatternSyntax(). Searching can be done forward with indexIn() or backward with lastIndexIn(). Captured text can be accessed using capturedTexts() which returns a string list of all captured strings, or using cap() which returns the captured string for the From aee59f06e0017e225363d4207d3d96c2b30698e1 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 8 Apr 2014 14:41:06 +0200 Subject: [PATCH 021/180] QNX: Fix QDir::entryInfoList() If D_FLAG_FILTER is set, duplicate name entries are filtered out, so this flag has to be set along with D_FLAG_STAT in the call to dircntl. Also releaved dependencies between defines__EXT_QNX__READDIR_R, __EXT_QNX__READDIR64_R and _POSIX_THREAD_SAFE_FUNCTIONS Task-number: QTBUG-38189 Change-Id: I4e620cb9967e3d1baf6f2109a7c83703702f805b Reviewed-by: Thomas McGuire --- mkspecs/qnx-armle-v7-qcc/qplatformdefs.h | 2 +- mkspecs/qnx-x86-qcc/qplatformdefs.h | 2 +- src/corelib/io/qfilesystemengine.cpp | 4 ++-- src/corelib/io/qfilesystemiterator_p.h | 4 ++-- src/corelib/io/qfilesystemiterator_unix.cpp | 15 ++++++++------- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h index 2f95f0d392c..27e4a3aa412 100644 --- a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h +++ b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h @@ -83,7 +83,7 @@ #include #define QT_USE_XOPEN_LFS_EXTENSIONS -#if !defined(__EXT_QNX__READDIR64_R) +#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R) #define QT_NO_READDIR64 #endif #include "../common/posix/qplatformdefs.h" diff --git a/mkspecs/qnx-x86-qcc/qplatformdefs.h b/mkspecs/qnx-x86-qcc/qplatformdefs.h index b47aecde0d0..246f82e27fd 100644 --- a/mkspecs/qnx-x86-qcc/qplatformdefs.h +++ b/mkspecs/qnx-x86-qcc/qplatformdefs.h @@ -83,7 +83,7 @@ #include #define QT_USE_XOPEN_LFS_EXTENSIONS -#if !defined(__EXT_QNX__READDIR64_R) +#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R) #define QT_NO_READDIR64 #endif #include "../common/posix/qplatformdefs.h" diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 53cf6158ad8..8b6ceebc62a 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -224,7 +224,7 @@ bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) return false; } -#if defined(Q_OS_QNX) +#if defined(QT_EXT_QNX_READDIR_R) static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32) { statBuf64->st_mode = statBuf32.st_mode; @@ -289,7 +289,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) { -#if defined(Q_OS_QNX) +#if defined(QT_EXT_QNX_READDIR_R) knownFlagsMask = 0; entryFlags = 0; for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry); diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 41640203598..18a9c2dbda7 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -95,10 +95,10 @@ class QFileSystemIterator #else QT_DIR *dir; QT_DIRENT *dirEntry; -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R) // for readdir_r QScopedPointer mt_file; -#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R) +#if defined(QT_EXT_QNX_READDIR_R) // for _readdir_r size_t direntSize; #endif diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 0b59aa169a9..0f9bbd8a296 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -70,7 +70,7 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi if (!nativePath.endsWith('/')) nativePath.append('/'); -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R) // ### Race condition; we should use fpathconf and dirfd(). size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX); if (maxPathName == size_t(-1)) @@ -81,13 +81,14 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi Q_CHECK_PTR(p); mt_file.reset(p); -#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R) +#if defined(QT_EXT_QNX_READDIR_R) direntSize = maxPathName; - // Include extra stat information in the readdir() call (d_stat member of dirent_extra_stat). - // This is used in QFileSystemMetaData::fillFromDirEnt() to avoid extra stat() calls when iterating - // over directories - if (dircntl(dir, D_SETFLAG, D_FLAG_STAT) == -1) + // Include extra stat information in the readdir() call (d_stat member of + // dirent_extra_stat). This is used in QFileSystemMetaData::fillFromDirEnt() to + // avoid extra stat() calls when iterating over directories + int flags = dircntl(dir, D_GETFLAG) | D_FLAG_STAT | D_FLAG_FILTER; + if (dircntl(dir, D_SETFLAG, flags) == -1) lastError = errno; #endif #endif @@ -105,7 +106,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa if (!dir) return false; -#if defined(Q_OS_QNX) && defined(QT_EXT_QNX_READDIR_R) +#if defined(QT_EXT_QNX_READDIR_R) lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize); if (lastError) return false; From 94742faeceb44fd2d8131b12480e59b699b0ac6f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 12 Apr 2014 10:01:50 -0700 Subject: [PATCH 022/180] Remove the #ifdef check just before #undef No warning is printed anyway. This code is only for one compiler (GCC on QNX, a.k.a. QCC). Change-Id: I28d085c72ab5a957146efab0a36c72f213d9d2c3 Reviewed-by: Marc Mutz --- src/corelib/global/qcompilerdetection.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 950647004a7..1f82425459d 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -848,12 +848,8 @@ // QNX: libcpp (Dinkumware-based) doesn't have the // header, so the feature is useless, even if the compiler supports // it. Disable. -# ifdef Q_COMPILER_INITIALIZER_LISTS -# undef Q_COMPILER_INITIALIZER_LISTS -# endif -# ifdef Q_COMPILER_RVALUE_REFS -# undef Q_COMPILER_RVALUE_REFS -# endif +# undef Q_COMPILER_INITIALIZER_LISTS +# undef Q_COMPILER_RVALUE_REFS # endif # endif #endif // Q_OS_QNX From 070e1637ebe3ee899d44b92c948e2e148c237e03 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 11 Apr 2014 13:26:48 -0700 Subject: [PATCH 023/180] Disable all C++11 rvalue refs with Dinkumware C++ library too Our code assumes that Q_COMPILER_REF_QUALIFIERS implies Q_COMPILER_RVALUE_REFS. Technically, it should check both macros, but the only point of ref qualifiers is to have both lvalue- and rvalue- reference member functions. We might then use std::move without a check to see if the standard library does provide it. Change-Id: Ia3eedd298c2218f100aee2e41bdea6e2c5c07a15 Reviewed-by: Marc Mutz Reviewed-by: Fawzi Mohamed Reviewed-by: Rafael Roquetto --- src/corelib/global/qcompilerdetection.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 1f82425459d..e93201f1022 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -849,7 +849,10 @@ // header, so the feature is useless, even if the compiler supports // it. Disable. # undef Q_COMPILER_INITIALIZER_LISTS +// That libcpp doesn't have std::move either, so disable everything +// related to rvalue refs. # undef Q_COMPILER_RVALUE_REFS +# undef Q_COMPILER_REF_QUALIFIERS # endif # endif #endif // Q_OS_QNX From 56da768c595e9efa47166f690eb119b4e6a9c908 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 15:22:50 +0200 Subject: [PATCH 024/180] QNX: Fix QComboBox autotest Change-Id: I9fe4da6e02921c0474bf7ef31a2ba14e751584bf Reviewed-by: Sergio Ahumada --- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 509ccc37b65..abc0129f8bd 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -2064,7 +2064,7 @@ void tst_QComboBox::itemListPosition() topLevel.move(screen.width() - topLevel.sizeHint().width() - 10, 0); //puts the combo to the top-right corner - topLevel.show(); + topLevel.showNormal(); //wait because the window manager can move the window if there is a right panel QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); @@ -2232,7 +2232,7 @@ void tst_QComboBox::task190205_setModelAdjustToContents() box.move(100, 100); box.setSizeAdjustPolicy(QComboBox::AdjustToContents); box.addItems(initialContent); - box.show(); + box.showNormal(); //wait needed in order to get the combo initial size QTRY_VERIFY(box.isVisible()); @@ -2244,7 +2244,7 @@ void tst_QComboBox::task190205_setModelAdjustToContents() correctBox.move(400, 100); correctBox.addItems(finalContent); - correctBox.show(); + correctBox.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&box)); QVERIFY(QTest::qWaitForWindowExposed(&correctBox)); @@ -2266,7 +2266,7 @@ void tst_QComboBox::task248169_popupWithMinimalSize() comboBox.setGeometry(desktopSize.width() - (desktopSize.width() / 4), (desktopSize.width() / 4), (desktopSize.width() / 2), (desktopSize.width() / 4)); - comboBox.show(); + comboBox.showNormal(); QVERIFY(QTest::qWaitForWindowExposed(&comboBox)); QTRY_VERIFY(comboBox.isVisible()); comboBox.showPopup(); @@ -2274,7 +2274,7 @@ void tst_QComboBox::task248169_popupWithMinimalSize() QTest::qWaitForWindowExposed(comboBox.view()); QTRY_VERIFY(comboBox.view()->isVisible()); -#ifdef QT_BUILD_INTERNAL +#if defined QT_BUILD_INTERNAL && !defined Q_OS_BLACKBERRY QFrame *container = comboBox.findChild(); QVERIFY(container); QTRY_VERIFY(desktop.screenGeometry(container).contains(container->geometry())); @@ -2609,7 +2609,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse() for (int i = 0; i < 80; i++) combo.addItem( QString::number(i)); - combo.show(); + combo.showNormal(); centerCursor(&combo); // QTBUG-33973, cursor needs to be within view from start on Mac. QApplication::setActiveWindow(&combo); QVERIFY(QTest::qWaitForWindowActive(&combo)); @@ -2629,7 +2629,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse() QCOMPARE(combo.currentText(), QLatin1String("0")); // When calling cursor function, Windows CE responds with: This function is not supported on this system. -#ifndef Q_OS_WINCE +#if !defined Q_OS_WINCE && !defined Q_OS_QNX // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA: centerCursor(combo.view()); QTest::qWait(200); From 3cc84f210a20226744a1cf6518539a0dbd450eb9 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 19:21:17 +0200 Subject: [PATCH 025/180] BlackBerry: Fix QDoubleSpinBox autotests Change-Id: I380e983294c4467ad79f0835c05387a0ee155eb5 Reviewed-by: Sergio Ahumada --- .../auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp index 6784ee477b5..6b763f5a4c7 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -825,6 +825,8 @@ void tst_QDoubleSpinBox::editingFinished() QCOMPARE(editingFinishedSpy1.count(), 4); QCOMPARE(editingFinishedSpy2.count(), 4); + testFocusWidget->show(); // On BlackBerry this is our root window we need to show it again + // otherwise subsequent tests will fail } void tst_QDoubleSpinBox::removeAll() From 4a169ac0156ede6b0757b8e8c6d92ede19ba19d5 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 18:04:49 +0200 Subject: [PATCH 026/180] QNX: Fix QDockWidget autotest Show translates to showFullScreen on some platforms. This patch replaces show with showNormal in the "task248604_infiniteResize" test. On BlackBerry the test is skipped because all top level windows are forced fullscreen by the platform. Change-Id: Ia974c3fcbd0c71c107f4cc3f8405b8ef79ffb5b7 Reviewed-by: Sergio Ahumada --- tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index 6551a882324..095fa3347d8 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -801,13 +801,16 @@ void tst_QDockWidget::task237438_setFloatingCrash() void tst_QDockWidget::task248604_infiniteResize() { +#if defined Q_OS_BLACKBERRY + QSKIP("Top level window is stretched to fullscreen"); +#endif QDockWidget d; QTabWidget *t = new QTabWidget; t->addTab(new QWidget, "Foo"); d.setWidget(t); d.setContentsMargins(2, 2, 2, 2); d.setMinimumSize(320, 240); - d.show(); + d.showNormal(); QTest::qWait(400); QCOMPARE(d.size(), QSize(320, 240)); } From c3bd4d08b0e4508d4699a757761f6edb81bfd8c4 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 19:36:52 +0200 Subject: [PATCH 027/180] QNX: Skip QGLBuffer autotest see QTBUG-38275 Change-Id: If9a329b07f83ace77b05336d16534032310e0f82 Reviewed-by: Sergio Ahumada --- tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp index 915f503b3f4..a8a9deb25f4 100644 --- a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp +++ b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp @@ -207,6 +207,10 @@ void tst_QGLBuffer::bufferSharing() QSKIP("Unreproducible timeout on Windows (MSVC/MinGW) CI bots"); #endif +#if defined(Q_OS_QNX) + QSKIP("Crashes on QNX when destroying the second QGLWidget (see QTBUG-38275)"); +#endif + QGLWidget *w1 = new QGLWidget(); w1->makeCurrent(); From 387f75c39bfad4439a6bd013089c2cd216cda5ea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Apr 2014 10:41:55 -0700 Subject: [PATCH 028/180] Disable C++11 initializer lists and rvalue refs for old libstdc++ This can happen if you're using a recent compiler other than GCC (that is, Clang or Intel) and using an older version of the GCC headers. The check is not strictly correct: we're disabling for libstdc++ that came with GCC 4.2 and enabling for everything afterwards, even though both of those features were not present in GCC 4.3. However, the __GLIBC_LIBSTD__ macro only exists on Apple's patched version of libstdc++ and they're not going to update it anyway. libstdc++ does not provide a version macro that we can use. Task-number: QTBUG-38193 Change-Id: I34d38a2f2e5b4ac51bce35c30ec0fcf19de9cdf4 Reviewed-by: Marc Mutz Reviewed-by: Fawzi Mohamed --- src/corelib/global/qcompilerdetection.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index e93201f1022..dd880d8ede7 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -842,8 +842,8 @@ #endif /* Q_CC_MSVC */ #ifdef __cplusplus +# include # if defined(Q_OS_QNX) -# include # if defined(_YVALS) || defined(_LIBCPP_VER) // QNX: libcpp (Dinkumware-based) doesn't have the // header, so the feature is useless, even if the compiler supports @@ -854,8 +854,16 @@ # undef Q_COMPILER_RVALUE_REFS # undef Q_COMPILER_REF_QUALIFIERS # endif +# endif // Q_OS_QNX +# if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) && defined(__GNUC_LIBSTD__) \ + && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402) +// Mac OS X: Apple has not updated libstdc++ since 2007, which means it does not have +// or std::move. Let's disable these features +# undef Q_COMPILER_INITIALIZER_LISTS +# undef Q_COMPILER_RVALUE_REFS +# undef Q_COMPILER_REF_QUALIFIERS # endif -#endif // Q_OS_QNX +#endif /* * C++11 keywords and expressions From ff2dbe609ef4482d66d1ecd135b4f53f6aff7e60 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 14 Apr 2014 17:02:42 +0200 Subject: [PATCH 029/180] Fix crash when deleting top level windows embedded into QGraphicsProxyWidget. Clear proxyWidget pointer in slot QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot(). Task-number: QTBUG-29684 Task-number: QTBUG-33213 Change-Id: Ibdbd52aa810ca908e3d98daa00954345e7a93a48 Reviewed-by: Andreas Aardal Hanssen --- src/widgets/graphicsview/qgraphicsproxywidget.cpp | 4 ++++ .../qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index 68944817f64..f5db85b6989 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -379,6 +379,10 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot() { Q_Q(QGraphicsProxyWidget); + if (!widget.isNull()) { + if (QWExtra *extra = widget->d_func()->extra) + extra->proxyWidget = 0; + } widget = 0; delete q; } diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 5b178903cf9..8f57eca0a7c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -2502,9 +2502,6 @@ void tst_QGraphicsProxyWidget::popup_basic() void tst_QGraphicsProxyWidget::popup_subwidget() { -#ifdef Q_OS_WIN - QSKIP("This test crashes on Windows, QTBUG-33213"); -#endif QGroupBox *groupBox = new QGroupBox; groupBox->setTitle("GroupBox"); groupBox->setCheckable(true); @@ -3183,10 +3180,6 @@ void tst_QGraphicsProxyWidget::actionsContextMenu() void tst_QGraphicsProxyWidget::deleteProxyForChildWidget() { -#if defined(Q_OS_WIN) - QSKIP("This test is crashing on windows, it needs to be fixed. QTBUG-29684"); -#endif - QDialog dialog; dialog.resize(320, 120); dialog.move(80, 40); From cd46e9d959b6ef5f4d28ed83711fd18d692c07c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simo=20F=C3=A4lt?= Date: Wed, 19 Feb 2014 10:24:57 +0200 Subject: [PATCH 030/180] Add make check target for iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabling check target to run test apps in iPhone simulator. Task-number: QTBUG-36639 Change-Id: I700d998fe9f1a6c910431789e98e4789d820f3e4 Reviewed-by: Oswald Buddenhagen Reviewed-by: Tony Sarajärvi Reviewed-by: Tor Arne Vestbø --- mkspecs/macx-ios-clang/features/default_post.prf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 496553f8c00..79024c588c7 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -77,6 +77,9 @@ equals(TEMPLATE, app) { args += $$system_quote($$arg) system("cd $$system_quote($$OUT_PWD) && $$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode") + check.commands = "$(MAKE) -f $(MAKEFILE).ReleaseSimulator xcode_build_check" + QMAKE_EXTRA_TARGETS += check + } else { load(resolve_config) @@ -113,6 +116,9 @@ equals(TEMPLATE, app) { QMAKE_EXTRA_TARGETS += xcode_build_dir_distclean distclean.depends = xcode_build_dir_distclean QMAKE_EXTRA_TARGETS += distclean + + xcode_build_check.commands = "$(TESTRUNNER) $$title($$cfg)-$${sdk}/$(TARGET).app $(TESTARGS)" + QMAKE_EXTRA_TARGETS += xcode_build_check } CONFIG = From 3fdf53786f33094771ae067eb0e5bfa9d3459ec7 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 25 Mar 2014 17:07:24 +0100 Subject: [PATCH 031/180] Unite the documentation for qmath.h functions Some functions in qmath.h was documented under QtMath, and some under QtCore/qmath.h, the latter does not appear to lead to functional links in the function list, so we should move them all to QtMath. Task-number: QTBUG-37799 Change-Id: I3118c65ccbfb2401bdc324dbef2885d4e7d1c8f6 Reviewed-by: Leena Miettinen --- src/corelib/kernel/qmath.cpp | 84 ------------------------------- src/corelib/kernel/qmath.qdoc | 95 ++++++++++++++++++++++++++++------- 2 files changed, 78 insertions(+), 101 deletions(-) diff --git a/src/corelib/kernel/qmath.cpp b/src/corelib/kernel/qmath.cpp index b1860fa24a3..9f276b4ca96 100644 --- a/src/corelib/kernel/qmath.cpp +++ b/src/corelib/kernel/qmath.cpp @@ -303,88 +303,4 @@ const qreal qt_sine_table[QT_SINE_TABLE_SIZE] = { qreal(-0.024541228522912448) }; -/*! - \headerfile - \title Generic Math Declarations - \ingroup funclists - - \brief The header file includes generic math declarations. - - These functions are partly convenience definitions for basic - operations, for instance not available in the Standard Template Library et - al. -*/ - -/*! - \fn float qDegreesToRadians(float degrees) - \relates - \since 5.1 - - \brief The function converts the \a degrees in float to radians. - - The purpose of the function is to aid the conversion as such a convenient - function is not part of the Standard Template Library, i.e. in or - elsewhere. - - Example: - - \snippet code/src_corelib_kernel_qmath.cpp 0 - - \sa qRadiansToDegrees() -*/ - -/*! - \fn double qDegreesToRadians(double degrees) - \relates - \since 5.1 - - \brief The function converts the \a degrees in double to radians. - - The purpose of the function is to aid the conversion as such a convenient - function is not part of the Standard Template Library, i.e. in or - elsewhere. - - Example: - - \snippet code/src_corelib_kernel_qmath.cpp 1 - - \sa qRadiansToDegrees() -*/ - -/*! - \fn float qRadiansToDegrees(float radians) - \relates - \since 5.1 - - \brief The function converts the \a radians in float to degrees. - - The purpose of the function is to aid the conversion as such a convenient - function is not part of the Standard Template Library, i.e. in or - elsewhere. - - Example: - - \snippet code/src_corelib_kernel_qmath.cpp 2 - - \sa qDegreesToRadians() -*/ - -/*! - \fn double qRadiansToDegrees(double radians) - \relates - \since 5.1 - - \brief The function converts the \a radians in double to degrees. - - The purpose of the function is to aid the conversion as such a convenient - function is not part of the Standard Template Library, i.e. in or - elsewhere. - - Example: - - \snippet code/src_corelib_kernel_qmath.cpp 3 - - \sa qDegreesToRadians() -*/ - QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmath.qdoc b/src/corelib/kernel/qmath.qdoc index 06d8db9277d..04dbbb0a3b2 100644 --- a/src/corelib/kernel/qmath.qdoc +++ b/src/corelib/kernel/qmath.qdoc @@ -26,10 +26,15 @@ ****************************************************************************/ /*! - \headerfile - \title Math Functions + \headerfile + \title Generic Math Functions \ingroup funclists - \brief The header provides various math functions. + + \brief The header file provides various math functions. + + These functions are partly convenience definitions for basic math operations + not available in the C or Standard Template Libraries. + \pagekeywords math trigonometry qmath floor ceiling absolute sine cosine tangent inverse tan exponent power natural logarithm */ @@ -40,7 +45,7 @@ The ceiling is the smallest integer that is not less than \a v. For example, if \a v is 41.2, then the ceiling is 42. - \relates + \relates \sa qFloor() */ @@ -51,7 +56,7 @@ The floor is the largest integer that is not greater than \a v. For example, if \a v is 41.2, then the floor is 41. - \relates + \relates \sa qCeil() */ @@ -59,14 +64,14 @@ \fn qreal qFabs(qreal v) Returns the absolute value of \a v as a qreal. - \relates + \relates */ /*! \fn qreal qSin(qreal v) Returns the sine of the angle \a v in radians. - \relates + \relates \sa qCos(), qTan() */ @@ -74,7 +79,7 @@ \fn qreal qCos(qreal v) Returns the cosine of an angle \a v in radians. - \relates + \relates \sa qSin(), qTan() */ @@ -82,7 +87,7 @@ \fn qreal qTan(qreal v) Returns the tangent of an angle \a v in radians. - \relates + \relates \sa qSin(), qCos() */ @@ -91,7 +96,7 @@ Returns the arccosine of \a v as an angle in radians. Arccosine is the inverse operation of cosine. - \relates + \relates \sa qAtan(), qAsin(), qCos() */ @@ -100,7 +105,7 @@ Returns the arcsine of \a v as an angle in radians. Arcsine is the inverse operation of sine. - \relates + \relates \sa qSin(), qAtan(), qAcos() */ @@ -109,7 +114,7 @@ Returns the arctangent of \a v as an angle in radians. Arctangent is the inverse operation of tangent. - \relates + \relates \sa qTan(), qAcos(), qAsin() */ @@ -118,7 +123,7 @@ Returns the arctangent of a point specified by the coordinates \a y and \a x. This function will return the angle (argument) of that point. - \relates + \relates \sa qAtan() */ @@ -127,7 +132,7 @@ Returns the square root of \a v. This function returns a NaN if \a v is a negative number. - \relates + \relates \sa qPow() */ @@ -135,7 +140,7 @@ \fn qreal qLn(qreal v) Returns the natural logarithm of \a v. Natural logarithm uses base e. - \relates + \relates \sa qExp() */ @@ -143,7 +148,7 @@ \fn qreal qExp(qreal v) Returns the exponential function of \c e to the power of \a v. - \relates + \relates \sa qLn() */ @@ -152,6 +157,62 @@ Returns the value of \a x raised to the power of \a y. That is, \a x is the base and \a y is the exponent. - \relates + \relates \sa qSqrt() */ + +/*! + \fn float qDegreesToRadians(float degrees) + \relates + \since 5.1 + + This function converts the \a degrees in float to radians. + + Example: + + \snippet code/src_corelib_kernel_qmath.cpp 0 + + \sa qRadiansToDegrees() +*/ + +/*! + \fn double qDegreesToRadians(double degrees) + \relates + \since 5.1 + + This function converts the \a degrees in double to radians. + + Example: + + \snippet code/src_corelib_kernel_qmath.cpp 1 + + \sa qRadiansToDegrees() +*/ + +/*! + \fn float qRadiansToDegrees(float radians) + \relates + \since 5.1 + + This function converts the \a radians in float to degrees. + + Example: + + \snippet code/src_corelib_kernel_qmath.cpp 2 + + \sa qDegreesToRadians() +*/ + +/*! + \fn double qRadiansToDegrees(double radians) + \relates + \since 5.1 + + This function converts the \a radians in double to degrees. + + Example: + + \snippet code/src_corelib_kernel_qmath.cpp 3 + + \sa qDegreesToRadians() +*/ From fb7da5cc8c13bbf9a134306c1d290d34373687b0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 11 Apr 2014 12:09:59 +0200 Subject: [PATCH 032/180] Reload lastScrollPosition on window enter We need the lastScrollPosition position to calculated scrolling deltas on scroll events. Since the position is tied to the device and might have changed while scroll events were send to other applications we need to reload the value when mouse focus reenters our application. Task-number: QTBUG-38274 Change-Id: Ic166648f8e7ae486288cbed339a057e3faa1ef2d Reviewed-by: Laszlo Agocs Reviewed-by: Daniel Teske Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.h | 4 +++ .../platforms/xcb/qxcbconnection_xi2.cpp | 29 +++++++++++++++++++ src/plugins/platforms/xcb/qxcbwindow.cpp | 3 ++ 3 files changed, 36 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index a994c51c7db..13a0280baf9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -454,6 +454,10 @@ class QXcbConnection : public QObject QXcbSystemTrayTracker *systemTrayTracker(); +#ifdef XCB_USE_XINPUT2 + void handleEnterEvent(const xcb_enter_notify_event_t *); +#endif + private slots: void processXcbEvents(); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index d80b49ccbba..d7b3c75aee9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -524,6 +524,35 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) } } +void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) +{ +#ifdef XCB_USE_XINPUT21 + QHash::iterator it = m_scrollingDevices.begin(); + const QHash::iterator end = m_scrollingDevices.end(); + while (it != end) { + ScrollingDevice& scrollingDevice = it.value(); + int nrDevices = 0; + XIDeviceInfo* xiDeviceInfo = XIQueryDevice(static_cast(m_xlib_display), scrollingDevice.deviceId, &nrDevices); + if (nrDevices <= 0) { + it = m_scrollingDevices.erase(it); + continue; + } + for (int c = 0; c < xiDeviceInfo->num_classes; ++c) { + if (xiDeviceInfo->classes[c]->type == XIValuatorClass) { + XIValuatorClassInfo *vci = reinterpret_cast(xiDeviceInfo->classes[c]); + const int valuatorAtom = qatom(vci->label); + if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel) + scrollingDevice.lastScrollPosition.setX(vci->value); + else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel) + scrollingDevice.lastScrollPosition.setY(vci->value); + } + } + XIFreeDeviceInfo(xiDeviceInfo); + ++it; + } +#endif +} + void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice) { #ifdef XCB_USE_XINPUT21 diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 5a2002f1d4f..ad7e99bd498 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1778,6 +1778,9 @@ class EnterEventChecker void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) { connection()->setTime(event->time); +#ifdef XCB_USE_XINPUT2 + connection()->handleEnterEvent(event); +#endif if ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB) || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL From 50b25458cc6a1c7e725e153f56e5f911f4eb0c20 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 16:27:01 +0200 Subject: [PATCH 033/180] don't emit -L/-F/-I with system dirs to .pc files Change-Id: Idecb6f8ba61872c23856a8c7e22305c01c67f0b9 Reviewed-by: Joerg Bornemann Reviewed-by: Davide Pesavento --- qmake/generators/makefile.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index bad4eb54561..a20e8ff2177 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -3284,10 +3284,12 @@ MakefileGenerator::writePkgConfigFile() // libs t << "Libs: "; - QString pkgConfiglibDir; QString pkgConfiglibName; if (target_mode == TARG_MAC_MODE && project->isActiveConfig("lib_bundle")) { - pkgConfiglibDir = "-F${libdir}"; + if (libDir != QLatin1String("/System/Library/Frameworks") + && libDir != QLatin1String("/Library/Frameworks")) { + t << "-F${libdir} "; + } ProString bundle; if (!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME")) bundle = unescapeFilePath(project->first("QMAKE_FRAMEWORK_BUNDLE_NAME")); @@ -3298,12 +3300,13 @@ MakefileGenerator::writePkgConfigFile() bundle = bundle.left(suffix); pkgConfiglibName = "-framework " + bundle + " "; } else { - pkgConfiglibDir = "-L${libdir}"; + if (!project->values("QMAKE_DEFAULT_LIBDIRS").contains(libDir)) + t << "-L${libdir} "; pkgConfiglibName = "-l" + unescapeFilePath(project->first("QMAKE_ORIG_TARGET")); if (project->isActiveConfig("shared")) pkgConfiglibName += project->first("TARGET_VERSION_EXT").toQString(); } - t << pkgConfiglibDir << " " << pkgConfiglibName << " \n"; + t << pkgConfiglibName << " \n"; ProStringList libs; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) { @@ -3327,7 +3330,10 @@ MakefileGenerator::writePkgConfigFile() << varGlue("PRL_EXPORT_CXXFLAGS", "", " ", " ") << varGlue("QMAKE_PKGCONFIG_CFLAGS", "", " ", " ") // << varGlue("DEFINES","-D"," -D"," ") - << "-I${includedir}\n"; + ; + if (!project->values("QMAKE_DEFAULT_INCDIRS").contains(includeDir)) + t << "-I${includedir}"; + t << endl; // requires const QString requires = project->values("QMAKE_PKGCONFIG_REQUIRES").join(' '); From 50bc2b25d8dc3e420be63da7af3b2bc8bd38bb2b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 17:07:26 +0200 Subject: [PATCH 034/180] fix default QMAKE_PKGCONFIG_LIBDIR it needs neither native separators, nor a trailing separator. the QMAKE_PKGCONFIG_INCDIR default was already ok. Change-Id: I1048b3870fd3ca09aa76b41aecda7d90402aa64a Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index a20e8ff2177..3870d1ef0dd 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -3217,7 +3217,7 @@ MakefileGenerator::writePkgConfigFile() QString prefix = pkgConfigPrefix(); QString libDir = project->first("QMAKE_PKGCONFIG_LIBDIR").toQString(); if(libDir.isEmpty()) - libDir = prefix + Option::dir_sep + "lib" + Option::dir_sep; + libDir = prefix + "/lib"; QString includeDir = project->first("QMAKE_PKGCONFIG_INCDIR").toQString(); if(includeDir.isEmpty()) includeDir = prefix + "/include"; From 8d04d622b9ebbe8a6d1ec4d1362b6fc01e56eece Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 16:28:17 +0200 Subject: [PATCH 035/180] enable path replacement in installed qml plugin prl files on all platforms amends 08a2d8df4, take 2. Change-Id: If827612caf15b0d5d79fea38fa4915b1d36743d6 Reviewed-by: Joerg Bornemann --- mkspecs/features/qml_plugin.prf | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index f3739572c73..0b47a2b4cf5 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -101,11 +101,9 @@ load(qt_common) load(qml_module) -unix|mingw { - !isEmpty(_QMAKE_SUPER_CACHE_): \ - lib_replace.match = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*/lib - else: \ - lib_replace.match = $$MODULE_BASE_OUTDIR - lib_replace.replace = $$[QT_INSTALL_LIBS/raw] - QMAKE_PRL_INSTALL_REPLACE += lib_replace -} +!isEmpty(_QMAKE_SUPER_CACHE_): \ + lib_replace.match = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*/lib +else: \ + lib_replace.match = $$MODULE_BASE_OUTDIR +lib_replace.replace = $$[QT_INSTALL_LIBS/raw] +QMAKE_PRL_INSTALL_REPLACE += lib_replace From a5e4d3d4db03ba3092d0d415cee6c5ed1a7b4f5b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 17:17:49 +0200 Subject: [PATCH 036/180] properly replace windows paths in installed qml plugin prl files amends 53f48a4b, take 2. Change-Id: Ia20d7879e4e1b6a34d5bb9e36b4fd7f17139b5fe Reviewed-by: Joerg Bornemann --- mkspecs/features/qml_plugin.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index 0b47a2b4cf5..7314cb1f04b 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -106,4 +106,5 @@ load(qml_module) else: \ lib_replace.match = $$MODULE_BASE_OUTDIR lib_replace.replace = $$[QT_INSTALL_LIBS/raw] +lib_replace.CONFIG = path QMAKE_PRL_INSTALL_REPLACE += lib_replace From ee86ce89a63a5a7b071ec4116987609aa2a17600 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 16:53:55 +0200 Subject: [PATCH 037/180] don't attempt to replace include paths in meta files neither .prl nor .la files even contain include paths. in .pc files, we assign the final path to start with, so there is nothing to replace, either. Change-Id: I919dfa01e0a1d0ef8ef1220174de1d33c66cedf9 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_module.prf | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 2134077ed39..1ff55019f39 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -170,30 +170,27 @@ load(qt_installs) rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]* else: \ rplbase = $$MODULE_BASE_OUTDIR -include_replace.match = $$rplbase/include -include_replace.replace = $$[QT_INSTALL_HEADERS/raw] -include_replace.CONFIG = path lib_replace.match = $$rplbase/lib host_build: \ lib_replace.replace = $$[QT_HOST_LIBS] else: \ lib_replace.replace = $$[QT_INSTALL_LIBS/raw] lib_replace.CONFIG = path -QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace +QMAKE_PRL_INSTALL_REPLACE += lib_replace unix|mingw { CONFIG += create_pc QMAKE_PKGCONFIG_LIBDIR = $$lib_replace.replace - QMAKE_PKGCONFIG_INCDIR = $$include_replace.replace + QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME QMAKE_PKGCONFIG_DESTDIR = pkgconfig - QMAKE_PKGCONFIG_INSTALL_REPLACE += include_replace lib_replace + QMAKE_PKGCONFIG_INSTALL_REPLACE += lib_replace } unix { CONFIG += create_libtool explicitlib QMAKE_LIBTOOL_LIBDIR = $$lib_replace.replace - QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace + QMAKE_LIBTOOL_INSTALL_REPLACE += lib_replace } unix|mingw { From aa20e7f9d86cb43462d835e4e9c7ce1905478c30 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 17:51:41 +0200 Subject: [PATCH 038/180] reshuffle code for clarity move a bit around, nest/de-duplicate dependent conditionals Change-Id: I048bd3f409ce42b4138bccb28fcc513840202e7a Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_module.prf | 38 +++++++++++++++------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 1ff55019f39..a247b2cc6b1 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -127,6 +127,8 @@ win32 { # keeps the code clean and helps in writing code that is # safe across all platforms. DEFINES *= _CRT_SECURE_NO_WARNINGS + + DEFINES += _USE_MATH_DEFINES } aix-g++* { @@ -166,6 +168,9 @@ android: CONFIG += qt_android_deps #install directives load(qt_installs) +load(qt_targets) +load(qt_common) + !isEmpty(_QMAKE_SUPER_CACHE_): \ rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]* else: \ @@ -179,27 +184,24 @@ lib_replace.CONFIG = path QMAKE_PRL_INSTALL_REPLACE += lib_replace unix|mingw { - CONFIG += create_pc - QMAKE_PKGCONFIG_LIBDIR = $$lib_replace.replace - QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] - QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME - QMAKE_PKGCONFIG_DESTDIR = pkgconfig - QMAKE_PKGCONFIG_INSTALL_REPLACE += lib_replace -} - -unix { - CONFIG += create_libtool explicitlib - QMAKE_LIBTOOL_LIBDIR = $$lib_replace.replace - QMAKE_LIBTOOL_INSTALL_REPLACE += lib_replace -} - -unix|mingw { + CONFIG += create_pc + QMAKE_PKGCONFIG_DESTDIR = pkgconfig + QMAKE_PKGCONFIG_LIBDIR = $$lib_replace.replace + QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] + QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$section(VERSION, ., 0, 0) ") QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$section(VERSION, ., 0, 0)) for(i, MODULE_DEPENDS): \ QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$eval(QT.$${i}.MAJOR_VERSION)) isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \ QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module + QMAKE_PKGCONFIG_INSTALL_REPLACE += lib_replace + + unix { + CONFIG += create_libtool explicitlib + QMAKE_LIBTOOL_LIBDIR = $$lib_replace.replace + QMAKE_LIBTOOL_INSTALL_REPLACE += lib_replace + } } contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE @@ -218,9 +220,3 @@ win32 { } TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end - -load(qt_targets) -load(qt_common) - -win32:DEFINES+=_USE_MATH_DEFINES - From a33afed1989d08d6f76994052f0d34ea50bfd01e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 16:33:18 +0200 Subject: [PATCH 039/180] de-duplicate setup of libdir replacement in prl files Change-Id: Ia93fa02d9e63597d3347fee3aaf2aca65e7cc83a Reviewed-by: Joerg Bornemann Reviewed-by: Davide Pesavento --- mkspecs/features/qml_plugin.prf | 8 -------- mkspecs/features/qt_common.prf | 12 ++++++++++++ mkspecs/features/qt_module.prf | 13 +------------ mkspecs/features/qt_plugin.prf | 9 --------- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index 7314cb1f04b..f161a71ef9d 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -100,11 +100,3 @@ load(qt_common) } load(qml_module) - -!isEmpty(_QMAKE_SUPER_CACHE_): \ - lib_replace.match = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*/lib -else: \ - lib_replace.match = $$MODULE_BASE_OUTDIR -lib_replace.replace = $$[QT_INSTALL_LIBS/raw] -lib_replace.CONFIG = path -QMAKE_PRL_INSTALL_REPLACE += lib_replace diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index 6cd848b4052..b58f969b07d 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -19,6 +19,18 @@ contains(TEMPLATE, .*lib) { unix:contains(QT_CONFIG, reduce_relocations): CONFIG += bsymbolic_functions contains(QT_CONFIG, largefile): CONFIG += largefile contains(QT_CONFIG, separate_debug_info): CONFIG += separate_debug_info + + !isEmpty(_QMAKE_SUPER_CACHE_): \ + rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]* + else: \ + rplbase = $$MODULE_BASE_OUTDIR + lib_replace.match = $$rplbase/lib + host_build: \ + lib_replace.replace = $$[QT_HOST_LIBS] + else: \ + lib_replace.replace = $$[QT_INSTALL_LIBS/raw] + lib_replace.CONFIG = path + QMAKE_PRL_INSTALL_REPLACE += lib_replace } warnings_are_errors:warning_clean { diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index a247b2cc6b1..e250f936964 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -171,18 +171,7 @@ load(qt_installs) load(qt_targets) load(qt_common) -!isEmpty(_QMAKE_SUPER_CACHE_): \ - rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]* -else: \ - rplbase = $$MODULE_BASE_OUTDIR -lib_replace.match = $$rplbase/lib -host_build: \ - lib_replace.replace = $$[QT_HOST_LIBS] -else: \ - lib_replace.replace = $$[QT_INSTALL_LIBS/raw] -lib_replace.CONFIG = path -QMAKE_PRL_INSTALL_REPLACE += lib_replace - +# this builds on top of qt_common unix|mingw { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index c020bd27671..52567eaff07 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -83,12 +83,3 @@ load(qt_common) wince*:LIBS += $$QMAKE_LIBS_GUI QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF - -!isEmpty(_QMAKE_SUPER_CACHE_): \ - rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]* -else: \ - rplbase = $$MODULE_BASE_OUTDIR -lib_replace.match = $$rplbase/lib -lib_replace.replace = $$[QT_INSTALL_LIBS/raw] -lib_replace.CONFIG = path -QMAKE_PRL_INSTALL_REPLACE += lib_replace From eaefbe36e88e75725083d52e03d3a7843aa418f6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 17:32:23 +0200 Subject: [PATCH 040/180] snuff -L/-I with system paths when installing meta files Task-number: QTBUG-37963 Change-Id: I8e268387f9dc33d7fab76395301b1396ca0445ff Reviewed-by: Joerg Bornemann Reviewed-by: Davide Pesavento --- mkspecs/features/qt_common.prf | 12 +++++++++--- mkspecs/features/qt_module.prf | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index b58f969b07d..4dcabe92374 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -24,11 +24,17 @@ contains(TEMPLATE, .*lib) { rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]* else: \ rplbase = $$MODULE_BASE_OUTDIR - lib_replace.match = $$rplbase/lib host_build: \ - lib_replace.replace = $$[QT_HOST_LIBS] + qt_libdir = $$[QT_HOST_LIBS] else: \ - lib_replace.replace = $$[QT_INSTALL_LIBS/raw] + qt_libdir = $$[QT_INSTALL_LIBS/raw] + contains(QMAKE_DEFAULT_LIBDIRS, $$qt_libdir) { + lib_replace.match = "[^ ']*$$rplbase/lib" + lib_replace.replace = + } else { + lib_replace.match = $$rplbase/lib + lib_replace.replace = $$qt_libdir + } lib_replace.CONFIG = path QMAKE_PRL_INSTALL_REPLACE += lib_replace } diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index e250f936964..5dac0250eaa 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -175,7 +175,7 @@ load(qt_common) unix|mingw { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig - QMAKE_PKGCONFIG_LIBDIR = $$lib_replace.replace + QMAKE_PKGCONFIG_LIBDIR = $$qt_libdir QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$section(VERSION, ., 0, 0) ") @@ -188,7 +188,7 @@ unix|mingw { unix { CONFIG += create_libtool explicitlib - QMAKE_LIBTOOL_LIBDIR = $$lib_replace.replace + QMAKE_LIBTOOL_LIBDIR = $$qt_libdir QMAKE_LIBTOOL_INSTALL_REPLACE += lib_replace } } From a75153f8d0ae2b1203f8341deb71d753be009efd Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Tue, 15 Apr 2014 10:34:20 +0200 Subject: [PATCH 041/180] Fix objcopy config test for concurrent make processes The make targets had no dependency to the built binary. Therefore when building with multiple make processes(-j8) it was not guaranteed that the binary was available for the objcopy tests. Change-Id: Ifd04e3f49fdadf030e82e81498668899ad4e7fd3 Reviewed-by: Oswald Buddenhagen --- config.tests/unix/objcopy/objcopy.pro | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/config.tests/unix/objcopy/objcopy.pro b/config.tests/unix/objcopy/objcopy.pro index d2f9c738f6b..3c28b89ef37 100644 --- a/config.tests/unix/objcopy/objcopy.pro +++ b/config.tests/unix/objcopy/objcopy.pro @@ -1,10 +1,4 @@ SOURCES = objcopy.cpp CONFIG -= qt -all.depends += only_keep_debug strip_debug add_gnu_debuglink - -only_keep_debug.commands = $$QMAKE_OBJCOPY --only-keep-debug objcopy objcopy.debug -strip_debug.commands = $$QMAKE_OBJCOPY --strip-debug objcopy -add_gnu_debuglink.commands = $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopy.debug objcopy - -QMAKE_EXTRA_TARGETS += all only_keep_debug strip_debug add_gnu_debuglink +QMAKE_POST_LINK += $$QMAKE_OBJCOPY --only-keep-debug objcopy objcopy.debug && $$QMAKE_OBJCOPY --strip-debug objcopy && $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopy.debug objcopy From 3536823c7f967b164f64a6bcfa64e4c5e3b8eb01 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 14 Apr 2014 11:29:37 +0200 Subject: [PATCH 042/180] QCollator: Add note about ICU dependency. Task-number: QTBUG-28766 Change-Id: If661915457c4874a72e1111b85897aea596362bf Reviewed-by: Leena Miettinen Reviewed-by: Thiago Macieira --- src/corelib/tools/qcollator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp index 9c97d6b158a..f7dfaa7d330 100644 --- a/src/corelib/tools/qcollator.cpp +++ b/src/corelib/tools/qcollator.cpp @@ -205,6 +205,11 @@ QLocale QCollator::locale() const By default this mode is off. + \note On Windows, this functionality makes use of the \l{ICU} library. If Qt was + compiled without ICU support, it falls back to code using native Windows API, + which only works from Windows 7 onwards. On older versions of Windows, it will not work + and a warning will be emitted at runtime. + \sa numericMode() */ From 454ebcac45a170abdc67ac08ea04a4efb8c586ad Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 15 Apr 2014 16:49:08 +0200 Subject: [PATCH 043/180] Doc: recommend using QLocale for loading translations Users can choose to use different UI languages and regional settings on their devices. QTranslator::load(const QLocale &) function uses QLocale::uiLanguages() and not to the locale name, which refers to the formatting of dates and numbers. Change-Id: Iec6327dd1e91d913176499b23482d725b9d0a8aa Reviewed-by: Fawzi Mohamed Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qtranslator.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 843a6edce15..94c77302dd7 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -465,6 +465,12 @@ QTranslator::~QTranslator() \li \c /opt/foolib/foo.qm \li \c /opt/foolib/foo \endlist + + Usually, it is better to use the QTranslator::load(const QLocale &, + const QString &, const QString &, const QString &, const QString &) + function instead, because it uses \l{QLocale::uiLanguages()} and not simply + the locale name, which refers to the formatting of dates and numbers and not + necessarily the UI language. */ bool QTranslator::load(const QString & filename, const QString & directory, From ffc0e68a167cca112f05b310c3db2d564f444712 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 15 Apr 2014 14:51:37 +0200 Subject: [PATCH 044/180] fix debug_and_release builds Task-number: QTBUG-38358 Change-Id: Idb02fd845c1f36b963150cc150dd2ee5bdd7bc4a Reviewed-by: Eike Ziller Reviewed-by: Joerg Bornemann --- src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index 7d997d7d8bc..d505c30aa6b 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -7,6 +7,9 @@ CONFIG += \ exceptions_off rtti_off CONFIG -= qt +contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release +contains(QT_CONFIG, build_all):CONFIG += build_all + DESTDIR = $$QT_BUILD_TREE/lib DEFINES += HAVE_CONFIG_H From a08b5201c15a2fb13afd2cb28fe138e3e3439051 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 14 Apr 2014 14:12:00 +0200 Subject: [PATCH 045/180] Doc: Adding Enginio's export macro to the list of excluded QDoc tokens. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -helps the QDoc parser read C++ API when the macro is excluded. Task-number: QTBUG-33360 Change-Id: Ic7e86c0d1cec4a1960d20b1c92c4b60396eb3ea6 Reviewed-by: Jędrzej Nowacki Reviewed-by: Martin Smith Reviewed-by: Topi Reiniö --- doc/global/qt-cpp-defines.qdocconf | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 3240ec4a207..1039c88e8d0 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -19,6 +19,7 @@ defines += Q_QDOC \ Q_COMPILER_RVALUE_REFS Cpp.ignoretokens += \ + ENGINIOCLIENT_EXPORT \ PHONON_EXPORT \ Q_AUTOTEST_EXPORT \ Q_BLUETOOTH_EXPORT \ From c99f909bedad3f590c92deeeefa02e4e74029c1c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 11:51:02 +0200 Subject: [PATCH 046/180] don't make relative paths if we don't know the top-level build dir regression from qt4. Task-number: QTBUG-37113 Change-Id: I34813f03d8ec686e3ecb49f66629079489a3d83d Reviewed-by: Eskil Abrahamsen Blomfeldt --- qmake/option.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/option.cpp b/qmake/option.cpp index a2bd9386664..677899950c8 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -488,7 +488,7 @@ bool Option::postProcessProject(QMakeProject *project) Option::dir_sep = project->dirSep().toQString(); - if (Option::output_dir.startsWith(project->buildRoot())) + if (!project->buildRoot().isEmpty() && Option::output_dir.startsWith(project->buildRoot())) Option::mkfile::cachefile_depth = Option::output_dir.mid(project->buildRoot().length()).count('/'); From fec19027a508f7f6b7711d844b0f5a42bb0d4e83 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 12 Apr 2014 03:45:28 +0300 Subject: [PATCH 047/180] Fix font merging for complex scripts on Windows As long as QWindowsFontDatabase::fallbacksForFamily() does not take script parameter into account, we should prefer QFontEngineMultiQPA's loadEngine() implementation for complex scripts; otherwise we could fall into a situation where reported fallback fonts doesn't support the requested script at all. This finishes c3b2425791ec1e17a8b1e2f5b35b8e79176fc9c4. Task-number: QTBUG-37836 Change-Id: I2c43d97f1331ad05116856f9fe77560ed4dd02c7 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 9 ++++++--- .../platforms/windows/qwindowsfontdatabase_ft.cpp | 3 +-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 1432dfdcd94..940d75614c7 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1040,7 +1040,11 @@ QWindowsFontDatabase::~QWindowsFontDatabase() QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) { - return new QWindowsMultiFontEngine(fontEngine, script); + if (script == QChar::Script_Common) + return new QWindowsMultiFontEngine(fontEngine, script); + // ### as long as fallbacksForFamily() does not take script parameter into account, + // prefer QFontEngineMultiQPA's loadEngine() implementation for complex scripts + return QPlatformFontDatabase::fontEngineMulti(fontEngine, script); } QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) @@ -1619,8 +1623,7 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon result << QString::fromLatin1("Arial"); } - if (script == QChar::Script_Common || script == QChar::Script_Han) - result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); + result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint << script << result << m_families.size(); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 51961014d95..734f645e656 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -477,8 +477,7 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF } #endif - if (script == QChar::Script_Common || script == QChar::Script_Han) - result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); + result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint << script << result << m_families; From 3f9ad1efd61c76fe0671d28aac9e4886951856ec Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 11 Apr 2014 13:46:48 +0200 Subject: [PATCH 048/180] Android: Reset input method when focus changes Qt Quick does not have the widgets workaround of explicitly hiding the input method on focus out. This fix copies what happens in the iOS port: Commit the current preedit and reset the IM when we see that the focus object changes. Task-number: QTBUG-38047 Change-Id: I30805265286dc650b3734e2a24807cdc8bfbcd16 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../platforms/android/qandroidinputcontext.cpp | 14 +++++++++++++- .../platforms/android/qandroidinputcontext.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 3324d9ba490..12005d8fce6 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -338,7 +338,7 @@ static JNINativeMethod methods[] = { QAndroidInputContext::QAndroidInputContext() - : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0) + : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0) { QtAndroid::AttachedJNIEnv env; if (!env.jniEnv) @@ -532,6 +532,18 @@ void QAndroidInputContext::clear() m_extractedText.clear(); } + +void QAndroidInputContext::setFocusObject(QObject *object) +{ + if (object != m_focusObject) { + m_focusObject = object; + if (!m_composingText.isEmpty()) + finishComposingText(); + reset(); + } + QPlatformInputContext::setFocusObject(object); +} + void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodEvent *event) { QCoreApplication::sendEvent(receiver, event); diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h index f7b29a855fe..3ce141ae152 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -95,6 +95,7 @@ class QAndroidInputContext: public QPlatformInputContext bool isComposing() const; void clear(); + void setFocusObject(QObject *object); //---------------// jboolean beginBatchEdit(); @@ -136,6 +137,7 @@ private slots: QMetaObject::Connection m_updateCursorPosConnection; bool m_blockUpdateSelection; int m_batchEditNestingLevel; + QObject *m_focusObject; }; QT_END_NAMESPACE From 50b8506eaccc3c9bc3d717b241193bc8be9708b0 Mon Sep 17 00:00:00 2001 From: Jorgen Lind Date: Thu, 3 Apr 2014 13:11:59 +0200 Subject: [PATCH 049/180] XCB: fix that modal dialogs can go behind other process windows Task-number: QTBUG-35302 Change-Id: I1ad7a66e530710d5338a15057254360dae676451 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- .../platforms/windows/qwindowscontext.cpp | 8 +- .../platforms/windows/qwindowswindow.cpp | 22 ++-- src/plugins/platforms/xcb/qxcbwindow.cpp | 104 +++++++++++----- src/plugins/platforms/xcb/qxcbwindow.h | 4 + tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 113 ++++++++++++++++++ 5 files changed, 206 insertions(+), 45 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 6462cb8d3ea..f66859b72a3 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -49,11 +49,11 @@ #include "qwindowsmime.h" #include "qwindowsinputcontext.h" #include "qwindowstabletsupport.h" +#include #ifndef QT_NO_ACCESSIBILITY # include "accessible/qwindowsaccessibility.h" #endif #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) -# include # include # include "qwindowssessionmanager.h" #endif @@ -1025,6 +1025,12 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et, { QWindow *nextActiveWindow = 0; if (et == QtWindows::FocusInEvent) { + QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window()); + QWindow *modalWindow = 0; + if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) { + modalWindow->requestActivate(); + return; + } nextActiveWindow = platformWindow->window(); } else { // Focus out: Is the next window known and different diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ee9bf9936c7..db065255089 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1016,17 +1016,17 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w) while (QWindow *parent = w->parent()) w = parent; - const QWindowsWindow *ww = static_cast(w->handle()); - - // In case the topmost parent is embedded, find next ancestor using native methods - if (ww->isEmbedded(0)) { - HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT); - const HWND desktopHwnd = GetDesktopWindow(); - const QWindowsContext *ctx = QWindowsContext::instance(); - while (parentHWND && parentHWND != desktopHwnd) { - if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND)) - return topLevelOf(ancestor->window()); - parentHWND = GetAncestor(parentHWND, GA_PARENT); + if (const QPlatformWindow *handle = w->handle()) { + const QWindowsWindow *ww = static_cast(handle); + if (ww->isEmbedded(0)) { + HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT); + const HWND desktopHwnd = GetDesktopWindow(); + const QWindowsContext *ctx = QWindowsContext::instance(); + while (parentHWND && parentHWND != desktopHwnd) { + if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND)) + return topLevelOf(ancestor->window()); + parentHWND = GetAncestor(parentHWND, GA_PARENT); + } } } return w; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 193e75c1d66..dbffd577c15 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -485,7 +485,7 @@ QXcbWindow::~QXcbWindow() void QXcbWindow::destroy() { if (connection()->focusWindow() == this) - connection()->setFocusWindow(0); + doFocusOut(); if (m_syncCounter && m_usingSyncProtocol) Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter)); @@ -671,6 +671,9 @@ void QXcbWindow::show() Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); + if (QGuiApplication::modalWindow() == window()) + requestActivateWindow(); + m_screen->windowShown(this); connection()->sync(); @@ -694,6 +697,68 @@ void QXcbWindow::hide() m_mapped = false; } +static QWindow *tlWindow(QWindow *window) +{ + if (window && window->parent()) + return tlWindow(window->parent()); + return window; +} + +bool QXcbWindow::relayFocusToModalWindow() const +{ + QWindow *w = tlWindow(static_cast(QObjectPrivate::get(window()))->eventReceiver()); + QWindow *modal_window = 0; + if (QGuiApplicationPrivate::instance()->isWindowBlocked(w,&modal_window) && modal_window != w) { + modal_window->requestActivate(); + connection()->flush(); + return true; + } + + return false; +} + +void QXcbWindow::doFocusIn() +{ + if (relayFocusToModalWindow()) + return; + QWindow *w = static_cast(QObjectPrivate::get(window()))->eventReceiver(); + connection()->setFocusWindow(static_cast(w->handle())); + QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); +} + +static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) +{ + if (!event) { + // FocusIn event is not in the queue, proceed with FocusOut normally. + QWindowSystemInterface::handleWindowActivated(0, Qt::ActiveWindowFocusReason); + return true; + } + uint response_type = event->response_type & ~0x80; + if (response_type == XCB_FOCUS_IN) + return true; + + /* We are also interested in XEMBED_FOCUS_IN events */ + if (response_type == XCB_CLIENT_MESSAGE) { + xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; + if (cme->type == connection->atom(QXcbAtom::_XEMBED) + && cme->data.data32[1] == XEMBED_FOCUS_IN) + return true; + } + + return false; +} + +void QXcbWindow::doFocusOut() +{ + if (relayFocusToModalWindow()) + return; + connection()->setFocusWindow(0); + // Do not set the active window to 0 if there is a FocusIn coming. + // There is however no equivalent for XPutBackEvent so register a + // callback for QXcbConnection instead. + connection()->addPeekFunc(focusInPeeker); +} + struct QtMotifWmHints { quint32 flags, functions, decorations; qint32 input_mode; @@ -1514,6 +1579,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even QWindowSystemInterface::handleCloseEvent(window()); } else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) { connection()->setTime(event->data.data32[1]); + relayFocusToModalWindow(); + return; } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) { if (event->window == m_screen->root()) return; @@ -1549,8 +1616,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even } else if (event->type == atom(QXcbAtom::_XEMBED)) { handleXEmbedMessage(event); } else if (event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)) { - connection()->setFocusWindow(this); - QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason); + doFocusIn(); } else if (event->type == atom(QXcbAtom::MANAGER) || event->type == atom(QXcbAtom::_NET_WM_STATE) || event->type == atom(QXcbAtom::WM_CHANGE_STATE)) { @@ -1865,41 +1931,13 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) { - QWindow *w = window(); - w = static_cast(QObjectPrivate::get(w))->eventReceiver(); - connection()->setFocusWindow(static_cast(w->handle())); - QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); + doFocusIn(); } -static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) -{ - if (!event) { - // FocusIn event is not in the queue, proceed with FocusOut normally. - QWindowSystemInterface::handleWindowActivated(0, Qt::ActiveWindowFocusReason); - return true; - } - uint response_type = event->response_type & ~0x80; - if (response_type == XCB_FOCUS_IN) - return true; - - /* We are also interested in XEMBED_FOCUS_IN events */ - if (response_type == XCB_CLIENT_MESSAGE) { - xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; - if (cme->type == connection->atom(QXcbAtom::_XEMBED) - && cme->data.data32[1] == XEMBED_FOCUS_IN) - return true; - } - - return false; -} void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) { - connection()->setFocusWindow(0); - // Do not set the active window to 0 if there is a FocusIn coming. - // There is however no equivalent for XPutBackEvent so register a - // callback for QXcbConnection instead. - connection()->addPeekFunc(focusInPeeker); + doFocusOut(); } void QXcbWindow::updateSyncRequestCounter() diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index a90ad7b5edf..12d17023fb8 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -176,6 +176,10 @@ class QXcbWindow : public QXcbObject, public QXcbWindowEventListener, public QPl void show(); void hide(); + bool relayFocusToModalWindow() const; + void doFocusIn(); + void doFocusOut(); + QXcbScreen *m_screen; xcb_window_t m_window; diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index eefa85a745d..589f3e66e1c 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -88,6 +88,10 @@ private slots: void visibility(); void mask(); void initialSize(); + void modalDialog(); + void modalDialogClosingOneOfTwoModal(); + void modalWithChildWindow(); + void modalWindowModallity(); void initTestCase() { @@ -1316,6 +1320,115 @@ void tst_QWindow::initialSize() } } +void tst_QWindow::modalDialog() +{ + QWindow normalWindow; + normalWindow.resize(400, 400); + normalWindow.show(); + QVERIFY(QTest::qWaitForWindowExposed(&normalWindow)); + + QWindow dialog; + dialog.resize(200,200); + dialog.setModality(Qt::ApplicationModal); + dialog.setFlags(Qt::Dialog); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + + normalWindow.requestActivate(); + + QGuiApplication::sync(); + QGuiApplication::processEvents(); + QTRY_COMPARE(QGuiApplication::focusWindow(), &dialog); +} + +void tst_QWindow::modalDialogClosingOneOfTwoModal() +{ + QWindow normalWindow; + normalWindow.resize(400, 400); + normalWindow.show(); + QVERIFY(QTest::qWaitForWindowExposed(&normalWindow)); + + QWindow first_dialog; + first_dialog.resize(200,200); + first_dialog.setModality(Qt::ApplicationModal); + first_dialog.setFlags(Qt::Dialog); + first_dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&first_dialog)); + + { + QWindow second_dialog; + second_dialog.resize(200,200); + second_dialog.setModality(Qt::ApplicationModal); + second_dialog.setFlags(Qt::Dialog); + second_dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&second_dialog)); + + QTRY_COMPARE(QGuiApplication::focusWindow(), &second_dialog); + + second_dialog.close(); + } + + QGuiApplication::sync(); + QGuiApplication::processEvents(); + QTRY_COMPARE(QGuiApplication::focusWindow(), &first_dialog); +} + +void tst_QWindow::modalWithChildWindow() +{ + QWindow normalWindow; + normalWindow.resize(400, 400); + normalWindow.show(); + QVERIFY(QTest::qWaitForWindowExposed(&normalWindow)); + + QWindow tlw_dialog; + tlw_dialog.resize(400,200); + tlw_dialog.setModality(Qt::ApplicationModal); + tlw_dialog.setFlags(Qt::Dialog); + tlw_dialog.create(); + + QWindow sub_window(&tlw_dialog); + sub_window.resize(200,300); + sub_window.show(); + + tlw_dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&tlw_dialog)); + QVERIFY(QTest::qWaitForWindowExposed(&sub_window)); + + QTRY_COMPARE(QGuiApplication::focusWindow(), &tlw_dialog); + + sub_window.requestActivate(); + QGuiApplication::sync(); + QGuiApplication::processEvents(); + QTRY_COMPARE(QGuiApplication::focusWindow(), &sub_window); +} + +void tst_QWindow::modalWindowModallity() +{ + QWindow normal_window; + normal_window.resize(400, 400); + normal_window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&normal_window)); + + QWindow parent_to_modal; + parent_to_modal.resize(400, 400); + parent_to_modal.show(); + QVERIFY(QTest::qWaitForWindowExposed(&parent_to_modal)); + QTRY_COMPARE(QGuiApplication::focusWindow(), &parent_to_modal); + + QWindow modal_dialog; + modal_dialog.resize(400,200); + modal_dialog.setModality(Qt::WindowModal); + modal_dialog.setFlags(Qt::Dialog); + modal_dialog.setTransientParent(&parent_to_modal); + modal_dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&modal_dialog)); + QTRY_COMPARE(QGuiApplication::focusWindow(), &modal_dialog); + + normal_window.requestActivate(); + QTRY_COMPARE(QGuiApplication::focusWindow(), &normal_window); + +} + #include QTEST_MAIN(tst_QWindow) From 839c54e070727540570b5994908d461bb7bb4dfd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 9 Apr 2014 15:46:26 +0200 Subject: [PATCH 050/180] iOS: fix crash in auto correction when using unknown font family If QFont reports a family name that cannot be used to instanciate a UIFont, we end up trying to insert a nil object to an NSDictionary. This will raise an exception. This patch will check that we have a valid UIFont before using it. Task-number: QTBUG-38018 Change-Id: Id8a2e4afea8c915ff43a7e4680304ba19328f9c2 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/ios/quiview_textinput.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm index 28fb23d57b3..3f6c6d12568 100644 --- a/src/plugins/platforms/ios/quiview_textinput.mm +++ b/src/plugins/platforms/ios/quiview_textinput.mm @@ -473,6 +473,8 @@ - (NSDictionary *)textStylingAtPosition:(UITextPosition *)position inDirection:( QCoreApplication::sendEvent(focusObject, &e); QFont qfont = qvariant_cast(e.value(Qt::ImFont)); UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()]; + if (!uifont) + return [NSDictionary dictionary]; return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey]; } From 8b0fd78caa8e257757d3eb84732e38cf735b2136 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Thu, 10 Apr 2014 17:12:20 +0300 Subject: [PATCH 051/180] WinRT: Don't use the native thread handle for waiting There is no guarantee that the handle from std::thread will be valid when a wait is made. Instead, simply use an elapsed timer and check if the thread is finished. This prevents an exception from being thrown when a bad handle is encountered. Task-number: QTBUG-31397 Change-Id: Ie2a7e6cbfbb27bf1baff779322670d85e92e10dd Reviewed-by: Oliver Wolff --- src/corelib/thread/qthread_win.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index a12636778e9..bdc3463b9f1 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -63,6 +63,7 @@ #include #ifdef Q_OS_WINRT +#include #include #endif @@ -680,21 +681,11 @@ bool QThread::wait(unsigned long time) break; } #else // !Q_OS_WINRT - if (d->handle->joinable()) { - HANDLE handle = d->handle->native_handle(); - switch (WaitForSingleObjectEx(handle, time, FALSE)) { - case WAIT_OBJECT_0: - ret = true; - d->handle->join(); - break; - case WAIT_FAILED: - qErrnoWarning("QThread::wait: WaitForSingleObjectEx() failed"); - break; - case WAIT_ABANDONED: - case WAIT_TIMEOUT: - default: - break; - } + if (!d->finished) { + QElapsedTimer timer; + timer.start(); + while (timer.elapsed() < time && !d->finished) + yieldCurrentThread(); } #endif // Q_OS_WINRT From cd21b56c9dbb078828c86a5a073f13074b1645d2 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Wed, 16 Apr 2014 12:50:24 +0900 Subject: [PATCH 052/180] remove context unmatched warning in QOpenGLTexture destroy() or destructor complain when QOpenGLTexture is not created or it is already destroyed. Change-Id: I6b3135849e3ba2ce35678fcdbf1c9b6e588a063c Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltexture.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 078274eabd3..51d35cbd59c 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -180,6 +180,10 @@ bool QOpenGLTexturePrivate::create() void QOpenGLTexturePrivate::destroy() { + if (!context) { + // not created or already destroyed + return; + } if (QOpenGLContext::currentContext() != context) { qWarning("Requires a valid current OpenGL context.\n" "Texture has not been destroyed"); From f961425256f2be8034029912239b331b25dca1c5 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 7 Apr 2014 14:11:27 +0300 Subject: [PATCH 053/180] Direct2D QPA: Improve gradient support This change adds support for those gradients which can be expressed using Direct2D. At the moment this means linear and radial gradient with pad spread only. Change-Id: Ib1b1bc38a793dd826a259bbf8a7b31c25906dd59 Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 97 +++++++++++++++++-- 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index d8f34fc3ed0..1f2321e8857 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.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 plugins of the Qt Toolkit. @@ -658,7 +658,91 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate break; case Qt::LinearGradientPattern: + if (newBrush.gradient()->spread() != QGradient::PadSpread) { + *needsEmulation = true; + } else { + ComPtr linear; + const QLinearGradient *qlinear = static_cast(newBrush.gradient()); + + D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties; + ComPtr gradientStopCollection; + + const QGradientStops &qstops = qlinear->stops(); + QVector stops(qstops.count()); + + linearGradientBrushProperties.startPoint = to_d2d_point_2f(qlinear->start()); + linearGradientBrushProperties.endPoint = to_d2d_point_2f(qlinear->finalStop()); + + for (int i = 0; i < stops.size(); i++) { + stops[i].position = qstops[i].first; + stops[i].color = to_d2d_color_f(qstops[i].second); + } + + hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection); + if (FAILED(hr)) { + qWarning("%s: Could not create gradient stop collection for linear gradient: %#x", __FUNCTION__, hr); + break; + } + + hr = dc()->CreateLinearGradientBrush(linearGradientBrushProperties, gradientStopCollection.Get(), + &linear); + if (FAILED(hr)) { + qWarning("%s: Could not create Direct2D linear gradient brush: %#x", __FUNCTION__, hr); + break; + } + + hr = linear.As(&result); + if (FAILED(hr)) { + qWarning("%s: Could not convert Direct2D linear gradient brush: %#x", __FUNCTION__, hr); + break; + } + } + break; + case Qt::RadialGradientPattern: + if (newBrush.gradient()->spread() != QGradient::PadSpread) { + *needsEmulation = true; + } else { + ComPtr radial; + const QRadialGradient *qradial = static_cast(newBrush.gradient()); + + D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties; + ComPtr gradientStopCollection; + + const QGradientStops &qstops = qradial->stops(); + QVector stops(qstops.count()); + + radialGradientBrushProperties.center = to_d2d_point_2f(qradial->center()); + radialGradientBrushProperties.gradientOriginOffset = to_d2d_point_2f(qradial->focalPoint() - qradial->center()); + radialGradientBrushProperties.radiusX = qradial->radius(); + radialGradientBrushProperties.radiusY = qradial->radius(); + + for (int i = 0; i < stops.size(); i++) { + stops[i].position = qstops[i].first; + stops[i].color = to_d2d_color_f(qstops[i].second); + } + + hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection); + if (FAILED(hr)) { + qWarning("%s: Could not create gradient stop collection for radial gradient: %#x", __FUNCTION__, hr); + break; + } + + hr = dc()->CreateRadialGradientBrush(radialGradientBrushProperties, gradientStopCollection.Get(), + &radial); + if (FAILED(hr)) { + qWarning("%s: Could not create Direct2D radial gradient brush: %#x", __FUNCTION__, hr); + break; + } + + radial.As(&result); + if (FAILED(hr)) { + qWarning("%s: Could not convert Direct2D radial gradient brush: %#x", __FUNCTION__, hr); + break; + } + } + break; + case Qt::ConicalGradientPattern: *needsEmulation = true; break; @@ -706,16 +790,9 @@ QWindowsDirect2DPaintEngine::QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap : QPaintEngineEx(*(new QWindowsDirect2DPaintEnginePrivate(bitmap))) { QPaintEngine::PaintEngineFeatures unsupported = - // As of 1.1 Direct2D gradient support is deficient for linear and radial gradients - QPaintEngine::LinearGradientFill - | QPaintEngine::RadialGradientFill - - // As of 1.1 Direct2D does not support conical gradients at all - | QPaintEngine::ConicalGradientFill - // As of 1.1 Direct2D does not natively support complex composition modes // However, using Direct2D effects that implement them should be possible - | QPaintEngine::PorterDuff + QPaintEngine::PorterDuff | QPaintEngine::BlendModes | QPaintEngine::RasterOpModes @@ -796,7 +873,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (d->brush.emulate) { // We mostly (only?) get here when gradients are required. - // We could probably natively support linear and radial gradients that have pad reflect + // We natively support only linear and radial gradients that have pad reflect due to D2D limitations QImage img(d->bitmap->size(), QImage::Format_ARGB32); img.fill(Qt::transparent); From 7d0f4dde0688ec65c34e7a5309257c840409a607 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Tue, 15 Apr 2014 09:57:58 +0300 Subject: [PATCH 054/180] Direct2D QPA: Optimize rectangle fills. Detect rectangle hints in the QVectorPath and react accordingly. Change-Id: Ic72ce0c46d10e995c0824972854e2d88162eae45 Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 1f2321e8857..cabcda70ee5 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -897,13 +897,25 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (!d->brush.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; - } + if (path.hints() & QVectorPath::RectangleShapeMask) { + const qreal * const points = path.points(); + D2D_RECT_F rect = { + points[0], // left + points[1], // top + points[2], // right, + points[5] // bottom + }; + + d->dc()->FillRectangle(rect, d->brush.brush.Get()); + } else { + 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()->FillGeometry(geometry.Get(), d->brush.brush.Get()); + d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get()); + } } // For clipping we convert everything to painter paths since it allows From 0c95332f8fb2da910d43bc8d0e28ebf7e3f725d4 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Tue, 15 Apr 2014 16:45:53 +0300 Subject: [PATCH 055/180] Direct2D QPA: Refactor code to reduce code duplication Refactor duplicate logic in painterPathToPathGeometry and vectorPathToID2D1PathGeometry into one utility class. At the same time make the naming of the two functions consistent with each other. Change-Id: I03c8fc183863473b7337223e51835cf080914a41 Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 222 ++++++++++-------- 1 file changed, 120 insertions(+), 102 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index cabcda70ee5..d0076fa4de1 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -92,51 +92,124 @@ static inline ID2D1Factory1 *factory() return QWindowsDirect2DContext::instance()->d2dFactory(); } -// XXX reduce code duplication between painterPathToPathGeometry and -// vectorPathToID2D1PathGeometry, the two are quite similar - -static ComPtr painterPathToPathGeometry(const QPainterPath &path) +class Direct2DPathGeometryWriter { - ComPtr geometry; - ComPtr sink; +public: + Direct2DPathGeometryWriter() + : m_inFigure(false) + , m_roundCoordinates(false) + { - HRESULT hr = factory()->CreatePathGeometry(&geometry); - if (FAILED(hr)) { - qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr); - return NULL; } - hr = geometry->Open(&sink); - if (FAILED(hr)) { - qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr); - return NULL; + bool begin() + { + HRESULT hr = factory()->CreatePathGeometry(&m_geometry); + if (FAILED(hr)) { + qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr); + return false; + } + + hr = m_geometry->Open(&m_sink); + if (FAILED(hr)) { + qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr); + return false; + } + + return true; } - switch (path.fillRule()) { - case Qt::WindingFill: - sink->SetFillMode(D2D1_FILL_MODE_WINDING); - break; - case Qt::OddEvenFill: - sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); - break; + void setWindingFillEnabled(bool enable) + { + if (enable) + m_sink->SetFillMode(D2D1_FILL_MODE_WINDING); + else + m_sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE); + } + + void setAliasingEnabled(bool enable) + { + m_roundCoordinates = enable; + } + + bool isInFigure() const + { + return m_inFigure; + } + + void moveTo(const QPointF &point) + { + if (m_inFigure) + m_sink->EndFigure(D2D1_FIGURE_END_OPEN); + + m_sink->BeginFigure(adjusted(point), D2D1_FIGURE_BEGIN_FILLED); + m_inFigure = true; + } + + void lineTo(const QPointF &point) + { + m_sink->AddLine(adjusted(point)); + } + + void curveTo(const QPointF &p1, const QPointF &p2, const QPointF &p3) + { + D2D1_BEZIER_SEGMENT segment = { + adjusted(p1), + adjusted(p2), + adjusted(p3) + }; + + m_sink->AddBezier(segment); + } + + void close() + { + if (m_inFigure) + m_sink->EndFigure(D2D1_FIGURE_END_OPEN); + + m_sink->Close(); + } + + ComPtr geometry() const + { + return m_geometry; + } + +private: + D2D1_POINT_2F adjusted(const QPointF &point) + { + if (m_roundCoordinates) + return to_d2d_point_2f(point.toPoint()); + else + return to_d2d_point_2f(point); } - bool inFigure = false; + ComPtr m_geometry; + ComPtr m_sink; + + bool m_inFigure; + bool m_roundCoordinates; +}; + +static ComPtr painterPathToID2D1PathGeometry(const QPainterPath &path, bool alias) +{ + Direct2DPathGeometryWriter writer; + if (!writer.begin()) + return NULL; + + writer.setWindingFillEnabled(path.fillRule() == Qt::WindingFill); + writer.setAliasingEnabled(alias); for (int i = 0; i < path.elementCount(); i++) { const QPainterPath::Element element = path.elementAt(i); switch (element.type) { case QPainterPath::MoveToElement: - if (inFigure) - sink->EndFigure(D2D1_FIGURE_END_OPEN); - - sink->BeginFigure(to_d2d_point_2f(element), D2D1_FIGURE_BEGIN_FILLED); - inFigure = true; + writer.moveTo(element); break; case QPainterPath::LineToElement: - sink->AddLine(to_d2d_point_2f(element)); + writer.lineTo(element); break; case QPainterPath::CurveToElement: @@ -149,13 +222,7 @@ static ComPtr painterPathToPathGeometry(const QPainterPath & Q_ASSERT(data1.type == QPainterPath::CurveToDataElement); Q_ASSERT(data2.type == QPainterPath::CurveToDataElement); - D2D1_BEZIER_SEGMENT segment; - - segment.point1 = to_d2d_point_2f(element); - segment.point2 = to_d2d_point_2f(data1); - segment.point3 = to_d2d_point_2f(data2); - - sink->AddBezier(segment); + writer.curveTo(element, data1, data2); } break; @@ -165,55 +232,22 @@ static ComPtr painterPathToPathGeometry(const QPainterPath & } } - if (inFigure) - sink->EndFigure(D2D1_FIGURE_END_OPEN); - - sink->Close(); - - return geometry; + writer.close(); + return writer.geometry(); } static ComPtr vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias) { - ComPtr pathGeometry; - HRESULT hr = factory()->CreatePathGeometry(pathGeometry.GetAddressOf()); - if (FAILED(hr)) { - qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr); + Direct2DPathGeometryWriter writer; + if (!writer.begin()) return NULL; - } - - if (path.isEmpty()) - return pathGeometry; - ComPtr sink; - hr = pathGeometry->Open(sink.GetAddressOf()); - if (FAILED(hr)) { - qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr); - return NULL; - } - - sink->SetFillMode(path.hasWindingFill() ? D2D1_FILL_MODE_WINDING - : D2D1_FILL_MODE_ALTERNATE); - - bool inFigure = false; + writer.setWindingFillEnabled(path.hasWindingFill()); + writer.setAliasingEnabled(alias); const QPainterPath::ElementType *types = path.elements(); const int count = path.elementCount(); - const qreal *points = 0; - - QScopedArrayPointer rounded_points; - - if (alias) { - // Aliased painting, round to whole numbers - rounded_points.reset(new qreal[count * 2]); - points = rounded_points.data(); - - for (int i = 0; i < (count * 2); i++) - rounded_points[i] = qRound(path.points()[i]); - } else { - // Antialiased painting, keep original numbers - points = path.points(); - } + const qreal *points = path.points(); Q_ASSERT(points); @@ -226,15 +260,11 @@ static ComPtr vectorPathToID2D1PathGeometry(const QVectorPat switch (types[i]) { case QPainterPath::MoveToElement: - if (inFigure) - sink->EndFigure(D2D1_FIGURE_END_OPEN); - - sink->BeginFigure(D2D1::Point2F(x, y), D2D1_FIGURE_BEGIN_FILLED); - inFigure = true; + writer.moveTo(QPointF(x, y)); break; case QPainterPath::LineToElement: - sink->AddLine(D2D1::Point2F(x, y)); + writer.lineTo(QPointF(x, y)); break; case QPainterPath::CurveToElement: @@ -251,13 +281,7 @@ static ComPtr vectorPathToID2D1PathGeometry(const QVectorPat const qreal x3 = points[i * 2]; const qreal y3 = points[i * 2 + 1]; - D2D1_BEZIER_SEGMENT segment = { - D2D1::Point2F(x, y), - D2D1::Point2F(x2, y2), - D2D1::Point2F(x3, y3) - }; - - sink->AddBezier(segment); + writer.curveTo(QPointF(x, y), QPointF(x2, y2), QPointF(x3, y3)); } break; @@ -267,23 +291,17 @@ static ComPtr vectorPathToID2D1PathGeometry(const QVectorPat } } } else { - sink->BeginFigure(D2D1::Point2F(points[0], points[1]), D2D1_FIGURE_BEGIN_FILLED); - inFigure = true; - + writer.moveTo(QPointF(points[0], points[1])); for (int i = 1; i < count; i++) - sink->AddLine(D2D1::Point2F(points[i * 2], points[i * 2 + 1])); + writer.lineTo(QPointF(points[i * 2], points[i * 2 + 1])); } - if (inFigure) { + if (writer.isInFigure()) if (path.hasImplicitClose()) - sink->AddLine(D2D1::Point2F(points[0], points[1])); - - sink->EndFigure(D2D1_FIGURE_END_OPEN); - } - - sink->Close(); + writer.lineTo(QPointF(points[0], points[1])); - return pathGeometry; + writer.close(); + return writer.geometry(); } class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate @@ -375,7 +393,7 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate { popClip(); - ComPtr geometry = painterPathToPathGeometry(clipPath); + ComPtr geometry = painterPathToID2D1PathGeometry(clipPath, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); if (!geometry) return; @@ -816,7 +834,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev) QPainterPath p; p.addRegion(systemClip()); - ComPtr geometry = painterPathToPathGeometry(p); + ComPtr geometry = painterPathToID2D1PathGeometry(p, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); if (!geometry) return false; From d0cf69eaff95e5c15573b5673deda8fd85a61dcd Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Tue, 15 Apr 2014 16:50:10 +0300 Subject: [PATCH 056/180] Direct2D QPA: Fix text drawing with brush but no pen We were incorrectly bailing out early in the text drawing code when there was no pen. This is incorrect as drawing with only a brush should be possible. Change-Id: I94eaadd3cf6c4d82033b5d74d7ca47a05601083f Reviewed-by: Friedemann Kleint --- .../platforms/direct2d/qwindowsdirect2dpaintengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index d0076fa4de1..86f78a35d5e 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -1143,7 +1143,7 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText Q_D(QWindowsDirect2DPaintEngine); D2D_TAG(D2DDebugDrawStaticTextItemTag); - if (qpen_style(d->pen.qpen) == Qt::NoPen) + if (qpen_style(d->pen.qpen) == Qt::NoPen && qbrush_style(d->brush.qbrush) == Qt::NoBrush) return; if (staticTextItem->numGlyphs == 0) @@ -1193,7 +1193,7 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem Q_D(QWindowsDirect2DPaintEngine); D2D_TAG(D2DDebugDrawTextItemTag); - if (qpen_style(d->pen.qpen) == Qt::NoPen) + if (qpen_style(d->pen.qpen) == Qt::NoPen && qbrush_style(d->brush.qbrush) == Qt::NoBrush) return; const QTextItemInt &ti = static_cast(textItem); From 2ba9a2584f90bf2849182143d90c988ddb937c3a Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 10 Apr 2014 15:31:48 +0200 Subject: [PATCH 057/180] Fix polling file system watcher addPaths Fixes QFileSystemWatcher::addPath() auto test when polling file system watcher is in use: adding the same path twice should fail. Change-Id: I2a0df3ffa587fa90fae744858f4471d667443e6f Reviewed-by: Oswald Buddenhagen Reviewed-by: Robin Burchell Reviewed-by: Fabian Bumberger --- src/corelib/io/qfilesystemwatcher_polling.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_polling.cpp b/src/corelib/io/qfilesystemwatcher_polling.cpp index 689f05bb1ba..401f95ae824 100644 --- a/src/corelib/io/qfilesystemwatcher_polling.cpp +++ b/src/corelib/io/qfilesystemwatcher_polling.cpp @@ -65,14 +65,16 @@ QStringList QPollingFileSystemWatcherEngine::addPaths(const QStringList &paths, if (!fi.exists()) continue; if (fi.isDir()) { - if (!directories->contains(path)) - directories->append(path); + if (directories->contains(path)) + continue; + directories->append(path); if (!path.endsWith(QLatin1Char('/'))) fi = QFileInfo(path + QLatin1Char('/')); this->directories.insert(path, fi); } else { - if (!files->contains(path)) - files->append(path); + if (files->contains(path)) + continue; + files->append(path); this->files.insert(path, fi); } it.remove(); From a420c6e838d4cced25ee77ff7ee3fd41806a88db Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 16 Apr 2014 13:49:07 +0200 Subject: [PATCH 058/180] CMake: Include the CMakeParseArguments module for dbus macros. The cmake_parse_arguments macro is used already in the file. The module happens to already be included via Qt5CoreMacros, so the existing code is not currently a problem. Add the include to comply with 'include what you use' and to ensure that it continues to work even if Qt5CoreMacros is changed in the future. Change-Id: I7369261bce9d0e58488e584ef0743e33e9f9ec9e Reviewed-by: Volker Krause Reviewed-by: Stephen Kelly --- src/dbus/Qt5DBusMacros.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dbus/Qt5DBusMacros.cmake b/src/dbus/Qt5DBusMacros.cmake index ff497e8ebce..2364c6710c1 100644 --- a/src/dbus/Qt5DBusMacros.cmake +++ b/src/dbus/Qt5DBusMacros.cmake @@ -32,6 +32,7 @@ include(MacroAddFileDependencies) +include(CMakeParseArguments) function(QT5_ADD_DBUS_INTERFACE _sources _interface _basename) get_filename_component(_infile ${_interface} ABSOLUTE) From 154b35e8c0d9c1c6bf28eab0636e4178524fe9ea Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 16 Apr 2014 12:18:18 +0200 Subject: [PATCH 059/180] CMake: Include the definition of the Qt5::AccessibleFactory target. The file will not exist if the accessible plugin is not built. Task-number: QTBUG-37849 Change-Id: I2983d01a085b11737bf49805edab5ca33fb5174a Reviewed-by: Volker Krause Reviewed-by: Stephen Kelly --- src/widgets/Qt5WidgetsConfigExtras.cmake.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/Qt5WidgetsConfigExtras.cmake.in b/src/widgets/Qt5WidgetsConfigExtras.cmake.in index e5650ff3621..99d87e2e46f 100644 --- a/src/widgets/Qt5WidgetsConfigExtras.cmake.in +++ b/src/widgets/Qt5WidgetsConfigExtras.cmake.in @@ -14,4 +14,6 @@ if (NOT TARGET Qt5::uic) ) endif() +include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5Widgets_AccessibleFactory.cmake\" OPTIONAL) + set(Qt5Widgets_UIC_EXECUTABLE Qt5::uic) From efa7a5a659696901fddc8a93f870d1b83473dc64 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 8 Apr 2014 18:27:52 +0200 Subject: [PATCH 060/180] Cocoa: Force menubar update after inserting a new menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-38135 Change-Id: I7bb9f41789cc77c26a9623d69c28e3ad1607bb9c Reviewed-by: Shawn Rutledge Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenubar.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index ffc0fabdced..aceb9b619b1 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -124,6 +124,8 @@ m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu); if (!menu->menuBar()) insertNativeMenu(menu, beforeMenu); + if (m_window && m_window->window()->isActive()) + updateMenuBarImmediately(); } void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu) From 329752517c387d782b6496ca8217364c61777834 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Tue, 15 Apr 2014 21:24:21 +0800 Subject: [PATCH 061/180] Doc: Improve docs for file permission checking on NTFS - Reduce verbosity in qfiledevice.cpp - Copy to qfileinfo.cpp Task-number: QTBUG-35232 Change-Id: I4b0de36bdf266ebf486f73daecec8fbb74fa1d4c Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen Reviewed-by: Jerome Pasion --- src/corelib/io/qfiledevice.cpp | 7 +++---- src/corelib/io/qfileinfo.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index d2c8d37d4ac..f7e58a7bed6 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -139,10 +139,9 @@ void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum) are returned and on Windows the rights of the current user are returned. This behavior might change in a future Qt version. - Note that Qt does not by default check for permissions on NTFS - file systems, as this may decrease the performance of file - handling considerably. It is possible to force permission checking - on NTFS by including the following code in your source: + \note On NTFS file systems, ownership and permissions checking is + disabled by default for performance reasons. To enable it, + include the following line: \snippet ntfsp.cpp 0 diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 2cf97ef94eb..60f7e47e622 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -271,6 +271,17 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) groupId(). You can examine a file's permissions and ownership in a single statement using the permission() function. + \note On NTFS file systems, ownership and permissions checking is + disabled by default for performance reasons. To enable it, + include the following line: + + \snippet ntfsp.cpp 0 + + Permission checking is then turned on and off by incrementing and + decrementing \c qt_ntfs_permission_lookup by 1. + + \snippet ntfsp.cpp 1 + \section1 Performance Issues Some of QFileInfo's functions query the file system, but for From 7aac93b6ce4e88c8e47c4b2cd8c283daeac5cdb3 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 10 Apr 2014 11:49:48 +0200 Subject: [PATCH 062/180] Remove internal public function from QOpenGLFunctions QOpenGLContext uses glGetTexLevelParameteriv on desktop OpenGL and so it got recently added to QOpenGLFunctions as part of the dynamic GL loading support. This is unnecessary since such desktop-only code can use the versioned wrappers (QOpenGLFunction_1_0 for example). In related upcoming changes in 5.4 the function is removed. This change has to be backported to 5.3 to prevent introducing this public API unnecessarily. Change-Id: I6fc331091e4e6416e430bf985afcc17a392fc2e3 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qopenglcontext.cpp | 10 ++++++++-- src/gui/opengl/qopenglfunctions.cpp | 25 ++----------------------- src/gui/opengl/qopenglfunctions.h | 24 ------------------------ 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 7382d63a06f..dbca05037b9 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -61,6 +61,10 @@ #include +#ifndef QT_OPENGL_ES_2 +#include +#endif + QT_BEGIN_NAMESPACE class QOpenGLVersionProfilePrivate @@ -366,7 +370,9 @@ int QOpenGLContextPrivate::maxTextureSize() GLint size; GLint next = 64; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); + QOpenGLFunctions_1_0 *gl1funcs = q->versionFunctions(); + gl1funcs->initializeOpenGLFunctions(); + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size); if (size == 0) { return max_texture_size; } @@ -377,7 +383,7 @@ int QOpenGLContextPrivate::maxTextureSize() if (next > max_texture_size) break; funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); + gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); } while (next > size); max_texture_size = size; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index eb2c98e1f55..af536fa9273 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -2011,12 +2011,6 @@ void QOpenGLFunctions::initializeOpenGLFunctions() This convenience function will do nothing on OpenGL ES 1.x systems. */ -/*! - \fn void QOpenGLFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) - - \internal -*/ - /*! \fn bool QOpenGLFunctions::isInitialized(const QOpenGLFunctionsPrivate *d) \internal @@ -3174,15 +3168,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qop (target, offset, size, data); } -#ifndef QT_OPENGL_ES_2 -// Desktop only - -static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) -{ - RESOLVE_FUNC_VOID(0, GetTexLevelParameteriv)(target, level, pname, params); -} - -#ifndef QT_OPENGL_DYNAMIC +#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC) // Special translation functions for ES-specific calls on desktop GL static void QOPENGLF_APIENTRY qopenglfTranslateClearDepthf(GLclampf depth) @@ -3194,10 +3180,7 @@ static void QOPENGLF_APIENTRY qopenglfTranslateDepthRangef(GLclampf zNear, GLcla { ::glDepthRange(zNear, zFar); } - -#endif // QT_OPENGL_DYNAMIC - -#endif // QT_OPENGL_ES2 +#endif // !ES && !DYNAMIC QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) { @@ -3256,8 +3239,6 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) TexParameteriv = qopenglfResolveTexParameteriv; TexSubImage2D = qopenglfResolveTexSubImage2D; Viewport = qopenglfResolveViewport; - - GetTexLevelParameteriv = qopenglfResolveGetTexLevelParameteriv; } else { #ifndef QT_OPENGL_DYNAMIC // Use the functions directly. This requires linking QtGui to an OpenGL implementation. @@ -3308,8 +3289,6 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) TexParameteriv = ::glTexParameteriv; TexSubImage2D = ::glTexSubImage2D; Viewport = ::glViewport; - - GetTexLevelParameteriv = ::glGetTexLevelParameteriv; #else // QT_OPENGL_DYNAMIC // This should not happen. qFatal("QOpenGLFunctions: Dynamic OpenGL builds do not support platforms with insufficient function resolving capabilities"); diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h index 03c12200d54..de1de39db21 100644 --- a/src/gui/opengl/qopenglfunctions.h +++ b/src/gui/opengl/qopenglfunctions.h @@ -407,9 +407,6 @@ class Q_GUI_EXPORT QOpenGLFunctions void glVertexAttrib4fv(GLuint indx, const GLfloat* values); void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); - // OpenGL1, not GLES2 - void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); - protected: QOpenGLFunctionsPrivate *d_ptr; static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } @@ -565,9 +562,6 @@ struct QOpenGLFunctionsPrivate void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values); void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); - // OpenGL1 only, not GLES2 - void (QOPENGLF_APIENTRYP GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params); - // Special non-ES OpenGL variants, not to be called directly void (QOPENGLF_APIENTRYP ClearDepth)(GLdouble depth); void (QOPENGLF_APIENTRYP DepthRange)(GLdouble zNear, GLdouble zFar); @@ -2154,24 +2148,6 @@ inline void QOpenGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLe Q_OPENGL_FUNCTIONS_DEBUG } -// OpenGL1, not GLES2 - -inline void QOpenGLFunctions::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) -{ -#ifdef QT_OPENGL_ES_2 - Q_UNUSED(target); - Q_UNUSED(level); - Q_UNUSED(pname); - Q_UNUSED(params); - // Cannot get here. - qFatal("QOpenGLFunctions: glGetTexLevelParameteriv not available with OpenGL ES"); -#else - Q_ASSERT(QOpenGLFunctions::isInitialized(d_ptr)); - d_ptr->GetTexLevelParameteriv(target, level, pname, params); -#endif - Q_OPENGL_FUNCTIONS_DEBUG -} - QT_END_NAMESPACE #endif // QT_NO_OPENGL From 4dbef58c3d2a63f59c5ae32ba9dc47a2a9157474 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 15 Apr 2014 18:14:08 +0200 Subject: [PATCH 063/180] Restore Qt 4 behavior in default double click handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert 3bb902495291c50a2f06e8e03a62a647db3e5cd4. That fix was an attempt to handle the issue that has been fixed in 5.3 by 9063edef796ad10eb9ac2229627f36d60168f0e2 and should have been reverted when the new approach, that restores Qt 4 behavior for widgets, was introduced. Task-number: QTBUG-38242 Task-number: QTBUG-36423 Change-Id: I8f8a82da22605fac90543492e9b2cd2b568544e7 Reviewed-by: Jørgen Lind Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget.cpp | 4 +++- tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp | 6 ++++-- tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 7eecd3d84d6..f79eaf197d9 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8525,6 +8525,8 @@ void QWidget::mouseReleaseEvent(QMouseEvent *event) This event handler, for event \a event, can be reimplemented in a subclass to receive mouse double click events for the widget. + The default implementation calls mousePressEvent(). + \note The widget will also receive mouse press and mouse release events in addition to the double click event. It is up to the developer to ensure that the application interprets these events @@ -8536,7 +8538,7 @@ void QWidget::mouseReleaseEvent(QMouseEvent *event) void QWidget::mouseDoubleClickEvent(QMouseEvent *event) { - event->ignore(); + mousePressEvent(event); } #ifndef QT_NO_WHEELEVENT diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index 345b8d82ada..06dd6233689 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -679,7 +679,8 @@ void tst_QTabBar::tabBarClicked() QCOMPARE(doubleClickSpy.count(), 0); QTest::mouseDClick(&tabBar, button, 0, tabPos); - QCOMPARE(clickSpy.count(), 0); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0); QCOMPARE(doubleClickSpy.count(), 1); QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0); @@ -691,7 +692,8 @@ void tst_QTabBar::tabBarClicked() QCOMPARE(doubleClickSpy.count(), 0); QTest::mouseDClick(&tabBar, button, 0, barPos); - QCOMPARE(clickSpy.count(), 0); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1); QCOMPARE(doubleClickSpy.count(), 1); QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1); diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index df11ea9b14a..90af617e877 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -690,7 +690,8 @@ void tst_QTabWidget::tabBarClicked() QCOMPARE(doubleClickSpy.count(), 0); QTest::mouseDClick(&tabBar, button, 0, tabPos); - QCOMPARE(clickSpy.count(), 0); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0); QCOMPARE(doubleClickSpy.count(), 1); QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0); @@ -702,7 +703,8 @@ void tst_QTabWidget::tabBarClicked() QCOMPARE(doubleClickSpy.count(), 0); QTest::mouseDClick(&tabBar, button, 0, barPos); - QCOMPARE(clickSpy.count(), 0); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1); QCOMPARE(doubleClickSpy.count(), 1); QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1); From d449c0e0e4e39606e0421090b9356c46bc29030c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 22 Jan 2014 14:17:31 +0100 Subject: [PATCH 064/180] When a window loses focus to a popup, event has PopupFocusReason MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to debe31e047060d790fb32c06e514d9df476df8bf : a popup window can have focus, but a QQuickWindow needs to know why it loses focus when a menu is opened, so that for example copy/cut/paste Actions can apply to the text which did have focus before the menu opened. The event's focus reason provides enough information to deal with this situation. Task-number: QTBUG-36292 Task-number: QTBUG-36332 Change-Id: Ifae999a364a61b125a4764c9db204a167bddf0b7 Reviewed-by: Jørgen Lind --- src/gui/kernel/qguiapplication.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index bdedc9d75f8..ab71fe9081e 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1872,7 +1872,11 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate return; if (previous) { - QFocusEvent focusOut(QEvent::FocusOut, e->reason); + Qt::FocusReason r = e->reason; + if ((r == Qt::OtherFocusReason || r == Qt::ActiveWindowFocusReason) && + newFocus && (newFocus->flags() & Qt::Popup) == Qt::Popup) + r = Qt::PopupFocusReason; + QFocusEvent focusOut(QEvent::FocusOut, r); QCoreApplication::sendSpontaneousEvent(previous, &focusOut); QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)), qApp, SLOT(_q_updateFocusObject(QObject*))); @@ -1881,7 +1885,11 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate } if (QGuiApplicationPrivate::focus_window) { - QFocusEvent focusIn(QEvent::FocusIn, e->reason); + Qt::FocusReason r = e->reason; + if ((r == Qt::OtherFocusReason || r == Qt::ActiveWindowFocusReason) && + previous && (previous->flags() & Qt::Popup) == Qt::Popup) + r = Qt::PopupFocusReason; + QFocusEvent focusIn(QEvent::FocusIn, r); QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn); QObject::connect(QGuiApplicationPrivate::focus_window, SIGNAL(focusObjectChanged(QObject*)), qApp, SLOT(_q_updateFocusObject(QObject*))); From 0c3301f0b1b516942be735291ee798914f3d9a09 Mon Sep 17 00:00:00 2001 From: Paul Eggleton Date: Tue, 28 Feb 2012 15:10:24 +0000 Subject: [PATCH 065/180] configure: make pulseaudio and alsa configurable options Allows disabling pulseaudio and alsa support at configure time making builds more deterministic. Change-Id: I4f1719cf831458b1d5ad3ebc01f6782b897d392c Reviewed-by: Martin Jansa Reviewed-by: Oswald Buddenhagen Reviewed-by: Kalle Viironen Reviewed-by: Thiago Macieira --- configure | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/configure b/configure index 67a5a4b537a..55d68efc9c6 100755 --- a/configure +++ b/configure @@ -1805,6 +1805,20 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + pulseaudio) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_PULSEAUDIO="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; + alsa) + if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then + CFG_ALSA="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; gtkstyle) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_QGTKSTYLE="$VAL" @@ -2369,6 +2383,12 @@ Third Party Libraries: -no-glib ........... Do not compile Glib support. + -glib .............. Compile Glib support. + -no-pulseaudio ..... Do not compile PulseAudio support. + + -pulseaudio ........ Compile PulseAudio support. + + -no-alsa ........... Do not compile ALSA support. + + -alsa .............. Compile ALSA support. + Additional options: -make ....... Add part to the list of parts to be built at make time. From c4c9883d13d363cf914b4ef7dd5d11b593c6b515 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 16 Apr 2014 15:08:59 +0200 Subject: [PATCH 066/180] fix read notification in QWindowsPipeReader::waitForPipeClosed In QWindowsPipeReader::waitForPipeClosed we must check for available bytes in the internal buffer and trigger the notified signal. This fixes tst_QLocalSocket::writeToClientAndDisconnect on Windows. Change-Id: I0f4d6cd73a0a8eac5b438b82984457068a9551d1 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index df65aebcff0..7dd2125e70a 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -318,6 +318,7 @@ bool QWindowsPipeReader::waitForPipeClosed(int msecs) QElapsedTimer stopWatch; stopWatch.start(); forever { + waitForReadyRead(0); checkPipeState(); if (pipeBroken) return true; From 5ad594a061f5494295b8e4cde73d4e5a7da7491d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 1 Apr 2014 18:15:18 +0200 Subject: [PATCH 067/180] QMacNativeWidget: Fix background rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The widget's background is transparent, but Qt is not owning the backing store in this case, so we must make sure it gets properly cleared and flushed. Task-number: QTBUG-19840 Change-Id: I1087ce80aae3620d64a8c180129d79b5b022750b Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig --- src/widgets/widgets/qmacnativewidget_mac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/widgets/qmacnativewidget_mac.mm b/src/widgets/widgets/qmacnativewidget_mac.mm index 66a1ed7ce7d..d3f3515b047 100644 --- a/src/widgets/widgets/qmacnativewidget_mac.mm +++ b/src/widgets/widgets/qmacnativewidget_mac.mm @@ -128,6 +128,7 @@ QMacNativeWidget pretends it is a window (i.e. isWindow() will return true), setAttribute(Qt::WA_SetPalette, false); setAttribute(Qt::WA_LayoutUsesWidgetRect); setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_NoSystemBackground, false); } /*! From 454dc332b3856c1726683595575c34281650a469 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 1 Apr 2014 18:26:19 +0200 Subject: [PATCH 068/180] QPA: Adding API to support QWidgetAction on Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Includes the Cocoa implementation. Task-number: QTBUG-19840 Change-Id: Id33bc8053b82116cf76ed591b6df823df3aef9bc Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qplatformmenu.h | 5 +++++ src/plugins/platforms/cocoa/qcocoamenu.h | 1 + src/plugins/platforms/cocoa/qcocoamenu.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoamenuitem.h | 4 ++++ src/plugins/platforms/cocoa/qcocoamenuitem.mm | 15 +++++++++++++++ 5 files changed, 30 insertions(+) diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index 19e2d9bccfe..b88f2a7e847 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -86,6 +86,9 @@ Q_OBJECT virtual void setChecked(bool isChecked) = 0; virtual void setShortcut(const QKeySequence& shortcut) = 0; virtual void setEnabled(bool enabled) = 0; + + virtual void setNativeContents(WId item) { Q_UNUSED(item); } + Q_SIGNALS: void activated(); void hovered(); @@ -118,6 +121,8 @@ Q_OBJECT setVisible(true); } + virtual void dismiss() { } // Closes this and all its related menu popups + virtual QPlatformMenuItem *menuItemAt(int position) const = 0; virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 59fda96dff3..3ee1dab84d8 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -68,6 +68,7 @@ class QCocoaMenu : public QPlatformMenu void setEnabled(bool enabled); void setVisible(bool visible); void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item); + void dismiss(); void syncSeparatorsCollapsible(bool enable); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 6acc062eb9c..44bc3b8f690 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -490,6 +490,11 @@ - (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteg [(QNSView *)view resetMouseButtons]; } +void QCocoaMenu::dismiss() +{ + [m_nativeMenu cancelTracking]; +} + QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const { if (0 <= position && position < m_menuItems.count()) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 61706c19bc0..1efc9f9bfd7 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -57,6 +57,7 @@ QT_FORWARD_DECLARE_OBJC_CLASS(NSMenuItem); QT_FORWARD_DECLARE_OBJC_CLASS(NSMenu); QT_FORWARD_DECLARE_OBJC_CLASS(NSObject); +QT_FORWARD_DECLARE_OBJC_CLASS(NSView); QT_BEGIN_NAMESPACE @@ -86,6 +87,8 @@ class QCocoaMenuItem : public QPlatformMenuItem void setChecked(bool isChecked); void setEnabled(bool isEnabled); + void setNativeContents(WId item); + inline QString text() const { return m_text; } inline NSMenuItem * nsItem() { return m_native; } NSMenuItem *sync(); @@ -105,6 +108,7 @@ class QCocoaMenuItem : public QPlatformMenuItem QKeySequence mergeAccel(); NSMenuItem *m_native; + NSView *m_itemView; QString m_text; bool m_textSynced; QIcon m_icon; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 58fe07bc628..99d26034bf6 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -91,6 +91,7 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) QCocoaMenuItem::QCocoaMenuItem() : m_native(NULL), + m_itemView(nil), m_textSynced(false), m_menu(NULL), m_isVisible(true), @@ -110,6 +111,8 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) } else { [m_native release]; } + + [m_itemView release]; } void QCocoaMenuItem::setText(const QString &text) @@ -178,6 +181,17 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) m_enabled = enabled; } +void QCocoaMenuItem::setNativeContents(WId item) +{ + NSView *itemView = (NSView *)item; + [m_itemView release]; + m_itemView = [itemView retain]; + [m_itemView setAutoresizesSubviews:YES]; + [m_itemView setAutoresizingMask:NSViewWidthSizable]; + [m_itemView setHidden:NO]; + [m_itemView setNeedsDisplay:YES]; +} + NSMenuItem *QCocoaMenuItem::sync() { if (m_isSeparator != [m_native isSeparatorItem]) { @@ -281,6 +295,7 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) [m_native setHidden: !m_isVisible]; [m_native setEnabled: m_enabled]; + [m_native setView:m_itemView]; QString text = mergeText(); QKeySequence accel = mergeAccel(); From dcfd36c2686bcbd56b6a0295640e228f76d7bf1d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 19:35:17 +0200 Subject: [PATCH 069/180] Revert "Automatically link printsupport plugins to static applications." It has been fully obsoleted by 4255ba40ab073afcf2a095b135883612859af4c2. This reverts commit 99eecab83d4a4c79979aa0b1fcf1f58c14dcf526. Change-Id: Id7b8d3bba27ff43e38e4fe32a4f2950de9ced493 Reviewed-by: Friedemann Kleint Reviewed-by: John Layt --- configure | 13 ------------- mkspecs/features/qt.prf | 2 -- src/printsupport/printsupport.pro | 1 - tools/configure/configureapp.cpp | 14 +++----------- tools/configure/configureapp.h | 1 - 5 files changed, 3 insertions(+), 28 deletions(-) diff --git a/configure b/configure index a1b006b4ea8..1b839c1456d 100755 --- a/configure +++ b/configure @@ -781,8 +781,6 @@ QT_LIBS_GLIB= # default qpa platform QT_QPA_DEFAULT_PLATFORM= -# default print support plugin -QT_PRINTSUPPORT_DEFAULT_PLUGIN= # Android vars CFG_DEFAULT_ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT @@ -5181,15 +5179,6 @@ if [ -z "$QT_QPA_DEFAULT_PLATFORM" ]; then fi fi -# Determine print support plugin belonging to the default QPA platform -if [ "$QT_QPA_DEFAULT_PLATFORM" = "cocoa" ]; then - QT_PRINTSUPPORT_DEFAULT_PLUGIN=cocoaprintersupport -elif [ "$QT_QPA_DEFAULT_PLATFORM" = "windows" ]; then - QT_PRINTSUPPORT_DEFAULT_PLUGIN=windowsprintersupport -elif [ "$QT_QPA_DEFAULT_PLATFORM" = "xcb" ]; then - QT_PRINTSUPPORT_DEFAULT_PLUGIN=cupsprintersupport -fi - if [ -n "$QMAKE_CFLAGS_XCB" ] || [ -n "$QMAKE_LIBS_XCB" ]; then QMakeVar set QMAKE_CFLAGS_XCB "$QMAKE_CFLAGS_XCB" QMakeVar set QMAKE_LIBS_XCB "$QMAKE_LIBS_XCB" @@ -6149,7 +6138,6 @@ EOF fi echo "#define QT_QPA_DEFAULT_PLATFORM_NAME \"$QT_QPA_DEFAULT_PLATFORM\"" >>"$outpath/src/corelib/global/qconfig.h.new" -echo "#define QT_QPA_DEFAULT_PRINTSUPPORTPLUGIN_NAME \"QT_PRINTSUPPORT_DEFAULT_PLUGIN\"" >>"$outpath/src/corelib/global/qconfig.h.new" # avoid unecessary rebuilds by copying only if qconfig.h has changed if cmp -s "$outpath/src/corelib/global/qconfig.h" "$outpath/src/corelib/global/qconfig.h.new"; then @@ -6219,7 +6207,6 @@ EOF if [ "$CFG_SHARED" = "no" ]; then echo "QT_DEFAULT_QPA_PLUGIN = q$QT_QPA_DEFAULT_PLATFORM" >> "$QTCONFIG.tmp" - echo "QT_DEFAULT_PRINTSUPPORTPLUGIN = $QT_PRINTSUPPORT_DEFAULT_PLUGIN" >> "$QTCONFIG.tmp" echo >> "$QTCONFIG.tmp" fi diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 5968a8a4ffa..418b124a85a 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -204,8 +204,6 @@ contains(QT_CONFIG, static) { else: \ QTPLUGIN += $$QT_DEFAULT_QPA_PLUGIN } - needs_printsupport_plugin: \ - QTPLUGIN += $$QT_DEFAULT_PRINTSUPPORTPLUGIN import_plugins:!isEmpty(QTPLUGIN) { IMPORT_FILE_CONT = \ "// This file is autogenerated by qmake. It imports static plugin classes for" \ diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro index b32ba91c074..6dd3eaab3c0 100644 --- a/src/printsupport/printsupport.pro +++ b/src/printsupport/printsupport.pro @@ -1,7 +1,6 @@ TARGET = QtPrintSupport QT = core-private gui-private widgets-private -MODULE_CONFIG = needs_printsupport_plugin DEFINES += QT_NO_USING_NAMESPACE MODULE_PLUGIN_TYPES = \ diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index d149511218e..fe2caa2efa1 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3372,10 +3372,8 @@ void Configure::generateQConfigPri() if (!dictionary["QT_NAMESPACE"].isEmpty()) configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl; - if (dictionary[ "SHARED" ] == "no") { - configStream << "QT_DEFAULT_QPA_PLUGIN = q" << qpaPlatformName() << endl - << "QT_DEFAULT_PRINTSUPPORTPLUGIN = " << qpaPrintSupportPluginName() << endl; - } + if (dictionary[ "SHARED" ] == "no") + configStream << "QT_DEFAULT_QPA_PLUGIN = q" << qpaPlatformName() << endl; if (!configStream.flush()) dictionary[ "DONE" ] = "error"; @@ -3548,8 +3546,7 @@ void Configure::generateConfigfiles() for (int i = 0; i < qconfigList.count(); ++i) tmpStream << addDefine(qconfigList.at(i)); - tmpStream << "#define QT_QPA_DEFAULT_PLATFORM_NAME \"" << qpaPlatformName() << "\"" << endl - << "#define QT_QPA_DEFAULT_PRINTSUPPORTPLUGIN_NAME \"" << qpaPrintSupportPluginName() << "\"" << endl; + tmpStream<<"#define QT_QPA_DEFAULT_PLATFORM_NAME \"" << qpaPlatformName() << "\""< Date: Thu, 3 Apr 2014 09:47:32 +0200 Subject: [PATCH 070/180] Android input method fix Let textBeforeCursor return the text immediately before the cursor, and not the text at the beginning of the paragraph, even if that is also technically before the cursor. (Apparently I do not know the difference between left and right.) Change-Id: I6043ebe53838e68880b6407dbb9e5370bc785c1b Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidinputcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 12005d8fce6..02fda19d760 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -690,7 +690,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/) { QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length)); if (textBefore.isValid()) { - return textBefore.toString().left(length) + m_composingText; + return textBefore.toString().right(length) + m_composingText; } //compatibility code for old controls that do not implement the new API From 4e4b2d67010f1fc90a0227c36adab56a3e1ce679 Mon Sep 17 00:00:00 2001 From: John Layt Date: Wed, 16 Apr 2014 15:47:14 +0100 Subject: [PATCH 071/180] QPrintDialog - Fix mac change of printer name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the user changes the printer name in the Mac print dialog then update the print device in QPrint to reflect this. Task-number: QTBUG-37808 Change-Id: I3aaf27e2db7277ab083dc8f8d59f0f80ecd424f1 Reviewed-by: Morten Johan Sørvig --- src/printsupport/dialogs/qprintdialog_mac.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index 9ff7c4766a1..33a11cc0793 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -143,11 +143,11 @@ - (void)printPanelDidEnd:(NSPrintPanel *)printPanel CFURLGetFileSystemRepresentation(file, true, localFile, sizeof(localFile)); printer->setOutputFileName(QString::fromUtf8(reinterpret_cast(localFile))); } else { - // Keep output format. - QPrinter::OutputFormat format; - format = printer->outputFormat(); - printer->setOutputFileName(QString()); - printer->setOutputFormat(format); + PMPrinter macPrinter; + PMSessionGetCurrentPrinter(session, &macPrinter); + QString printerId = QString::fromCFString(PMPrinterGetID(macPrinter)); + if (printer->printerName() != printerId) + printer->setPrinterName(printerId); } } From 13e3f269fd0cbebaded595416fc8fe907fbdc730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 16 Apr 2014 22:09:36 +0200 Subject: [PATCH 072/180] QPrintDialog - Fix Mac reference counting error. "key" is accessed with a "Get" function and should not be released. Switch from using QCFString to a CFStringsRef. Change-Id: Id4eecc642de8698314fc57d44af05c202966b11c Reviewed-by: Jake Petroules Reviewed-by: John Layt --- src/printsupport/dialogs/qprintdialog_mac.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index 33a11cc0793..ef3e88be398 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -160,13 +160,13 @@ - (void)printPanelDidEnd:(NSPrintPanel *)printPanel PMOrientation orientation; PMGetOrientation(pageFormat, &orientation); QPageSize pageSize; - QCFString key; + CFStringRef key; double width = 0; double height = 0; // If the PPD name is empty then is custom, for some reason PMPaperIsCustom doesn't work here PMPaperGetPPDPaperName(paper, &key); if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) { - QString ppdKey = key; + QString ppdKey = QString::fromCFString(key); if (ppdKey.isEmpty()) { // Is using a custom page size as defined in the Print Dialog custom settings using mm or inches. // We can't ask PMPaper what those units actually are, we can only get the point size which may return @@ -185,7 +185,7 @@ - (void)printPanelDidEnd:(NSPrintPanel *)printPanel pageSize = QPageSize(QSizeF(w / 100.0, h / 100.0), QPageSize::Inch); } } else { - pageSize = QPlatformPrintDevice::createPageSize(key, QSize(width, height), QString()); + pageSize = QPlatformPrintDevice::createPageSize(ppdKey, QSize(width, height), QString()); } } if (pageSize.isValid() && !pageSize.isEquivalentTo(printer->pageLayout().pageSize())) From c7bd85e97df1b188bcbd4a2a511313d221c5bb83 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 1 Apr 2014 18:18:17 +0200 Subject: [PATCH 073/180] Cocoa: NSMenu views never get viewDidUnhide called MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the case for QWidgets added as native menu items with QWidgetAction. According to Cocoa's documentation [1], we should rely on -[QNSView viewDidMoveToWindow] instead. On 10.9 however, we receive NSWindowDidChangeOcclusionStateNotification from the NSMenu window, which is preferable to using -[QNSView viewDidMoveToWindow] as it guarantees the view is actually visible. We do runtime symbol lookup to get this to work on 10.9 regardless of the build SDK version. [1] https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/MenuList/Articles/ViewsInMenuItems.html Task-number: QTBUG-19840 Change-Id: If4676df5d79c359965f09ef2e5eddf4c925e3533 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 0b9683a3efb..e2572d607a2 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -42,6 +42,7 @@ #include #include +#include #include "qnsview.h" #include "qcocoawindow.h" @@ -65,6 +66,9 @@ static QTouchDevice *touchDevice = 0; +// ### HACK Remove once 10.8 is unsupported +static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; + @interface NSEvent (Qt_Compile_Leopard_DeviceDelta) - (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaY; @@ -73,6 +77,13 @@ - (CGFloat)deviceDeltaZ; @implementation QNSView ++ (void)initialize +{ + NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification"); + if (notificationNameVar) + _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar; +} + - (id) init { self = [super initWithFrame : NSMakeRect(0,0, 300,300)]; @@ -192,6 +203,19 @@ - (void)viewDidMoveToSuperview } } +- (void)viewDidMoveToWindow +{ + if (self.window) { + // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu. + // 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification + if (!_q_NSWindowDidChangeOcclusionStateNotification + && [self.window.className isEqualToString:@"NSCarbonMenuWindow"]) + m_platformWindow->exposeWindow(); + } else { + m_platformWindow->obscureWindow(); + } +} + - (void)viewWillMoveToWindow:(NSWindow *)newWindow { // ### Merge "normal" window code path with this one for 5.1. @@ -325,6 +349,23 @@ - (void)windowNotification : (NSNotification *) windowNotification m_platformWindow->obscureWindow(); } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) { m_platformWindow->exposeWindow(); + } else if (_q_NSWindowDidChangeOcclusionStateNotification + && [notificationName isEqualToString:_q_NSWindowDidChangeOcclusionStateNotification]) { +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 +// ### HACK Remove the enum declaration, the warning disabling and the cast further down once 10.8 is unsupported +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-method-access" + enum { NSWindowOcclusionStateVisible = 1UL << 1 }; +#endif + // Older versions managed in -[QNSView viewDidMoveToWindow]. + // Support QWidgetAction in NSMenu. Mavericks only sends this notification. + // Ideally we should support this in Qt as well, in order to disable animations + // when the window is occluded. + if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) + m_platformWindow->exposeWindow(); +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 +#pragma clang diagnostic pop +#endif } else if (notificationName == NSWindowDidChangeScreenNotification) { if (m_window) { NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen]; From 4a28205bed4e94391464e21d3af68e03dc6aec09 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Fri, 18 Apr 2014 11:21:20 +0100 Subject: [PATCH 074/180] Fix copy-paste error. Fix copy-paste error identified by static analysis at http://www.viva64.com/en/b/0251/ Change-Id: I2e454c2e7535924dd533c0ceb4fd2283a8f9862f Reviewed-by: Daniel Molkentin --- src/xml/sax/qxml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 4b434822b8a..9d91ce42a54 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -3247,7 +3247,7 @@ void QXmlSimpleReader::setFeature(const QString& name, bool enable) || name == QLatin1String("http://qt-project.org/xml/features/report-whitespace-only-CharData")) { d->reportWhitespaceCharData = enable; } else if (name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity") // For compat with Qt 4 - || name == QLatin1String("http://trolltech.com/xml/features/report-start-end-entity")) { + || name == QLatin1String("http://qt-project.org/xml/features/report-start-end-entity")) { d->reportEntities = enable; } else { qWarning("Unknown feature %s", name.toLatin1().data()); From 22bb244d6dcd8dfcdf8c99864b42aad0246bce38 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Fri, 18 Apr 2014 11:18:14 +0100 Subject: [PATCH 075/180] Fix copy-paste error. Fix copy-paste error identified by static analysis at http://www.viva64.com/en/b/0251/ Change-Id: I214d6bf8494a946a6c772b6dca1395e4140a471f Reviewed-by: Daniel Molkentin Reviewed-by: Konstantin Ritt --- src/plugins/platforms/windows/qwindowsfontengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 4f3a007bd70..29c43fc7a55 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -1032,7 +1032,7 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, int iw = gm.width.toInt(); int ih = gm.height.toInt(); - if (iw <= 0 || iw <= 0) + if (iw <= 0 || ih <= 0) return 0; bool has_transformation = t.type() > QTransform::TxTranslate; From 207598fd8e69be34e8ba2c9db7720cb6003ea114 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Fri, 18 Apr 2014 11:14:19 +0100 Subject: [PATCH 076/180] Fix copy-paste error. Fix an error identified by static analysis from http://www.viva64.com/en/b/0251/ Change-Id: I3b69f8eb8c9e10772d5ca2afad75582e8a54beb7 Reviewed-by: Daniel Molkentin Reviewed-by: Konstantin Ritt --- 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 f66859b72a3..af7713ba6f5 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -213,7 +213,7 @@ bool QWindowsUser32DLL::initTouch() unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); - return registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && getTouchInputInfo; + return registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; } /*! From 078c71ac8f0c74e06e0d81ea1a5a44126abc27b6 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 22 Apr 2014 12:43:28 +0300 Subject: [PATCH 077/180] WinRT: Fix TCP socket reads All read calls are now pulled from an intermediate buffer which is populated from the asynchronous callback (this was a TODO previously, and was breaking downloads of large requests). As a side-benefit, the use of only async callbacks ensures fewer first-chance exceptions appear in the debug output. Task-number: QTBUG-30196 Change-Id: I5653742d8d94934a4b4a4227298865d20518bc4c Reviewed-by: Oliver Wolff --- .../socket/qnativesocketengine_winrt.cpp | 319 +++++++++++------- .../socket/qnativesocketengine_winrt_p.h | 18 +- 2 files changed, 215 insertions(+), 122 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 4b2d1c372ee..db1d3dc96b6 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -74,6 +74,7 @@ typedef ITypedEventHandler DatagramReceivedHandler; typedef IAsyncOperationWithProgressCompletedHandler SocketReadCompletedHandler; typedef IAsyncOperationWithProgressCompletedHandler SocketWriteCompletedHandler; +typedef IAsyncOperationWithProgress IAsyncBufferOperation; QT_BEGIN_NAMESPACE @@ -130,6 +131,8 @@ QString qt_QStringFromHSTRING(HSTRING string) return QString::fromWCharArray(rawString, length); } +#define READ_BUFFER_SIZE 8192 + class ByteArrayBuffer : public Microsoft::WRL::RuntimeClass, IBuffer, Windows::Storage::Streams::IBufferByteAccess> { @@ -167,16 +170,6 @@ class ByteArrayBuffer : public Microsoft::WRL::RuntimeClass inputStream() const { return m_stream; @@ -190,13 +183,33 @@ class ByteArrayBuffer : public Microsoft::WRL::RuntimeClass m_engine; ComPtr m_stream; }; +template +static AsyncStatus opStatus(const ComPtr &op) +{ + ComPtr info; + HRESULT hr = op.As(&info); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to cast op to IAsyncInfo."); + return Error; + } + AsyncStatus status; + hr = info->get_Status(&status); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get AsyncStatus."); + return Error; + } + return status; +} + QNativeSocketEngine::QNativeSocketEngine(QObject *parent) : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent) { + connect(this, SIGNAL(connectionReady()), SLOT(connectionNotification()), Qt::QueuedConnection); + connect(this, SIGNAL(readReady()), SLOT(readNotification()), Qt::QueuedConnection); + connect(this, SIGNAL(writeReady()), SLOT(writeNotification()), Qt::QueuedConnection); } QNativeSocketEngine::~QNativeSocketEngine() @@ -230,7 +243,7 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket:: // Currently, only TCP sockets are initialized this way. SocketHandler *handler = gSocketHandler(); - d->tcp = handler->pendingTcpSockets.value(socketDescriptor, Q_NULLPTR); + d->tcp = handler->pendingTcpSockets.take(socketDescriptor); d->socketType = QAbstractSocket::TcpSocket; if (!d->tcp || !d->fetchConnectionParameters()) @@ -271,23 +284,33 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) return false; } + ComPtr op; const QString portString = QString::number(port); HStringReference portReference(reinterpret_cast(portString.utf16())); - ComPtr action; HRESULT hr = E_FAIL; if (d->socketType == QAbstractSocket::TcpSocket) - hr = d->tcp->ConnectAsync(remoteHost.Get(), portReference.Get(), &action); + hr = d->tcp->ConnectAsync(remoteHost.Get(), portReference.Get(), &op); else if (d->socketType == QAbstractSocket::UdpSocket) - hr = d->udp->ConnectAsync(remoteHost.Get(), portReference.Get(), &action); + hr = d->udp->ConnectAsync(remoteHost.Get(), portReference.Get(), &op); if (FAILED(hr)) { qWarning("QNativeSocketEnginePrivate::nativeConnect:: Could not obtain connect action"); return false; } - action->put_Completed(Callback(&QNativeSocketEnginePrivate::interruptEventDispatcher).Get()); - hr = action->GetResults(); - while ((hr = action->GetResults()) == E_ILLEGAL_METHOD_CALL) - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); + hr = op->put_Completed(Callback( + d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Unable to set host connection callback."); + return false; + } + d->socketState = QAbstractSocket::ConnectingState; + while (opStatus(op) == Started) + d->eventLoop.processEvents(); + + AsyncStatus status = opStatus(op); + if (status == Error || status == Canceled) + return false; + if (hr == 0x8007274c) { // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. d->setError(QAbstractSocket::NetworkError, d->ConnectionTimeOutErrorString); d->socketState = QAbstractSocket::UnconnectedState; @@ -305,24 +328,21 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) } if (d->socketType == QAbstractSocket::TcpSocket) { - UINT32 capacity; - hr = d->inputBuffer->get_Capacity(&capacity); - if (FAILED(hr)) - return false; IInputStream *stream; hr = d->tcp->get_InputStream(&stream); if (FAILED(hr)) return false; - ByteArrayBuffer *buffer = static_cast(d->inputBuffer.Get()); - buffer->setEngine(this); + ByteArrayBuffer *buffer = static_cast(d->readBuffer.Get()); buffer->setInputStream(stream); - ComPtr> op; - hr = stream->ReadAsync(buffer, capacity, InputStreamOptions_Partial, &op); + ComPtr op; + hr = stream->ReadAsync(buffer, READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); if (FAILED(hr)) return false; - hr = op->put_Completed(Callback(&QNativeSocketEnginePrivate::handleReadyRead).Get()); - if (FAILED(hr)) + hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to set socket read callback."); return false; + } } d->socketState = QAbstractSocket::ConnectedState; return true; @@ -358,21 +378,35 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) d->tcpListener->add_ConnectionReceived(Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &token); hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); if (FAILED(hr)) { - qWarning("Unable to bind"); // ### Set error message + qErrnoWarning(hr, "Unable to bind socket."); // ### Set error message return false; } } else if (d->socketType == QAbstractSocket::UdpSocket) { hr = d->udp->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); if (FAILED(hr)) { - qWarning("unable to bind"); // ### Set error message + qErrnoWarning(hr, "Unable to bind socket."); // ### Set error message + return false; + } + hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Unable to set bind callback."); return false; } } if (op) { - // Wait for connection to enter bound state - TODO: timeout, check result - while ((hr = op->GetResults()) == E_ILLEGAL_METHOD_CALL) - QCoreApplication::processEvents(); + while (opStatus(op) == Started) + d->eventLoop.processEvents(); + + AsyncStatus status = opStatus(op); + if (status == Error || status == Canceled) + return false; + + hr = op->GetResults(); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to bind socket"); + return false; + } d->socketState = QAbstractSocket::BoundState; d->fetchConnectionParameters(); @@ -410,17 +444,22 @@ int QNativeSocketEngine::accept() if (d->socketType == QAbstractSocket::TcpSocket) { IStreamSocket *socket = d->pendingConnections.takeFirst(); - UINT32 capacity; - d->inputBuffer->get_Capacity(&capacity); IInputStream *stream; socket->get_InputStream(&stream); // TODO: delete buffer and stream on socket close - ByteArrayBuffer *buffer = static_cast(d->inputBuffer.Get()); - buffer->setEngine(this); + ByteArrayBuffer *buffer = static_cast(d->readBuffer.Get()); buffer->setInputStream(stream); - ComPtr> op; - stream->ReadAsync(buffer, capacity, InputStreamOptions_Partial, &op); - op->put_Completed(Callback(&QNativeSocketEnginePrivate::handleReadyRead).Get()); + ComPtr op; + HRESULT hr = stream->ReadAsync(buffer, READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); + if (FAILED(hr)) { + qErrnoWarning(hr, "Faild to read from the socket buffer."); + return -1; + } + hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to set socket read callback."); + return -1; + } d->currentConnections.append(socket); SocketHandler *handler = gSocketHandler(); @@ -445,7 +484,6 @@ void QNativeSocketEngine::close() d->closingDown = true; socket->Close(); socket->Release(); - closeNotification(); d->socketDescriptor = -1; } d->socketDescriptor = -1; @@ -493,13 +531,7 @@ qint64 QNativeSocketEngine::bytesAvailable() const if (d->socketType != QAbstractSocket::TcpSocket) return -1; - if (d->inputBuffer) { - UINT32 len; - d->inputBuffer->get_Length(&len); - return len; - } - - return -1; + return d->readBytes.size() - d->readBytes.pos(); } qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) @@ -508,54 +540,56 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) if (d->socketType != QAbstractSocket::TcpSocket) return -1; - ComPtr dataReaderStatics; - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(), &dataReaderStatics); - ComPtr reader; - - dataReaderStatics->FromBuffer(d->inputBuffer.Get(), &reader); - - UINT32 bufferCapacity; - d->inputBuffer->get_Capacity(&bufferCapacity); - qint64 lengthToRead = maxlen < bufferCapacity ? maxlen : bufferCapacity; - - UINT32 bufferLength; - d->inputBuffer->get_Length(&bufferLength); - - lengthToRead = bufferLength < lengthToRead ? bufferLength : lengthToRead; - reader->ReadBytes(lengthToRead, (unsigned char*)data); - return lengthToRead; + QMutexLocker mutexLocker(&d->readMutex); + return d->readBytes.read(data, maxlen); } -template -static qint64 nativeWrite(T *socket, const char *data, qint64 len) +qint64 QNativeSocketEngine::write(const char *data, qint64 len) { + Q_D(QNativeSocketEngine); + HRESULT hr = E_FAIL; ComPtr stream; - HRESULT hr = socket->get_OutputStream(&stream); - if (FAILED(hr)) + if (d->socketType == QAbstractSocket::TcpSocket) + hr = d->tcp->get_OutputStream(&stream); + else if (d->socketType == QAbstractSocket::UdpSocket) + hr = d->udp->get_OutputStream(&stream); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get output stream to socket."); return -1; + } + ComPtr buffer = Make(data, len); ComPtr> op; hr = stream->WriteAsync(buffer.Get(), &op); - if (FAILED(hr)) + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to write to socket."); + return -1; + } + hr = op->put_Completed(Callback>( + d, &QNativeSocketEnginePrivate::handleWriteCompleted).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to set socket write callback."); return -1; + } + + while (opStatus(op) == Started) + d->eventLoop.processEvents(); + + AsyncStatus status = opStatus(op); + if (status == Error || status == Canceled) + return -1; + UINT32 bytesWritten; - while ((hr = op->GetResults(&bytesWritten)) == E_ILLEGAL_METHOD_CALL) - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); - return bytesWritten; -} + hr = op->GetResults(&bytesWritten); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get written socket length."); + return -1; + } -qint64 QNativeSocketEngine::write(const char *data, qint64 len) -{ - Q_D(QNativeSocketEngine); - qint64 bytesWritten = -1; - if (d->socketType == QAbstractSocket::TcpSocket) - bytesWritten = nativeWrite(d->tcp, data, len); - else if (d->socketType == QAbstractSocket::UdpSocket) - bytesWritten = nativeWrite(d->udp, data, len); - if (bytesWritten != -1 && d->notifyOnWrite) - writeNotification(); - return bytesWritten; + if (bytesWritten && d->notifyOnWrite) + emit writeReady(); + return bytesWritten; } qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr, quint16 *port) @@ -698,7 +732,7 @@ bool QNativeSocketEngine::setOption(QAbstractSocketEngine::SocketOption option, bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut) { - Q_D(const QNativeSocketEngine); + Q_D(QNativeSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForRead(), false); Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForRead(), QAbstractSocket::UnconnectedState, false); @@ -714,14 +748,12 @@ bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut) return true; // If we are a client, we are ready to read if our buffer has data - UINT32 length; - if (FAILED(d->inputBuffer->get_Length(&length))) - return false; - if (length) + QMutexLocker locker(&d->readMutex); + if (!d->readBytes.atEnd()) return true; // Nothing to do, wait for more events - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::WaitForMoreEvents); + d->eventLoop.processEvents(); } d->setError(QAbstractSocket::SocketTimeoutError, @@ -832,8 +864,8 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() , closingDown(false) , socketDescriptor(-1) { - ComPtr buffer = Make(8192); - inputBuffer = buffer; + ComPtr buffer = Make(READ_BUFFER_SIZE); + readBuffer = buffer; } QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate() @@ -1119,6 +1151,11 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() return true; } +HRESULT QNativeSocketEnginePrivate::handleBindCompleted(IAsyncAction *, AsyncStatus) +{ + return S_OK; +} + HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener *listener, IStreamSocketListenerConnectionReceivedEventArgs *args) { Q_Q(QNativeSocketEngine); @@ -1126,47 +1163,91 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener IStreamSocket *socket; args->get_Socket(&socket); pendingConnections.append(socket); - q->connectionNotification(); - q->readNotification(); - return interruptEventDispatcher(0, Completed); + emit q->connectionReady(); + emit q->readReady(); + return S_OK; } -HRESULT QNativeSocketEnginePrivate::interruptEventDispatcher(IAsyncAction *, AsyncStatus) +HRESULT QNativeSocketEnginePrivate::handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus) { - if (QThread *thread = QThread::currentThread()) { - if (QAbstractEventDispatcher *dispatcher = thread->eventDispatcher()) - dispatcher->interrupt(); - } return S_OK; } -HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncOperationWithProgress *asyncInfo, AsyncStatus) +HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) { + Q_Q(QNativeSocketEngine); + if (wasDeleted || isDeletingChildren) + return S_OK; + + if (status == Error || status == Canceled) + return S_OK; + ByteArrayBuffer *buffer = 0; HRESULT hr = asyncInfo->GetResults((IBuffer **)&buffer); - if (FAILED(hr)) - return hr; + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get ready read results."); + return S_OK; + } UINT32 len; buffer->get_Length(&len); - QNativeSocketEngine *q = buffer->engine(); - if (!q) + if (!len) { + if (q->isReadNotificationEnabled()) + emit q->readReady(); + return S_OK; + } + + byte *data; + buffer->Buffer(&data); + + readMutex.lock(); + if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset + readBytes.close(); + if (!readBytes.isOpen()) + readBytes.open(QBuffer::ReadWrite|QBuffer::Truncate); + qint64 readPos = readBytes.pos(); + readBytes.seek(readBytes.size()); + Q_ASSERT(readBytes.atEnd()); + readBytes.write(reinterpret_cast(data), qint64(len)); + readBytes.seek(readPos); + readMutex.unlock(); + + if (q->isReadNotificationEnabled()) + emit q->readReady(); + + ComPtr op; + hr = buffer->inputStream()->ReadAsync(buffer, READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); + if (FAILED(hr)) { + qErrnoWarning(hr, "Could not read into socket stream buffer."); return S_OK; - if (len > 0 && q->isReadNotificationEnabled()) { - q->readNotification(); } + hr = op->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to set socket read callback."); + return S_OK; + } + return S_OK; +} - // Continue reading ### TODO: read into offset!!! - UINT32 capacity; - buffer->get_Capacity(&capacity); - ComPtr> op; - if (SUCCEEDED(buffer->inputStream()->ReadAsync(buffer, capacity, InputStreamOptions_Partial, &op))) { - if (q) - return op->put_Completed(Callback(&QNativeSocketEnginePrivate::handleReadyRead).Get()); - else - return op->put_Completed(nullptr); +HRESULT QNativeSocketEnginePrivate::handleWriteCompleted(IAsyncOperationWithProgress *op, AsyncStatus status) +{ + if (status == Error) { + ComPtr info; + HRESULT hr = op->QueryInterface(IID_PPV_ARGS(&info)); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to cast operation."); + return S_OK; + } + HRESULT errorCode; + hr = info->get_ErrorCode(&errorCode); + if (FAILED(hr)) { + qErrnoWarning(hr, "Failed to get error code."); + return S_OK; + } + qErrnoWarning(errorCode, "A socket error occurred."); + return S_OK; } - return E_FAIL; + return S_OK; } HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args) @@ -1174,7 +1255,7 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I Q_Q(QNativeSocketEngine); Q_ASSERT(udp == socket); pendingDatagrams.append(args); - q->readNotification(); + emit q->readReady(); return S_OK; } diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index b5be5fa8302..ec2e1b3ad4f 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -52,6 +52,8 @@ // // We mean it. // +#include +#include #include "QtNetwork/qhostaddress.h" #include "private/qabstractsocketengine_p.h" #include @@ -127,6 +129,11 @@ class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine bool isExceptionNotificationEnabled() const; void setExceptionNotificationEnabled(bool enable); +signals: + void connectionReady(); + void readReady(); + void writeReady(); + private: Q_DECLARE_PRIVATE(QNativeSocketEngine) Q_DISABLE_COPY(QNativeSocketEngine) @@ -191,17 +198,22 @@ class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate ABI::Windows::Networking::Sockets::IDatagramSocket *udp; }; Microsoft::WRL::ComPtr tcpListener; - Microsoft::WRL::ComPtr inputBuffer; + Microsoft::WRL::ComPtr readBuffer; + QBuffer readBytes; + QMutex readMutex; QList pendingDatagrams; QList pendingConnections; QList currentConnections; + QEventLoop eventLoop; + HRESULT handleBindCompleted(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); HRESULT handleNewDatagram(ABI::Windows::Networking::Sockets::IDatagramSocket *socket, ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args); HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); - static HRESULT interruptEventDispatcher(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); - static HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus); + HRESULT handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); + HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus); + HRESULT handleWriteCompleted(ABI::Windows::Foundation::IAsyncOperationWithProgress *, ABI::Windows::Foundation::AsyncStatus); }; QT_END_NAMESPACE From 878da15f2cfadf249a355b33d31f7937078ea174 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 22 Apr 2014 09:14:39 +0300 Subject: [PATCH 078/180] ANGLE WinRT: Call Trim() when application suspends This is required by Windows Store Apps to pass certification. Task-number: QTBUG-38481 Change-Id: I6dc00431ee5f6c7d4c64111ccc38f46483d3b9a8 Reviewed-by: Friedemann Kleint Reviewed-by: Maurice Kalinowski --- .../libGLESv2/renderer/d3d11/Renderer11.cpp | 47 +++++++ .../src/libGLESv2/renderer/d3d11/Renderer11.h | 15 +++ ...-Call-Trim-when-application-suspends.patch | 118 ++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 src/angle/patches/0016-ANGLE-WinRT-Call-Trim-when-application-suspends.patch diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp index 2de477b3bce..e70727c65e8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp @@ -40,6 +40,13 @@ #include "libEGL/Display.h" +#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) +# include +# include +# include +typedef ABI::Windows::Foundation::IEventHandler SuspendEventHandler; +#endif + #ifdef _DEBUG // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples // and conformance tests. to enable all warnings, remove this define. @@ -426,9 +433,49 @@ EGLint Renderer11::initialize() } } +#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) + // Monitor when the application suspends so that Trim() can be called + Microsoft::WRL::ComPtr application; + result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + IID_PPV_ARGS(&application)); + if (FAILED(result)) + { + ERR("Error obtaining CoreApplication: 0x%08X", result); + return EGL_NOT_INITIALIZED; + } + + EventRegistrationToken cookie; + result = application->add_Suspending(Microsoft::WRL::Callback(this, &Renderer11::onSuspend).Get(), &cookie); + if (FAILED(result)) + { + ERR("Error setting suspend callback: 0x%08X", result); + return EGL_NOT_INITIALIZED; + } +#endif + return EGL_SUCCESS; } +#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) +HRESULT Renderer11::onSuspend(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *) +{ + if (!mDevice) + return S_OK; + + Microsoft::WRL::ComPtr dxgiDevice; + HRESULT result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); + if (FAILED(result)) + { + ERR("Error obtaining DXGIDevice3 on suspend: 0x%08X", result); + return S_OK; + } + + dxgiDevice->Trim(); + + return S_OK; +} +#endif + // do any one-time device initialization // NOTE: this is also needed after a device lost/reset // to reset the scene status and ensure the default states are reset. diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h index a8a722c56c9..773fc26db1c 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h @@ -18,6 +18,17 @@ #include "libGLESv2/renderer/d3d11/InputLayoutCache.h" #include "libGLESv2/renderer/RenderTarget.h" +#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) +struct IInspectable; +namespace ABI { + namespace Windows { + namespace ApplicationModel { + struct ISuspendingEventArgs; + } + } +} +#endif + namespace gl { class Renderbuffer; @@ -202,6 +213,10 @@ class Renderer11 : public Renderer RenderTarget *drawRenderTarget, bool wholeBufferCopy); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); +#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) + HRESULT onSuspend(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); +#endif + HMODULE mD3d11Module; HMODULE mDxgiModule; diff --git a/src/angle/patches/0016-ANGLE-WinRT-Call-Trim-when-application-suspends.patch b/src/angle/patches/0016-ANGLE-WinRT-Call-Trim-when-application-suspends.patch new file mode 100644 index 00000000000..bf2a1ad3634 --- /dev/null +++ b/src/angle/patches/0016-ANGLE-WinRT-Call-Trim-when-application-suspends.patch @@ -0,0 +1,118 @@ +From 158b7642c53843ed954fa667ff23b8746f95f8eb Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Tue, 22 Apr 2014 09:13:57 +0300 +Subject: [PATCH] ANGLE WinRT: Call Trim() when application suspends + +This is required by Windows Store Apps to pass certification. + +Task-number: QTBUG-38481 +Change-Id: I6dc00431ee5f6c7d4c64111ccc38f46483d3b9a8 +--- + .../src/libGLESv2/renderer/d3d11/Renderer11.cpp | 47 ++++++++++++++++++++++ + .../src/libGLESv2/renderer/d3d11/Renderer11.h | 15 +++++++ + 2 files changed, 62 insertions(+) + +diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp +index 2de477b..e70727c 100644 +--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp +@@ -40,6 +40,13 @@ + + #include "libEGL/Display.h" + ++#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) ++# include ++# include ++# include ++typedef ABI::Windows::Foundation::IEventHandler SuspendEventHandler; ++#endif ++ + #ifdef _DEBUG + // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples + // and conformance tests. to enable all warnings, remove this define. +@@ -426,9 +433,49 @@ EGLint Renderer11::initialize() + } + } + ++#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) ++ // Monitor when the application suspends so that Trim() can be called ++ Microsoft::WRL::ComPtr application; ++ result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), ++ IID_PPV_ARGS(&application)); ++ if (FAILED(result)) ++ { ++ ERR("Error obtaining CoreApplication: 0x%08X", result); ++ return EGL_NOT_INITIALIZED; ++ } ++ ++ EventRegistrationToken cookie; ++ result = application->add_Suspending(Microsoft::WRL::Callback(this, &Renderer11::onSuspend).Get(), &cookie); ++ if (FAILED(result)) ++ { ++ ERR("Error setting suspend callback: 0x%08X", result); ++ return EGL_NOT_INITIALIZED; ++ } ++#endif ++ + return EGL_SUCCESS; + } + ++#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) ++HRESULT Renderer11::onSuspend(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *) ++{ ++ if (!mDevice) ++ return S_OK; ++ ++ Microsoft::WRL::ComPtr dxgiDevice; ++ HRESULT result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); ++ if (FAILED(result)) ++ { ++ ERR("Error obtaining DXGIDevice3 on suspend: 0x%08X", result); ++ return S_OK; ++ } ++ ++ dxgiDevice->Trim(); ++ ++ return S_OK; ++} ++#endif ++ + // do any one-time device initialization + // NOTE: this is also needed after a device lost/reset + // to reset the scene status and ensure the default states are reset. +diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h +index a8a722c..773fc26 100644 +--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h ++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h +@@ -18,6 +18,17 @@ + #include "libGLESv2/renderer/d3d11/InputLayoutCache.h" + #include "libGLESv2/renderer/RenderTarget.h" + ++#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) ++struct IInspectable; ++namespace ABI { ++ namespace Windows { ++ namespace ApplicationModel { ++ struct ISuspendingEventArgs; ++ } ++ } ++} ++#endif ++ + namespace gl + { + class Renderbuffer; +@@ -202,6 +213,10 @@ class Renderer11 : public Renderer + RenderTarget *drawRenderTarget, bool wholeBufferCopy); + ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); + ++#if defined(ANGLE_OS_WINRT) && !defined(ANGLE_OS_WINPHONE) ++ HRESULT onSuspend(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); ++#endif ++ + HMODULE mD3d11Module; + HMODULE mDxgiModule; + +-- +1.9.0.msysgit.0 + From c97edb25796487c719376dd73c365603bcd68782 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 22 Apr 2014 08:51:40 +0300 Subject: [PATCH 079/180] WinRT: Handle back button as press or release Earlier, only the back press was checked for acceptance. By also checking the release event, this makes the backstepping behavior consistent with Qt for Android, and fixes the expected behavior found in our demo applications. Task-number: QTBUG-35951 Change-Id: I9c2f18816b838d57713ba4dd3624e2f3f1ac40ac Reviewed-by: Maurice Kalinowski Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 2e38f81499c..583441f3965 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1020,7 +1020,9 @@ HRESULT QWinRTScreen::onOrientationChanged(IInspectable *) HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) { QKeyEvent backPress(QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier); + QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); backPress.setAccepted(false); + backRelease.setAccepted(false); QObject *receiver = m_visibleWindows.isEmpty() ? static_cast(QGuiApplication::instance()) @@ -1028,12 +1030,8 @@ HRESULT QWinRTScreen::onBackButtonPressed(IInspectable *, IBackPressedEventArgs // If the event is ignored, the app will suspend QGuiApplication::sendEvent(receiver, &backPress); - if (backPress.isAccepted()) { - args->put_Handled(true); - // If the app accepts the event, send the release for symmetry - QKeyEvent backRelease(QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier); - QGuiApplication::sendEvent(receiver, &backRelease); - } + QGuiApplication::sendEvent(receiver, &backRelease); + args->put_Handled(backPress.isAccepted() || backRelease.isAccepted()); return S_OK; } From aeb0d58782cb75fa70ffc1b08422a0a44129e4b6 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 18 Apr 2014 15:51:51 +0300 Subject: [PATCH 080/180] Fix warning with -Wswitch-enum > warning: enumeration values 'Joining_None', 'Joining_Left', and 'Joining_Transparent' > not explicitly handled in switch [-Wswitch-enum] Change-Id: I314b486462451e7d62980b6185b46cd115be1547 Reviewed-by: Lars Knoll --- src/corelib/tools/qchar.h | 3 +++ src/corelib/tools/qstring.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index 266effb66a5..1955758fca9 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -358,6 +358,9 @@ class Q_CORE_EXPORT QChar { case QChar::Joining_Causing: return QChar::Center; case QChar::Joining_Dual: return QChar::Dual; case QChar::Joining_Right: return QChar::Right; + case QChar::Joining_None: + case QChar::Joining_Left: + case QChar::Joining_Transparent: default: return QChar::OtherJoining; } } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 2d9a42957ec..359d0c49e52 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -954,6 +954,9 @@ class Q_CORE_EXPORT QCharRef { case QChar::Joining_Causing: return QChar::Center; case QChar::Joining_Dual: return QChar::Dual; case QChar::Joining_Right: return QChar::Right; + case QChar::Joining_None: + case QChar::Joining_Left: + case QChar::Joining_Transparent: default: return QChar::OtherJoining; } } From 1cb0cd9e7a381636455bb147f93cc0c7cc92565f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 22 Apr 2014 12:01:05 +0200 Subject: [PATCH 081/180] Windows printer support: Fix linking problem when built with -no-opengl . Add missing libraries that were otherwise pulled in by opengl.prf. Task-number: QTBUG-38431 Change-Id: I1705d432088a47b5a202595e818e9efcd5f6a4cf Reviewed-by: Andy Shaw --- src/plugins/printsupport/windows/windows.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro index 364e19e68e1..3366262ef03 100644 --- a/src/plugins/printsupport/windows/windows.pro +++ b/src/plugins/printsupport/windows/windows.pro @@ -21,4 +21,4 @@ HEADERS += \ OTHER_FILES += windows.json -LIBS += -lwinspool -lcomdlg32 +LIBS += -lwinspool -lcomdlg32 -lgdi32 -luser32 From b0d996aed19570da73e9bdc166a38bbb14f4b859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 22 Apr 2014 14:53:36 +0200 Subject: [PATCH 082/180] Build Qt tools for iOS Change-Id: Ie3dc93e01ed878233c8094ca92bef25a6cf4dcd9 Reviewed-by: Frederik Gladhorn --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 1b839c1456d..601d84ab930 100755 --- a/configure +++ b/configure @@ -3101,7 +3101,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then CFG_PKGCONFIG="no" CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples" CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store - CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qttools qtwebkit qtwebkit-examples" + CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples" # If the user passes -sdk on the command line we build a SDK-specific Qt build. # Otherwise we build a joined simulator and device build, which is the default. From f0e8f9c4de3abd6dc52bf2312fc8baf2b5f4a297 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Thu, 17 Apr 2014 16:55:25 +0200 Subject: [PATCH 083/180] Bump Qt version to 5.3.1 Change-Id: Ie84329ab67143c3a8560bc49c4f0f8e0c423bdfc Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qglobal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index fba8b019e7b..09f2d73db4a 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -45,11 +45,11 @@ #include -#define QT_VERSION_STR "5.3.0" +#define QT_VERSION_STR "5.3.1" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x050300 +#define QT_VERSION 0x050301 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ From a564b4e70a4635cea69bd3279abf16ede86137ef Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 23 Apr 2014 12:16:34 +0300 Subject: [PATCH 084/180] Direct2D QPA: Do not attempt to create swap chain for desktop widget We can't and don't need to create a swap chain for the desktop widget. Change-Id: I84cd5c753710af09bab5c7afc27e202e661343db Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight Reviewed-by: Risto Avila --- src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index bf860f982e7..a7cd8aedab8 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -54,6 +54,9 @@ QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWi : QWindowsWindow(window, data) , m_needsFullFlush(true) { + if (window->type() == Qt::Desktop) + return; // No further handling for Qt::Desktop + DXGI_SWAP_CHAIN_DESC1 desc = {}; desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; From d5a4732c1a4ae85e0e3adf9519209e69defb8f68 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Mon, 7 Apr 2014 17:46:31 +0200 Subject: [PATCH 085/180] Allow logging to stderr Introduced a new environment variable "QT_LOGGING_TO_CONSOLE". When set on QNX for instance, log output is directed to the console instead of slog2. This can be more convenient when working on the command line. Besides, many declarative auto tests expect that, as well. Marked QT_NO_JOURNALD_LOG and QT_ANDROID_PLAIN_LOG as deprecated, to be replaced with QT_LOGGING_TO_CONSOLE. Change-Id: I7329fa2d10d31506eff145e956eaaa45d94f8e20 Reviewed-by: Fabian Bumberger Reviewed-by: BogDan Vatra Reviewed-by: Robin Burchell Reviewed-by: Kai Koehne --- src/corelib/global/qlogging.cpp | 36 +++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index da26490d186..4a602e4b2bd 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1207,6 +1207,23 @@ static void android_default_message_handler(QtMsgType type, static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &buf) { + // to determine logging destination and marking logging environment variable as deprecated + // ### remove when deprecated + struct LogDestination { + LogDestination(const char *deprecated, bool forceConsole) { + const char* replacement = "QT_LOGGING_TO_CONSOLE"; + bool newEnv = qEnvironmentVariableIsSet(replacement); + bool oldEnv = qEnvironmentVariableIsSet(deprecated); + if (oldEnv && !newEnv && !forceConsole) { + fprintf(stderr, "Warning: Environment variable %s is deprecated, " + "use %s instead.\n", deprecated, replacement); + fflush(stderr); + } + toConsole = newEnv || oldEnv || forceConsole; + } + bool toConsole; + }; + QString logMessage = qMessageFormatString(type, context, buf); #if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) @@ -1217,12 +1234,19 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con #endif // Q_OS_WIN #if defined(QT_USE_SLOG2) - slog2_default_handler(type, logMessage.toLocal8Bit().constData()); + static const bool logToConsole = qEnvironmentVariableIsSet("QT_LOGGING_TO_CONSOLE"); + if (!logToConsole) { + slog2_default_handler(type, logMessage.toLocal8Bit().constData()); + } else { + fprintf(stderr, "%s", logMessage.toLocal8Bit().constData()); + fflush(stderr); + } #elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED) // We use isatty to catch the obvious case of someone running something interactively. - // We also support an environment variable for Qt Creator use, or more complicated cases like subprocesses. - static bool logToConsole = isatty(fileno(stdin)) || !qEnvironmentVariableIsEmpty("QT_NO_JOURNALD_LOG"); - if (Q_LIKELY(!logToConsole)) { + // We also support environment variables for Qt Creator use, or more complicated cases + // like subprocesses. + static const LogDestination logdest("QT_NO_JOURNALD_LOG", isatty(fileno(stdin))); + if (Q_LIKELY(!logdest.toConsole)) { // remove trailing \n, systemd appears to want them newline-less logMessage.chop(1); systemd_default_message_handler(type, context, logMessage); @@ -1231,8 +1255,8 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con fflush(stderr); } #elif defined(Q_OS_ANDROID) - static bool logToAndroid = qEnvironmentVariableIsEmpty("QT_ANDROID_PLAIN_LOG"); - if (logToAndroid) { + static const LogDestination logdest("QT_ANDROID_PLAIN_LOG", false); + if (!logdest.toConsole) { android_default_message_handler(type, context, logMessage); } else { fprintf(stderr, "%s", logMessage.toLocal8Bit().constData()); From f9d7f85079f0ecf8f36399eeccc42bad8f1d3306 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 23 Apr 2014 14:16:22 +0200 Subject: [PATCH 086/180] Fix up EGL config selection comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After cross-checking with the spec and some embedded devices providing both 888 and 565 configs, it turns out the behavior and the old legacy comments are correct. Rephrase and extend the comments a bit to make it maintainable. Change-Id: If6043a39ca0129cfd075c997f362891f0c28dc2c Reviewed-by: Jørgen Lind --- .../eglconvenience/qeglconvenience.cpp | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index e6624fb9ff4..ed18a23c4fd 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -66,26 +66,30 @@ QVector q_createConfigAttributesFromFormat(const QSurfaceFormat &format) int stencilSize = format.stencilBufferSize(); int sampleCount = format.samples(); - // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide - // the best performance. The EGL config selection algorithm is a bit stange in this regard: - // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard - // 32-bit configs completely from the selection. So it then comes to the sorting algorithm. - // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort - // order is special and described as "by larger _total_ number of color bits.". So EGL will - // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on - // to say "If the requested number of bits in attrib_list for a particular component is 0, - // then the number of bits for that component is not considered". This part of the spec also - // seems to imply that setting the red/green/blue bits to zero means none of the components - // are considered and EGL disregards the entire sorting rule. It then looks to the next - // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being - // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are - // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit, - // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that - // if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat, - // they might still get a 32-bit config, even when there's an RGB565 config available. - QVector configAttributes; + // Map default, unspecified values (-1) to 0. This is important due to sorting rule #3 + // in section 3.4.1 of the spec and allows picking a potentially faster 16-bit config + // over 32-bit ones when there is no explicit request for the color channel sizes: + // + // The red/green/blue sizes have a sort priority of 3, so they are sorted by + // first. (unless a caveat like SLOW or NON_CONFORMANT is present) The sort order is + // Special and described as "by larger _total_ number of color bits.". So EGL will put + // 32-bit configs in the list before the 16-bit configs. However, the spec also goes + // on to say "If the requested number of bits in attrib_list for a particular + // component is 0, then the number of bits for that component is not considered". This + // part of the spec also seems to imply that setting the red/green/blue bits to zero + // means none of the components are considered and EGL disregards the entire sorting + // rule. It then looks to the next highest priority rule, which is + // EGL_BUFFER_SIZE. Despite the selection criteria being "AtLeast" for + // EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are put in the + // list before 32-bit configs. + // + // This also means that explicitly specifying a size like 565 will still result in + // having larger (888) configs first in the returned list. We need to handle this + // ourselves later by manually filtering the list, instead of just blindly taking the + // first config from it. + configAttributes.append(EGL_RED_SIZE); configAttributes.append(redSize > 0 ? redSize : 0); @@ -293,6 +297,13 @@ EGLConfig QEglConfigChooser::chooseConfig() if (!cfg && matching > 0) cfg = configs.first(); + // Filter the list. Due to the EGL sorting rules configs with higher depth are + // placed first when the minimum color channel sizes have been specified (i.e. the + // QSurfaceFormat contains color sizes > 0). To prevent returning a 888 config + // when the QSurfaceFormat explicitly asked for 565, go through the returned + // configs and look for one that exactly matches the requested sizes. When no + // sizes have been given, take the first, which will be a config with the smaller + // (e.g. 16-bit) depth. for (int i = 0; i < configs.size(); ++i) { if (filterConfig(configs[i])) return configs.at(i); @@ -306,6 +317,8 @@ EGLConfig QEglConfigChooser::chooseConfig() bool QEglConfigChooser::filterConfig(EGLConfig config) const { + // If we are fine with the highest depth (e.g. RGB888 configs) even when something + // smaller (565) was explicitly requested, do nothing. if (m_ignore) return true; @@ -314,6 +327,7 @@ bool QEglConfigChooser::filterConfig(EGLConfig config) const EGLint blue = 0; EGLint alpha = 0; + // Compare only if a size was given. Otherwise just accept. if (m_confAttrRed) eglGetConfigAttrib(display(), config, EGL_RED_SIZE, &red); if (m_confAttrGreen) From 02a9f065c5df58cc9dbbc947d7367c80bd1d1ca5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Apr 2014 07:55:10 -0700 Subject: [PATCH 087/180] Autotest: fix use of dangling pointer The "data" pointer became technically dangling after line 1866 did copy = data; as copy was the last reference to the original data. That made the pointer address available to be reused by the system malloc(), which sometimes happened, causing the unit test to fail. Discussed-on: http://lists.qt-project.org/pipermail/development/2014-April/016588.html Change-Id: Ifa6a27bd53a6e60392b77a6609f2d47148695211 Reviewed-by: Olivier Goffart --- tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 6e183f32126..cdcbd19ae8a 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1863,7 +1863,7 @@ void tst_QByteArray::reserve() QCOMPARE(qba.capacity(), capacity); QCOMPARE(copy.capacity(), capacity); - copy = qba; + qba = copy; qba.reserve(capacity * 2); QCOMPARE(qba.size(), capacity); QCOMPARE(qba.capacity(), capacity * 2); From bbcdccd6768f999a49717dfc78efd4bb9d880412 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 21:18:27 +0200 Subject: [PATCH 088/180] deprecate import_qpa_plugin and qpa_minimal_plugin they have been fully superseded by 4255ba40ab073afcf2a095b135883612859af4c2. Change-Id: If7ac14c8b7d3cf00fb0cb916036b62eb86c9cee0 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt.prf | 14 ++++++++------ src/gui/gui.pro | 3 +-- src/plugins/platforms/cocoa/cocoa.pro | 1 + src/plugins/platforms/direct2d/direct2d.pro | 1 + src/plugins/platforms/directfb/directfb.pro | 1 + src/plugins/platforms/eglfs/eglfs.pro | 1 + src/plugins/platforms/ios/ios.pro | 1 + src/plugins/platforms/kms/kms.pro | 1 + src/plugins/platforms/linuxfb/linuxfb.pro | 1 + src/plugins/platforms/minimal/minimal.pro | 1 + src/plugins/platforms/minimalegl/minimalegl.pro | 1 + src/plugins/platforms/offscreen/offscreen.pro | 1 + src/plugins/platforms/openwfd/openwf.pro | 1 + src/plugins/platforms/qnx/qnx.pro | 1 + src/plugins/platforms/windows/windows.pro | 1 + src/plugins/platforms/winrt/winrt.pro | 1 + src/plugins/platforms/xcb/xcb-plugin.pro | 1 + 17 files changed, 24 insertions(+), 8 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 418b124a85a..54423017ee4 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -163,6 +163,14 @@ contains(qt_module_deps, qml): \ } } +!import_qpa_plugin { + warning("CONFIG-=import_qpa_plugin is deprecated. Use QTPLUGIN.platforms=- instead.") + QTPLUGIN.platforms = - +} else: qpa_minimal_plugin { + warning("CONFIG+=qpa_minimal_plugin is deprecated. Use QTPLUGIN.platforms=qminimal instead.") + QTPLUGIN.platforms = qminimal +} + contains(TEMPLATE, .*app) { autoplugs = for (qtmod, qt_module_deps) { @@ -198,12 +206,6 @@ QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN contains(QT_CONFIG, static) { QT_PLUGIN_VERIFY += QTPLUGIN force_import_plugins|contains(TEMPLATE, .*app) { - needs_qpa_plugin:import_qpa_plugin { - qpa_minimal_plugin: \ - QTPLUGIN += qminimal - else: \ - QTPLUGIN += $$QT_DEFAULT_QPA_PLUGIN - } import_plugins:!isEmpty(QTPLUGIN) { IMPORT_FILE_CONT = \ "// This file is autogenerated by qmake. It imports static plugin classes for" \ diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 6af692984af..af84eb7342d 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -1,8 +1,7 @@ TARGET = QtGui QT = core-private -MODULE_CONFIG = needs_qpa_plugin -contains(QT_CONFIG, opengl.*):MODULE_CONFIG += opengl +contains(QT_CONFIG, opengl.*): MODULE_CONFIG = opengl DEFINES += QT_NO_USING_NAMESPACE diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index a60f4adc28a..1f9c0e051d7 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -2,6 +2,7 @@ TARGET = qcocoa PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QCocoaIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) OBJECTIVE_SOURCES += main.mm \ diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 4f986b57d70..439d31fb56f 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -2,6 +2,7 @@ TARGET = qdirect2d PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT *= core-private diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index ec4a612b525..89d8d42ceae 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -2,6 +2,7 @@ TARGET = qdirectfb PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QDirectFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 8827f7680ce..3ebe05b35ef 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -2,6 +2,7 @@ TARGET = qeglfs PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QEglFSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) SOURCES += $$PWD/main.cpp diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index b7e074b95a2..ffc4ff9b125 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -2,6 +2,7 @@ TARGET = qios PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QIOSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro index 1b3678f13ab..baa87781536 100644 --- a/src/plugins/platforms/kms/kms.pro +++ b/src/plugins/platforms/kms/kms.pro @@ -2,6 +2,7 @@ TARGET = qkms PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QKmsIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro index 9e9f9b29b7d..389d45c29c4 100644 --- a/src/plugins/platforms/linuxfb/linuxfb.pro +++ b/src/plugins/platforms/linuxfb/linuxfb.pro @@ -2,6 +2,7 @@ TARGET = qlinuxfb PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QLinuxFbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 3131b162320..3ed4d2cdde1 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -2,6 +2,7 @@ TARGET = qminimal PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro index 00c83eb1caf..e78dcb8bc50 100644 --- a/src/plugins/platforms/minimalegl/minimalegl.pro +++ b/src/plugins/platforms/minimalegl/minimalegl.pro @@ -2,6 +2,7 @@ TARGET = qminimalegl PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalEglIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index 5db5e32e65c..94eeac6accb 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -2,6 +2,7 @@ TARGET = qoffscreen PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QOffscreenIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro index 2dbcb282db7..38bac057bd4 100644 --- a/src/plugins/platforms/openwfd/openwf.pro +++ b/src/plugins/platforms/openwfd/openwf.pro @@ -2,6 +2,7 @@ TARGET = qopenwf PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QOpenWFDIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 04c6087cd11..856b7d2abea 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -161,4 +161,5 @@ include (../../../platformsupport/fontdatabases/fontdatabases.pri) PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QQnxIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 188bd7917c3..cc0373c0770 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -2,6 +2,7 @@ TARGET = qwindows PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWindowsIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT *= core-private diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 60c87bb61a3..0122bf94753 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -12,6 +12,7 @@ winphone { PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index 9e4e997f559..a52aaa4a2ef 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -2,6 +2,7 @@ TARGET = qxcb PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QXcbIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - load(qt_plugin) QT += core-private gui-private platformsupport-private From cae970c68663c320bcce86160d44d857bfc68fd0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 21:19:07 +0200 Subject: [PATCH 089/180] doc fixes Change-Id: I77da456b89accd7fc363471fe8e370da17e2fdcc Reviewed-by: Leena Miettinen Reviewed-by: Joerg Bornemann --- src/corelib/doc/src/plugins-howto.qdoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc index 7565d610ccd..7fc4682fd48 100644 --- a/src/corelib/doc/src/plugins-howto.qdoc +++ b/src/corelib/doc/src/plugins-howto.qdoc @@ -234,7 +234,7 @@ application is to compile it into a dynamic library that is shipped separately, and detected and loaded at runtime. - Plugins can be linked statically against your application. If you + Plugins can be linked statically into your application. If you build the static version of Qt, this is the only option for including Qt's predefined plugins. Using static plugins makes the deployment less error-prone, but has the disadvantage that no @@ -253,7 +253,8 @@ \row \li \c qico \li Image formats \li ICO \row \li \c qsvg \li Image formats \li SVG \row \li \c qtiff \li Image formats \li TIFF - \row \li \c qsqldb2 \li SQL driver \li IBM DB2 \row \li \c qsqlibase \li SQL driver \li Borland InterBase + \row \li \c qsqldb2 \li SQL driver \li IBM DB2 + \row \li \c qsqlibase \li SQL driver \li Borland InterBase \row \li \c qsqlite \li SQL driver \li SQLite version 3 \row \li \c qsqlite2 \li SQL driver \li SQLite version 2 \row \li \c qsqlmysql \li SQL driver \li MySQL @@ -263,7 +264,7 @@ \row \li \c qsqltds \li SQL driver \li Sybase Adaptive Server (TDS) \endtable - To link statically against those plugins, you need to add + To link those plugins statically, you need to add the required plugins to your build using \c QTPLUGIN. Q_IMPORT_PLUGIN() macros are also needed in application code, but those are automatically generated by qmake and added to From f56ef579ba5b1d3adda060fa9c0707e37f9f1baa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Apr 2014 11:18:17 -0700 Subject: [PATCH 090/180] Restore handling of BOMs in QString::fromUtf8 8dd47e34b9b96ac27a99cdcf10b8aec506882fc2 removed the handling of the BOMs but did not document it. This brings the behavior back and adds a unit test so we don't break it again. Discussed-on: http://lists.qt-project.org/pipermail/development/2014-April/016532.html Change-Id: Ifb7a9a6e5a494622f46b8ab435e1d168b862d952 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- src/corelib/codecs/qutfcodec.cpp | 44 ++++++++++++------- .../corelib/tools/qstring/tst_qstring.cpp | 8 ++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 54312601e4e..072cda63aa5 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE enum { Endian = 0, Data = 1 }; +static const uchar utf8bom[] = { 0xef, 0xbb, 0xbf }; + #if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2) static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const ushort *&src, const ushort *end) { @@ -187,9 +189,9 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve int invalid = 0; if (state && !(state->flags & QTextCodec::IgnoreHeader)) { // append UTF-8 BOM - *cursor++ = 0xef; - *cursor++ = 0xbb; - *cursor++ = 0xbf; + *cursor++ = utf8bom[0]; + *cursor++ = utf8bom[1]; + *cursor++ = utf8bom[2]; } const ushort *nextAscii = src; @@ -240,19 +242,31 @@ QString QUtf8::convertToUnicode(const char *chars, int len) const uchar *src = reinterpret_cast(chars); const uchar *end = src + len; - while (src < end) { - const uchar *nextAscii = end; - if (simdDecodeAscii(dst, nextAscii, src, end)) - break; + // attempt to do a full decoding in SIMD + const uchar *nextAscii = end; + if (!simdDecodeAscii(dst, nextAscii, src, end)) { + // at least one non-ASCII entry + // check if we failed to decode the UTF-8 BOM; if so, skip it + if (Q_UNLIKELY(src == reinterpret_cast(chars)) + && end - src >= 3 + && Q_UNLIKELY(src[0] == utf8bom[0] && src[1] == utf8bom[1] && src[2] == utf8bom[2])) { + src += 3; + } - do { - uchar b = *src++; - int res = QUtf8Functions::fromUtf8(b, dst, src, end); - if (res < 0) { - // decoding error - *dst++ = QChar::ReplacementCharacter; - } - } while (src < nextAscii); + while (src < end) { + nextAscii = end; + if (simdDecodeAscii(dst, nextAscii, src, end)) + break; + + do { + uchar b = *src++; + int res = QUtf8Functions::fromUtf8(b, dst, src, end); + if (res < 0) { + // decoding error + *dst++ = QChar::ReplacementCharacter; + } + } while (src < nextAscii); + } } result.truncate(dst - reinterpret_cast(result.constData())); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index d9d6b985b72..95d377b1765 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -3619,6 +3619,14 @@ void tst_QString::fromUtf8_data() str += " some "; QTest::newRow("str3-len") << QByteArray("\342\202\254 some text") << str << 9; + // test that QString::fromUtf8 suppresses an initial BOM, but not a ZWNBSP + str = "hello"; + QByteArray bom("\357\273\277"); + QTest::newRow("bom0") << bom << QString() << 3; + QTest::newRow("bom1") << bom + "hello" << str << -1; + QTest::newRow("bom+zwnbsp0") << bom + bom << QString(QChar(0xfeff)) << -1; + QTest::newRow("bom+zwnbsp1") << bom + "hello" + bom << str + QChar(0xfeff) << -1; + str = "hello"; str += QChar::ReplacementCharacter; str += QChar(0x68); From bbf37b61d00a6470349b728a4e6982a359e0931c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 4 Apr 2014 10:34:15 -0700 Subject: [PATCH 091/180] Document QString's UTF-8 conversion behaviors We haven't handled the Unicode non-characters specially since Qt 5.2 (since commit 9327bc87c3abf58bb471693b5448cd78e3db1b46), so this part of the documentation was stale. Since Qt 5.3 (since 8dd47e34b9b96ac27a99cdcf10b8aec506882fc2), QString will insert one replacement character for each byte that can't be decoded properly. [ChangeLog][Important Behavior Changes][UTF-8 decoding] The QString UTF-8 decoder changed behavior slightly: when it encounters invalid sequences, it will insert one replacement character per byte that is invalid, instead of one replacement character for the whole invalid length. Change-Id: Ia4ec78afded9445bbe937311d6be80f71bd1a55f Reviewed-by: Richard J. Moore Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- src/corelib/tools/qstring.cpp | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 79365b11b1b..aac9c493c35 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4331,14 +4331,6 @@ QByteArray QString::toLocal8Bit_helper(const QChar *data, int size) UTF-8 is a Unicode codec and can represent all characters in a Unicode string like QString. - However, in the Unicode range, there are certain codepoints that are not - considered characters. The Unicode standard reserves the last two - codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, - U+2FFFE, etc.), as well as 32 codepoints in the range U+FDD0..U+FDEF, - inclusive, as non-characters. If any of those appear in the string, they - may be discarded and will not appear in the UTF-8 representation, or they - may be replaced by one or more replacement characters. - \sa fromUtf8(), toLatin1(), toLocal8Bit(), QTextCodec */ @@ -4493,10 +4485,10 @@ QString QString::fromLocal8Bit_helper(const char *str, int size) sequences, non-characters, overlong sequences or surrogate codepoints encoded into UTF-8. - Non-characters are codepoints that the Unicode standard reserves and must - not be used in text interchange. They are the last two codepoints in each - Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, etc.), as well - as 32 codepoints in the range U+FDD0..U+FDEF, inclusive. + This function can be used to process incoming data incrementally as long as + all UTF-8 characters are terminated within the incoming data. Any + unterminated characters at the end of the string will be replaced or + suppressed. In order to do stateful decoding, please use \l QTextDecoder. \sa toUtf8(), fromLatin1(), fromLocal8Bit() */ @@ -9517,14 +9509,6 @@ QByteArray QStringRef::toLocal8Bit() const UTF-8 is a Unicode codec and can represent all characters in a Unicode string like QString. - However, in the Unicode range, there are certain codepoints that are not - considered characters. The Unicode standard reserves the last two - codepoints in each Unicode Plane (U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, - U+2FFFE, etc.), as well as 16 codepoints in the range U+FDD0..U+FDDF, - inclusive, as non-characters. If any of those appear in the string, they - may be discarded and will not appear in the UTF-8 representation, or they - may be replaced by one or more replacement characters. - \sa toLatin1(), toLocal8Bit(), QTextCodec */ QByteArray QStringRef::toUtf8() const From 2b88e9973b4c0a49be184b092481288180840372 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Apr 2014 16:09:16 -0700 Subject: [PATCH 092/180] Update the changelog for 5.3.0 Change-Id: Ic678258dc37d271daa4ee6a871907ca15db2ffde Reviewed-by: Lars Knoll --- dist/changes-5.3.0 | 465 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 459 insertions(+), 6 deletions(-) diff --git a/dist/changes-5.3.0 b/dist/changes-5.3.0 index cb2c3608f05..ae837fc023e 100644 --- a/dist/changes-5.3.0 +++ b/dist/changes-5.3.0 @@ -15,6 +15,50 @@ corresponding to tasks in the Qt Bug Tracker: Each of these identifiers can be entered in the bug tracker to obtain more information about a particular change. +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - SIMD support in CPUs: + * [QTBUG-30440] Qt no longer checks for support for the Neon FPU on + ARM platforms at runtime. Code optimized for Neon must be enabled + unconditionally at compile time by ensuring the compiler supports + Neon. You may need to edit your mkspec for that. + + * Qt now automatically generates code for processors supporting SSE2 + on i386 platforms. To disable this, pass the -no-sse2 option during + Qt configuration. Since this feature has been present on CPUs for + 10 years and since Qt no longer checks for runtime support for + SSE2, we strongly encourage users to leave the default setting on + for best performance. + - For Linux distributions that must retain support for CPUs without + SSE2, we recommend doing two builds of Qt and installing the + SSE2-enabled libraries in the LIBDIR/sse2 directory (specially + QtGui, QtQml and QtQuick libraries). Tools, plugins, and examples + are not affected. + - See discussion on the Qt development mailing list: + http://lists.qt-project.org/pipermail/development/2013-November/014085.html + + - SSL and security: + * The default set of ciphers used by QSslSocket has been changed to + exclude ciphers that are using key lengths smaller than 128 + bits. These ciphers are still available and can be enabled by + applications if required. + * [QTBUG-20666] Support for DH and ECDH key exchange cipher suites + when acting as an SSL server has been made possible. This change + means the you can now implement servers that offer forward-secrecy + using Qt. + * Running Qt applications that are setuid is no longer allowed by + default. If you really need to do this then you can call + QCoreApplication::setSetuidAllowed(true) before creating the + QCoreApplication instance. + + - UTF-8 decoding: + * The QString and QTextCodec UTF-8 decoder changed behavior slightly: + when it encounters invalid sequences, it will insert one + replacement character per byte that is invalid, instead of one + replacement character for the whole invalid length. + **************************************************************************** * Platform deprecation notice * **************************************************************************** @@ -24,17 +68,125 @@ information about a particular change. not tested, and most likely has issues that are not fully documented. **************************************************************************** -* Library * +* General * **************************************************************************** -QtWidgets ---------- + - Support for the following platforms has been removed, due to lack of + interest in updating support: INTEGRITY, VxWorks, Solaris on UltraSPARC + (with the Sun Studio compiler suite), AIX on POWER processors (with IBM + Visual Age compiler suite). + - Builtin command-line options such as -reverse, -session, -style + -etc. now all support double dash, e.g. --reverse, --session, + --style... + +**************************************************************************** +* Library * +**************************************************************************** QtCore ------ - Added QSignalBlocker, a RAII-style wrapper around QObject::blockSignals(). + - QLibraryInfo provides information on how Qt was built. + - Added class QMarginsF to support handling margins with floating-point + values. + + - Atomic support: + * Added more operations to the atomic classes, including operator T(), + operator=(T), operator++, operator--. For the QAtomicInteger, + bit-manipulation operations are also provided, both in operator and in + fetchAndXxxYyyyyy modes. + + - Event loop: + * [QTBUG-36611] QCoreApplication::hasPendingEvents and + QAbstractEventDispatcher::hasPendingEvents are now deprecated. Please + refer to the documentation for more information. + + - Logging: + * It is now possible for the qCDebug macros to be used in a printf + style. + * All qCDebug categories are enabled by default, except for Qt's own + categories. + * The logging framework can now be configured with an .ini file. + * Q_LOGGING_CATEGORY and Q_DECLARE_LOGGING_CATEGORY now return a const + object. + + - QByteArray: + * Added NSData/CDataRef converters for QByteArray. + + - QChar: + * Added JoiningType enum and joiningType() method that deprecates the + old QChar::Joining enum and joining() method. + + - QFileSelector: + * [QTBUG-35073] The identifier for OS X has been changed back to + 'osx' from 'mac', and 'mac' and 'darwin' have now been added as + selectors for Darwin OS (which is the base of both OS X and iOS). + + - QHash/QSet: + * Added qHash overloads for float, double and long double. + + - QJsonArray: + * Added convenience methods to QJsonArray for appending QJsonValues + + - QJsonValue: + * Added constructor to QJsonValue for const char * + * QJsonValue::fromVariant() will now convert single-precision Floats + into Doubles instead of Strings + + - QMargins: + * Added missing addition and subtraction operators. + + - QProcess: + * [QTBUG-26136] Added processId() to QProcess. This function will, + unlike pid(), return the actual process identifier on both Windows + and Unix. + + - QRect: + * Added QMargins subtraction operator. + + - QSettings: + * [QTBUG-9824][QTBUG-21062][QTBUG-22745] QSettings now returns the + correct value for isWritable() when using SystemScope settings. + + - QSortFilterProxyModel: + * [QTBUG-30662] Fixed sorting when a previously empty proxy model + becomes populated because of a change in the filter. + + - QStandardPaths: + * [QTBUG-34631] Added QStandardPaths implementation for Android. + + - QString: + * Added QLatin1String overload of contains() + * QString::toUcs4 now does not return invalid UCS-4 code units belonging + to the surrogate range (U+D800 to U+DFFF) when the QString contains + malformed UTF-16 data. Instead, U+FFFD is returned in place of the + malformed subsequence. + + - QTextCodec: + * Encoding a QString in UTF-32 will now replace malformed UTF-16 + subsequences in the string with the Unicode replacement character + (U+FFFD). + + - QVarLengthArray: + * Added the indexOf, lastIndexOf and contains functions to + QVarLengthArray. These functions make the class more similar to + QVector. + + - Windows: + * [QTBUG-35194] Now QStandardPaths::DownloadLocation returns the proper + path for Windows Vista and up + +QtDBus +------ + + - QtDBus adaptors now include the PropertiesChanged signal in + introspection data + + - QDBusServer: + * Added method to QDBusServer to allow anonymous client connections, + even if the connecting client is not authenticated as a user. QtGui ----- @@ -42,12 +194,313 @@ QtGui - Added setSwapInterval() to QSurfaceFormat. Platforms that support setting the swap interval are now defaulting to the value of 1, meaning vsync is enabled. + - [QTBUG-35220] Reading bmp images with alpha channel is now supported + - [QTBUG-36394] The main Embedded Linux platform plugins (eglfs, linuxfb, + kms) are changed to behave identically with regards to terminal keyboard + input: it is turned off by default on all of these platforms. If this + feature is not desired, it can be disabled by setting the environment + variable QT_QPA_ENABLE_TERMINAL_KEYBOARD. + - [QTBUG-36374] Mouse hotplugging is now fully supported in eglfs when + running on Embedded Linux systems with libudev support enabled. + - [QTBUG-36603] Windows Accessibility now handles the disabled state of + widgets correctly. + - Accessibility on Linux now reports the active state correctly. + - [QTBUG-36483] Qt builds on Windows can now be configured for dynamic + loading of the OpenGL implementation. This can be requested by passing + -opengl dynamic to configure. In this mode no modules will link to + opengl32.dll or Angle's libegl/libglesv2. Instead, QtGui will + dynamically choose between desktop and Angle during the first GL/EGL/WGL + call. This allows deploying applications with a single set of Qt + libraries with the ability of transparently falling back to Angle in + case the opengl32.dll is not suitable, due to missing graphics drivers + for example. + - Added class QPageLayout to support handling page layouts including the + page size, orientation and margins. + - [QTBUG-28813][QTBUG-29930][QTBUG-35836] Fixed regression in + arabic text rendering. + - [QTBUG-37332] GLES3 and desktop OpenGL are now fully supported with + EGL + - [QTBUG-36993] Native (that is, not distance field based) text + rendering is now functional on OpenGL 3.2+ core profiles too. + + - Accessibility: + * [QTBUG-37204] Implemented text attributes to enable VoiceOver to read + QTextEdit and QPlainTextEdit. + * Assistive apps such as VoiceOver can now set the focus on widgets + and controls. + + - QColor: + * Exported highly optimized methods for premultiply and unpremultiply of + QRgb values. + + - QFont: + * Added qHash overload for this class. + + - QGuiApplication: + * Restored support for -title command line argument on X11 and added + -qwindowtitle on all platforms. + + - QImage: + * Added rvalue-qualified overloads for mirrored(), rgbSwapped() and + convertToFormat(), allowing in-place conversion in some cases + + - QOpenGLFramebufferObject: + * [QTBUG-35881] Added takeTexture() for retrieving and detaching the + texture from the framebuffer object. + + - QPageSize: + * Added new QPageSize class to implement Adobe Postscript PPD standard + page sizes. This class supports the standard page sizes, names and + keys from the PPD standard, and provides convenient size and rect + conversion methods. + + - QPagedPaintDevice: + * [QTBUG-27685][QTBUG-25744] Paged paint devices such as QPrinter and + QPdfWriter now support all Postscript standard page sizes. + + - QPdfWriter: + * The QPdfWriter now supports setting the PDF orientation, layout and + resolution by using QPageSize and QPageLayout. + + - QTextLayout: + * [QTBUG-18060] Fixed visual cursor movement in bidirectional text. + + - QWindow: + * QWindow::icon() now defaults to the application icon, which can be set + with QGuiApplication::setWindowIcon(). + +QtNetwork +--------- + + - [QTBUG-18714] Added support for the SPDY protocol (version 3.0). + + - QNetworkReply: + * [QTBUG-30880] Added more (specific) HTTP status codes to NetworkError + enum. + + - QSslConfiguration: + * [QTBUG-33208] Added support for the Next Protocol Negotiation (NPN) + TLS extension. + +QtPrintSupport +-------------- + + - [QTBUG-29663] Made the Qt buildsystem automatically include the + necessary plugins so that static applications can print. + - CUPS 1.4 is now required for print support on Linux and other *nix + platforms. + + - QPrintPreviewDialog: + * [QTBUG-36561] Fixed initialization of QPrintPreviewDialog's image + resources for static builds. + + - QPrinter: + * QPrinter can now use QPageSize and QPageLayout in the public api to + control the page layout for a print job. + + - QPrinterInfo: + * [QTBUG-35248] Added new public api for isRemote(), state(), + defaultPageSize(), supportedPageSizes(), supportsCustomPageSizes(), + minimumPhysicalPageSize(), maximumPhysicalPageSize(), + supportedResolutions(), availablePrinterNames(), and + defaultPrinterName(). The use of availablePrinters() is discouraged + due to performance concerns. QtSql ----- - QSqlQuery::isNull(field) now correctly returns true for "no such field". - QSqlQuery::isNull(fieldname) is a new overload. - - QSQLITE: Empty database name now opens in-memory database. - - QSqlError: Now handles alphanumeric error codes. Used by QPSQL. - Old numeric code is deprecated. + - [QTBUG-12186] Fixed the order of values with positional binding in a + QSqlQuery + + - QSQLITE: + * Creating temporary databases is now possible + * Empty database name now opens in-memory database. + + - QSqlError + * Now handles alphanumeric error codes. Used by QPSQL. Old numeric + code is deprecated. + +QtTest +------ + + - Added test duration to xml output. When running tests with xml output a + new tag of the form + is added to each test function and the test as a + whole. + - Added a CSV logging mode that is suitable for importing benchmark + results into spreadsheets. This can be enabled by the -csv option on the + command-line. The CSV logging mode will not print test failures, debug + messages, warnings, etc. + - QtTest now prints an escaped version of QStrings that failed to compare + with QCOMPARE. That is, instead of converting non-printable characters + to question marks, QtTest will print the Unicode representation of the + character in question. + + - Windows: + * [QTBUG-35743] Use correct UTF-8 encoding for XML test results on + platforms with different console encoding. + +QtWidgets +--------- + + - Accessibility: + * Fixed QTextEdit not reporting newlines to accessibility frameworks and + add editable text interface. + + - QAbstractSpinBox: + * [QTBUG-5142] QSpinBox and QDoubleSpinBox widgets can now show the + group (thousands) separators. + + - QColorDialog: + * Ensured QColorDialog::DontUseNativeDialog is respected when showing + the dialog. + + - QDateEdit: + * [QTBUG-36692] Fixed incorrect appearance on OS X of QDateEdit with + calendarPopup enabled. + + - QDrag + * Fixed Drag and Drop driven by touch-synthesized mouse events on + Windows. + + - QListView: + * [QTBUG-4714] Fixed QListView ignoring the grid size for word + wrapping in icon mode + + - QMdiSubWindow: + * [QTBUG-9933][QTBUG-27274] Fixed setWindowFlags() for QMdiSubWindow. + + - QMenu: + * [QTBUG-20094] Enabled sloppy submenu mouse navigation. + * [QTBUG-36142] QMenu now correctly uses text color set by style + sheet for menu items on Windows. + * [QTBUG-36218] Fixed position of menu gutter on Windows when using a + custom widget action. + + - QPlainTextEdit: + * Added find method overload using QRegExp + + - QSpinBox: + * [QTBUG-3032] Fixed keyboard selection with multiple-character strings. + + - QScrollArea: + * [QTBUG-36314] The setting for click position is now respected on OS X. + + - QTextDocument: + * [QTBUG-33336] Added support for empty inline elements in block tags. + + - QTextEdit: + * Added find method overload using QRegExp + + - QWidget: + * [QTBUG-25831] Restored the Qt 4 behavior in the sequence of events + that are delivered to widget windows and their children when a + mouse double click happens: the second MouseButtonPress event from + Qt 5.0-5.2 is no longer sent. + * [QTBUG-33716] QWidgets embedded in QGraphicsProxyWidget are no longer + sent close events when the app is closed on OS X. + * [QTBUG-36178] Fixed an issue where stay-on-top widgets would cover + their own children on OS X. + + - QWizard: + * [QTBUG-7484] Added NoCancelButtonOnLastPage option. + * [QTBUG-36192] Fixed frame when using Vista style/MSVC2012. + + - Text support: + * [QTBUG-36444] Fixed off-by-one in the height of text background. + + - Windows: + * [QTBUG-21371][QTBUG-4397] QWidget::restoreGeometry() now restores + maximized/full screen widgets to the correct screen. + +**************************************************************************** +* Compiler Specific Changes * +**************************************************************************** + + - Variadic macros are now enabled more liberally for gcc, clang, icc. If + you have warnings (because you e.g. compile with -pedantic), disable + them by -Wno-variadic-macros. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - [QTBUG-34781] Fixed regression in "make install" on library projects on + Android so they can be used inside subdirs projects again. + - [QTBUG-36074] Fixed crash on populating large combo boxes or menus. + - [QTBUG-36528] Fixed QDir::entryList() for assets scheme to no longer + skip the first file in the directory. + - [QTBUG-30652] It is now possible to define a splash screen which will be + visible until the first window is created. + - [QTBUG-33704] Sped up first time directory listing in assets by using + pregenerated entry list. + - [QTBUG-37738] Fixed font merging problem which caused e.g. missing + glyphs for Arabic numerals. + - [QTBUG-36025] Fixed a memory leak in the clipboard + + - Fonts: + * [QTBUG-36789] Fixed support for Arabic text. + +Linux +----- + + - Systems with systemd may now pass -journald to configure to send + logging output to journald. Logging will still be sent to stderr for + interactive applications (run from a tty) or with QT_NO_JOURNALD_LOG + set to a non-empty value. + +OS X +---- + + - [QTBUG-18980][QTBUG-38246] Use CoreText text shaping engine for + support of complex scripts. If required, the shaping engine used in + previous versions can be preferred by configuring Qt with + -no-harfbuzz. Alternatively, the QT_HARFBUZZ environment variable + could be set to "old". + +Windows +------- + + - Introduced experimental direct2d platform plugin for Windows. This + plugin shares most code with the current windows plugin, but + substitutes a direct2d-based paint engine for window backing stores + and pixmaps. + + - QtWidgets / QFileDialog: + * Handled the case of having trailing spaces in a filename correctly so + if the filename ends up being empty that the parent path is used + instead. + + - Windows Embedded: + * Fixed building issue when configuring Qt with -qtlibinfix + +X11 / XCB +--------- + + - Qt now supports XInput2 smooth scrolling events + +**************************************************************************** +* Tools * +**************************************************************************** + +moc +--- + + - [QTBUG-33668] Fixed passing -D of a macro defined to something more + complex than a single identifier. + + - QTBUG-36128: + * [QTBUG-36128] Fixed sign conversion warning in generated file. + +qdbus +----- + + - [QTBUG-36524] Fixed a bug that caused the qdbus tool to crash when + trying to display remote interfaces that had complex types without a + matching base Qt type. + From cafa3848e2315d851a338c9821fb4cb47db511be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 23 Apr 2014 14:29:03 +0200 Subject: [PATCH 093/180] QOpenGLFunctions: Compile on Mac OS 10.6 The 10.6 OpenGL headers have "GLenum" as the type for the 3rd argument. The OpenGL standard has "Glint", which is also what Qt expects. Work around this by casting the pointer type. Task-id: QTBUG-38406 Change-Id: I6d820f41e0d14cbc2d50d91997b6c40b626b159f Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglfunctions.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index af536fa9273..85b893e434a 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -3282,7 +3282,11 @@ QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *) StencilFunc = ::glStencilFunc; StencilMask = ::glStencilMask; StencilOp = ::glStencilOp; - TexImage2D = ::glTexImage2D; +#if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + TexImage2D = reinterpret_cast(glTexImage2D); +#else + TexImage2D = glTexImage2D; +#endif TexParameterf = ::glTexParameterf; TexParameterfv = ::glTexParameterfv; TexParameteri = ::glTexParameteri; From e57b521d950575a96d54e6944ab153a9505e51f7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 6 Mar 2014 13:01:20 -0800 Subject: [PATCH 094/180] Deprecate setSharable in Qt containers The ability to set a container to be unsharable has very little use and it costs us an extra conditional for every refcount up and possibly down. This change is a no-op for current Qt 5. It shuffles a few things around just so Qt can compile if you define QT_NO_UNSHARABLE_CONTAINERS. That is done to ease the fixing of the code in Qt 6 and to make my life easier: I'll keep that defined in my local Qt build so I can catch any misuses of this deprecated API. The newly deprecated methods are not marked QT_DEPRECATED because the bootstrapped tools wouldn't build -- they're built with QT_NO_DEPRECATED defined, which causes build errors. [ChangeLog][QtCore] The setSharable() and isSharable() functions in Qt containers has been deprecated and will be removed in Qt 6. New applications should not use this feature, while old applications that may be using this (undocumented) feature should port away from it. Discussed-on: http://lists.qt-project.org/pipermail/development/2014-February/015724.html Change-Id: I789771743dcaed6a43eccd99382f8b3ffa61e479 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/global/qglobal.h | 3 + src/corelib/tools/qarraydata.cpp | 13 +- src/corelib/tools/qarraydata.h | 4 + src/corelib/tools/qarraydatapointer.h | 4 + src/corelib/tools/qcontiguouscache.h | 2 + src/corelib/tools/qhash.h | 2 + src/corelib/tools/qlinkedlist.h | 2 + src/corelib/tools/qlist.h | 2 + src/corelib/tools/qmap.h | 2 + src/corelib/tools/qrefcount.h | 18 ++- src/corelib/tools/qset.h | 2 + src/corelib/tools/qvector.h | 14 ++- .../corelib/tools/qarraydata/simplevector.h | 3 +- .../tools/qarraydata/tst_qarraydata.cpp | 44 ++++++- tests/auto/corelib/tools/qhash/tst_qhash.cpp | 4 +- .../tools/qlinkedlist/tst_qlinkedlist.cpp | 6 +- tests/auto/corelib/tools/qlist/tst_qlist.cpp | 8 +- tests/auto/corelib/tools/qmap/tst_qmap.cpp | 8 +- .../corelib/tools/qvector/tst_qvector.cpp | 115 ++++++++++++------ 19 files changed, 196 insertions(+), 60 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index fba8b019e7b..391466448f5 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -58,7 +58,10 @@ #if !defined(QT_BUILD_QMAKE) && !defined(QT_BUILD_CONFIGURE) #include #include +#endif #define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE)) +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +# define QT_NO_UNSHARABLE_CONTAINERS #endif /* These two macros makes it possible to turn the builtin line expander into a diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 825b3289c7b..12736d5c2e6 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -75,10 +75,13 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, && !(alignment & (alignment - 1))); // Don't allocate empty headers - if (!(options & RawData) && !capacity) - return !(options & Unsharable) - ? const_cast(&qt_array_empty) - : const_cast(&qt_array_unsharable_empty); + if (!(options & RawData) && !capacity) { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + if (options & Unsharable) + return const_cast(&qt_array_unsharable_empty); +#endif + return const_cast(&qt_array_empty); + } size_t headerSize = sizeof(QArrayData); @@ -118,8 +121,10 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize, && !(alignment & (alignment - 1))); Q_UNUSED(objectSize) Q_UNUSED(alignment) +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (data == &qt_array_unsharable_empty) return; +#endif Q_ASSERT_X(!data->ref.isStatic(), "QArrayData::deallocate", "Static data can not be deleted"); ::free(data); diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index ffb2b8765e3..10a9e355428 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -80,7 +80,9 @@ struct Q_CORE_EXPORT QArrayData enum AllocationOption { CapacityReserved = 0x1, +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Unsharable = 0x2, +#endif RawData = 0x4, Grow = 0x8, @@ -99,8 +101,10 @@ struct Q_CORE_EXPORT QArrayData AllocationOptions detachFlags() const { AllocationOptions result; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (!ref.isSharable()) result |= Unsharable; +#endif if (capacityReserved) result |= CapacityReserved; return result; diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 533f7a306f8..2245106ec0e 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -134,6 +134,7 @@ struct QArrayDataPointer return (!d->isMutable() || d->ref.isShared()); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) void setSharable(bool sharable) { if (needsDetach()) { @@ -147,6 +148,9 @@ struct QArrayDataPointer } } + bool isSharable() const { return d->isSharable(); } +#endif + void swap(QArrayDataPointer &other) { qSwap(d, other.d); diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index d601ddb8191..e05ef33aa2f 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -104,7 +104,9 @@ class QContiguousCache { inline void detach() { if (d->ref.load() != 1) detach_helper(); } inline bool isDetached() const { return d->ref.load() == 1; } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } +#endif QContiguousCache &operator=(const QContiguousCache &other); #ifdef Q_COMPILER_RVALUE_REFS diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 40e501355cd..f68b02be2c5 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -330,7 +330,9 @@ class QHash inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QHashData::shared_null) d->sharable = sharable; } +#endif inline bool isSharedWith(const QHash &other) const { return d == other.d; } void clear(); diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index bdacdbcd265..3377d1bbc30 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -106,7 +106,9 @@ class QLinkedList inline void detach() { if (d->ref.isShared()) detach_helper2(this->e); } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (!sharable) detach(); if (d != &QLinkedListData::shared_null) d->sharable = sharable; } +#endif inline bool isSharedWith(const QLinkedList &other) const { return d == other.d; } inline bool isEmpty() const { return d->size == 0; } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 3a0d01aa8db..9e4ba70908a 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -146,6 +146,7 @@ class QList } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -155,6 +156,7 @@ class QList if (d != &QListData::shared_null) d->ref.setSharable(sharable); } +#endif inline bool isSharedWith(const QList &other) const { return d == other.d; } inline bool isEmpty() const { return p.isEmpty(); } diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 487039ccfba..76f8bd6f179 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -377,6 +377,7 @@ class QMap inline void detach() { if (d->ref.isShared()) detach_helper(); } inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -386,6 +387,7 @@ class QMap // Don't call on shared_null d->ref.setSharable(sharable); } +#endif inline bool isSharedWith(const QMap &other) const { return d == other.d; } void clear(); diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h index 84314b1fcc6..3a8f0f3982e 100644 --- a/src/corelib/tools/qrefcount.h +++ b/src/corelib/tools/qrefcount.h @@ -55,8 +55,10 @@ class RefCount public: inline bool ref() Q_DECL_NOTHROW { int count = atomic.load(); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; +#endif if (count != -1) // !isStatic atomic.ref(); return true; @@ -64,13 +66,16 @@ class RefCount inline bool deref() Q_DECL_NOTHROW { int count = atomic.load(); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) if (count == 0) // !isSharable return false; +#endif if (count == -1) // isStatic return true; return atomic.deref(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) bool setSharable(bool sharable) Q_DECL_NOTHROW { Q_ASSERT(!isShared()); @@ -80,17 +85,18 @@ class RefCount return atomic.testAndSetRelaxed(1, 0); } - bool isStatic() const Q_DECL_NOTHROW - { - // Persistent object, never deleted - return atomic.load() == -1; - } - bool isSharable() const Q_DECL_NOTHROW { // Sharable === Shared ownership. return atomic.load() != 0; } +#endif + + bool isStatic() const Q_DECL_NOTHROW + { + // Persistent object, never deleted + return atomic.load() == -1; + } bool isShared() const Q_DECL_NOTHROW { diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index ad2f91b983b..0cc704b6cfc 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -91,7 +91,9 @@ class QSet inline void detach() { q_hash.detach(); } inline bool isDetached() const { return q_hash.isDetached(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { q_hash.setSharable(sharable); } +#endif inline void clear() { q_hash.clear(); } diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index b0be98c2966..6f7c534085d 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -107,6 +107,7 @@ class QVector inline void detach(); inline bool isDetached() const { return !d->ref.isShared(); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) inline void setSharable(bool sharable) { if (sharable == d->ref.isSharable()) @@ -122,6 +123,7 @@ class QVector } Q_ASSERT(d->ref.isSharable() == sharable); } +#endif inline bool isSharedWith(const QVector &other) const { return d == other.d; } @@ -329,10 +331,12 @@ template void QVector::detach() { if (!isDetached()) { - if (d->alloc) - reallocData(d->size, int(d->alloc)); - else +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + if (!d->alloc) d = Data::unsharableEmpty(); + else +#endif + reallocData(d->size, int(d->alloc)); } Q_ASSERT(isDetached()); } @@ -484,7 +488,9 @@ void QVector::reallocData(const int asize, const int aalloc, QArrayData::Allo x = Data::allocate(aalloc, options); Q_CHECK_PTR(x); // aalloc is bigger then 0 so it is not [un]sharedEmpty +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable)); +#endif Q_ASSERT(!x->ref.isStatic()); x->size = asize; @@ -550,7 +556,9 @@ void QVector::reallocData(const int asize, const int aalloc, QArrayData::Allo Q_ASSERT(d->data()); Q_ASSERT(uint(d->size) <= d->alloc); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(d != Data::unsharableEmpty()); +#endif Q_ASSERT(aalloc ? d != Data::sharedNull() : d == Data::sharedNull()); Q_ASSERT(d->alloc >= uint(aalloc)); Q_ASSERT(d->size == asize); diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 40917c0172b..af0ced130ce 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -101,9 +101,10 @@ struct SimpleVector bool isStatic() const { return d->ref.isStatic(); } bool isShared() const { return d->ref.isShared(); } bool isSharedWith(const SimpleVector &other) const { return d == other.d; } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) bool isSharable() const { return d->ref.isSharable(); } - void setSharable(bool sharable) { d.setSharable(sharable); } +#endif size_t size() const { return d->size; } size_t capacity() const { return d->alloc; } diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 60b807a7bc1..35ec0ef0195 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -52,7 +52,9 @@ struct SharedNullVerifier { Q_ASSERT(QArrayData::shared_null[0].ref.isStatic()); Q_ASSERT(QArrayData::shared_null[0].ref.isShared()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) Q_ASSERT(QArrayData::shared_null[0].ref.isSharable()); +#endif } }; @@ -107,7 +109,9 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), 1); QVERIFY(!array.ref.isStatic()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); +#endif QVERIFY(array.ref.ref()); QCOMPARE(array.ref.atomic.load(), 2); @@ -127,6 +131,7 @@ void tst_QArrayData::referenceCounting() // Now would be a good time to free/release allocated data } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { // Reference counting initialized to 0 (non-sharable) QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 }; @@ -145,6 +150,7 @@ void tst_QArrayData::referenceCounting() // Free/release data } +#endif { // Reference counting initialized to -1 (static read-only data) @@ -153,13 +159,16 @@ void tst_QArrayData::referenceCounting() QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.isStatic()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(array.ref.isSharable()); +#endif QVERIFY(array.ref.ref()); QCOMPARE(array.ref.atomic.load(), -1); QVERIFY(array.ref.deref()); QCOMPARE(array.ref.atomic.load(), -1); + } } @@ -169,16 +178,19 @@ void tst_QArrayData::sharedNullEmpty() QArrayData *empty = QArrayData::allocate(1, Q_ALIGNOF(QArrayData), 0); QVERIFY(null->ref.isStatic()); - QVERIFY(null->ref.isSharable()); QVERIFY(null->ref.isShared()); QVERIFY(empty->ref.isStatic()); - QVERIFY(empty->ref.isSharable()); QVERIFY(empty->ref.isShared()); QCOMPARE(null->ref.atomic.load(), -1); QCOMPARE(empty->ref.atomic.load(), -1); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + QVERIFY(null->ref.isSharable()); + QVERIFY(empty->ref.isSharable()); +#endif + QVERIFY(null->ref.ref()); QVERIFY(empty->ref.ref()); @@ -305,6 +317,7 @@ void tst_QArrayData::simpleVector() QVERIFY(!v7.isShared()); QVERIFY(!v8.isShared()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(v1.isSharable()); QVERIFY(v2.isSharable()); QVERIFY(v3.isSharable()); @@ -313,6 +326,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v6.isSharable()); QVERIFY(v7.isSharable()); QVERIFY(v8.isSharable()); +#endif QVERIFY(v1.isSharedWith(v2)); QVERIFY(v1.isSharedWith(v3)); @@ -496,6 +510,7 @@ void tst_QArrayData::simpleVector() for (int i = 0; i < 120; ++i) QCOMPARE(v1[i], v8[i % 10]); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { v7.setSharable(true); QVERIFY(v7.isSharable()); @@ -558,6 +573,7 @@ void tst_QArrayData::simpleVector() QVERIFY(null.isEmpty()); QVERIFY(empty.isEmpty()); } +#endif } Q_DECLARE_METATYPE(SimpleVector) @@ -648,7 +664,7 @@ void tst_QArrayData::allocate_data() QTest::addColumn("alignment"); QTest::addColumn("allocateOptions"); QTest::addColumn("isCapacityReserved"); - QTest::addColumn("isSharable"); + QTest::addColumn("isSharable"); // ### Qt6: remove QTest::addColumn("commonEmpty"); struct { @@ -662,10 +678,12 @@ void tst_QArrayData::allocate_data() }; QArrayData *shared_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0); - QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); - QVERIFY(shared_empty); + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + QArrayData *unsharable_empty = QArrayData::allocate(0, Q_ALIGNOF(QArrayData), 0, QArrayData::Unsharable); QVERIFY(unsharable_empty); +#endif struct { char const *description; @@ -676,10 +694,12 @@ void tst_QArrayData::allocate_data() } options[] = { { "Default", QArrayData::Default, false, true, shared_empty }, { "Reserved", QArrayData::CapacityReserved, true, true, shared_empty }, +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { "Reserved | Unsharable", QArrayData::CapacityReserved | QArrayData::Unsharable, true, false, unsharable_empty }, { "Unsharable", QArrayData::Unsharable, false, false, unsharable_empty }, +#endif { "Grow", QArrayData::Grow, false, true, shared_empty } }; @@ -700,7 +720,6 @@ void tst_QArrayData::allocate() QFETCH(size_t, alignment); QFETCH(QArrayData::AllocationOptions, allocateOptions); QFETCH(bool, isCapacityReserved); - QFETCH(bool, isSharable); QFETCH(const QArrayData *, commonEmpty); // Minimum alignment that can be requested is that of QArrayData. @@ -725,7 +744,10 @@ void tst_QArrayData::allocate() else QCOMPARE(data->alloc, uint(capacity)); QCOMPARE(data->capacityReserved, uint(isCapacityReserved)); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + QFETCH(bool, isSharable); QCOMPARE(data->ref.isSharable(), isSharable); +#endif // Check that the allocated array can be used. Best tested with a // memory checker, such as valgrind, running. @@ -1302,6 +1324,7 @@ static inline bool arrayIsFilledWith(const QArrayDataPointer &array, void tst_QArrayData::setSharable_data() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QTest::addColumn >("array"); QTest::addColumn("size"); QTest::addColumn("capacity"); @@ -1342,10 +1365,12 @@ void tst_QArrayData::setSharable_data() QTest::newRow("non-empty-reserved") << nonEmptyReserved << size_t(7) << size_t(15) << true << 2; QTest::newRow("static-array") << staticArray << size_t(10) << size_t(0) << false << 3; QTest::newRow("raw-data") << rawData << size_t(10) << size_t(0) << false << 3; +#endif } void tst_QArrayData::setSharable() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QFETCH(QArrayDataPointer, array); QFETCH(size_t, size); QFETCH(size_t, capacity); @@ -1424,6 +1449,7 @@ void tst_QArrayData::setSharable() QCOMPARE(array->ref.isShared(), !(size || isCapacityReserved)); QVERIFY(array->ref.isSharable()); +#endif } struct ResetOnDtor @@ -1474,6 +1500,7 @@ void fromRawData_impl() QVERIFY((const T *)raw.constBegin() != array); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) { // Immutable, unsharable SimpleVector raw = SimpleVector::fromRawData(array, @@ -1502,6 +1529,7 @@ void fromRawData_impl() QCOMPARE(raw.back(), T(11)); QVERIFY((const T *)raw.constBegin() != array); } +#endif } void tst_QArrayData::fromRawData_data() @@ -1558,7 +1586,9 @@ void tst_QArrayData::literals() QVERIFY(v.isStatic()); #endif +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); +#endif QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd()); for (int i = 0; i < 10; ++i) @@ -1607,7 +1637,9 @@ void tst_QArrayData::variadicLiterals() QVERIFY(v.isStatic()); +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QVERIFY(v.isSharable()); +#endif QCOMPARE((const int *)(v.constBegin() + v.size()), (const int *)v.constEnd()); for (int i = 0; i < 7; ++i) diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 73f8973245c..9c96aaf78d7 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -1217,12 +1217,14 @@ void tst_QHash::noNeedlessRehashes() void tst_QHash::const_shared_null() { + QHash hash2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QHash hash1; hash1.setSharable(false); QVERIFY(hash1.isDetached()); - QHash hash2; hash2.setSharable(true); +#endif QVERIFY(!hash2.isDetached()); } diff --git a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp index 49b32d5534e..9e47e9c6d64 100644 --- a/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp +++ b/tests/auto/corelib/tools/qlinkedlist/tst_qlinkedlist.cpp @@ -1018,12 +1018,14 @@ void tst_QLinkedList::initializeList() const template void tst_QLinkedList::constSharedNull() const { + QLinkedList list2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QLinkedList list1; list1.setSharable(false); QVERIFY(list1.isDetached()); - QLinkedList list2; list2.setSharable(true); +#endif QVERIFY(!list2.isDetached()); } @@ -1049,6 +1051,7 @@ void tst_QLinkedList::constSharedNullComplex() const void tst_QLinkedList::setSharableInt() const { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QLinkedList orglist; orglist << 0 << 1 << 2 << 3 << 4 << 5; int size = 6; @@ -1094,6 +1097,7 @@ void tst_QLinkedList::setSharableInt() const } QCOMPARE(list.size(), size); +#endif } QTEST_APPLESS_MAIN(tst_QLinkedList) diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index d77cc4a37cb..b368359c62b 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -1522,12 +1522,14 @@ void tst_QList::initializeList() const template void tst_QList::constSharedNull() const { + QList list2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QList list1; list1.setSharable(false); QVERIFY(list1.isDetached()); - QList list2; list2.setSharable(true); +#endif QVERIFY(!list2.isDetached()); } @@ -1553,16 +1555,19 @@ void tst_QList::constSharedNullComplex() const template void generateSetSharableData() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QTest::addColumn >("list"); QTest::addColumn("size"); QTest::newRow("null") << QList() << 0; QTest::newRow("non-empty") << (QList() << T(0) << T(1) << T(2) << T(3) << T(4)) << 5; +#endif } template void runSetSharableTest() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QFETCH(QList, list); QFETCH(int, size); @@ -1602,6 +1607,7 @@ void runSetSharableTest() QCOMPARE(int(list[i]), i); QCOMPARE(list.size(), size); +#endif } void tst_QList::setSharableInt_data() const diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index e812e5a337a..00e669c1d8e 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -984,12 +984,14 @@ void tst_QMap::qmultimap_specific() void tst_QMap::const_shared_null() { + QMap map2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QMap map1; map1.setSharable(false); QVERIFY(map1.isDetached()); - QMap map2; map2.setSharable(true); +#endif QVERIFY(!map2.isDetached()); } @@ -1046,6 +1048,7 @@ const T &const_(const T &t) void tst_QMap::setSharable() { +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) QMap map; map.insert(1, "um"); @@ -1095,6 +1098,7 @@ void tst_QMap::setSharable() QVERIFY(!map.isDetached()); QVERIFY(copy.isSharedWith(map)); } +#endif } void tst_QMap::insert() @@ -1204,7 +1208,6 @@ void tst_QMap::initializerList() void tst_QMap::testInsertWithHint() { QMap map; - map.setSharable(false); // Check with end hint(); map.insert(map.constEnd(), 3, 1); // size == 1 @@ -1268,7 +1271,6 @@ void tst_QMap::testInsertWithHint() void tst_QMap::testInsertMultiWithHint() { QMap map; - map.setSharable(false); typedef QMap::const_iterator cite; // Hack since we define QT_STRICT_ITERATORS map.insertMulti(cite(map.end()), 64, 65); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index c9545c8eb48..f1efbf08125 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -265,12 +265,15 @@ private slots: void initializeListCustom(); void const_shared_null(); +#if 1 + // ### Qt6 remove this section void setSharableInt_data(); void setSharableInt(); void setSharableMovable_data(); void setSharableMovable(); void setSharableCustom_data(); void setSharableCustom(); +#endif void detachInt() const; void detachMovable() const; @@ -395,15 +398,17 @@ void tst_QVector::copyConstructor() const } { QVector v1; - v1.setSharable(false); + v1 << value1 << value2 << value3 << value4; QVector v2(v1); - QVERIFY(!v1.isSharedWith(v2)); QCOMPARE(v1, v2); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v1; - v1 << value1 << value2 << value3 << value4; + v1.setSharable(false); QVector v2(v1); + QVERIFY(!v1.isSharedWith(v2)); QCOMPARE(v1, v2); } { @@ -414,6 +419,7 @@ void tst_QVector::copyConstructor() const QVERIFY(!v1.isSharedWith(v2)); QCOMPARE(v1, v2); } +#endif } void tst_QVector::copyConstructorInt() const @@ -514,6 +520,8 @@ void tst_QVector::append() const QVERIFY(v.size() == 3); QCOMPARE(v.at(v.size() - 1), SimpleValue::at(0)); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v(2); v.reserve(12); @@ -522,6 +530,7 @@ void tst_QVector::append() const QVERIFY(v.size() == 3); QCOMPARE(v.last(), SimpleValue::at(0)); } +#endif } void tst_QVector::appendInt() const @@ -819,12 +828,15 @@ void tst_QVector::eraseEmpty() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v; v.setSharable(false); v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#endif } void tst_QVector::eraseEmptyInt() const @@ -855,6 +867,8 @@ void tst_QVector::eraseEmptyReserved() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v; v.reserve(10); @@ -862,6 +876,7 @@ void tst_QVector::eraseEmptyReserved() const v.erase(v.begin(), v.end()); QCOMPARE(v.size(), 0); } +#endif } void tst_QVector::eraseEmptyReservedInt() const @@ -968,6 +983,8 @@ void tst_QVector::erase(bool shared) const if (shared) QCOMPARE(SimpleValue::vector(12), *svc.copy); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v = SimpleValue::vector(10); SharedVectorChecker svc(v, shared); @@ -980,6 +997,7 @@ void tst_QVector::erase(bool shared) const if (shared) QCOMPARE(SimpleValue::vector(10), *svc.copy); } +#endif } void tst_QVector::eraseInt() const @@ -1052,6 +1070,8 @@ template void tst_QVector::eraseReserved() const v.erase(v.begin() + 1, v.end() - 1); QCOMPARE(v.size(), 2); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section { QVector v(10); v.reserve(16); @@ -1061,6 +1081,7 @@ template void tst_QVector::eraseReserved() const v.erase(v.begin(), v.end() - 1); QCOMPARE(v.size(), 1); } +#endif } void tst_QVector::eraseReservedInt() const @@ -1512,6 +1533,14 @@ void tst_QVector::resizePOD_data() const QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector nullNotShared; QVector emptyNotShared(0, 5); QVector emptyReservedNotShared; @@ -1530,16 +1559,12 @@ void tst_QVector::resizePOD_data() const nonEmptyNotShared.setSharable(false); nonEmptyReservedNotShared.setSharable(false); - QTest::newRow("null") << null << 10; - QTest::newRow("empty") << empty << 10; - QTest::newRow("emptyReserved") << emptyReserved << 10; - QTest::newRow("nonEmpty") << nonEmpty << 10; - QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; QTest::newRow("nullNotShared") << nullNotShared << 10; QTest::newRow("emptyNotShared") << emptyNotShared << 10; QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +#endif } void tst_QVector::resizePOD() const @@ -1583,6 +1608,14 @@ void tst_QVector::resizeComplexMovable_data() const QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector nullNotShared; QVector emptyNotShared(0, 'Q'); QVector emptyReservedNotShared; @@ -1601,16 +1634,12 @@ void tst_QVector::resizeComplexMovable_data() const nonEmptyNotShared.setSharable(false); nonEmptyReservedNotShared.setSharable(false); - QTest::newRow("null") << null << 10; - QTest::newRow("empty") << empty << 10; - QTest::newRow("emptyReserved") << emptyReserved << 10; - QTest::newRow("nonEmpty") << nonEmpty << 10; - QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; QTest::newRow("nullNotShared") << nullNotShared << 10; QTest::newRow("emptyNotShared") << emptyNotShared << 10; QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +#endif } void tst_QVector::resizeComplexMovable() const @@ -1658,6 +1687,14 @@ void tst_QVector::resizeComplex_data() const QVERIFY(emptyReserved.capacity() >= 10); QVERIFY(nonEmptyReserved.capacity() >= 15); + QTest::newRow("null") << null << 10; + QTest::newRow("empty") << empty << 10; + QTest::newRow("emptyReserved") << emptyReserved << 10; + QTest::newRow("nonEmpty") << nonEmpty << 10; + QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; + +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector nullNotShared; QVector emptyNotShared(0, '0'); QVector emptyReservedNotShared; @@ -1676,16 +1713,12 @@ void tst_QVector::resizeComplex_data() const nonEmptyNotShared.setSharable(false); nonEmptyReservedNotShared.setSharable(false); - QTest::newRow("null") << null << 10; - QTest::newRow("empty") << empty << 10; - QTest::newRow("emptyReserved") << emptyReserved << 10; - QTest::newRow("nonEmpty") << nonEmpty << 10; - QTest::newRow("nonEmptyReserved") << nonEmptyReserved << 10; QTest::newRow("nullNotShared") << nullNotShared << 10; QTest::newRow("emptyNotShared") << emptyNotShared << 10; QTest::newRow("emptyReservedNotShared") << emptyReservedNotShared << 10; QTest::newRow("nonEmptyNotShared") << nonEmptyNotShared << 10; QTest::newRow("nonEmptyReservedNotShared") << nonEmptyReservedNotShared << 10; +#endif } void tst_QVector::resizeComplex() const @@ -2070,15 +2103,20 @@ void tst_QVector::initializeListCustom() void tst_QVector::const_shared_null() { + QVector v2; +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) + // ### Qt6 remove this section QVector v1; v1.setSharable(false); QVERIFY(v1.isDetached()); - QVector v2; v2.setSharable(true); +#endif QVERIFY(!v2.isDetached()); } +#if QT_SUPPORTS(UNSHARABLE_CONTAINERS) +// ### Qt6 remove this section template void tst_QVector::setSharable_data() const { @@ -2109,21 +2147,6 @@ void tst_QVector::setSharable_data() const QTest::newRow("non-empty, Reserved") << nonEmptyReserved << 7 << 15 << true; } -void tst_QVector::setSharableInt_data() -{ - setSharable_data(); -} - -void tst_QVector::setSharableMovable_data() -{ - setSharable_data(); -} - -void tst_QVector::setSharableCustom_data() -{ - setSharable_data(); -} - template void tst_QVector::setSharable() const { @@ -2185,6 +2208,30 @@ void tst_QVector::setSharable() const .arg(vector.capacity()) .arg(capacity))); } +#else +template void tst_QVector::setSharable_data() const +{ +} + +template void tst_QVector::setSharable() const +{ +} +#endif + +void tst_QVector::setSharableInt_data() +{ + setSharable_data(); +} + +void tst_QVector::setSharableMovable_data() +{ + setSharable_data(); +} + +void tst_QVector::setSharableCustom_data() +{ + setSharable_data(); +} void tst_QVector::setSharableInt() { From 08edb8742c4c232601c97c538b2a9fadee500ac4 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Thu, 24 Apr 2014 16:17:39 +0200 Subject: [PATCH 095/180] Remove unneeded ; Warnings returned by pedantic Change-Id: I501621df6e9f39b18576625b321714a862dc971a Reviewed-by: Laszlo Agocs --- src/gui/kernel/qopenglcontext_p.h | 2 +- src/gui/painting/qblittable_p.h | 2 +- src/gui/painting/qpaintengine_blitter.cpp | 2 +- src/plugins/bearer/networkmanager/qnetworkmanagerservice.h | 4 ++-- src/plugins/platforms/eglfs/qeglfswindow.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index b21ff670680..aa1b3b6245a 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -127,7 +127,7 @@ class Q_GUI_EXPORT QOpenGLSharedResourceGuard : public QOpenGLSharedResource class Q_GUI_EXPORT QOpenGLContextGroupPrivate : public QObjectPrivate { - Q_DECLARE_PUBLIC(QOpenGLContextGroup); + Q_DECLARE_PUBLIC(QOpenGLContextGroup) public: QOpenGLContextGroupPrivate() : m_context(0) diff --git a/src/gui/painting/qblittable_p.h b/src/gui/painting/qblittable_p.h index 159e60079fc..f65549d63ce 100644 --- a/src/gui/painting/qblittable_p.h +++ b/src/gui/painting/qblittable_p.h @@ -68,7 +68,7 @@ class Q_GUI_EXPORT QBlittable // Internal ones OutlineCapability = 0x0001000 }; - Q_DECLARE_FLAGS (Capabilities, Capability); + Q_DECLARE_FLAGS (Capabilities, Capability) QBlittable(const QSize &size, Capabilities caps); virtual ~QBlittable(); diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index 26eacacd493..67a692e2db9 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -238,7 +238,7 @@ class CapabilitiesToStateMask class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate { - Q_DECLARE_PUBLIC(QBlitterPaintEngine); + Q_DECLARE_PUBLIC(QBlitterPaintEngine) public: QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p) : QRasterPaintEnginePrivate() diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 74a25c1370a..9493218024e 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -197,7 +197,7 @@ class QNetworkManagerInterfaceAccessPoint : public QObject Privacy = 0x1 }; - Q_DECLARE_FLAGS(ApFlags, ApFlag); + Q_DECLARE_FLAGS(ApFlags, ApFlag) enum ApSecurityFlag { ApSecurityNone = 0x0, @@ -213,7 +213,7 @@ class QNetworkManagerInterfaceAccessPoint : public QObject Key8021x = 0x200 }; - Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag); + Q_DECLARE_FLAGS(ApSecurityFlags, ApSecurityFlag) explicit QNetworkManagerInterfaceAccessPoint(const QString &dbusPathName, QObject *parent = 0); ~QNetworkManagerInterfaceAccessPoint(); diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index c8c31816a0c..f3fd06037ec 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -91,7 +91,7 @@ class QEglFSWindow : public QEGLPlatformWindow Created = 0x01, HasNativeWindow = 0x02 }; - Q_DECLARE_FLAGS(Flags, Flag); + Q_DECLARE_FLAGS(Flags, Flag) Flags m_flags; }; From 9a07ea69d678515d88068b7453afe378704abfc2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Apr 2014 11:03:28 -0700 Subject: [PATCH 096/180] Again to fix compilation after b0afad8f0b6a3be7ab3a23e063b0201cd68ada95 Commit 125bb81bef7729d182f533989ffdf53685abbe31 wasn't enough. Let's just make it simpler and use a regular function. Change-Id: I9627dedaa87873b4b138224afd182e4fd9a55265 Reviewed-by: Olivier Goffart --- tests/auto/corelib/codecs/utf8/tst_utf8.cpp | 23 ++++++++++++--------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index b00fd0dfd49..8755e65d0ca 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -53,11 +53,7 @@ class tst_Utf8 : public QObject // test data: QTextCodec *codec; QString (*from8BitPtr)(const char *, int); -#ifdef Q_COMPILER_REF_QUALIFIERS - QByteArray (QString:: *to8Bit)() const &; -#else - QByteArray (QString:: *to8Bit)() const; -#endif + static QByteArray to8Bit(const QString &); inline QString from8Bit(const QByteArray &ba) { return from8BitPtr(ba.constData(), ba.length()); } @@ -97,14 +93,21 @@ void tst_Utf8::init() if (useLocale) { codec = QTextCodec::codecForLocale(); from8BitPtr = &QString::fromLocal8Bit; - to8Bit = &QString::toLocal8Bit; } else { codec = QTextCodec::codecForMib(106); from8BitPtr = &QString::fromUtf8; - to8Bit = &QString::toUtf8; } } +QByteArray tst_Utf8::to8Bit(const QString &s) +{ + QFETCH_GLOBAL(bool, useLocale); + if (useLocale) + return s.toLocal8Bit(); + else + return s.toUtf8(); +} + void tst_Utf8::roundTrip_data() { QTest::addColumn("utf8"); @@ -161,11 +164,11 @@ void tst_Utf8::roundTrip() QFETCH(QByteArray, utf8); QFETCH(QString, utf16); - QCOMPARE((utf16.*to8Bit)(), utf8); + QCOMPARE(to8Bit(utf16), utf8); QCOMPARE(from8Bit(utf8), utf16); - QCOMPARE((from8Bit(utf8).*to8Bit)(), utf8); - QCOMPARE(from8Bit((utf16.*to8Bit)()), utf16); + QCOMPARE(to8Bit(from8Bit(utf8)), utf8); + QCOMPARE(from8Bit(to8Bit(utf16)), utf16); } void tst_Utf8::charByChar_data() From ec74461e9dd80d9f857038dc74cecfad1827f606 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Apr 2014 11:05:00 -0700 Subject: [PATCH 097/180] Ensure we try the UTF-8 conversions with longer strings The SSE2-based conversion only kicks in with strings with 8 characters or more in length. Change-Id: Ic1daad0845571be03547553cc001d83550f0c89c Reviewed-by: Olivier Goffart --- tests/auto/corelib/codecs/utf8/tst_utf8.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index 8755e65d0ca..d1aadab7d85 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -117,10 +117,10 @@ void tst_Utf8::roundTrip_data() QTest::newRow("nul") << QByteArray("", 1) << QString(QChar(QChar::Null)); static const char ascii[] = "This is a standard US-ASCII message"; - QTest::newRow("ascii") << QByteArray(ascii) << ascii; + QTest::newRow("ascii") << QByteArray(ascii) << QString::fromLatin1(ascii); static const char ascii2[] = "\1This\2is\3an\4US-ASCII\020 message interspersed with control chars"; - QTest::newRow("ascii2") << QByteArray(ascii2) << ascii2; + QTest::newRow("ascii2") << QByteArray(ascii2) << QString::fromLatin1(ascii2); static const char utf8_1[] = "\302\240"; // NBSP QTest::newRow("utf8_1") << QByteArray(utf8_1) << QString(QChar(QChar::Nbsp)); @@ -169,6 +169,15 @@ void tst_Utf8::roundTrip() QCOMPARE(to8Bit(from8Bit(utf8)), utf8); QCOMPARE(from8Bit(to8Bit(utf16)), utf16); + + // repeat with a longer message + utf8.prepend("12345678901234"); + utf16.prepend(QLatin1String("12345678901234")); + QCOMPARE(to8Bit(utf16), utf8); + QCOMPARE(from8Bit(utf8), utf16); + + QCOMPARE(to8Bit(from8Bit(utf8)), utf8); + QCOMPARE(from8Bit(to8Bit(utf16)), utf16); } void tst_Utf8::charByChar_data() From d7dd22bb29eb263b5dbcf52542a0bbc67da02316 Mon Sep 17 00:00:00 2001 From: Martin Jansa Date: Fri, 14 Mar 2014 19:42:18 +0100 Subject: [PATCH 098/180] configure: gtk style related cosmetical fixes * add -help text for gtkstyle * use capital GTK in warning message for consistency Change-Id: Iff522cc49497dda406dd111594857930d82e4231 Reviewed-by: Martin Jansa Reviewed-by: Oswald Buddenhagen --- configure | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 55d68efc9c6..dd356e435a8 100755 --- a/configure +++ b/configure @@ -2389,6 +2389,9 @@ Third Party Libraries: -no-alsa ........... Do not compile ALSA support. + -alsa .............. Compile ALSA support. + -no-gtkstyle ....... Do not compile GTK theme support. + + -gtkstyle .......... Compile GTK theme support. + Additional options: -make ....... Add part to the list of parts to be built at make time. @@ -4639,7 +4642,7 @@ if [ "$CFG_GLIB" = "yes" -a "$CFG_QGTKSTYLE" != "no" ]; then QMakeVar set QT_LIBS_QGTK2 "$QT_LIBS_QGTK2" else if [ "$CFG_QGTKSTYLE" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Gtk theme support cannot be enabled due to functionality tests!" + echo "GTK theme support cannot be enabled due to functionality tests!" echo " Turn on verbose messaging (-v) to $0 to see the fin al report." echo " If you believe this message is in error you may use the continue" echo " switch (-continue) to $0 to continue." From eb1325047f2697d24e93ebaf924900affc876bc1 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 24 Apr 2014 15:33:27 +0200 Subject: [PATCH 099/180] Don't crash on broken GIF images Broken GIF images could set invalid width and height values inside the image, leading to Qt creating a null QImage for it. In that case we need to abort decoding the image and return an error. Initial patch by Rich Moore. Task-number: QTBUG-38367 Change-Id: Id82a4036f478bd6e49c402d6598f57e7e5bb5e1e Security-advisory: CVE-2014-0190 Reviewed-by: Richard J. Moore --- src/gui/image/qgifhandler.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index eeb62af4e55..19b838240f1 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -359,6 +359,13 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, memset(bits, 0, image->byteCount()); } + // Check if the previous attempt to create the image failed. If it + // did then the image is broken and we should give up. + if (image->isNull()) { + state = Error; + return -1; + } + disposePrevious(image); disposed = false; From d29a750c0cc423bf65171338eeaa767f272d4ef0 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 24 Apr 2014 17:52:29 +0200 Subject: [PATCH 100/180] QAbstractSocket: enable read notification for unbuffered sockets This restores behavior for UDP sockets as it was in 5.2.1. Change 13c246ee119fdb10d91f509b968a221d4fc1d8ba introduced a behavioral change / regression in that respect. Task-number: QTBUG-37489 Change-Id: I8f0b26d763dd66ea6edcc343e91ff5c9c7bdc0f2 Reviewed-by: Richard J. Moore --- src/network/socket/qabstractsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 1ceec717c6e..b8f76f8d4f2 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -748,7 +748,7 @@ bool QAbstractSocketPrivate::canReadNotification() return true; } - if (isBuffered && socketEngine) + if ((isBuffered || socketType != QAbstractSocket::TcpSocket) && socketEngine) socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable()); // reset the read socket notifier state if we reentered inside the From 7e071cebaa731b3f635ef515627985e27726aba1 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 3 Apr 2014 15:36:27 +0200 Subject: [PATCH 101/180] Android input method fixes for SwiftKey Try to conform to the input method protocol in the way that SwiftKey expects (and the way that the stock android components actually do). * Refactor cursor position logic * fix getExtractedText() so it includes preedit text * ignore the hintMaxChars parameter to getExtractedText(), since it looks like everybody else does * fix setComposingRegion when preedit is active * track the start of the preedit and the preedit cursor position, since the Qt input method query does not give us this information Change-Id: I2ed8797abacd97ca749ca152fab2a2d5446ef603 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../android/qandroidinputcontext.cpp | 182 ++++++++++++++---- .../platforms/android/qandroidinputcontext.h | 2 + 2 files changed, 143 insertions(+), 41 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 02fda19d760..e255a49ac7f 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2012 BogDan Vatra ** Contact: http://www.qt-project.org/legal ** @@ -338,7 +339,7 @@ static JNINativeMethod methods[] = { QAndroidInputContext::QAndroidInputContext() - : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0) + : QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0) { QtAndroid::AttachedJNIEnv env; if (!env.jniEnv) @@ -431,9 +432,24 @@ QAndroidInputContext *QAndroidInputContext::androidInputContext() return m_androidInputContext; } +// cursor position getter that also works with editors that have not been updated to the new API +static inline int getAbsoluteCursorPosition(const QSharedPointer &query) +{ + QVariant absolutePos = query->value(Qt::ImAbsolutePosition); + return absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); +} + +// position of the start of the current block +static inline int getBlockPosition(const QSharedPointer &query) +{ + QVariant absolutePos = query->value(Qt::ImAbsolutePosition); + return absolutePos.isValid() ? absolutePos.toInt() - query->value(Qt::ImCursorPosition).toInt() : 0; +} + void QAndroidInputContext::reset() { clear(); + m_batchEditNestingLevel = 0; if (qGuiApp->focusObject()) QtAndroidInput::resetSoftwareKeyboard(); else @@ -449,13 +465,20 @@ void QAndroidInputContext::updateCursorPosition() { QSharedPointer query = focusObjectInputMethodQuery(); if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) { - // make sure it also works with editors that have not been updated to the new API - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); + const int cursorPos = getAbsoluteCursorPosition(query); const int composeLength = m_composingText.length(); - const int composeStart = composeLength ? cursorPos : -1; - QtAndroidInput::updateSelection(cursorPos + composeLength, cursorPos + composeLength, //empty selection - composeStart, composeStart + composeLength); // pre-edit text + + //Q_ASSERT(m_composingText.isEmpty() == (m_composingTextStart == -1)); + if (m_composingText.isEmpty() != (m_composingTextStart == -1)) + qWarning() << "Input method out of sync" << m_composingText << m_composingTextStart; + + + // Qt's idea of the cursor position is the start of the preedit area, so we have to maintain our own preedit cursor pos + int realCursorPosition = cursorPos; + if (!m_composingText.isEmpty()) + realCursorPosition = m_composingCursor; + QtAndroidInput::updateSelection(realCursorPosition, realCursorPosition, //empty selection + m_composingTextStart, m_composingTextStart + composeLength); // pre-edit text } } @@ -529,6 +552,7 @@ bool QAndroidInputContext::isComposing() const void QAndroidInputContext::clear() { m_composingText.clear(); + m_composingTextStart = -1; m_extractedText.clear(); } @@ -569,8 +593,18 @@ jboolean QAndroidInputContext::endBatchEdit() jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/) { + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_FALSE; + + + const int cursorPos = getAbsoluteCursorPosition(query); m_composingText = text; - return finishComposingText(); + m_composingTextStart = cursorPos; + m_composingCursor = cursorPos + text.length(); + finishComposingText(); + //### move cursor to newCursorPosition and call updateCursorPosition() + return JNI_TRUE; } jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint rightLength) @@ -580,6 +614,7 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right return JNI_TRUE; m_composingText.clear(); + m_composingTextStart = -1; QInputMethodEvent event; event.setCommitString(QString(), -leftLength, leftLength+rightLength); @@ -617,7 +652,9 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/) return res; } -const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/) + + +const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint /*hintMaxChars*/, jint /*hintMaxLines*/, jint /*flags*/) { // Note to self: "if the GET_EXTRACTED_TEXT_MONITOR flag is set, you should be calling // updateExtractedText(View, int, ExtractedText) whenever you call @@ -628,28 +665,37 @@ const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedTex return m_extractedText; int localPos = query->value(Qt::ImCursorPosition).toInt(); //position before pre-edit text relative to the current block - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - int blockPos = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; // position of the start of the current block - QString blockText = query->value(Qt::ImSurroundingText).toString() + m_composingText; + int blockPos = getBlockPosition(query); + QString blockText = query->value(Qt::ImSurroundingText).toString(); int composeLength = m_composingText.length(); + if (composeLength > 0) { + //Qt doesn't give us the preedit text, so we have to insert it at the correct position + int localComposePos = m_composingTextStart - blockPos; + blockText = blockText.left(localComposePos) + m_composingText + blockText.mid(localComposePos); + } + int cpos = localPos + composeLength; //actual cursor pos relative to the current block int localOffset = 0; // start of extracted text relative to the current block - if (hintMaxChars) { - if (cpos > hintMaxChars) - localOffset = cpos - hintMaxChars; - m_extractedText.text = blockText.mid(localOffset, hintMaxChars); - } - m_extractedText.startOffset = blockPos + localOffset; // "The offset in the overall text at which the extracted text starts." + // It is documented that we should try to return hintMaxChars + // characters, but that's not what the standard Android controls do, and + // there are input methods out there that (surprise) seem to depend on + // what happens in reality rather than what's documented. + + m_extractedText.text = blockText; + m_extractedText.startOffset = blockPos + localOffset; const QString &selection = query->value(Qt::ImCurrentSelection).toString(); const int selLen = selection.length(); if (selLen) { m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt() - localOffset; m_extractedText.selectionEnd = m_extractedText.selectionStart + selLen; - } else { + } else if (composeLength > 0) { + m_extractedText.selectionStart = m_composingCursor - m_extractedText.startOffset; + m_extractedText.selectionEnd = m_composingCursor - m_extractedText.startOffset; + } else { m_extractedText.selectionStart = cpos - localOffset; m_extractedText.selectionEnd = cpos - localOffset; } @@ -668,6 +714,7 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/) QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/) { + //### the preedit text could theoretically be after the cursor QVariant textAfter = queryFocusObjectThreadSafe(Qt::ImTextAfterCursor, QVariant(length)); if (textAfter.isValid()) { return textAfter.toString().left(length); @@ -703,15 +750,34 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/) if (!text.length()) return text; - const int wordLeftPos = cursorPos - length; - return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos) + m_composingText; + //### the preedit text does not need to be immediately before the cursor + if (cursorPos <= length) + return text.left(cursorPos) + m_composingText; + else + return text.mid(cursorPos - length, length) + m_composingText; } +/* + Android docs say that this function should remove the current preedit text + if any, and replace it with the given text. Any selected text should be + removed. The cursor is then moved to newCursorPosition. If > 0, this is + relative to the end of the text - 1; if <= 0, this is relative to the start + of the text. + */ + jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition) { + QSharedPointer query = focusObjectInputMethodQuery(); + if (query.isNull()) + return JNI_FALSE; + + const int cursorPos = getAbsoluteCursorPosition(query); if (newCursorPosition > 0) newCursorPosition += text.length() - 1; + m_composingText = text; + m_composingTextStart = text.isEmpty() ? -1 : cursorPos; + m_composingCursor = cursorPos + newCursorPosition; QList attributes; attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, newCursorPosition, @@ -726,23 +792,26 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur QInputMethodEvent event(m_composingText, attributes); sendInputMethodEvent(&event); - QSharedPointer query = focusObjectInputMethodQuery(); - if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) { - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); - const int preeditLength = text.length(); - QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, -1, -1); - } + updateCursorPosition(); return JNI_TRUE; } // Android docs say: // * start may be after end, same meaning as if swapped -// * this function must not trigger updateSelection +// * this function should not trigger updateSelection // * if start == end then we should stop composing jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) { + // Qt will not include the current preedit text in the query results, and interprets all + // parameters relative to the text excluding the preedit. The simplest solution is therefore to + // tell Qt that we commit the text before we set the new region. This may cause a little flicker, but is + // much more robust than trying to keep the two different world views in sync + + bool wasComposing = !m_composingText.isEmpty(); + if (wasComposing) + finishComposingText(); + QSharedPointer query = focusObjectInputMethodQuery(); if (query.isNull()) return JNI_FALSE; @@ -757,19 +826,23 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) Therefore, the length of the region is end - start */ + int length = end - start; int localPos = query->value(Qt::ImCursorPosition).toInt(); - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; + int blockPosition = getBlockPosition(query); int localStart = start - blockPosition; // Qt uses position inside block + int currentCursor = wasComposing ? m_composingCursor : blockPosition + localPos; bool updateSelectionWasBlocked = m_blockUpdateSelection; m_blockUpdateSelection = true; QString text = query->value(Qt::ImSurroundingText).toString(); + m_composingText = text.mid(localStart, length); + m_composingTextStart = start; + m_composingCursor = currentCursor; - //in the Qt text controls, the cursor position is the start of the preedit + //in the Qt text controls, the preedit is defined relative to the cursor position int relativeStart = localStart - localPos; QList attributes; @@ -781,13 +854,22 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end) QVariant(underlined))); // Keep the cursor position unchanged (don't move to end of preedit) - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, localPos - localStart, length, QVariant())); + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, currentCursor - start, 1, QVariant())); QInputMethodEvent event(m_composingText, attributes); event.setCommitString(QString(), relativeStart, length); sendInputMethodEvent(&event); m_blockUpdateSelection = updateSelectionWasBlocked; + +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + QSharedPointer query2 = focusObjectInputMethodQuery(); + if (!query2.isNull()) { + qDebug() << "Setting. Prev local cpos:" << localPos << "block pos:" <value(Qt::ImCursorPosition).toInt(); - QVariant absolutePos = query->value(Qt::ImAbsolutePosition); - int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; + int blockPosition = getBlockPosition(query); + int localCursorPos = start - blockPosition; QList attributes; - attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, - start - blockPosition, - end - start, - QVariant())); + if (!m_composingText.isEmpty() && start == end) { + // not actually changing the selection; just moving the + // preedit cursor + int localOldPos = query->value(Qt::ImCursorPosition).toInt(); + int pos = localCursorPos - localOldPos; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, pos, 1, QVariant())); + + //but we have to tell Qt about the compose text all over again + + // Show compose text underlined + QTextCharFormat underlined; + underlined.setFontUnderline(true); + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, m_composingText.length(), + QVariant(underlined))); + m_composingCursor = start; - QInputMethodEvent event(QString(), attributes); + } else { + // actually changing the selection + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, + localCursorPos, + end - start, + QVariant())); + } + QInputMethodEvent event(m_composingText, attributes); sendInputMethodEvent(&event); + updateCursorPosition(); return JNI_TRUE; } diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h index 3ce141ae152..a467e4849ef 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -134,6 +134,8 @@ private slots: private: ExtractedText m_extractedText; QString m_composingText; + int m_composingTextStart; + int m_composingCursor; QMetaObject::Connection m_updateCursorPosConnection; bool m_blockUpdateSelection; int m_batchEditNestingLevel; From 06fef71775c187de690dc54749956bad62cda2f5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 15:43:29 +0200 Subject: [PATCH 102/180] document new QTPLUGIN magic Change-Id: Ia12f55a3e6bd670cb95c21c8f896b0451dd63693 Reviewed-by: Fawzi Mohamed Reviewed-by: Leena Miettinen Reviewed-by: Oswald Buddenhagen --- qmake/doc/src/qmake-manual.qdoc | 10 +++++ .../snippets/code/doc_src_plugins-howto.pro | 4 +- src/corelib/doc/src/plugins-howto.qdoc | 43 +++++++++++++------ 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 91629ec9ddc..94fe02dc707 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2133,6 +2133,16 @@ linked with an application so that they are available as built-in resources. + qmake automatically adds the plugins that are typically needed + by the used Qt modules (see \c QT). + The defaults are tuned towards an optimal out-of-the-box experience. + See \l{Static Plugins} for a list of available plugins, and ways + to override the automatic linking. + + This variable currently has no effect when linking against a + shared/dynamic build of Qt, or when linking libraries. + It may be used for deployment of dynamic plugins at a later time. + \target QT_VERSION_variable \section1 QT_VERSION diff --git a/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro b/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro index 5eb9604ed73..dc75c1d9d76 100644 --- a/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro +++ b/src/corelib/doc/snippets/code/doc_src_plugins-howto.pro @@ -43,7 +43,7 @@ CONFIG += release #! [3] #! [4] -CONFIG += qpa_minimal_plugin +QTPLUGIN.platforms = qminimal #! [4] #! [5] @@ -53,7 +53,7 @@ QTPLUGIN += qjpeg \ #! [5] #! [6] -CONFIG -= import_qpa_plugin +QTPLUGIN.platforms = - #! [6] #! [7] diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc index 7fc4682fd48..7dc0d01ccef 100644 --- a/src/corelib/doc/src/plugins-howto.qdoc +++ b/src/corelib/doc/src/plugins-howto.qdoc @@ -266,20 +266,46 @@ To link those plugins statically, you need to add the required plugins to your build using \c QTPLUGIN. - Q_IMPORT_PLUGIN() macros are also needed in application code, - but those are automatically generated by qmake and added to - your application project. In the \c .pro file for your application, you need the following entry: \snippet code/doc_src_plugins-howto.pro 5 + qmake automatically adds the plugins to QTPLUGIN that are typically + needed by the used Qt modules (see \c QT), while more specialized + plugins need to be added manually. + The default list of automatically added plugins can be overridden + per type. + For example, to link the minimal plugin instead of the default Qt + platform adaptation plugin, use: + + \snippet code/doc_src_plugins-howto.pro 4 + + If you want neither the default nor the minimal QPA plugin to be + linked automatically, use: + + \snippet code/doc_src_plugins-howto.pro 6 + + The defaults are tuned towards an optimal out-of-the-box experience, + but may unnecessarily bloat the application. + It is recommended to inspect the linker command line built by qmake + and eliminate unnecessary plugins. + + \section2 Details of Linking Static Plugins + + To cause static plugins actually being linked and instantiated, + Q_IMPORT_PLUGIN() macros are also needed in application code, + but those are automatically generated by qmake and added to + your application project. + If you do not want all plugins added to QTPLUGIN to be automatically linked, remove \c import_plugins from the \c CONFIG variable: \snippet code/doc_src_plugins-howto.pro 7 + \section2 Creating Static Plugins + It is also possible to create your own static plugins, by following these steps: @@ -298,17 +324,6 @@ to make sure that the \c{QT_STATICPLUGIN} preprocessor macro is defined. - The default Qt platform adaptation plugin is automatically added to QTPLUGIN - in static builds. If you want to add the minimal plugin instead, add \c qpa_minimal_plugin - to \c CONFIG: - - \snippet code/doc_src_plugins-howto.pro 4 - - If you want neither the default nor the minimal QPA plugin to be linked automatically, - remove \c import_qpa_plugin from \c CONFIG: - - \snippet code/doc_src_plugins-howto.pro 6 - \section1 Deploying and Debugging Plugins The \l{Deploying Plugins} document covers the process of deploying From a162a3cbbc3c27b42c86f870aba051a408f04ed4 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 23 Apr 2014 16:26:26 +0200 Subject: [PATCH 103/180] Android: Add "unversioned_libname" configuration On Android, there's a limitation set on the names of the libraries you deploy that they must start with "lib" and end with ".so", so Android apps will link against and deploy with the unversioned libQt5FooBar.so libraries. When cross-compiling on Windows however, due to the lack of symbolic links, the only installed library used to be the main library target "libQt5FooBar.so.X.Y.Z" (for version X.Y.Z.) This has been worked around in packaging, but breaks building add-on modules on top of Qt, and is clearly wrong. This patch introduces a new "unversioned_libname" configuration in qmake which is currently only supported for the Unix makefile generator and only enabled for Android builds. When it is enabled, only the unversioned library "libQt5FooBar.so" will be created. Task-number: QTBUG-38347 Change-Id: Ia8897ca7a23a62e2a526d0e02854899b02eb19dc Reviewed-by: Oswald Buddenhagen --- mkspecs/android-g++/qmake.conf | 2 +- qmake/generators/unix/unixmake.cpp | 4 +- qmake/generators/unix/unixmake2.cpp | 70 +++++++++++++++++++---------- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 44624fcca52..c9497edfad9 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -3,7 +3,7 @@ MAKEFILE_GENERATOR = UNIX QMAKE_PLATFORM = android QMAKE_COMPILER = gcc -CONFIG += android_install unversioned_soname android_deployment_settings +CONFIG += android_install unversioned_soname unversioned_libname android_deployment_settings include(../common/linux.conf) include(../common/gcc-base-unix.conf) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 4c3df4efe8f..5ea47cc8674 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -749,7 +749,9 @@ UnixMakefileGenerator::defaultInstall(const QString &t) target = "$(QMAKE_TARGET)"; } else if(project->first("TEMPLATE") == "lib") { if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) { - if(!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin")) { + if (!project->isActiveConfig("staticlib") + && !project->isActiveConfig("plugin") + && !project->isActiveConfig("unversioned_libname")) { if(project->isEmpty("QMAKE_HPUX_SHLIB")) { links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)"; } else { diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 6e08c138edb..a28760015e0 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -234,14 +234,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_BUNDLE")) { t << "TARGETD = " << escapeFilePath(var("TARGET_x.y")) << endl; t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; - } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { - t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; - t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; - t << "TARGET1 = " << escapeFilePath(var("TARGET_x")) << endl; - t << "TARGET2 = " << escapeFilePath(var("TARGET_x.y")) << endl; - } else { - t << "TARGETD = " << escapeFilePath(var("TARGET_x")) << endl; + } else if (!project->isActiveConfig("unversioned_libname")) { t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; + if (project->isEmpty("QMAKE_HPUX_SHLIB")) { + t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; + t << "TARGET1 = " << escapeFilePath(var("TARGET_x")) << endl; + t << "TARGET2 = " << escapeFilePath(var("TARGET_x.y")) << endl; + } else { + t << "TARGETD = " << escapeFilePath(var("TARGET_x")) << endl; + } } } writeExtraCompilerVariables(t); @@ -574,22 +575,36 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { - t << "\n\t" - << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)\n\t" - << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; - t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); - if(!destdir.isEmpty()) + t << "\n\t"; + + if (!project->isActiveConfig("unversioned_libname")) + t << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)"; + else + t << "-$(DEL_FILE) $(TARGET)"; + + t << "\n\t" << var("QMAKE_LINK_SHLIB_CMD"); + + if (!project->isActiveConfig("unversioned_libname")) { + t << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); + } + if (!destdir.isEmpty()) { t << "\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t" - << "-$(MOVE) $(TARGET) " << destdir << " \n\t" - << "-$(MOVE) $(TARGET0) " << destdir << " \n\t" - << "-$(MOVE) $(TARGET1) " << destdir << " \n\t" - << "-$(MOVE) $(TARGET2) " << destdir << " \n\t"; + << "-$(MOVE) $(TARGET) " << destdir << " "; + + if (!project->isActiveConfig("unversioned_libname")) { + t << "\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t" + << "-$(MOVE) $(TARGET0) " << destdir << " \n\t" + << "-$(MOVE) $(TARGET1) " << destdir << " \n\t" + << "-$(MOVE) $(TARGET2) " << destdir << " "; + } + } if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; @@ -924,8 +939,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty() && !project->isActiveConfig("plugin")) { t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n"; - t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " - << destdir << "$(TARGET2) $(TARGETA)\n"; + if (!project->isActiveConfig("unversioned_libname")) { + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " + << destdir << "$(TARGET2) $(TARGETA)\n"; + } else { + t << "\t-$(DEL_FILE) $(TARGETA)\n"; + } } else { t << "\t-$(DEL_FILE) " << destdir << "$(TARGET) \n"; } @@ -1165,7 +1184,10 @@ void UnixMakefileGenerator::init2() project->first("VER_MIN") + "." + project->first("VER_PAT")); } - project->values("TARGET") = project->values("TARGET_x.y.z"); + if (project->isActiveConfig("unversioned_libname")) + project->values("TARGET") = project->values("TARGET_"); + else + project->values("TARGET") = project->values("TARGET_x.y.z"); } if(project->isEmpty("QMAKE_LN_SHLIB")) project->values("QMAKE_LN_SHLIB").append("ln -s"); From c0825cbfc0c568542a9e4c09e23d42eb76a5a706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 24 Apr 2014 14:34:34 +0200 Subject: [PATCH 104/180] Cocoa: Make Qt::Tool windows hide on deactivate This is a regression from 5.1. Task-number: QTBUG-37706 Change-Id: Ib28eead869dde37ded37397a89a94b67fb150cca Reviewed-by: Gabriel de Dietrich Reviewed-by: Liang Qi --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5def64ee0a6..60152b56b20 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1375,7 +1375,8 @@ - (void)dealloc qPlatformWindow:this]; if ((type & Qt::Popup) == Qt::Popup) [window setHasShadow:YES]; - [window setHidesOnDeactivate: NO]; + + [window setHidesOnDeactivate:(type & Qt::Tool) == Qt::Tool]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { From 89ecac46075e51c8125a96bb98e99d39f546dacd Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 23 Apr 2014 15:12:46 +0200 Subject: [PATCH 105/180] QSqlError: Mark deprecated functiond with QT_DEPRECATED And move the default argument from the deprecated constructor to the new one Also make sure that the error number is consistent across the two constructor Change-Id: I3721266b39ab493f0add35b2d1f892b2f6094992 Reviewed-by: Lars Knoll --- src/sql/kernel/qsqlerror.cpp | 5 +++-- src/sql/kernel/qsqlerror.h | 16 +++++++--------- .../sql/kernel/qsqlerror/tst_qsqlerror.cpp | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/sql/kernel/qsqlerror.cpp b/src/sql/kernel/qsqlerror.cpp index 1763722e8ac..1979e5d1f58 100644 --- a/src/sql/kernel/qsqlerror.cpp +++ b/src/sql/kernel/qsqlerror.cpp @@ -107,7 +107,8 @@ QSqlError::QSqlError(const QString& driverText, const QString& databaseText, Err d->driverError = driverText; d->databaseError = databaseText; d->errorType = type; - d->errorCode = QString::number(number); + if (number != -1) + d->errorCode = QString::number(number); } #endif @@ -287,7 +288,7 @@ void QSqlError::setType(ErrorType type) #if QT_DEPRECATED_SINCE(5, 3) int QSqlError::number() const { - return d->errorCode.toInt(); + return d->errorCode.isEmpty() ? -1 : d->errorCode.toInt(); } #endif diff --git a/src/sql/kernel/qsqlerror.h b/src/sql/kernel/qsqlerror.h index 4e27ab03ae8..679e0f9e3cb 100644 --- a/src/sql/kernel/qsqlerror.h +++ b/src/sql/kernel/qsqlerror.h @@ -60,15 +60,13 @@ class Q_SQL_EXPORT QSqlError UnknownError }; #if QT_DEPRECATED_SINCE(5, 3) - QSqlError( const QString& driverText = QString(), - const QString& databaseText = QString(), - ErrorType type = NoError, - int number = -1); + QT_DEPRECATED QSqlError(const QString &driverText, const QString &databaseText, + ErrorType type, int number); #endif - QSqlError(const QString &driverText, - const QString &databaseText, - ErrorType type, - const QString &errorCode); + QSqlError(const QString &driverText = QString(), + const QString &databaseText = QString(), + ErrorType type = NoError, + const QString &errorCode = QString()); QSqlError(const QSqlError& other); QSqlError& operator=(const QSqlError& other); bool operator==(const QSqlError& other) const; @@ -79,7 +77,7 @@ class Q_SQL_EXPORT QSqlError QString databaseText() const; ErrorType type() const; #if QT_DEPRECATED_SINCE(5, 3) - int number() const; + QT_DEPRECATED int number() const; #endif QString nativeErrorCode() const; QString text() const; diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp index 9763e3e7e6b..847453b3ed4 100644 --- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp +++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp @@ -102,6 +102,7 @@ void tst_QSqlError::construction() QCOMPARE(obj1.databaseText(), QString("databasetext")); QCOMPARE(obj1.type(), QSqlError::UnknownError); QCOMPARE(obj1.number(), 123); + QCOMPARE(obj1.nativeErrorCode(), QStringLiteral("123")); QVERIFY(obj1.isValid()); QSqlError obj2(obj1); @@ -109,6 +110,7 @@ void tst_QSqlError::construction() QCOMPARE(obj2.databaseText(), obj1.databaseText()); QCOMPARE(obj2.type(), obj1.type()); QCOMPARE(obj2.number(), obj1.number()); + QCOMPARE(obj2.nativeErrorCode(), obj1.nativeErrorCode()); QVERIFY(obj2.isValid()); QSqlError obj3 = obj2; @@ -116,10 +118,16 @@ void tst_QSqlError::construction() QCOMPARE(obj3.databaseText(), obj2.databaseText()); QCOMPARE(obj3.type(), obj2.type()); QCOMPARE(obj3.number(), obj2.number()); + QCOMPARE(obj3.nativeErrorCode(), obj2.nativeErrorCode()); QVERIFY(obj3.isValid()); QSqlError obj4; QVERIFY(!obj4.isValid()); + QCOMPARE(obj4.driverText(), QString()); + QCOMPARE(obj4.databaseText(), QString()); + QCOMPARE(obj4.type(), QSqlError::NoError); + QCOMPARE(obj4.number(), -1); + QCOMPARE(obj4.nativeErrorCode(), QString()); QSqlError obj5(QStringLiteral("drivertext"), QStringLiteral("databasetext"), QSqlError::UnknownError, QStringLiteral("123")); @@ -138,6 +146,16 @@ void tst_QSqlError::construction() QCOMPARE(obj6.number(), 0); QCOMPARE(obj6.nativeErrorCode(), QStringLiteral("Err123")); QVERIFY(obj6.isValid()); + + // Default constructed object as constructed before Qt 5.3 + QSqlError obj7(QString(), QString(), QSqlError::NoError, -1); + QVERIFY(!obj7.isValid()); + QCOMPARE(obj7.driverText(), QString()); + QCOMPARE(obj7.databaseText(), QString()); + QCOMPARE(obj7.type(), QSqlError::NoError); + QCOMPARE(obj7.number(), -1); + QCOMPARE(obj7.nativeErrorCode(), QString()); + } void tst_QSqlError::operators() From 58bb42dc2c338338b7b6079993ace3d55c2e1d7e Mon Sep 17 00:00:00 2001 From: John Layt Date: Wed, 16 Apr 2014 15:56:13 +0200 Subject: [PATCH 106/180] QPrintEngine - Fix alpha engine state sync Move the copy of the paint engine to after the engine state has been synced, otherwise the transform is incorrectly applied after the new page. Task-number: QTBUG-38329 Change-Id: I2e134889b3ef10f6e3dce42edac2a58e78c66c30 Reviewed-by: Michael Bruning Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw Reviewed-by: Lars Knoll --- src/printsupport/kernel/qpaintengine_alpha.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp index 7d4dc181114..ddfa918b90f 100644 --- a/src/printsupport/kernel/qpaintengine_alpha.cpp +++ b/src/printsupport/kernel/qpaintengine_alpha.cpp @@ -345,8 +345,8 @@ void QAlphaPaintEngine::flushAndInit(bool init) d->m_picpainter->setFont(painter()->font()); d->m_picpainter->setOpacity(painter()->opacity()); d->m_picpainter->setTransform(painter()->combinedTransform()); - *d->m_picpainter->d_func()->state = *painter()->d_func()->state; d->m_picengine->syncState(); + *d->m_picpainter->d_func()->state = *painter()->d_func()->state; } } From c1625ef8237cff4d313a07ac7091a50c9444a106 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 23 Apr 2014 08:54:12 +0300 Subject: [PATCH 107/180] Fix vcxproj generation on Windows Phone f412f2b5 refactored the platform tool set retrieval, but made the call too early to choose the right tool set on Windows Phone. This fixes the call so that it does not depend on the WinPhone member variable, and also makes it forward-compatible with Windows Phone 8.1. Task-number: QTBUG-38516 Change-Id: Ide91563f5c7f909c4d1a258adc29af6c94595dc9 Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_vcproj.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index ac258e2841b..2bd3301e16c 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -397,8 +397,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return envVar; QString suffix; - if (vcProject.Configuration.WinPhone) - suffix = "_wp80"; + if (project->isActiveConfig("winphone")) + suffix = '_' + project->first("WINTARGET_VER").toQString().toLower(); else if (project->first("QMAKE_TARGET_OS") == "xp") suffix = "_xp"; From 93c6976a394275d5fdad6266512925f6c7c94911 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Apr 2014 16:45:55 -0700 Subject: [PATCH 108/180] Un-export QSignalBlocker: it's all inline Change-Id: I0fb5a30eebd9edba853b7e4bd74cc7e9b06da486 Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart --- src/corelib/kernel/qobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index ee6ef23139c..a54690606a3 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -549,7 +549,7 @@ template inline const char * qobject_interface_iid() Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *); #endif -class Q_CORE_EXPORT QSignalBlocker +class QSignalBlocker { public: inline explicit QSignalBlocker(QObject *o); From d8cd99992f1f09aa1ce51fb7611983b9d47c7d8b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Apr 2014 15:40:26 +0200 Subject: [PATCH 109/180] Stabilize tst_qfiledialog. selectFile(): Ensure dialog is destroyed before the temporary file to prevent leak. selectFiles(): Introduce scopes to prevent co-existence of 2 instances of QFileDialog, which causes warnings from file watchers and occasional crashes in accessibility. Discovered while investigating: Task-number: QTBUG-38414 Change-Id: I94d2bb3e05538416286641cb08a88d8b3837a8a6 Reviewed-by: Frederik Gladhorn --- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index d360a646f15..de8528216d9 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -857,36 +857,38 @@ void tst_QFiledialog::selectFile() { QFETCH(QString, file); QFETCH(int, count); - QNonNativeFileDialog fd; - QFileSystemModel *model = fd.findChild("qt_filesystem_model"); + QScopedPointer fd(new QNonNativeFileDialog); + QFileSystemModel *model = fd->findChild("qt_filesystem_model"); QVERIFY(model); - fd.setDirectory(QDir::currentPath()); + fd->setDirectory(QDir::currentPath()); // default value - QCOMPARE(fd.selectedFiles().count(), 1); + QCOMPARE(fd->selectedFiles().count(), 1); - QTemporaryFile tempFile(QDir::tempPath() + "/aXXXXXX"); - bool inTemp = (file == "temp"); - if (inTemp) { - tempFile.open(); - file = tempFile.fileName(); + QScopedPointer tempFile; + if (file == QLatin1String("temp")) { + tempFile.reset(new QTemporaryFile(QDir::tempPath() + QStringLiteral("/aXXXXXX"))); + QVERIFY(tempFile->open()); + file = tempFile->fileName(); } - fd.selectFile(file); - QCOMPARE(fd.selectedFiles().count(), count); - if (inTemp) { - QCOMPARE(model->index(fd.directory().path()), model->index(QDir::tempPath())); + fd->selectFile(file); + QCOMPARE(fd->selectedFiles().count(), count); + if (tempFile.isNull()) { + QCOMPARE(model->index(fd->directory().path()), model->index(QDir::currentPath())); } else { - QCOMPARE(model->index(fd.directory().path()), model->index(QDir::currentPath())); + QCOMPARE(model->index(fd->directory().path()), model->index(QDir::tempPath())); } + fd.reset(); // Ensure the file dialog let's go of the temporary file for "temp". } void tst_QFiledialog::selectFiles() { - QNonNativeFileDialog fd; - fd.setViewMode(QFileDialog::List); QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); const QString tempPath = tempDir.path(); + { + QNonNativeFileDialog fd; + fd.setViewMode(QFileDialog::List); fd.setDirectory(tempPath); QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(QString))); QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(QString))); @@ -931,17 +933,20 @@ void tst_QFiledialog::selectFiles() QCOMPARE(spyFilesSelected.count(), 0); QCOMPARE(spyFilterSelected.count(), 0); - //If the selection is invalid then we fill the line edit but without the / - QNonNativeFileDialog * dialog = new QNonNativeFileDialog( 0, "Save" ); - dialog->setFileMode( QFileDialog::AnyFile ); - dialog->setAcceptMode( QFileDialog::AcceptSave ); - dialog->selectFile(tempPath + QStringLiteral("/blah")); - dialog->show(); - QVERIFY(QTest::qWaitForWindowExposed(dialog)); - QLineEdit *lineEdit = dialog->findChild("fileNameEdit"); - QVERIFY(lineEdit); - QCOMPARE(lineEdit->text(),QLatin1String("blah")); - delete dialog; + } + + { + //If the selection is invalid then we fill the line edit but without the / + QNonNativeFileDialog dialog( 0, "Save" ); + dialog.setFileMode( QFileDialog::AnyFile ); + dialog.setAcceptMode( QFileDialog::AcceptSave ); + dialog.selectFile(tempPath + QStringLiteral("/blah")); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + QLineEdit *lineEdit = dialog.findChild("fileNameEdit"); + QVERIFY(lineEdit); + QCOMPARE(lineEdit->text(),QLatin1String("blah")); + } } void tst_QFiledialog::viewMode() From 403a9d97d618916b8d15504b198e9d83b56fdea2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 17 Apr 2014 11:38:56 +0200 Subject: [PATCH 110/180] Stabilize tst_qfilesystemwatcher::watchFileAndItsDirectory(). Use QTRY_COMPARE for dirChangedSpy, remove all unneeded remove()/setPermission() calls (originating from the time the test did not use QTemporaryFile), add more QVERIFY() and messages for the other operations. Task-number: QTBUG-30943 Change-Id: Ib3b78b1c6922539fd5e9238aa017fcdb554aacc8 Reviewed-by: Sergio Ahumada Reviewed-by: Robin Burchell --- .../tst_qfilesystemwatcher.cpp | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index a58c7dfb4b9..4f7ddce9c34 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.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 test suite of the Qt Toolkit. @@ -405,6 +405,13 @@ void tst_QFileSystemWatcher::removePaths() watcher.removePaths(paths); } +static QByteArray msgFileOperationFailed(const char *what, const QFile &f) +{ + return what + QByteArrayLiteral(" failed on \"") + + QDir::toNativeSeparators(f.fileName()).toLocal8Bit() + + QByteArrayLiteral("\": ") + f.errorString().toLocal8Bit(); +} + void tst_QFileSystemWatcher::watchFileAndItsDirectory() { QFETCH(QString, backend); @@ -420,14 +427,10 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() QString testFileName = testDir.filePath("testFile.txt"); QString secondFileName = testDir.filePath("testFile2.txt"); - QFile::remove(secondFileName); QFile testFile(testFileName); - testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner); - testFile.remove(); - - QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); - testFile.write(QByteArray("hello")); + QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", testFile)); + QVERIFY2(testFile.write(QByteArrayLiteral("hello")) > 0, msgFileOperationFailed("write", testFile)); testFile.close(); QFileSystemWatcher watcher; @@ -449,8 +452,8 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() // wait before modifying the directory... QTest::qWait(2000); - QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); - testFile.write(QByteArray("hello again")); + QVERIFY2(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", testFile)); + QVERIFY2(testFile.write(QByteArrayLiteral("hello again")), msgFileOperationFailed("write", testFile)); testFile.close(); #ifdef Q_OS_MAC @@ -472,8 +475,8 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() fileChangedSpy.clear(); dirChangedSpy.clear(); QFile secondFile(secondFileName); - secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate); - secondFile.write("Foo"); + QVERIFY2(secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate), msgFileOperationFailed("open", secondFile)); + QVERIFY2(secondFile.write(QByteArrayLiteral("Foo")) > 0, msgFileOperationFailed("write", secondFile)); secondFile.close(); timer.start(3000); @@ -491,17 +494,17 @@ void tst_QFileSystemWatcher::watchFileAndItsDirectory() dirChangedSpy.clear(); - QFile::remove(testFileName); + QVERIFY(QFile::remove(testFileName)); QTRY_VERIFY(fileChangedSpy.count() > 0); - QCOMPARE(dirChangedSpy.count(), 1); + QTRY_COMPARE(dirChangedSpy.count(), 1); fileChangedSpy.clear(); dirChangedSpy.clear(); // removing a deleted file should fail QVERIFY(!watcher.removePath(testFileName)); - QFile::remove(secondFileName); + QVERIFY(QFile::remove(secondFileName)); timer.start(3000); eventLoop.exec(); From 61ce16d25c1eb837f93ab737cafe36893e27e0d3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Apr 2014 16:51:07 +0200 Subject: [PATCH 111/180] Stabilize tst_qfilesystemmodel::rowsInserted() on Windows. Introduce QTRY_COMPARE to let the sorting finish instead of a hard-coded time-out. Task-number: QTBUG-29403 Change-Id: I813bf6bcfe7110f49a5b95db589ed8a3f559db89 Reviewed-by: Frederik Gladhorn --- .../qfilesystemmodel/tst_qfilesystemmodel.cpp | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 9e0446388ee..39250904659 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.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 test suite of the Qt Toolkit. @@ -476,13 +476,19 @@ void tst_QFileSystemModel::rowCount() void tst_QFileSystemModel::rowsInserted_data() { QTest::addColumn("count"); - QTest::addColumn("assending"); + QTest::addColumn("ascending"); for (int i = 0; i < 4; ++i) { QTest::newRow(QString("Qt::AscendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::AscendingOrder; QTest::newRow(QString("Qt::DescendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::DescendingOrder; } } +static inline QString lastEntry(const QModelIndex &root) +{ + const QAbstractItemModel *model = root.model(); + return model->index(model->rowCount(root) - 1, 0, root).data().toString(); +} + void tst_QFileSystemModel::rowsInserted() { #if defined(Q_OS_WINCE) @@ -492,9 +498,9 @@ void tst_QFileSystemModel::rowsInserted() rowCount(); QModelIndex root = model->index(model->rootPath()); - QFETCH(int, assending); + QFETCH(int, ascending); QFETCH(int, count); - model->sort(0, (Qt::SortOrder)assending); + model->sort(0, (Qt::SortOrder)ascending); QSignalSpy spy0(model, SIGNAL(rowsInserted(QModelIndex,int,int))); QSignalSpy spy1(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); @@ -505,7 +511,6 @@ void tst_QFileSystemModel::rowsInserted() QVERIFY(createFiles(tmp, files, 5)); TRY_WAIT(model->rowCount(root) == oldCount + count); QTRY_COMPARE(model->rowCount(root), oldCount + count); - QTest::qWait(100); // Let the sort settle. int totalRowsInserted = 0; for (int i = 0; i < spy0.count(); ++i) { int start = spy0[i].value(1).toInt(); @@ -513,12 +518,9 @@ void tst_QFileSystemModel::rowsInserted() totalRowsInserted += end - start + 1; } QCOMPARE(totalRowsInserted, count); - if (assending == (Qt::SortOrder)Qt::AscendingOrder) { - QString letter = model->index(model->rowCount(root) - 1, 0, root).data().toString(); - QCOMPARE(letter, QString("j")); - } else { - QCOMPARE(model->index(model->rowCount(root) - 1, 0, root).data().toString(), QString("b")); - } + const QString expected = ascending == Qt::AscendingOrder ? QStringLiteral("j") : QStringLiteral("b"); + QTRY_COMPARE(lastEntry(root), expected); + if (spy0.count() > 0) { if (count == 0) QCOMPARE(spy0.count(), 0); @@ -548,8 +550,8 @@ void tst_QFileSystemModel::rowsRemoved() QModelIndex root = model->index(model->rootPath()); QFETCH(int, count); - QFETCH(int, assending); - model->sort(0, (Qt::SortOrder)assending); + QFETCH(int, ascending); + model->sort(0, (Qt::SortOrder)ascending); QTest::qWait(WAITTIME); QSignalSpy spy0(model, SIGNAL(rowsRemoved(QModelIndex,int,int))); From 817fe67839154e43998df2f459becf5e08fa5b8b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 24 Apr 2014 13:09:01 +0200 Subject: [PATCH 112/180] Improve COM error handling in the Windows platform plugin. Add error strings, print warning if OleInitialize() fails. Task-number: QTBUG-38398 Change-Id: I37f6b7003fd1cf524ce69d6843891943402b27a1 Reviewed-by: Joerg Bornemann --- .../platforms/windows/qwindowscontext.cpp | 70 ++++++++++++++----- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index af7713ba6f5..c210303e1e3 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Samuel Gaist -** 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 plugins of the Qt Toolkit. @@ -76,6 +76,9 @@ #include #include #include +#ifndef Q_OS_WINCE +# include +#endif QT_BEGIN_NAMESPACE @@ -309,6 +312,10 @@ QWindowsContextPrivate::QWindowsContextPrivate() m_systemInfo |= QWindowsContext::SI_RTL_Extensions; m_keyMapper.setUseRTLExtensions(true); } + if (FAILED(m_oleInitializeResult)) { + qWarning() << "QWindowsContext: OleInitialize() failed: " + << QWindowsContext::comErrorString(m_oleInitializeResult); + } } QWindowsContext::QWindowsContext() : @@ -691,45 +698,70 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, QByteArray QWindowsContext::comErrorString(HRESULT hr) { + QByteArray result = QByteArrayLiteral("COM error 0x") + + QByteArray::number(quintptr(hr), 16) + ' '; switch (hr) { case S_OK: - return QByteArrayLiteral("S_OK"); + result += QByteArrayLiteral("S_OK"); + break; case S_FALSE: - return QByteArrayLiteral("S_FALSE"); + result += QByteArrayLiteral("S_FALSE"); + break; case E_UNEXPECTED: - return QByteArrayLiteral("E_UNEXPECTED"); + result += QByteArrayLiteral("E_UNEXPECTED"); + break; case CO_E_ALREADYINITIALIZED: - return QByteArrayLiteral("CO_E_ALREADYINITIALIZED"); + result += QByteArrayLiteral("CO_E_ALREADYINITIALIZED"); + break; case CO_E_NOTINITIALIZED: - return QByteArrayLiteral("CO_E_NOTINITIALIZED"); + result += QByteArrayLiteral("CO_E_NOTINITIALIZED"); + break; case RPC_E_CHANGED_MODE: - return QByteArrayLiteral("RPC_E_CHANGED_MODE"); + result += QByteArrayLiteral("RPC_E_CHANGED_MODE"); + break; case OLE_E_WRONGCOMPOBJ: - return QByteArrayLiteral("OLE_E_WRONGCOMPOBJ"); + result += QByteArrayLiteral("OLE_E_WRONGCOMPOBJ"); + break; case CO_E_NOT_SUPPORTED: - return QByteArrayLiteral("CO_E_NOT_SUPPORTED"); + result += QByteArrayLiteral("CO_E_NOT_SUPPORTED"); + break; case E_NOTIMPL: - return QByteArrayLiteral("E_NOTIMPL"); + result += QByteArrayLiteral("E_NOTIMPL"); + break; case E_INVALIDARG: - return QByteArrayLiteral("E_INVALIDARG"); + result += QByteArrayLiteral("E_INVALIDARG"); + break; case E_NOINTERFACE: - return QByteArrayLiteral("E_NOINTERFACE"); + result += QByteArrayLiteral("E_NOINTERFACE"); + break; case E_POINTER: - return QByteArrayLiteral("E_POINTER"); + result += QByteArrayLiteral("E_POINTER"); + break; case E_HANDLE: - return QByteArrayLiteral("E_HANDLE"); + result += QByteArrayLiteral("E_HANDLE"); + break; case E_ABORT: - return QByteArrayLiteral("E_ABORT"); + result += QByteArrayLiteral("E_ABORT"); + break; case E_FAIL: - return QByteArrayLiteral("E_FAIL"); + result += QByteArrayLiteral("E_FAIL"); + break; case RPC_E_WRONG_THREAD: - return QByteArrayLiteral("RPC_E_WRONG_THREAD"); + result += QByteArrayLiteral("RPC_E_WRONG_THREAD"); + break; case RPC_E_THREAD_NOT_INIT: - return QByteArrayLiteral("RPC_E_THREAD_NOT_INIT"); + result += QByteArrayLiteral("RPC_E_THREAD_NOT_INIT"); + break; default: break; } - return "Unknown error 0x" + QByteArray::number(quint64(hr), 16); +#ifndef Q_OS_WINCE + _com_error error(hr); + result += QByteArrayLiteral(" ("); + result += QString::fromWCharArray(error.ErrorMessage()).toLocal8Bit(); + result += ')'; +#endif // !Q_OS_WINCE + return result; } /*! From 42bc626e4ee09d820b4b516b358882f0b3e7a37a Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Thu, 24 Apr 2014 13:58:21 +0300 Subject: [PATCH 113/180] Direct2D QPA: Disable vsync We shouldn't block the whole gui thread for vsyncing. This can slow things down a lot if a lot of drawing happens. Change-Id: Ie459f9dee2271e7908e2b7f56873393c67f82836 Reviewed-by: Risto Avila Reviewed-by: Andrew Knight --- src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index a7cd8aedab8..50d0cb81f59 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -128,7 +128,7 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion } m_bitmap->deviceContext()->end(); - m_swapChain->Present(1, 0); + m_swapChain->Present(0, 0); } void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size) From 5611b66c901867a2ea2855c90454c2267ef197dd Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 23 Apr 2014 14:23:38 +0300 Subject: [PATCH 114/180] Direct2D QPA: Optimize Clipping Use axis aligned clips when possible instead of layer-clipping. This can be much faster when a lot of clipping operations take place. Change-Id: I6865d69fc917a7da858033b4c362b307724d9006 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- src/gui/painting/qpaintengine_raster.cpp | 33 +---- src/gui/painting/qvectorpath_p.h | 28 +++- .../direct2d/qwindowsdirect2dpaintengine.cpp | 120 +++++++++--------- .../direct2d/qwindowsdirect2dpaintengine.h | 6 +- 4 files changed, 96 insertions(+), 91 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index bfcb24ae3ae..ce8c1d1ca7f 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.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 QtGui module of the Qt Toolkit. @@ -235,21 +235,6 @@ static const QRectF boundingRect(const QPointF *points, int pointCount) } #endif -template static inline bool isRect(const T *pts, int elementCount) { - return (elementCount == 5 // 5-point polygon, check for closed rect - && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point - && pts[0] == pts[6] && pts[2] == pts[4] // x values equal - && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... - && pts[0] < pts[4] && pts[1] < pts[5] - ) || - (elementCount == 4 // 4-point polygon, check for unclosed rect - && pts[0] == pts[6] && pts[2] == pts[4] // x values equal - && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... - && pts[0] < pts[4] && pts[1] < pts[5] - ); -} - - static void qt_ft_outline_move_to(qfixed x, qfixed y, void *data) { ((QOutlineMapper *) data)->moveTo(QPointF(qt_fixed_to_real(x), qt_fixed_to_real(y))); @@ -1193,22 +1178,14 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); - const qreal *points = path.points(); - const QPainterPath::ElementType *types = path.elements(); - // There are some cases that are not supported by clip(QRect) if (op != Qt::IntersectClip || !s->clip || s->clip->hasRectClip || s->clip->hasRegionClip) { if (s->matrix.type() <= QTransform::TxScale - && ((path.shape() == QVectorPath::RectangleHint) - || (isRect(points, path.elementCount()) - && (!types || (types[0] == QPainterPath::MoveToElement - && types[1] == QPainterPath::LineToElement - && types[2] == QPainterPath::LineToElement - && types[3] == QPainterPath::LineToElement))))) { + && path.isRect()) { #ifdef QT_DEBUG_DRAW qDebug() << " --- optimizing vector clip to rect clip..."; #endif - + const qreal *points = path.points(); QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]); if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op)) return; @@ -1939,7 +1916,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly #endif Q_ASSERT(pointCount >= 2); - if (mode != PolylineMode && isRect((qreal *) points, pointCount)) { + if (mode != PolylineMode && QVectorPath::isRect((qreal *) points, pointCount)) { QRectF r(points[0], points[2]); drawRects(&r, 1); return; @@ -1980,7 +1957,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg qDebug() << " - " << points[i]; #endif Q_ASSERT(pointCount >= 2); - if (mode != PolylineMode && isRect((int *) points, pointCount)) { + if (mode != PolylineMode && QVectorPath::isRect((int *) points, pointCount)) { QRect r(points[0].x(), points[0].y(), points[2].x() - points[0].x(), diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index e97d6e1dce6..ca95c325979 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -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 QtGui module of the Qt Toolkit. @@ -167,6 +167,32 @@ class Q_GUI_EXPORT QVectorPath return 0; } + template static inline bool isRect(const T *pts, int elementCount) { + return (elementCount == 5 // 5-point polygon, check for closed rect + && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point + && pts[0] == pts[6] && pts[2] == pts[4] // x values equal + && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... + && pts[0] < pts[4] && pts[1] < pts[5] + ) || + (elementCount == 4 // 4-point polygon, check for unclosed rect + && pts[0] == pts[6] && pts[2] == pts[4] // x values equal + && pts[1] == pts[3] && pts[5] == pts[7] // y values equal... + && pts[0] < pts[4] && pts[1] < pts[5] + ); + } + + inline bool isRect() const + { + const QPainterPath::ElementType * const types = elements(); + + return (shape() == QVectorPath::RectangleHint) + || (isRect(points(), elementCount()) + && (!types || (types[0] == QPainterPath::MoveToElement + && types[1] == QPainterPath::LineToElement + && types[2] == QPainterPath::LineToElement + && types[3] == QPainterPath::LineToElement))); + } + private: Q_DISABLE_COPY(QVectorPath) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 86f78a35d5e..f162f5e93c9 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -52,6 +52,7 @@ #include "qwindowsfontdatabase.h" #include "qwindowsintegration.h" +#include #include #include #include @@ -80,9 +81,14 @@ enum { //Clipping flags enum { - UserClip = 0x1, - SimpleSystemClip = 0x2 + SimpleSystemClip = 0x1 }; + +enum ClipType { + AxisAlignedClip, + LayerClip +}; + #define D2D_TAG(tag) d->dc()->SetTags(tag, tag) Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); @@ -320,8 +326,8 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate QWindowsDirect2DBitmap *bitmap; - QPainterPath clipPath; unsigned int clipFlags; + QStack pushedClips; QPointF currentBrushOrigin; @@ -389,30 +395,55 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate pen.brush->SetOpacity(opacity); } - void pushClip() + void pushClip(const QVectorPath &path) { - popClip(); + Q_Q(QWindowsDirect2DPaintEngine); + + if (path.isEmpty()) { + D2D_RECT_F rect = {0, 0, 0, 0}; + dc()->PushAxisAlignedClip(rect, antialiasMode()); + pushedClips.push(AxisAlignedClip); + } else if (path.isRect() && (q->state()->matrix.type() <= QTransform::TxScale)) { + const qreal * const points = path.points(); + D2D_RECT_F rect = { + points[0], // left + points[1], // top + points[2], // right, + points[5] // bottom + }; - ComPtr geometry = painterPathToID2D1PathGeometry(clipPath, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); - if (!geometry) - return; + dc()->PushAxisAlignedClip(rect, antialiasMode()); + pushedClips.push(AxisAlignedClip); + } else { + ComPtr geometry = vectorPathToID2D1PathGeometry(path, antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED); + if (!geometry) { + qWarning("%s: Could not convert vector path to painter path!", __FUNCTION__); + return; + } - dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(), - geometry.Get(), - antialiasMode(), - D2D1::IdentityMatrix(), - 1.0, - NULL, - D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND), - NULL); - clipFlags |= UserClip; + dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(), + geometry.Get(), + antialiasMode(), + D2D1::IdentityMatrix(), + 1.0, + NULL, + D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND), + NULL); + pushedClips.push(LayerClip); + } } - void popClip() + void clearClips() { - if (clipFlags & UserClip) { - dc()->PopLayer(); - clipFlags &= ~UserClip; + while (!pushedClips.isEmpty()) { + switch (pushedClips.pop()) { + case AxisAlignedClip: + dc()->PopAxisAlignedClip(); + break; + case LayerClip: + dc()->PopLayer(); + break; + } } } @@ -420,24 +451,23 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate { Q_Q(const QWindowsDirect2DPaintEngine); if (!q->state()->clipEnabled) - popClip(); - else if (!(clipFlags & UserClip)) - pushClip(); + clearClips(); + else if (pushedClips.isEmpty()) + replayClipOperations(); } - void updateClipPath(const QPainterPath &path, Qt::ClipOperation operation) + void clip(const QVectorPath &path, Qt::ClipOperation operation) { switch (operation) { case Qt::NoClip: - popClip(); + clearClips(); break; case Qt::ReplaceClip: - clipPath = path; - pushClip(); + clearClips(); + pushClip(path); break; case Qt::IntersectClip: - clipPath &= path; - pushClip(); + pushClip(path); break; } } @@ -863,7 +893,7 @@ bool QWindowsDirect2DPaintEngine::end() { Q_D(QWindowsDirect2DPaintEngine); // First pop any user-applied clipping - d->popClip(); + d->clearClips(); // Now the system clip from begin() above if (d->clipFlags & SimpleSystemClip) { d->dc()->PopAxisAlignedClip(); @@ -915,7 +945,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (!d->brush.brush) return; - if (path.hints() & QVectorPath::RectangleShapeMask) { + if (path.isRect()) { const qreal * const points = path.points(); D2D_RECT_F rect = { points[0], // left @@ -936,34 +966,10 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br } } -// For clipping we convert everything to painter paths since it allows -// calculating intersections easily. It might be faster to convert to -// ID2D1Geometry and use its operations, although that needs to measured. -// The implementation would be more complex in any case. - void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) -{ - clip(path.convertToPainterPath(), op); -} - -void QWindowsDirect2DPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) -{ - QPainterPath p; - p.addRect(rect); - clip(p, op); -} - -void QWindowsDirect2DPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) -{ - QPainterPath p; - p.addRegion(region); - clip(p, op); -} - -void QWindowsDirect2DPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) { Q_D(QWindowsDirect2DPaintEngine); - d->updateClipPath(path, op); + d->clip(path, op); } void QWindowsDirect2DPaintEngine::clipEnabledChanged() diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index 6c74a07e887..5af4eda1634 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -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 plugins of the Qt Toolkit. @@ -66,11 +66,7 @@ class QWindowsDirect2DPaintEngine : public QPaintEngineEx Type type() const Q_DECL_OVERRIDE; void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE; - void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE; - void clip(const QRect &rect, Qt::ClipOperation op) Q_DECL_OVERRIDE; - void clip(const QRegion ®ion, Qt::ClipOperation op) Q_DECL_OVERRIDE; - void clip(const QPainterPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE; void clipEnabledChanged() Q_DECL_OVERRIDE; void penChanged() Q_DECL_OVERRIDE; From 1467b63b0644573cfafa9ec358365660f3883f8d Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 23 Apr 2014 15:30:58 +0300 Subject: [PATCH 115/180] Direct2D QPA: Fix paint engine state handling Fix the paint handling to support QPaintEngineEx style state updates. This fixes most of the outstanding issues, as QPainter save and restore were essentially broken before Change-Id: I477d8acfd71bba32dfac4c491bc5bbaad1804ec5 Reviewed-by: Friedemann Kleint Reviewed-by: Risto Avila Reviewed-by: Andrew Knight --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 63 +++++++++++++++---- .../direct2d/qwindowsdirect2dpaintengine.h | 7 +++ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index f162f5e93c9..7c4ba6cb3fb 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -495,7 +495,7 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate { Q_Q(const QWindowsDirect2DPaintEngine); - if (qbrush_fast_equals(brush.qbrush, newBrush)) + if (qbrush_fast_equals(brush.qbrush, newBrush) && (brush.brush || brush.emulate)) return; brush.brush = to_d2d_brush(newBrush, &brush.emulate); @@ -540,12 +540,10 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate currentBrushOrigin = origin; } - void updatePen() + void updatePen(const QPen &newPen) { Q_Q(const QWindowsDirect2DPaintEngine); - const QPen &newPen = q->state()->pen; - - if (qpen_fast_equals(newPen, pen.qpen)) + if (qpen_fast_equals(newPen, pen.qpen) && (pen.brush || pen.emulate)) return; pen.reset(); @@ -909,6 +907,23 @@ QPaintEngine::Type QWindowsDirect2DPaintEngine::type() const return QPaintEngine::Direct2D; } +void QWindowsDirect2DPaintEngine::setState(QPainterState *s) +{ + Q_D(QWindowsDirect2DPaintEngine); + + QPaintEngineEx::setState(s); + d->clearClips(); + + clipEnabledChanged(); + penChanged(); + brushChanged(); + brushOriginChanged(); + opacityChanged(); + compositionModeChanged(); + renderHintsChanged(); + transformChanged(); +} + void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QWindowsDirect2DPaintEngine); @@ -917,7 +932,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (path.isEmpty()) return; - d->updateBrush(brush); + ensureBrush(brush); if (d->brush.emulate) { // We mostly (only?) get here when gradients are required. @@ -981,7 +996,7 @@ void QWindowsDirect2DPaintEngine::clipEnabledChanged() void QWindowsDirect2DPaintEngine::penChanged() { Q_D(QWindowsDirect2DPaintEngine); - d->updatePen(); + d->updatePen(state()->pen); } void QWindowsDirect2DPaintEngine::brushChanged() @@ -1051,6 +1066,8 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r, QWindowsDirect2DPlatformPixmap *pp = static_cast(pm.handle()); QWindowsDirect2DBitmap *bitmap = pp->bitmap(); + ensurePen(); + if (bitmap->bitmap() != d->bitmap->bitmap()) { // Good, src bitmap != dst bitmap if (sr.isValid()) @@ -1149,12 +1166,11 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText Q_D(QWindowsDirect2DPaintEngine); D2D_TAG(D2DDebugDrawStaticTextItemTag); - if (qpen_style(d->pen.qpen) == Qt::NoPen && qbrush_style(d->brush.qbrush) == Qt::NoBrush) - return; - if (staticTextItem->numGlyphs == 0) return; + ensurePen(); + // If we can't support the current configuration with Direct2D, fall back to slow path // Most common cases are perspective transform and gradient brush as pen if ((state()->transform().isAffine() == false) || d->pen.emulate) { @@ -1199,13 +1215,12 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem Q_D(QWindowsDirect2DPaintEngine); D2D_TAG(D2DDebugDrawTextItemTag); - if (qpen_style(d->pen.qpen) == Qt::NoPen && qbrush_style(d->brush.qbrush) == Qt::NoBrush) - return; - const QTextItemInt &ti = static_cast(textItem); if (ti.glyphs.numGlyphs == 0) return; + ensurePen(); + // If we can't support the current configuration with Direct2D, fall back to slow path // Most common cases are perspective transform and gradient brush as pen if ((state()->transform().isAffine() == false) || d->pen.emulate) { @@ -1307,4 +1322,26 @@ void QWindowsDirect2DPaintEngine::drawGlyphRun(const D2D1_POINT_2F &pos, DWRITE_MEASURING_MODE_GDI_CLASSIC); } +void QWindowsDirect2DPaintEngine::ensureBrush() +{ + ensureBrush(state()->brush); +} + +void QWindowsDirect2DPaintEngine::ensureBrush(const QBrush &brush) +{ + Q_D(QWindowsDirect2DPaintEngine); + d->updateBrush(brush); +} + +void QWindowsDirect2DPaintEngine::ensurePen() +{ + ensurePen(state()->pen); +} + +void QWindowsDirect2DPaintEngine::ensurePen(const QPen &pen) +{ + Q_D(QWindowsDirect2DPaintEngine); + d->updatePen(pen); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index 5af4eda1634..b8837f202a2 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -65,6 +65,8 @@ class QWindowsDirect2DPaintEngine : public QPaintEngineEx Type type() const Q_DECL_OVERRIDE; + void setState(QPainterState *s) Q_DECL_OVERRIDE; + void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE; void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE; @@ -87,6 +89,11 @@ class QWindowsDirect2DPaintEngine : public QPaintEngineEx void drawGlyphRun(const D2D1_POINT_2F &pos, IDWriteFontFace *fontFace, const QFont &font, int numGlyphs, const UINT16 *glyphIndices, const FLOAT *glyphAdvances, const DWRITE_GLYPH_OFFSET *glyphOffsets, bool rtl); + + void ensureBrush(); + void ensureBrush(const QBrush &brush); + void ensurePen(); + void ensurePen(const QPen &pen); }; QT_END_NAMESPACE From cc15a20d03fb81762680c19eb3c34a4e628c27a7 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Wed, 23 Apr 2014 16:07:05 +0300 Subject: [PATCH 116/180] Direct2D QPA: Improve software fallback mechanism Improve the way we fall back to the raster engine by forwarding painting state. Amongst other things this makes perspective transforms appear correct. Change-Id: I729de56ef3112bbc01516fc11c295f33a2aada0d Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- .../direct2d/qwindowsdirect2dhelpers.h | 2 - .../direct2d/qwindowsdirect2dpaintengine.cpp | 121 +++++++++++------- .../direct2d/qwindowsdirect2dpaintengine.h | 2 + 3 files changed, 80 insertions(+), 45 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h index 98248515e64..3be05ee1e0d 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h @@ -84,8 +84,6 @@ Q_DECL_CONSTEXPR inline D2D1::ColorF to_d2d_color_f(const QColor &c) Q_DECL_CONSTEXPR inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform) { - Q_ASSERT(transform.isAffine()); - return D2D1::Matrix3x2F(transform.m11(), transform.m12(), transform.m21(), transform.m22(), transform.m31(), transform.m32()); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 7c4ba6cb3fb..1e7c1752521 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -378,17 +378,13 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate : D2D1_ANTIALIAS_MODE_ALIASED; } - void updateTransform() + void updateTransform(const QTransform &transform) { - Q_Q(const QWindowsDirect2DPaintEngine); - // Note the loss of info going from 3x3 to 3x2 matrix here - dc()->SetTransform(to_d2d_matrix_3x2_f(q->state()->transform())); + dc()->SetTransform(to_d2d_matrix_3x2_f(transform)); } - void updateOpacity() + void updateOpacity(qreal opacity) { - Q_Q(const QWindowsDirect2DPaintEngine); - qreal opacity = q->state()->opacity; if (brush.brush) brush.brush->SetOpacity(opacity); if (pen.brush) @@ -447,10 +443,9 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate } } - void updateClipEnabled() + void updateClipEnabled(bool enabled) { - Q_Q(const QWindowsDirect2DPaintEngine); - if (!q->state()->clipEnabled) + if (!enabled) clearClips(); else if (pushedClips.isEmpty()) replayClipOperations(); @@ -472,11 +467,8 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate } } - void updateCompositionMode() + void updateCompositionMode(QPainter::CompositionMode mode) { - Q_Q(const QWindowsDirect2DPaintEngine); - QPainter::CompositionMode mode = q->state()->compositionMode(); - switch (mode) { case QPainter::CompositionMode_Source: dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY); @@ -507,12 +499,10 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate } } - void updateBrushOrigin() + void updateBrushOrigin(const QPointF &brushOrigin) { - Q_Q(const QWindowsDirect2DPaintEngine); - negateCurrentBrushOrigin(); - applyBrushOrigin(q->state()->brushOrigin); + applyBrushOrigin(brushOrigin); } void negateCurrentBrushOrigin() @@ -934,26 +924,8 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br ensureBrush(brush); - if (d->brush.emulate) { - // We mostly (only?) get here when gradients are required. - // We natively support only linear and radial gradients that have pad reflect due to D2D limitations - - QImage img(d->bitmap->size(), QImage::Format_ARGB32); - img.fill(Qt::transparent); - - QPainter p; - QPaintEngine *engine = img.paintEngine(); - if (engine->isExtended() && p.begin(&img)) { - QPaintEngineEx *extended = static_cast(engine); - extended->fill(path, brush); - if (!p.end()) - qWarning("%s: Paint Engine end returned false", __FUNCTION__); - - drawImage(img.rect(), img, img.rect()); - } else { - qWarning("%s: Could not fall back to QImage", __FUNCTION__); - } - + if (!state()->matrix.isAffine() || d->brush.emulate) { + rasterFill(path, brush); return; } @@ -990,7 +962,7 @@ void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperatio void QWindowsDirect2DPaintEngine::clipEnabledChanged() { Q_D(QWindowsDirect2DPaintEngine); - d->updateClipEnabled(); + d->updateClipEnabled(state()->clipEnabled); } void QWindowsDirect2DPaintEngine::penChanged() @@ -1008,19 +980,19 @@ void QWindowsDirect2DPaintEngine::brushChanged() void QWindowsDirect2DPaintEngine::brushOriginChanged() { Q_D(QWindowsDirect2DPaintEngine); - d->updateBrushOrigin(); + d->updateBrushOrigin(state()->brushOrigin); } void QWindowsDirect2DPaintEngine::opacityChanged() { Q_D(QWindowsDirect2DPaintEngine); - d->updateOpacity(); + d->updateOpacity(state()->opacity); } void QWindowsDirect2DPaintEngine::compositionModeChanged() { Q_D(QWindowsDirect2DPaintEngine); - d->updateCompositionMode(); + d->updateCompositionMode(state()->compositionMode()); } void QWindowsDirect2DPaintEngine::renderHintsChanged() @@ -1032,7 +1004,7 @@ void QWindowsDirect2DPaintEngine::renderHintsChanged() void QWindowsDirect2DPaintEngine::transformChanged() { Q_D(QWindowsDirect2DPaintEngine); - d->updateTransform(); + d->updateTransform(state()->transform()); } void QWindowsDirect2DPaintEngine::drawImage(const QRectF &rectangle, const QImage &image, @@ -1344,4 +1316,67 @@ void QWindowsDirect2DPaintEngine::ensurePen(const QPen &pen) d->updatePen(pen); } +void QWindowsDirect2DPaintEngine::rasterFill(const QVectorPath &path, const QBrush &brush) +{ + Q_D(QWindowsDirect2DPaintEngine); + + QImage img(d->bitmap->size(), QImage::Format_ARGB32); + img.fill(Qt::transparent); + + QPainter p; + QPaintEngine *engine = img.paintEngine(); + + if (engine->isExtended() && p.begin(&img)) { + p.setRenderHints(state()->renderHints); + p.setCompositionMode(state()->compositionMode()); + p.setOpacity(state()->opacity); + p.setBrushOrigin(state()->brushOrigin); + p.setBrush(state()->brush); + p.setPen(state()->pen); + + QPaintEngineEx *extended = static_cast(engine); + foreach (const QPainterClipInfo &info, state()->clipInfo) { + extended->state()->matrix = info.matrix; + extended->transformChanged(); + + switch (info.clipType) { + case QPainterClipInfo::RegionClip: + extended->clip(info.region, info.operation); + break; + case QPainterClipInfo::PathClip: + extended->clip(info.path, info.operation); + break; + case QPainterClipInfo::RectClip: + extended->clip(info.rect, info.operation); + break; + case QPainterClipInfo::RectFClip: + qreal right = info.rectf.x() + info.rectf.width(); + qreal bottom = info.rectf.y() + info.rectf.height(); + qreal pts[] = { info.rectf.x(), info.rectf.y(), + right, info.rectf.y(), + right, bottom, + info.rectf.x(), bottom }; + QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint); + extended->clip(vp, info.operation); + break; + } + } + + extended->state()->matrix = state()->matrix; + extended->transformChanged(); + + extended->fill(path, brush); + if (!p.end()) + qWarning("%s: Paint Engine end returned false", __FUNCTION__); + + d->updateClipEnabled(false); + d->updateTransform(QTransform()); + drawImage(img.rect(), img, img.rect()); + transformChanged(); + clipEnabledChanged(); + } else { + qWarning("%s: Could not fall back to QImage", __FUNCTION__); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index b8837f202a2..93ccf809e42 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -94,6 +94,8 @@ class QWindowsDirect2DPaintEngine : public QPaintEngineEx void ensureBrush(const QBrush &brush); void ensurePen(); void ensurePen(const QPen &pen); + + void rasterFill(const QVectorPath &path, const QBrush &brush); }; QT_END_NAMESPACE From f9d323279a0b3928acf40d56d84e9e5cc2cb7ee9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 24 Apr 2014 17:11:23 +0200 Subject: [PATCH 117/180] Rename new QOpenGLContext APIs isES() becomes isOpenGLES(). The library type enums are changed DesktopGL -> LibGL and GLES2 -> LibGLES. This removes the now unnecessary version number, the confusing "desktop" term and provides better readability. The old function/values are kept until the related qtdeclarative changes are integrated. Task-number: QTBUG-38564 Change-Id: Ibb0a1209985f1ce4bb9451f9b7b093c2b68a6505 Reviewed-by: Sean Harmer --- src/gui/kernel/qopenglcontext.cpp | 16 +++++----- src/gui/kernel/qopenglcontext.h | 12 +++++-- src/gui/kernel/qplatformintegration.cpp | 4 +-- src/gui/opengl/qopenglengineshadermanager.cpp | 2 +- src/gui/opengl/qopenglframebufferobject.cpp | 14 ++++---- src/gui/opengl/qopenglframebufferobject_p.h | 2 +- src/gui/opengl/qopenglfunctions.cpp | 8 ++--- src/gui/opengl/qopenglpaintengine.cpp | 8 ++--- src/gui/opengl/qopenglshaderprogram.cpp | 10 +++--- src/gui/opengl/qopengltexture.cpp | 32 +++++++++---------- src/gui/opengl/qopengltextureglyphcache.cpp | 6 ++-- src/gui/opengl/qopengltexturehelper.cpp | 6 ++-- src/gui/opengl/qopengltimerquery.cpp | 2 +- src/gui/opengl/qopenglvertexarrayobject.cpp | 4 +-- src/gui/painting/qplatformbackingstore.cpp | 2 +- .../qglengineshadermanager.cpp | 2 +- .../qpaintengineex_opengl2.cpp | 10 +++--- .../qtextureglyphcache_gl.cpp | 4 +-- src/opengl/qgl.cpp | 26 +++++++-------- src/opengl/qgl_qpa.cpp | 2 +- src/opengl/qglframebufferobject.cpp | 14 ++++---- src/opengl/qglframebufferobject_p.h | 2 +- src/opengl/qglfunctions.cpp | 2 +- src/opengl/qglpixelbuffer.cpp | 6 ++-- src/opengl/qglshaderprogram.cpp | 12 +++---- .../eglconvenience/qeglconvenience.cpp | 4 +-- .../platforms/windows/qwindowsintegration.cpp | 6 ++-- .../windows/qwindowsnativeinterface.cpp | 4 +-- .../platforms/windows/qwindowswindow.cpp | 2 +- tests/auto/opengl/qgl/tst_qgl.cpp | 12 +++---- .../opengl/qglfunctions/tst_qglfunctions.cpp | 2 +- .../auto/opengl/qglthreads/tst_qglthreads.cpp | 2 +- .../widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 2 +- 33 files changed, 124 insertions(+), 118 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index dbca05037b9..1af5c09fd2c 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -364,7 +364,7 @@ int QOpenGLContextPrivate::maxTextureSize() funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); #ifndef QT_OPENGL_ES - if (!q->isES()) { + if (!q->isOpenGLES()) { GLenum proxy = GL_PROXY_TEXTURE_2D; GLint size; @@ -676,7 +676,7 @@ QOpenGLFunctions *QOpenGLContext::functions() const QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const { #ifndef QT_OPENGL_ES_2 - if (isES()) { + if (isOpenGLES()) { qWarning("versionFunctions: Not supported on OpenGL ES"); return 0; } @@ -1036,8 +1036,8 @@ void *QOpenGLContext::openGLModuleHandle() \enum QOpenGLContext::OpenGLModuleType This enum defines the type of the underlying OpenGL implementation. - \value DesktopGL Desktop OpenGL - \value GLES2 OpenGL ES 2.0 or higher + \value LibGL OpenGL + \value LibGLES OpenGL ES 2.0 or higher \since 5.3 */ @@ -1052,7 +1052,7 @@ void *QOpenGLContext::openGLModuleHandle() \note A desktop OpenGL implementation may be capable of creating ES-compatible contexts too. Therefore in most cases it is more appropriate to check QSurfaceFormat::renderableType() or using the - the convenience function isES(). + the convenience function isOpenGLES(). \note This function requires that the QGuiApplication instance is already created. @@ -1064,9 +1064,9 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType() Q_ASSERT(qGuiApp); return QGuiApplicationPrivate::instance()->platformIntegration()->openGLModuleType(); #elif defined(QT_OPENGL_ES_2) - return GLES2; + return LibGLES; #else - return DesktopGL; + return LibGL; #endif } @@ -1080,7 +1080,7 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType() \since 5.3 */ -bool QOpenGLContext::isES() const +bool QOpenGLContext::isOpenGLES() const { return format().renderableType() == QSurfaceFormat::OpenGLES; } diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index fce983f9756..c422d008c18 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -195,13 +195,19 @@ class Q_GUI_EXPORT QOpenGLContext : public QObject static void *openGLModuleHandle(); enum OpenGLModuleType { - DesktopGL, - GLES2 + LibGL, + LibGLES, + + // ### + DesktopGL = LibGL, + GLES2 = LibGLES }; static OpenGLModuleType openGLModuleType(); - bool isES() const; + bool isOpenGLES() const; + + bool isES() const { return isOpenGLES(); } // ### Q_SIGNALS: void aboutToBeDestroyed(); diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index a6e0d4705b3..da192a8e256 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -491,14 +491,14 @@ void QPlatformIntegration::sync() a desktop OpenGL implementation may be capable of creating OpenGL ES-compatible contexts too. - \sa QOpenGLContext::openGLModuleType(), QOpenGLContext::isES() + \sa QOpenGLContext::openGLModuleType(), QOpenGLContext::isOpenGLES() \since 5.3 */ QOpenGLContext::OpenGLModuleType QPlatformIntegration::openGLModuleType() { qWarning("This plugin does not support dynamic OpenGL loading!"); - return QOpenGLContext::DesktopGL; + return QOpenGLContext::LibGL; } #endif diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp index a1215acb7e6..1c4231b79fa 100644 --- a/src/gui/opengl/qopenglengineshadermanager.cpp +++ b/src/gui/opengl/qopenglengineshadermanager.cpp @@ -164,7 +164,7 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context) code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader; code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader; - if (context->isES()) + if (context->isOpenGLES()) code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES; else code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop; diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 92a7330d6c9..cc829df9500 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -590,7 +590,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) { - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -602,7 +602,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen GL_DEPTH_COMPONENT, size.width(), size.height()); } } else { - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -631,7 +631,7 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen #ifdef QT_OPENGL_ES GLenum storage = GL_STENCIL_INDEX8; #else - GLenum storage = ctx->isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; + GLenum storage = ctx->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) @@ -773,7 +773,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar Q_D(QOpenGLFramebufferObject); d->init(this, size, NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -793,7 +793,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum Q_D(QOpenGLFramebufferObject); d->init(this, QSize(width, height), NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -850,7 +850,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, QSize(width, height), attachment, target, internal_format); } @@ -877,7 +877,7 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, size, attachment, target, internal_format); } diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h index bd830b38e98..7a653bc16d1 100644 --- a/src/gui/opengl/qopenglframebufferobject_p.h +++ b/src/gui/opengl/qopenglframebufferobject_p.h @@ -74,7 +74,7 @@ class QOpenGLFramebufferObjectFormatPrivate // context, so we need a fallback just to be safe, even though in pratice there // will usually be a context current. QOpenGLContext *ctx = QOpenGLContext::currentContext(); - const bool isES = ctx ? ctx->isES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL; + const bool isES = ctx ? ctx->isOpenGLES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL; internal_format = isES ? GL_RGBA : GL_RGBA8; #else internal_format = GL_RGBA; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 85b893e434a..bcb38ce7f1d 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -256,7 +256,7 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context) static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { // OpenGL ES 2 int features = QOpenGLFunctions::Multitexture | QOpenGLFunctions::Shaders | @@ -367,7 +367,7 @@ static int qt_gl_resolve_extensions() if (extensionMatcher.match("GL_ARB_pixel_buffer_object")) extensions |= QOpenGLExtensions::PixelBufferObject; - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (format.majorVersion() >= 2) extensions |= QOpenGLExtensions::GenerateMipmap; if (extensionMatcher.match("GL_OES_mapbuffer")) @@ -2415,7 +2415,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveClearColor(GLclampf red, GLclampf g static void QOPENGLF_APIENTRY qopenglfResolveClearDepthf(GLclampf depth) { - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { RESOLVE_FUNC_VOID(0, ClearDepthf)(depth); } else { RESOLVE_FUNC_VOID(0, ClearDepth)((GLdouble) depth); @@ -2464,7 +2464,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveDepthMask(GLboolean flag) static void QOPENGLF_APIENTRY qopenglfResolveDepthRangef(GLclampf zNear, GLclampf zFar) { - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { RESOLVE_FUNC_VOID(0, DepthRangef)(zNear, zFar); } else { RESOLVE_FUNC_VOID(0, DepthRange)((GLdouble) zNear, (GLdouble) zFar); diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index f160b340e0a..81a0d82c99f 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -221,7 +221,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture() currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); GLuint wrapMode = GL_REPEAT; - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, // we emulate GL_REPEAT by only taking the fractional part of the texture coords // in the qopenglslTextureBrushSrcFragmentShader program. @@ -598,7 +598,7 @@ void QOpenGL2PaintEngineExPrivate::resetGLState() setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { // gl_Color, corresponding to vertex attribute 3, may have been changed float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; funcs.glVertexAttrib4fv(3, color); @@ -1333,7 +1333,7 @@ void QOpenGL2PaintEngineEx::renderHintsChanged() state()->renderHintsChanged = true; #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGL2PaintEngineEx); if ((state()->renderHints & QPainter::Antialiasing) || (state()->renderHints & QPainter::HighQualityAntialiasing)) @@ -2011,7 +2011,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheFormat = QFontEngine::Format_A8; #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { d->funcs.glDisable(GL_MULTISAMPLE); d->glyphCacheFormat = QFontEngine::Format_A32; d->multisamplingAlwaysEnabled = false; diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index bfde2704461..c4862945bb1 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -176,7 +176,7 @@ class QOpenGLShaderPrivate : public QObjectPrivate #endif { #ifndef QT_OPENGL_ES_2 - if (!ctx->isES()) { + if (!ctx->isOpenGLES()) { QSurfaceFormat f = ctx->format(); // Geometry shaders require OpenGL >= 3.2 @@ -445,7 +445,7 @@ bool QOpenGLShader::compileSourceCode(const char *source) #ifdef QOpenGL_REDEFINE_HIGHP if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers - && QOpenGLContext::currentContext()->isES()) { + && QOpenGLContext::currentContext()->isOpenGLES()) { src.append(redefineHighp); srclen.append(GLint(sizeof(redefineHighp) - 1)); } @@ -674,7 +674,7 @@ bool QOpenGLShaderProgram::init() #ifndef QT_OPENGL_ES_2 // Resolve OpenGL 4 functions for tessellation shader support QSurfaceFormat format = context->format(); - if (!context->isES() + if (!context->isOpenGLES() && format.version() >= qMakePair(4, 0)) { d->tessellationFuncs = context->versionFunctions(); d->tessellationFuncs->initializeOpenGLFunctions(); @@ -3280,7 +3280,7 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context) #ifndef QT_OPENGL_ES_2 // Geometry shaders require OpenGL 3.2 or newer QSurfaceFormat format = context->format(); - return (!context->isES()) + return (!context->isOpenGLES()) && (format.version() >= qMakePair(3, 2)); #else // No geometry shader support in OpenGL ES2 @@ -3288,7 +3288,7 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context) #endif } else if (type == TessellationControl || type == TessellationEvaluation) { #if !defined(QT_OPENGL_ES_2) - return (!context->isES()) + return (!context->isOpenGLES()) && (format.version() >= qMakePair(4, 0)); #else // No tessellation shader support in OpenGL ES2 diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 078274eabd3..445e3ed64ea 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2432,7 +2432,7 @@ bool QOpenGLTexture::hasFeature(Feature feature) bool supported = false; #if !defined(QT_OPENGL_ES_2) - if (!ctx->isES()) { + if (!ctx->isOpenGLES()) { switch (feature) { case ImmutableMultisampleStorage: case TextureBuffer: @@ -2489,7 +2489,7 @@ bool QOpenGLTexture::hasFeature(Feature feature) } } - if (ctx->isES()) + if (ctx->isOpenGLES()) #endif { switch (feature) { @@ -2524,7 +2524,7 @@ bool QOpenGLTexture::hasFeature(Feature feature) void QOpenGLTexture::setMipBaseLevel(int baseLevel) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->textureId); @@ -2561,7 +2561,7 @@ int QOpenGLTexture::mipBaseLevel() const void QOpenGLTexture::setMipMaxLevel(int maxLevel) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->textureId); @@ -2598,7 +2598,7 @@ int QOpenGLTexture::mipMaxLevel() const void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->textureId); @@ -2708,7 +2708,7 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel) void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value) { #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -2737,7 +2737,7 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g, SwizzleValue b, SwizzleValue a) { #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -2786,7 +2786,7 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode) { #if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -2977,7 +2977,7 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire void QOpenGLTexture::setBorderColor(QColor color) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3007,7 +3007,7 @@ void QOpenGLTexture::setBorderColor(QColor color) void QOpenGLTexture::setBorderColor(float r, float g, float b, float a) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3040,7 +3040,7 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a) void QOpenGLTexture::setBorderColor(int r, int g, int b, int a) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3075,7 +3075,7 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a) void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3187,7 +3187,7 @@ void QOpenGLTexture::borderColor(unsigned int *border) const void QOpenGLTexture::setMinimumLevelOfDetail(float value) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3224,7 +3224,7 @@ float QOpenGLTexture::minimumLevelOfDetail() const void QOpenGLTexture::setMaximumLevelOfDetail(float value) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3260,7 +3260,7 @@ float QOpenGLTexture::maximumLevelOfDetail() const void QOpenGLTexture::setLevelOfDetailRange(float min, float max) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); @@ -3302,7 +3302,7 @@ QPair QOpenGLTexture::levelOfDetailRange() const void QOpenGLTexture::setLevelofDetailBias(float bias) { #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { Q_D(QOpenGLTexture); d->create(); Q_ASSERT(d->texFuncs); diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index 3287bbb9721..ac88d9d3a59 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -369,7 +369,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed || mask.format() == QImage::Format_ARGB32_Premultiplied #else || (mask.format() == QImage::Format_ARGB32_Premultiplied - && ctx->isES()) + && ctx->isOpenGLES()) #endif ) { for (int y = 0; y < maskHeight; ++y) { @@ -387,7 +387,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed src[x] = qRgba(r, g, b, avg); // swizzle the bits to accommodate for the GL_RGBA upload. #if Q_BYTE_ORDER != Q_BIG_ENDIAN - if (ctx->isES()) + if (ctx->isOpenGLES()) #endif src[x] = ARGB2RGBA(src[x]); } @@ -400,7 +400,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed #ifdef QT_OPENGL_ES_2 GLenum fmt = GL_RGBA; #else - GLenum fmt = ctx->isES() ? GL_RGBA : GL_BGRA; + GLenum fmt = ctx->isOpenGLES() ? GL_RGBA : GL_BGRA; #endif // QT_OPENGL_ES_2 #if Q_BYTE_ORDER == Q_BIG_ENDIAN diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 1d31fb56053..27aece8ecad 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) { // Resolve EXT_direct_state_access entry points if present - if (!context->isES() + if (!context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) { TextureParameteriEXT = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT"))); TextureParameterivEXT = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT"))); @@ -121,7 +121,7 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) } // Some DSA functions are part of NV_texture_multisample instead - if (!context->isES() + if (!context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) { TextureImage3DMultisampleNV = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureImage3DMultisampleNV"))); TextureImage2DMultisampleNV = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTextureImage2DMultisampleNV"))); @@ -190,7 +190,7 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) TexSubImage1D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexSubImage1D"))); #endif - if (context->isES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) { + if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) { TexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES"))); TexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES"))); CompressedTexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES"))); diff --git a/src/gui/opengl/qopengltimerquery.cpp b/src/gui/opengl/qopengltimerquery.cpp index 908a9cee079..5159ec58fc7 100644 --- a/src/gui/opengl/qopengltimerquery.cpp +++ b/src/gui/opengl/qopengltimerquery.cpp @@ -135,7 +135,7 @@ bool QOpenGLTimerQueryPrivate::create() return false; } - if (context->isES()) { + if (context->isOpenGLES()) { qWarning("QOpenGLTimerQuery: Not supported on OpenGL ES"); return false; } diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 9dfd5b2a6f3..5ebfc9a9c82 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -60,7 +60,7 @@ class QVertexArrayObjectHelper QVertexArrayObjectHelper(QOpenGLContext *context) { Q_ASSERT(context); - if (context->isES()) { + if (context->isOpenGLES()) { GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); @@ -159,7 +159,7 @@ bool QOpenGLVertexArrayObjectPrivate::create() context = ctx; QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { if (ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { vaoFuncs.helper = new QVertexArrayObjectHelper(ctx); vaoFuncsType = OES; diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 6425aa065e0..5b6c4bb83d9 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -314,7 +314,7 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu funcs->glGenTextures(1, &d_ptr->textureId); funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); } diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index f266318ba66..19e453e7838 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -163,7 +163,7 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; - if (!context->contextHandle()->isES()) + if (!context->contextHandle()->isOpenGLES()) code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop; else code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2b49e4d2d18..78c4b23665e 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -539,7 +539,7 @@ void QGL2PaintEngineEx::beginNativePainting() d->funcs.glDisableVertexAttribArray(i); #ifndef QT_OPENGL_ES_2 - if (!d->ctx->contextHandle()->isES()) { + if (!d->ctx->contextHandle()->isOpenGLES()) { const QGLContext *ctx = d->ctx; const QGLFormat &fmt = d->device->format(); if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1) @@ -597,7 +597,7 @@ void QGL2PaintEngineExPrivate::resetGLState() ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); #ifndef QT_OPENGL_ES_2 - if (!ctx->contextHandle()->isES()) { + if (!ctx->contextHandle()->isOpenGLES()) { // gl_Color, corresponding to vertex attribute 3, may have been changed float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; funcs.glVertexAttrib4fv(3, color); @@ -1364,7 +1364,7 @@ void QGL2PaintEngineEx::renderHintsChanged() state()->renderHintsChanged = true; #if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isES()) { + if (!d->ctx->contextHandle()->isOpenGLES()) { if ((state()->renderHints & QPainter::Antialiasing) || (state()->renderHints & QPainter::HighQualityAntialiasing)) glEnable(GL_MULTISAMPLE); @@ -2040,14 +2040,14 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glDisable(GL_SCISSOR_TEST); #if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isES()) + if (!d->ctx->contextHandle()->isOpenGLES()) glDisable(GL_MULTISAMPLE); #endif d->glyphCacheFormat = QFontEngine::Format_A8; #if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isES()) { + if (!d->ctx->contextHandle()->isOpenGLES()) { d->glyphCacheFormat = QFontEngine::Format_A32; d->multisamplingAlwaysEnabled = false; } else { diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index b1e289254f4..f1da50a6b9d 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -319,7 +319,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub uchar g = src[x] >> 8; uchar b = src[x]; quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. - if (ctx->contextHandle()->isES()) { + if (ctx->contextHandle()->isOpenGLES()) { // swizzle the bits to accommodate for the GL_RGBA upload. src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); } else { @@ -333,7 +333,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub if (mask.format() == QImage::Format_RGB32) { GLenum format = GL_RGBA; #if !defined(QT_OPENGL_ES_2) - if (!ctx->contextHandle()->isES()) + if (!ctx->contextHandle()->isOpenGLES()) format = GL_BGRA; #endif glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits()); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3cfdcc549c1..ae70072c4d7 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1700,7 +1700,7 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp int w = size.width(); int h = size.height(); #ifndef QT_OPENGL_ES - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { //### glGetTexImage not in GL ES 2.0, need to do something else here! glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); } @@ -2285,7 +2285,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); QOpenGLContext *ctx = QOpenGLContext::currentContext(); - bool genMipmap = !ctx->isES(); + bool genMipmap = !ctx->isOpenGLES(); if (glFormat.directRendering() && (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap)) && target == GL_TEXTURE_2D @@ -2427,7 +2427,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G printf(" - did byte swapping (%d ms)\n", time.elapsed()); #endif } - if (ctx->isES()) { + if (ctx->isOpenGLES()) { // OpenGL/ES requires that the internal and external formats be // identical. internalFormat = externalFormat; @@ -2440,7 +2440,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G const QImage &constRef = img; // to avoid detach in bits()... glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, pixel_type, constRef.bits()); - if (genMipmap && ctx->isES()) + if (genMipmap && ctx->isOpenGLES()) q->functions()->glGenerateMipmap(target); #ifndef QT_NO_DEBUG GLenum error = glGetError(); @@ -2524,7 +2524,7 @@ int QGLContextPrivate::maxTextureSize() #ifndef QT_OPENGL_ES Q_Q(QGLContext); - if (!q->contextHandle()->isES()) { + if (!q->contextHandle()->isOpenGLES()) { GLenum proxy = GL_PROXY_TEXTURE_2D; GLint size; @@ -2702,7 +2702,7 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex Q_UNUSED(textureHeight); Q_UNUSED(textureTarget); #else - if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isES()) { + if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isOpenGLES()) { if (textureWidth == -1 || textureHeight == -1) { glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); @@ -2769,7 +2769,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text #endif #ifndef QT_OPENGL_ES_2 - if (!contextHandle()->isES()) { + if (!contextHandle()->isOpenGLES()) { #ifdef QT_OPENGL_ES if (textureTarget != GL_TEXTURE_2D) { qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES"); @@ -2831,7 +2831,7 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text Q_UNUSED(textureId); Q_UNUSED(textureTarget); #else - if (!contextHandle()->isES()) { + if (!contextHandle()->isOpenGLES()) { const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D); GLint oldTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); @@ -4135,7 +4135,7 @@ void QGLWidget::glDraw() return; makeCurrent(); #ifndef QT_OPENGL_ES - if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isES()) + if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isOpenGLES()) glDrawBuffer(GL_FRONT); #endif QSize readback_target_size = d->glcx->d_ptr->readback_target_size; @@ -4180,7 +4180,7 @@ void QGLWidget::qglColor(const QColor& c) const #else Q_D(const QGLWidget); const QGLContext *ctx = QGLContext::currentContext(); - if (ctx && !ctx->contextHandle()->isES()) { + if (ctx && !ctx->contextHandle()->isOpenGLES()) { if (ctx->format().rgba()) glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? @@ -4212,7 +4212,7 @@ void QGLWidget::qglClearColor(const QColor& c) const #else Q_D(const QGLWidget); const QGLContext *ctx = QGLContext::currentContext(); - if (ctx && !ctx->contextHandle()->isES()) { + if (ctx && !ctx->contextHandle()->isOpenGLES()) { if (ctx->format().rgba()) glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? @@ -4387,7 +4387,7 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) { #ifndef QT_OPENGL_ES Q_D(QGLWidget); - if (!d->glcx->contextHandle()->isES()) { + if (!d->glcx->contextHandle()->isOpenGLES()) { Q_D(QGLWidget); if (str.isEmpty() || !isValid()) return; @@ -4477,7 +4477,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con { #ifndef QT_OPENGL_ES Q_D(QGLWidget); - if (!d->glcx->contextHandle()->isES()) { + if (!d->glcx->contextHandle()->isOpenGLES()) { Q_D(QGLWidget); if (str.isEmpty() || !isValid()) return; diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 10e6ffde460..61d295f1731 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -326,7 +326,7 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) d->context = new QOpenGLContext; #if !defined(QT_OPENGL_ES) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { // On desktop, request latest released version QSurfaceFormat format; #if defined(Q_OS_MAC) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index bd8bc2f64ac..419055f1a3b 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -595,7 +595,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else - if (ctx->contextHandle()->isES()) { + if (ctx->contextHandle()->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -617,7 +617,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, size.width(), size.height()); } #else - if (ctx->contextHandle()->isES()) { + if (ctx->contextHandle()->isOpenGLES()) { if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size.width(), size.height()); @@ -647,7 +647,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, #ifdef QT_OPENGL_ES GLenum storage = GL_STENCIL_INDEX8; #else - GLenum storage = ctx->contextHandle()->isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; + GLenum storage = ctx->contextHandle()->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; #endif if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) @@ -849,7 +849,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) Q_D(QGLFramebufferObject); d->init(this, size, NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -869,7 +869,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) Q_D(QGLFramebufferObject); d->init(this, QSize(width, height), NoAttachment, target, #ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8 + QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 #else GL_RGBA #endif @@ -926,7 +926,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, QSize(width, height), attachment, target, internal_format); } @@ -953,7 +953,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm #ifdef QT_OPENGL_ES_2 internal_format = GL_RGBA; #else - internal_format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; #endif d->init(this, size, attachment, target, internal_format); } diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h index 0edce5da2f1..1aefa0b4420 100644 --- a/src/opengl/qglframebufferobject_p.h +++ b/src/opengl/qglframebufferobject_p.h @@ -72,7 +72,7 @@ class QGLFramebufferObjectFormatPrivate { #ifndef QT_OPENGL_ES_2 QOpenGLContext *ctx = QOpenGLContext::currentContext(); - const bool isES = ctx ? ctx->isES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL; + const bool isES = ctx ? ctx->isOpenGLES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL; internal_format = isES ? GL_RGBA : GL_RGBA8; #else internal_format = GL_RGBA; diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 42b3b47f7fd..5ad842bad4d 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -223,7 +223,7 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { // OpenGL ES 2 int features = QGLFunctions::Multitexture | QGLFunctions::Shaders | diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 32b18bfda4d..12b26e5381f 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -361,7 +361,7 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const glBindTexture(GL_TEXTURE_2D, texture_id); #ifndef QT_OPENGL_ES - GLenum format = ctx->isES() ? GL_RGBA : GL_RGBA8; + GLenum format = ctx->isOpenGLES() ? GL_RGBA : GL_RGBA8; glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0); #else glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); @@ -488,7 +488,7 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target) { Q_D(QGLPixelBuffer); #ifndef QT_OPENGL_ES - GLenum format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + GLenum format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; return d->qctx->bindTexture(image, target, GLint(format)); #else return d->qctx->bindTexture(image, target, GL_RGBA); @@ -507,7 +507,7 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target) { Q_D(QGLPixelBuffer); #ifndef QT_OPENGL_ES - GLenum format = QOpenGLContext::currentContext()->isES() ? GL_RGBA : GL_RGBA8; + GLenum format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; return d->qctx->bindTexture(pixmap, target, GLint(format)); #else return d->qctx->bindTexture(pixmap, target, GL_RGBA); diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 65f217edf2d..6173ad12885 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -248,7 +248,7 @@ bool QGLShaderPrivate::create() shader = glfuncs->glCreateShader(GL_VERTEX_SHADER); #if !defined(QT_OPENGL_ES_2) else if (shaderType == QGLShader::Geometry - && !context->contextHandle()->isES()) + && !context->contextHandle()->isOpenGLES()) shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT); #endif else @@ -430,14 +430,14 @@ bool QGLShader::compileSourceCode(const char *source) srclen.append(GLint(headerLen)); } #ifdef QGL_DEFINE_QUALIFIERS - if (!QOpenGLContext::currentContext()->isES()) { + if (!QOpenGLContext::currentContext()->isOpenGLES()) { src.append(qualifierDefines); srclen.append(GLint(sizeof(qualifierDefines) - 1)); } #endif #ifdef QGL_REDEFINE_HIGHP if (d->shaderType == Fragment - && QOpenGLContext::currentContext()->isES()) { + && QOpenGLContext::currentContext()->isOpenGLES()) { src.append(redefineHighp); srclen.append(GLint(sizeof(redefineHighp) - 1)); } @@ -568,7 +568,7 @@ class ShaderProgramOpenGLFunctions : public QOpenGLFunctions void initializeGeometryShaderFunctions() { QOpenGLContext *context = QOpenGLContext::currentContext(); - if (!context->isES()) { + if (!context->isOpenGLES()) { glProgramParameteri = (type_glProgramParameteri) context->getProcAddress("glProgramParameteri"); @@ -936,7 +936,7 @@ bool QGLShaderProgram::link() #if !defined(QT_OPENGL_ES_2) // Set up the geometry shader parameters - if (!QOpenGLContext::currentContext()->isES() + if (!QOpenGLContext::currentContext()->isOpenGLES() && d->glfuncs->glProgramParameteri) { foreach (QGLShader *shader, d->shaders) { if (shader->shaderType() & QGLShader::Geometry) { @@ -3074,7 +3074,7 @@ int QGLShaderProgram::maxGeometryOutputVertices() const { GLint n = 0; #if !defined(QT_OPENGL_ES_2) - if (!QOpenGLContext::currentContext()->isES()) + if (!QOpenGLContext::currentContext()->isOpenGLES()) glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); #endif return n; diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index e6624fb9ff4..75789db153b 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -242,7 +242,7 @@ EGLConfig QEglConfigChooser::chooseConfig() #ifdef EGL_VERSION_1_4 case QSurfaceFormat::DefaultRenderableType: #ifndef QT_NO_OPENGL - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) configureAttributes.append(EGL_OPENGL_BIT); else #endif // QT_NO_OPENGL @@ -366,7 +366,7 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, format.setRenderableType(QSurfaceFormat::OpenGL); else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType #ifndef QT_NO_OPENGL - && QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL + && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL #endif && (renderableType & EGL_OPENGL_BIT)) format.setRenderableType(QSurfaceFormat::OpenGL); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index de346632869..78bf8335267 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -243,7 +243,7 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co return true; case ThreadedOpenGL: #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - return QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL + return QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true; # else return true; @@ -308,7 +308,7 @@ QPlatformOpenGLContext { qCDebug(lcQpaGl) << __FUNCTION__ << context->format(); #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) { if (d->m_staticEGLContext.isNull()) { QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create(); if (!staticContext) @@ -319,7 +319,7 @@ QPlatformOpenGLContext } #endif #if !defined(QT_OPENGL_ES_2) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { if (d->m_staticOpenGLContext.isNull()) d->m_staticOpenGLContext = QSharedPointer(QOpenGLStaticContext::create()); diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 7e15be1d196..06c0122bbba 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -125,7 +125,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour return 0; } #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) { QWindowsEGLContext *windowsEglContext = static_cast(context->handle()); if (resource == QByteArrayLiteral("eglDisplay")) return windowsEglContext->eglDisplay(); @@ -136,7 +136,7 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour } #endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC #if !defined(QT_OPENGL_ES_2) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL) { + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { QWindowsGLContext *windowsContext = static_cast(context->handle()); if (resource == QByteArrayLiteral("renderingContext")) return windowsContext->renderingContext(); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index ee9bf9936c7..a6b7d194325 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -880,7 +880,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->surfaceType() == QWindow::OpenGLSurface) { setFlag(OpenGLSurface); #if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) setFlag(OpenGL_ES2); #endif } diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 5831b33974f..ba2528d3cfe 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -754,7 +754,7 @@ void tst_QGL::openGLVersionCheck() #elif defined(QT_OPENGL_ES_2) QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); #else - if (QOpenGLContext::currentContext()->isES()) + if (QOpenGLContext::currentContext()->isOpenGLES()) QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); else QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1); @@ -1552,7 +1552,7 @@ void tst_QGL::fboFormat() #ifdef QT_OPENGL_ES_2 GL_RGBA; #else - QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL ? GL_RGBA : GL_RGBA8; + QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8; #endif QCOMPARE(int(format1.internalTextureFormat()), expectedFormat); @@ -1629,7 +1629,7 @@ void tst_QGL::fboFormat() #ifdef QT_OPENGL_ES_2 GL_RGBA #else - QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL ? GL_RGBA : GL_RGBA8 + QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8 #endif ); QVERIFY(!(format1c == format3c)); @@ -1642,7 +1642,7 @@ void tst_QGL::fboFormat() #ifdef QT_OPENGL_ES_2 GL_RGBA #else - QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL ? GL_RGBA : GL_RGBA8 + QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8 #endif ); QVERIFY(!(format1c == format4c)); @@ -2417,10 +2417,10 @@ void tst_QGL::extensions() QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Shaders)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Buffers)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Multisample)); - QVERIFY(!ctx->isES() || allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); + QVERIFY(!ctx->isOpenGLES() || allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::NPOTTextures) && allFeatures.testFlag(QOpenGLFunctions::NPOTTextureRepeat)); - if (ctx->isES()) { + if (ctx->isOpenGLES()) { QVERIFY(!allFeatures.testFlag(QOpenGLFunctions::FixedFunctionPipeline)); QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); } diff --git a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp index cdd820cf5b8..2f09d847729 100644 --- a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp +++ b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp @@ -96,7 +96,7 @@ void tst_QGLFunctions::features() funcs.initializeGLFunctions(); // Validate the features against what we expect for this platform. - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { #if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) QGLFunctions::OpenGLFeatures allFeatures = (QGLFunctions::Multitexture | diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp index 999761e3f02..70e3a3b62ae 100644 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp @@ -339,7 +339,7 @@ static inline float qrandom() { return (rand() % 100) / 100.f; } void renderAScene(int w, int h) { - if (QOpenGLContext::currentContext()->isES()) { + if (QOpenGLContext::currentContext()->isOpenGLES()) { QGLFunctions funcs(QGLContext::currentContext()); Q_UNUSED(w); Q_UNUSED(h); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index ba9652a1700..bc2e4caacd2 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -2598,7 +2598,7 @@ void tst_QMdiArea::nativeSubWindows() if (platformName != QLatin1String("xcb") && platformName != QLatin1String("windows")) QSKIP(qPrintable(QString::fromLatin1("nativeSubWindows() does not work on this platform (%1).").arg(platformName))); #if defined(Q_OS_WIN) && !defined(QT_NO_OPENGL) - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::DesktopGL) + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) QSKIP("nativeSubWindows() does not work with ANGLE on Windows, QTBUG-28545."); #endif { // Add native widgets after show. From 3f4c8293f250f5a94d44a7dac4f7d8e721598922 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 24 Apr 2014 13:28:23 +0200 Subject: [PATCH 118/180] QNX: Fix geometry change handling QWindowSystemInterface::handleGeometryChange has to be called with proper geometry whenever it changes. Change-Id: I691b85467a815ed21bce2bb64b33fa297c16f809 Reviewed-by: Fabian Bumberger --- src/plugins/platforms/qnx/qqnxwindow.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 2e0febff20e..d7256b08aa8 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -247,7 +247,6 @@ void QQnxWindow::setGeometry(const QRect &rect) setGeometryHelper(newGeometry); - QWindowSystemInterface::handleGeometryChange(window(), newGeometry); if (isExposed()) QWindowSystemInterface::handleExposeEvent(window(), newGeometry); } @@ -278,6 +277,8 @@ void QQnxWindow::setGeometryHelper(const QRect &rect) "Failed to set window source size"); screen_flush_context(m_screenContext, 0); + + QWindowSystemInterface::handleGeometryChange(window(), rect); } void QQnxWindow::setVisible(bool visible) @@ -711,12 +712,7 @@ void QQnxWindow::initWindow() if (window()->parent() && window()->parent()->handle()) setParent(window()->parent()->handle()); - if (shouldMakeFullScreen()) - setGeometryHelper(screen()->geometry()); - else - setGeometryHelper(window()->geometry()); - - QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry()); + setGeometryHelper(shouldMakeFullScreen() ? screen()->geometry() : window()->geometry()); } void QQnxWindow::createWindowGroup() From c1d41b42a18fc1566b2d5cfdae2a743f3e0fb8d9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 21 Apr 2014 18:58:29 +0200 Subject: [PATCH 119/180] Document that the connection stay active when objects used in a lambda are destroyed Task-number: QTBUG-37472 Change-Id: I44a6d7f8bf6928cd99a05d1b00fe36313cb18ffa Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qobject.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 01bedb4a3a9..ea02352d56d 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4433,6 +4433,8 @@ void qDeleteInEventHandler(QObject *o) \snippet code/src_corelib_kernel_qobject.cpp 46 The connection will automatically disconnect if the sender is destroyed. + However, you should take care that any objects used within the functor + are still alive when the signal is emitted. \note If the compiler does not support C++11 variadic templates, the number of arguments in the signal or slot are limited to 6, and the functor object @@ -4470,6 +4472,8 @@ void qDeleteInEventHandler(QObject *o) The connection will automatically disconnect if the sender or the context is destroyed. + However, you should take care that any objects used within the functor + are still alive when the signal is emitted. \note If the compiler does not support C++11 variadic templates, the number of arguments in the signal or slot are limited to 6, and the functor object From 9fc0c5466238eb8f43d2736d298ac36c65da529e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 16 Apr 2014 15:46:08 +0200 Subject: [PATCH 120/180] Windows: Add missing colors to tooltip palette. Task-number: QTBUG-38183 Change-Id: Ic3581cc87c0d61140624ddaf6fa85d682120ad4f Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowstheme.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 6349c1e3559..6a3930dc78b 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.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 plugins of the Qt Toolkit. @@ -230,12 +230,16 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette) result.setColor(QPalette::All, QPalette::Text, tipTextColor); result.setColor(QPalette::All, QPalette::WindowText, tipTextColor); result.setColor(QPalette::All, QPalette::ButtonText, tipTextColor); + result.setColor(QPalette::All, QPalette::ToolTipBase, tipBgColor); + result.setColor(QPalette::All, QPalette::ToolTipText, tipTextColor); const QColor disabled = mixColors(result.foreground().color(), result.button().color()); result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); result.setColor(QPalette::Disabled, QPalette::Text, disabled); + result.setColor(QPalette::Disabled, QPalette::ToolTipText, disabled); result.setColor(QPalette::Disabled, QPalette::Base, Qt::white); result.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white); + result.setColor(QPalette::Disabled, QPalette::ToolTipBase, Qt::white); return result; } From dda9b5325f4f8b500d399a3704f5fb48bb868255 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 23 Apr 2014 14:43:09 +0200 Subject: [PATCH 121/180] Add missing #ifndef QT_NO_SSL Change-Id: I2912dcca77270582f6e989b8b3fb72b82f6f70d6 Reviewed-by: Peter Hartmann Reviewed-by: Richard J. Moore --- tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index baaf21e6bbd..30a9e191384 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -273,10 +273,12 @@ void tst_QSslSocket::initTestCase_data() void tst_QSslSocket::initTestCase() { +#ifndef QT_NO_SSL qDebug("Using SSL library %s (%ld)", qPrintable(QSslSocket::sslLibraryVersionString()), QSslSocket::sslLibraryVersionNumber()); QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif } void tst_QSslSocket::init() From 6ddcfcdcbe79dcf1c58e211dbef4b653e8cfb068 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 16 Apr 2014 16:55:20 +0200 Subject: [PATCH 122/180] Update tooltip palette when receiving a theme change notification. Task-number: QTBUG-38183 Change-Id: Ia86ae698ae4afcf9d5c361f178f3ca44ae9a3ee5 Reviewed-by: Oliver Wolff --- src/widgets/kernel/qapplication.cpp | 2 ++ src/widgets/kernel/qapplication_qpa.cpp | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index d90e2f51638..b4c4ffe7c76 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -368,6 +368,7 @@ QApplicationPrivate::~QApplicationPrivate() void qt_init(QApplicationPrivate *priv, int type ); +void qt_init_tooltip_palette(); void qt_cleanup(); QStyle *QApplicationPrivate::app_style = 0; // default application style @@ -4025,6 +4026,7 @@ void QApplicationPrivate::notifyThemeChanged() QGuiApplicationPrivate::notifyThemeChanged(); clearSystemPalette(); initSystemPalette(); + qt_init_tooltip_palette(); } #ifndef QT_NO_DRAGANDDROP diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index c68bcc773f7..5893c52e1b0 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -442,6 +442,14 @@ void QApplication::alert(QWidget *widget, int duration) } } +void qt_init_tooltip_palette() +{ +#ifndef QT_NO_TOOLTIP + if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) + QToolTip::setPalette(*toolTipPalette); +#endif +} + void qt_init(QApplicationPrivate *priv, int type) { Q_UNUSED(priv); @@ -449,10 +457,7 @@ void qt_init(QApplicationPrivate *priv, int type) QColormap::initialize(); -#ifndef QT_NO_TOOLTIP - if (const QPalette *toolTipPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::ToolTipPalette)) - QToolTip::setPalette(*toolTipPalette); -#endif + qt_init_tooltip_palette(); QApplicationPrivate::initializeWidgetFontHash(); } From 0e99bd1990ecfc87d58e6a0865c65a148e06e7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 10 Apr 2014 17:52:50 +0000 Subject: [PATCH 123/180] Build fix with defined DEBUG_MOC Change-Id: I365feceda20625e95503eb5acfa58fc89bd3720a Reviewed-by: Olivier Goffart --- src/tools/moc/token.cpp | 171 +---------------- src/tools/moc/token.h | 410 ++++++++++++++++++++-------------------- 2 files changed, 211 insertions(+), 370 deletions(-) diff --git a/src/tools/moc/token.cpp b/src/tools/moc/token.cpp index a9365559808..36b413ca84a 100644 --- a/src/tools/moc/token.cpp +++ b/src/tools/moc/token.cpp @@ -47,174 +47,9 @@ QT_BEGIN_NAMESPACE const char *tokenTypeName(Token t) { switch (t) { - case NOTOKEN: return "NOTOKEN"; - case IDENTIFIER: return "IDENTIFIER"; - case INTEGER_LITERAL: return "INTEGER_LITERAL"; - case CHARACTER_LITERAL: return "CHARACTER_LITERAL"; - case STRING_LITERAL: return "STRING_LITERAL"; - case BOOLEAN_LITERAL: return "BOOLEAN_LITERAL"; - case HEADER_NAME: return "HEADER_NAME"; - case LANGLE: return "LANGLE"; - case RANGLE: return "RANGLE"; - case LPAREN: return "LPAREN"; - case RPAREN: return "RPAREN"; - case ELIPSIS: return "ELIPSIS"; - case LBRACK: return "LBRACK"; - case RBRACK: return "RBRACK"; - case LBRACE: return "LBRACE"; - case RBRACE: return "RBRACE"; - case EQ: return "EQ"; - case SCOPE: return "SCOPE"; - case SEMIC: return "SEMIC"; - case COLON: return "COLON"; - case DOTSTAR: return "DOTSTAR"; - case QUESTION: return "QUESTION"; - case DOT: return "DOT"; - case DYNAMIC_CAST: return "DYNAMIC_CAST"; - case STATIC_CAST: return "STATIC_CAST"; - case REINTERPRET_CAST: return "REINTERPRET_CAST"; - case CONST_CAST: return "CONST_CAST"; - case TYPEID: return "TYPEID"; - case THIS: return "THIS"; - case TEMPLATE: return "TEMPLATE"; - case THROW: return "THROW"; - case TRY: return "TRY"; - case CATCH: return "CATCH"; - case TYPEDEF: return "TYPEDEF"; - case FRIEND: return "FRIEND"; - case CLASS: return "CLASS"; - case NAMESPACE: return "NAMESPACE"; - case ENUM: return "ENUM"; - case STRUCT: return "STRUCT"; - case UNION: return "UNION"; - case VIRTUAL: return "VIRTUAL"; - case PRIVATE: return "PRIVATE"; - case PROTECTED: return "PROTECTED"; - case PUBLIC: return "PUBLIC"; - case EXPORT: return "EXPORT"; - case AUTO: return "AUTO"; - case REGISTER: return "REGISTER"; - case EXTERN: return "EXTERN"; - case MUTABLE: return "MUTABLE"; - case ASM: return "ASM"; - case USING: return "USING"; - case INLINE: return "INLINE"; - case EXPLICIT: return "EXPLICIT"; - case STATIC: return "STATIC"; - case CONST: return "CONST"; - case VOLATILE: return "VOLATILE"; - case OPERATOR: return "OPERATOR"; - case SIZEOF: return "SIZEOF"; - case NEW: return "NEW"; - case DELETE: return "DELETE"; - case PLUS: return "PLUS"; - case MINUS: return "MINUS"; - case STAR: return "STAR"; - case SLASH: return "SLASH"; - case PERCENT: return "PERCENT"; - case HAT: return "HAT"; - case AND: return "AND"; - case OR: return "OR"; - case TILDE: return "TILDE"; - case NOT: return "NOT"; - case PLUS_EQ: return "PLUS_EQ"; - case MINUS_EQ: return "MINUS_EQ"; - case STAR_EQ: return "STAR_EQ"; - case SLASH_EQ: return "SLASH_EQ"; - case PERCENT_EQ: return "PERCENT_EQ"; - case HAT_EQ: return "HAT_EQ"; - case AND_EQ: return "AND_EQ"; - case OR_EQ: return "OR_EQ"; - case LTLT: return "LTLT"; - case GTGT: return "GTGT"; - case GTGT_EQ: return "GTGT_EQ"; - case LTLT_EQ: return "LTLT_EQ"; - case EQEQ: return "EQEQ"; - case NE: return "NE"; - case LE: return "LE"; - case GE: return "GE"; - case ANDAND: return "ANDAND"; - case OROR: return "OROR"; - case INCR: return "INCR"; - case DECR: return "DECR"; - case COMMA: return "COMMA"; - case ARROW_STAR: return "ARROW_STAR"; - case ARROW: return "ARROW"; - case CHAR: return "CHAR"; - case WCHAR: return "WCHAR"; - case BOOL: return "BOOL"; - case SHORT: return "SHORT"; - case INT: return "INT"; - case LONG: return "LONG"; - case SIGNED: return "SIGNED"; - case UNSIGNED: return "UNSIGNED"; - case FLOAT: return "FLOAT"; - case DOUBLE: return "DOUBLE"; - case VOID: return "VOID"; - case CASE: return "CASE"; - case DEFAULT: return "DEFAULT"; - case IF: return "IF"; - case ELSE: return "ELSE"; - case SWITCH: return "SWITCH"; - case WHILE: return "WHILE"; - case DO: return "DO"; - case FOR: return "FOR"; - case BREAK: return "BREAK"; - case CONTINUE: return "CONTINUE"; - case GOTO: return "GOTO"; - case SIGNALS: return "SIGNALS"; - case SLOTS: return "SLOTS"; - case RETURN: return "RETURN"; - case Q_OBJECT_TOKEN: return "Q_OBJECT_TOKEN"; - case Q_GADGET_TOKEN: return "Q_GADGET_TOKEN"; - case Q_PROPERTY_TOKEN: return "Q_PROPERTY_TOKEN"; - case Q_ENUMS_TOKEN: return "Q_ENUMS_TOKEN"; - case Q_FLAGS_TOKEN: return "Q_FLAGS_TOKEN"; - case Q_DECLARE_FLAGS_TOKEN: return "Q_DECLARE_FLAGS_TOKEN"; - case Q_DECLARE_INTERFACE_TOKEN: return "Q_DECLARE_INTERFACE_TOKEN"; - case Q_CLASSINFO_TOKEN: return "Q_CLASSINFO_TOKEN"; - case Q_INTERFACES_TOKEN: return "Q_INTERFACES_TOKEN"; - case Q_SIGNALS_TOKEN: return "Q_SIGNALS_TOKEN"; - case Q_SLOTS_TOKEN: return "Q_SLOTS_TOKEN"; - case Q_SIGNAL_TOKEN: return "Q_SIGNAL_TOKEN"; - case Q_SLOT_TOKEN: return "Q_SLOT_TOKEN"; - case Q_PRIVATE_SLOT_TOKEN: return "Q_PRIVATE_SLOT_TOKEN"; - case Q_PRIVATE_PROPERTY_TOKEN: return "Q_PRIVATE_PROPERTY_TOKEN"; - case Q_REVISION_TOKEN: return "Q_REVISION_TOKEN"; - case SPECIAL_TREATMENT_MARK: return "SPECIAL_TREATMENT_MARK"; - case MOC_INCLUDE_BEGIN: return "MOC_INCLUDE_BEGIN"; - case MOC_INCLUDE_END: return "MOC_INCLUDE_END"; - case CPP_COMMENT: return "CPP_COMMENT"; - case C_COMMENT: return "C_COMMENT"; - case FLOATING_LITERAL: return "FLOATING_LITERAL"; - case HASH: return "HASH"; - case QUOTE: return "QUOTE"; - case SINGLEQUOTE: return "SINGLEQUOTE"; - case DIGIT: return "DIGIT"; - case CHARACTER: return "CHARACTER"; - case NEWLINE: return "NEWLINE"; - case WHITESPACE: return "WHITESPACE"; - case BACKSLASH: return "BACKSLASH"; - case INCOMPLETE: return "INCOMPLETE"; - case PP_DEFINE: return "PP_DEFINE"; - case PP_UNDEF: return "PP_UNDEF"; - case PP_IF: return "PP_IF"; - case PP_IFDEF: return "PP_IFDEF"; - case PP_IFNDEF: return "PP_IFNDEF"; - case PP_ELIF: return "PP_ELIF"; - case PP_ELSE: return "PP_ELSE"; - case PP_ENDIF: return "PP_ENDIF"; - case PP_INCLUDE: return "PP_INCLUDE"; - case PP_HASHHASH: return "PP_HASHHASH"; - case PP_HASH: return "PP_HASH"; - case PP_DEFINED: return "PP_DEFINED"; - case PP_INCOMPLETE: return "PP_INCOMPLETE"; - case PP_MOC_TRUE: return "PP_MOC_TRUE"; - case PP_MOC_FALSE: return "PP_MOC_FALSE"; - case Q_DECLARE_METATYPE_TOKEN: return "Q_DECLARE_METATYPE_TOKEN"; - case Q_MOC_COMPAT_TOKEN: return "Q_MOC_COMPAT_TOKEN"; - case Q_INVOKABLE_TOKEN: return "Q_INVOKABLE_TOKEN"; - case Q_SCRIPTABLE_TOKEN: return "Q_SCRIPTABLE_TOKEN"; +#define CREATE_CASE(Name) case Name: return #Name; + FOR_ALL_TOKENS(CREATE_CASE) +#undef CREATE_CASE } return ""; } diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h index 378d4c63f75..2920fadbb9d 100644 --- a/src/tools/moc/token.h +++ b/src/tools/moc/token.h @@ -46,222 +46,228 @@ QT_BEGIN_NAMESPACE -enum Token { - NOTOKEN, - IDENTIFIER, - INTEGER_LITERAL, - CHARACTER_LITERAL, - STRING_LITERAL, - BOOLEAN_LITERAL, - HEADER_NAME, - LANGLE, - RANGLE, - LPAREN, - RPAREN, - ELIPSIS, - LBRACK, - RBRACK, - LBRACE, - RBRACE, - EQ, - SCOPE, - SEMIC, - COLON, - DOTSTAR, - QUESTION, - DOT, - DYNAMIC_CAST, - STATIC_CAST, - REINTERPRET_CAST, - CONST_CAST, - TYPEID, - THIS, - TEMPLATE, - THROW, - TRY, - CATCH, - TYPEDEF, - FRIEND, - CLASS, - NAMESPACE, - ENUM, - STRUCT, - UNION, - VIRTUAL, - PRIVATE, - PROTECTED, - PUBLIC, - EXPORT, - AUTO, - REGISTER, - EXTERN, - MUTABLE, - ASM, - USING, - INLINE, - EXPLICIT, - STATIC, - CONST, - VOLATILE, - OPERATOR, - SIZEOF, - NEW, - DELETE, - PLUS, - MINUS, - STAR, - SLASH, - PERCENT, - HAT, - AND, - OR, - TILDE, - NOT, - PLUS_EQ, - MINUS_EQ, - STAR_EQ, - SLASH_EQ, - PERCENT_EQ, - HAT_EQ, - AND_EQ, - OR_EQ, - LTLT, - GTGT, - GTGT_EQ, - LTLT_EQ, - EQEQ, - NE, - LE, - GE, - ANDAND, - OROR, - INCR, - DECR, - COMMA, - ARROW_STAR, - ARROW, - CHAR, - WCHAR, - BOOL, - SHORT, - INT, - LONG, - SIGNED, - UNSIGNED, - FLOAT, - DOUBLE, - VOID, - CASE, - DEFAULT, - IF, - ELSE, - SWITCH, - WHILE, - DO, - FOR, - BREAK, - CONTINUE, - GOTO, - SIGNALS, - SLOTS, - RETURN, - Q_META_TOKEN_BEGIN, - Q_OBJECT_TOKEN = Q_META_TOKEN_BEGIN, - Q_GADGET_TOKEN, - Q_PROPERTY_TOKEN, - Q_PLUGIN_METADATA_TOKEN, - Q_ENUMS_TOKEN, - Q_FLAGS_TOKEN, - Q_DECLARE_FLAGS_TOKEN, - Q_DECLARE_INTERFACE_TOKEN, - Q_DECLARE_METATYPE_TOKEN, - Q_CLASSINFO_TOKEN, - Q_INTERFACES_TOKEN, - Q_SIGNALS_TOKEN, - Q_SLOTS_TOKEN, - Q_SIGNAL_TOKEN, - Q_SLOT_TOKEN, - Q_PRIVATE_SLOT_TOKEN, - Q_MOC_COMPAT_TOKEN, - Q_INVOKABLE_TOKEN, - Q_SCRIPTABLE_TOKEN, - Q_PRIVATE_PROPERTY_TOKEN, - Q_REVISION_TOKEN, - Q_META_TOKEN_END, - SPECIAL_TREATMENT_MARK = Q_META_TOKEN_END, - MOC_INCLUDE_BEGIN, - MOC_INCLUDE_END, - CPP_COMMENT, - C_COMMENT, - FLOATING_LITERAL, - HASH, - QUOTE, - SINGLEQUOTE, - LANGLE_SCOPE, - DIGIT, - CHARACTER, - NEWLINE, - WHITESPACE, - BACKSLASH, - INCOMPLETE, +#define FOR_ALL_TOKENS(F) \ + F(NOTOKEN) \ + F(IDENTIFIER) \ + F(INTEGER_LITERAL) \ + F(CHARACTER_LITERAL) \ + F(STRING_LITERAL) \ + F(BOOLEAN_LITERAL) \ + F(HEADER_NAME) \ + F(LANGLE) \ + F(RANGLE) \ + F(LPAREN) \ + F(RPAREN) \ + F(ELIPSIS) \ + F(LBRACK) \ + F(RBRACK) \ + F(LBRACE) \ + F(RBRACE) \ + F(EQ) \ + F(SCOPE) \ + F(SEMIC) \ + F(COLON) \ + F(DOTSTAR) \ + F(QUESTION) \ + F(DOT) \ + F(DYNAMIC_CAST) \ + F(STATIC_CAST) \ + F(REINTERPRET_CAST) \ + F(CONST_CAST) \ + F(TYPEID) \ + F(THIS) \ + F(TEMPLATE) \ + F(THROW) \ + F(TRY) \ + F(CATCH) \ + F(TYPEDEF) \ + F(FRIEND) \ + F(CLASS) \ + F(NAMESPACE) \ + F(ENUM) \ + F(STRUCT) \ + F(UNION) \ + F(VIRTUAL) \ + F(PRIVATE) \ + F(PROTECTED) \ + F(PUBLIC) \ + F(EXPORT) \ + F(AUTO) \ + F(REGISTER) \ + F(EXTERN) \ + F(MUTABLE) \ + F(ASM) \ + F(USING) \ + F(INLINE) \ + F(EXPLICIT) \ + F(STATIC) \ + F(CONST) \ + F(VOLATILE) \ + F(OPERATOR) \ + F(SIZEOF) \ + F(NEW) \ + F(DELETE) \ + F(PLUS) \ + F(MINUS) \ + F(STAR) \ + F(SLASH) \ + F(PERCENT) \ + F(HAT) \ + F(AND) \ + F(OR) \ + F(TILDE) \ + F(NOT) \ + F(PLUS_EQ) \ + F(MINUS_EQ) \ + F(STAR_EQ) \ + F(SLASH_EQ) \ + F(PERCENT_EQ) \ + F(HAT_EQ) \ + F(AND_EQ) \ + F(OR_EQ) \ + F(LTLT) \ + F(GTGT) \ + F(GTGT_EQ) \ + F(LTLT_EQ) \ + F(EQEQ) \ + F(NE) \ + F(LE) \ + F(GE) \ + F(ANDAND) \ + F(OROR) \ + F(INCR) \ + F(DECR) \ + F(COMMA) \ + F(ARROW_STAR) \ + F(ARROW) \ + F(CHAR) \ + F(WCHAR) \ + F(BOOL) \ + F(SHORT) \ + F(INT) \ + F(LONG) \ + F(SIGNED) \ + F(UNSIGNED) \ + F(FLOAT) \ + F(DOUBLE) \ + F(VOID) \ + F(CASE) \ + F(DEFAULT) \ + F(IF) \ + F(ELSE) \ + F(SWITCH) \ + F(WHILE) \ + F(DO) \ + F(FOR) \ + F(BREAK) \ + F(CONTINUE) \ + F(GOTO) \ + F(SIGNALS) \ + F(SLOTS) \ + F(RETURN) \ + F(Q_OBJECT_TOKEN) \ + F(Q_GADGET_TOKEN) \ + F(Q_PROPERTY_TOKEN) \ + F(Q_PLUGIN_METADATA_TOKEN) \ + F(Q_ENUMS_TOKEN) \ + F(Q_FLAGS_TOKEN) \ + F(Q_DECLARE_FLAGS_TOKEN) \ + F(Q_DECLARE_INTERFACE_TOKEN) \ + F(Q_DECLARE_METATYPE_TOKEN) \ + F(Q_CLASSINFO_TOKEN) \ + F(Q_INTERFACES_TOKEN) \ + F(Q_SIGNALS_TOKEN) \ + F(Q_SLOTS_TOKEN) \ + F(Q_SIGNAL_TOKEN) \ + F(Q_SLOT_TOKEN) \ + F(Q_PRIVATE_SLOT_TOKEN) \ + F(Q_MOC_COMPAT_TOKEN) \ + F(Q_INVOKABLE_TOKEN) \ + F(Q_SCRIPTABLE_TOKEN) \ + F(Q_PRIVATE_PROPERTY_TOKEN) \ + F(Q_REVISION_TOKEN) \ + F(SPECIAL_TREATMENT_MARK) \ + F(MOC_INCLUDE_BEGIN) \ + F(MOC_INCLUDE_END) \ + F(CPP_COMMENT) \ + F(C_COMMENT) \ + F(FLOATING_LITERAL) \ + F(HASH) \ + F(QUOTE) \ + F(SINGLEQUOTE) \ + F(LANGLE_SCOPE) \ + F(DIGIT) \ + F(CHARACTER) \ + F(NEWLINE) \ + F(WHITESPACE) \ + F(BACKSLASH) \ + F(INCOMPLETE) \ + F(PP_DEFINE) \ + F(PP_UNDEF) \ + F(PP_IF) \ + F(PP_IFDEF) \ + F(PP_IFNDEF) \ + F(PP_ELIF) \ + F(PP_ELSE) \ + F(PP_ENDIF) \ + F(PP_INCLUDE) \ + F(PP_HASHHASH) \ + F(PP_HASH) \ + F(PP_DEFINED) \ + F(PP_INCOMPLETE) \ + F(PP_MOC_TRUE) \ + F(PP_MOC_FALSE) + - PP_DEFINE, - PP_UNDEF, - PP_IF, - PP_IFDEF, - PP_IFNDEF, - PP_ELIF, - PP_ELSE, - PP_ENDIF, - PP_INCLUDE, - PP_HASHHASH, - PP_HASH, - PP_DEFINED, - PP_INCOMPLETE, +enum Token { - PP_MOC_TRUE, - PP_MOC_FALSE, +#define CREATE_ENUM_VALUE(Name) Name, + FOR_ALL_TOKENS(CREATE_ENUM_VALUE) +#undef CREATE_ENUM_VALUE - PP_NOTOKEN = NOTOKEN, + // aliases + PP_AND = AND, + PP_ANDAND = ANDAND, + PP_BACKSLASH = BACKSLASH, + PP_CHARACTER = CHARACTER, + PP_CHARACTER_LITERAL = CHARACTER_LITERAL, + PP_COLON = COLON, + PP_COMMA = COMMA, + PP_CPP_COMMENT = CPP_COMMENT, + PP_C_COMMENT = C_COMMENT, + PP_DIGIT = DIGIT, + PP_EQEQ = EQEQ, + PP_FLOATING_LITERAL = FLOATING_LITERAL, + PP_GE = GE, + PP_GTGT = GTGT, + PP_HAT = HAT, PP_IDENTIFIER = IDENTIFIER, PP_INTEGER_LITERAL = INTEGER_LITERAL, - PP_CHARACTER_LITERAL = CHARACTER_LITERAL, - PP_STRING_LITERAL = STRING_LITERAL, PP_LANGLE = LANGLE, - PP_RANGLE = RANGLE, + PP_LE = LE, PP_LPAREN = LPAREN, - PP_RPAREN = RPAREN, - PP_COMMA = COMMA, - PP_PLUS = PLUS, - PP_MINUS = MINUS, - PP_STAR = STAR, - PP_SLASH = SLASH, - PP_PERCENT = PERCENT, - PP_HAT = HAT, - PP_AND = AND, - PP_OR = OR, - PP_TILDE = TILDE, - PP_NOT = NOT, PP_LTLT = LTLT, - PP_GTGT = GTGT, - PP_EQEQ = EQEQ, + PP_MINUS = MINUS, PP_NE = NE, - PP_LE = LE, - PP_GE = GE, - PP_ANDAND = ANDAND, + PP_NEWLINE = NEWLINE, + PP_NOTOKEN = NOTOKEN, + PP_NOT = NOT, + PP_OR = OR, PP_OROR = OROR, + PP_PERCENT = PERCENT, + PP_PLUS = PLUS, PP_QUESTION = QUESTION, - PP_COLON = COLON, - PP_FLOATING_LITERAL = FLOATING_LITERAL, PP_QUOTE = QUOTE, + PP_RANGLE = RANGLE, + PP_RPAREN = RPAREN, PP_SINGLEQUOTE = SINGLEQUOTE, - PP_DIGIT = DIGIT, - PP_CHARACTER = CHARACTER, + PP_SLASH = SLASH, + PP_STAR = STAR, + PP_STRING_LITERAL = STRING_LITERAL, + PP_TILDE = TILDE, PP_WHITESPACE = WHITESPACE, - PP_NEWLINE = NEWLINE, - PP_CPP_COMMENT = CPP_COMMENT, - PP_C_COMMENT = C_COMMENT, - PP_BACKSLASH = BACKSLASH + Q_META_TOKEN_BEGIN = Q_OBJECT_TOKEN, + Q_META_TOKEN_END = SPECIAL_TREATMENT_MARK }; // for debugging only From 8369f6d3eae93293540ab8ed6f4ff1cc444cb6be Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 16 Apr 2014 11:20:50 +0200 Subject: [PATCH 124/180] QTcpSocket auto test: Temporarily disable Socks5 tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... because they are too unstable. We can check whether they are more stable once the new network tests server is in place. Task-number: QTBUG-38385 Change-Id: I5ced7cc1f89290812aa88f174a41965fd2ef7252 Reviewed-by: Jędrzej Nowacki --- tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index e589d520cb5..122ac63034e 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -331,8 +331,8 @@ void tst_QTcpSocket::initTestCase_data() qDebug() << QtNetworkSettings::serverName(); QTest::newRow("WithoutProxy") << false << 0 << false; - QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false; - QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false; + //QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false; ### temporarily disabled, QTBUG-38385 + //QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false; ### temporarily disabled, QTBUG-38385 QTest::newRow("WithHttpProxy") << true << int(HttpProxy) << false; QTest::newRow("WithHttpProxyBasicAuth") << true << int(HttpProxy | AuthBasic) << false; @@ -340,8 +340,8 @@ void tst_QTcpSocket::initTestCase_data() #ifndef QT_NO_SSL QTest::newRow("WithoutProxy SSL") << false << 0 << true; - QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true; - QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true; + //QTest::newRow("WithSocks5Proxy SSL") << true << int(Socks5Proxy) << true; ### temporarily disabled, QTBUG-38385 + //QTest::newRow("WithSocks5AuthProxy SSL") << true << int(Socks5Proxy | AuthBasic) << true; ### temporarily disabled, QTBUG-38385 QTest::newRow("WithHttpProxy SSL") << true << int(HttpProxy) << true; QTest::newRow("WithHttpProxyBasicAuth SSL") << true << int(HttpProxy | AuthBasic) << true; From 55d1aa3121063fcb41f8f4500c4319b64ca8ee67 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 24 Apr 2014 14:53:50 +0200 Subject: [PATCH 125/180] Use runtime detection of XInput 2.1 to disable legacy wheel events Ensure we fall back to using wheel button events if xinput 2.1 scroll events are not available. Handles lack of xinput 2.1 support in the server or in the input devices drivers. Task-number: QTBUG-38169 Change-Id: Ie4ad9069f648d0ab02d8f9540ed01ad58fd9e9d8 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection.cpp | 13 ++++++ src/plugins/platforms/xcb/qxcbconnection.h | 10 +++- .../platforms/xcb/qxcbconnection_xi2.cpp | 46 ++++++++++++++++++- src/plugins/platforms/xcb/qxcbwindow.cpp | 20 ++++---- 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index f5f6c712c5d..e3b81c2b40c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1791,6 +1791,19 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub return true; } +bool QXcbConnection::xi2GetButtonState(void *event, int buttonNum) +{ + xXIDeviceEvent *xideviceevent = static_cast(event); + unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1]; + + for (int i = 0; i < (xideviceevent->buttons_len * 4); i++) { + if (buttonNum < 8) + return (buttonsMaskAddr[i] & (1 << buttonNum)); + buttonNum -= 8; + } + return false; +} + // Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: // - "pad0" became "extension" // - "pad1" and "pad" became "pad0" diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 13a0280baf9..1933b89a190 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -402,6 +402,12 @@ class QXcbConnection : public QObject #elif defined(XCB_USE_XINPUT2) void xi2Select(xcb_window_t window); #endif +#ifdef XCB_USE_XINPUT21 + bool isUsingXInput21() { return m_xi2Enabled && m_xi2Minor >= 1; } +#else + bool isUsingXInput21() { return false; } +#endif + void sync(); void flush() { xcb_flush(m_connection); } @@ -511,11 +517,12 @@ private slots: QVector m_tabletData; #endif struct ScrollingDevice { - ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0) { } + ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } int deviceId; int verticalIndex, horizontalIndex; double verticalIncrement, horizontalIncrement; Qt::Orientations orientations; + Qt::Orientations legacyOrientations; QPointF lastScrollPosition; }; void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice); @@ -525,6 +532,7 @@ private slots: #if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO) static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value); static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode); + static bool xi2GetButtonState(void *event, int buttonNum); #endif xcb_connection_t *m_connection; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index d7b3c75aee9..831ccba6f66 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -134,7 +134,6 @@ void QXcbConnection::initializeXInput2() #ifdef XCB_USE_XINPUT21 case XIScrollClass: { XIScrollClassInfo *sci = reinterpret_cast(devices[i].classes[c]); - scrollingDevice.deviceId = devices[i].deviceid; if (sci->scroll_type == XIScrollTypeVertical) { scrollingDevice.orientations |= Qt::Vertical; scrollingDevice.verticalIndex = sci->number; @@ -147,6 +146,20 @@ void QXcbConnection::initializeXInput2() } break; } + case XIButtonClass: { + XIButtonClassInfo *bci = reinterpret_cast(devices[i].classes[c]); + for (int i=0; i < bci->num_buttons; ++i) { + const int buttonAtom = qatom(bci->labels[i]); + if (buttonAtom == QXcbAtom::ButtonWheelUp + || buttonAtom == QXcbAtom::ButtonWheelDown) { + scrollingDevice.legacyOrientations |= Qt::Vertical; + } else if (buttonAtom == QXcbAtom::ButtonHorizWheelLeft + || buttonAtom == QXcbAtom::ButtonHorizWheelRight) { + scrollingDevice.legacyOrientations |= Qt::Horizontal; + } + } + break; + } #endif default: break; @@ -170,7 +183,10 @@ void QXcbConnection::initializeXInput2() #endif // QT_NO_TABLETEVENT #ifdef XCB_USE_XINPUT21 - if (scrollingDevice.orientations) { + if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) { + scrollingDevice.deviceId = devices[i].deviceid; + // Only use legacy wheel button events when we don't have real scroll valuators. + scrollingDevice.legacyOrientations &= ~scrollingDevice.orientations; m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice); if (Q_UNLIKELY(debug_xinput_devices)) qDebug() << " it's a scrolling device"; @@ -256,6 +272,7 @@ void QXcbConnection::xi2Select(xcb_window_t window) if (!m_scrollingDevices.isEmpty()) { QVector xiEventMask(m_scrollingDevices.size()); bitMask = XI_MotionMask; + bitMask |= XI_ButtonReleaseMask; int i=0; Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) { xiEventMask[i].deviceid = scrollingDevice.deviceId; @@ -595,6 +612,31 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers); } } + } else if (xiEvent->evtype == XI_ButtonRelease) { + xXIDeviceEvent* xiDeviceEvent = reinterpret_cast(event); + if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) { + QPoint angleDelta; + if (scrollingDevice.legacyOrientations & Qt::Vertical) { + if (xi2GetButtonState(xiDeviceEvent, 4)) + angleDelta.setY(120); + else if (xi2GetButtonState(xiDeviceEvent, 5)) + angleDelta.setY(-120); + } + if (scrollingDevice.legacyOrientations & Qt::Horizontal) { + if (xi2GetButtonState(xiDeviceEvent, 6)) + angleDelta.setX(120); + if (xi2GetButtonState(xiDeviceEvent, 7)) + angleDelta.setX(-120); + } + if (!angleDelta.isNull()) { + QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y)); + QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y)); + Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods); + if (modifiers & Qt::AltModifier) + std::swap(angleDelta.rx(), angleDelta.ry()); + QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, QPoint(), angleDelta, modifiers); + } + } } #else Q_UNUSED(event); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index ad7e99bd498..386bf16c166 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1705,16 +1705,16 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); if (isWheel) { -#ifndef XCB_USE_XINPUT21 - // Logic borrowed from qapplication_x11.cpp - int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); - bool hor = (((event->detail == 4 || event->detail == 5) - && (modifiers & Qt::AltModifier)) - || (event->detail == 6 || event->detail == 7)); - - QWindowSystemInterface::handleWheelEvent(window(), event->time, - local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); -#endif + if (!connection()->isUsingXInput21()) { + // Logic borrowed from qapplication_x11.cpp + int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); + bool hor = (((event->detail == 4 || event->detail == 5) + && (modifiers & Qt::AltModifier)) + || (event->detail == 6 || event->detail == 7)); + + QWindowSystemInterface::handleWheelEvent(window(), event->time, + local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); + } return; } From 079f2bf5d8a4221b821ec8062affe2efaa9668a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 23 Apr 2014 11:32:44 +0200 Subject: [PATCH 126/180] Cocoa: Fix crash on Combobox popup close. Regression caused by 0be1c4899c. The calls to handleCloseEvent/flushWindowSystemEvents may result in popup window deletion and a stale/null pointer access. Get the window type before closing it. Task-number: QTBUG-38418 Change-Id: I212a56979e0248076e1eb5bf9ede1ff0d424e041 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 93462e7ea17..4065b57e467 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -637,9 +637,9 @@ - (void)mouseDown:(NSEvent *)theEvent return [super mouseDown:theEvent]; m_sendUpAsRightButton = false; if (m_platformWindow->m_activePopupWindow) { + Qt::WindowType type = m_platformWindow->m_activePopupWindow->type(); QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow); QWindowSystemInterface::flushWindowSystemEvents(); - Qt::WindowType type = m_platformWindow->m_activePopupWindow->type(); m_platformWindow->m_activePopupWindow = 0; // Consume the mouse event when closing the popup, except for tool tips // were it's expected that the event is processed normally. From 8ab1323842433fb6b45e7d6f381b4b9710a81da9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 23 Apr 2014 15:20:33 +0200 Subject: [PATCH 127/180] Don't use GL_REPEAT for image-brush drawing on OpenGL ES2 Backport of commit 8dfeb1c374972f06759a92b4edc5d6a18b96ccec in QtGui to the same class in the QtOpenGL module. OpenGL ES2 doesn't support NPOT textures in combination with GL_REPEAT, so for OpenGL ES2 we use a custom program that emulates repeat by taking the fractional part of the texture coordinates. This is not enough though, as merely setting GL_TEXTURE_WRAP_x to GL_REPEAT with a NPOT texture is an error in some implementations, so we have to guard the call to updateTextureFilter() in updateBrushTexture() with a check for OpenGL ES2 and use GL_CLAMP_TO_EDGE instead. Change-Id: Icbdd784c2c6d562849679f87da18b20d5441f389 Reviewed-by: Laszlo Agocs --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2b49e4d2d18..2ec4434d579 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -223,11 +223,19 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size) currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); + GLuint wrapMode = GL_REPEAT; + if (ctx->contextHandle()->isES()) { + // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, + // we emulate GL_REPEAT by only taking the fractional part of the texture coords + // in the qopenglslTextureBrushSrcFragmentShader program. + wrapMode = GL_CLAMP_TO_EDGE; + } + funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption | QGLContext::CanFlipNativePixmapBindOption); - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); + updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform); textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1; } brushTextureDirty = false; From fab46b1c6fb170bd8adc9a289fd5b33e7c6200ab Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 23 Apr 2014 13:07:04 +0200 Subject: [PATCH 128/180] Avoid a double memory copy during bindTexture If a painter is active on a QPixmap being uploaded, it will be copied twice, first to create a QImage and then from QImage into a texture. The first copy is unnecessary since the QImage is only temporary, so we can force it to be created as a reference instead of a copy. Change-Id: Iabcfb514a634446a01f1c4031349c185ec09290b Reviewed-by: Gunnar Sletta --- src/opengl/qgl.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3cfdcc549c1..d73109dfd90 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2497,7 +2497,19 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, } if (!texture) { - QImage image = pixmap.toImage(); + QImage image; + QPaintEngine* paintEngine = pixmap.paintEngine(); + if (!paintEngine || paintEngine->type() != QPaintEngine::Raster) + image = pixmap.toImage(); + else { + // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it. + // For performance reasons, we don't want that here, so we temporarily redirect the paint engine. + QPaintDevice* currentPaintDevice = paintEngine->paintDevice(); + paintEngine->setPaintDevice(0); + image = pixmap.toImage(); + paintEngine->setPaintDevice(currentPaintDevice); + } + // If the system depth is 16 and the pixmap doesn't have an alpha channel // then we convert it to RGB16 in the hope that it gets uploaded as a 16 // bit texture which is much faster to access than a 32-bit one. From 58e48831f17f154e4b7a4cd9b519e9ce4e645d8c Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 22 Apr 2014 18:41:37 +0200 Subject: [PATCH 129/180] Accessibility Mac: Fix reading of empty lines in text edit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit startOffset is already one char past the newline. By adding +1 we would skip one newline if the text was \n\n. Task-number: QTBUG-38257 Change-Id: Ida49a4b690bfa71f134e9be46126f418783a3c97 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 1df4230385b..474e799a113 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -332,7 +332,7 @@ - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)paramet startOffset = text.indexOf(QLatin1Char('\n'), startOffset) + 1; if (startOffset < 0) // invalid line number, return the first line startOffset = 0; - int endOffset = text.indexOf(QLatin1Char('\n'), startOffset + 1); + int endOffset = text.indexOf(QLatin1Char('\n'), startOffset); if (endOffset == -1) endOffset = text.length(); return [NSValue valueWithRange:NSMakeRange(quint32(startOffset), quint32(endOffset - startOffset))]; From aa920e627497f9f079e956132bcebc8eadddf3fd Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 23 Apr 2014 13:27:55 +0200 Subject: [PATCH 130/180] Accessibility Windows: Improve Menus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This would especially trigger when moving the focus between menus - after the right menu got the focus we would send another event for the QMenuBar, preventing the screen reader from reading the actually selected menu, announcing the menu bar instead. [ChangeLog][QtWidgets][QMenu] Accessibility: Menus are read by screen readers with more reliability. Task-number: QTBUG-38498 Change-Id: Ie4028120b234949380315296bf07ca53863d0ad8 Reviewed-by: Jan Arve Sæther --- src/widgets/kernel/qwidget.cpp | 2 -- src/widgets/widgets/qmenu.cpp | 3 --- src/widgets/widgets/qmenubar.cpp | 3 --- 3 files changed, 8 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f79eaf197d9..65e435fbdc3 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6002,10 +6002,8 @@ void QWidget::setFocus(Qt::FocusReason reason) if (!(testAttribute(Qt::WA_WState_Created) && window()->windowType() != Qt::Popup && internalWinId())) //setFocusWidget will already post a focus event for us (that the AT client receives) on Windows # endif -# ifdef Q_OS_UNIX // menus update the focus manually and this would create bogus events if (!(f->inherits("QMenuBar") || f->inherits("QMenu") || f->inherits("QMenuItem"))) -# endif { QAccessibleEvent event(f, QAccessible::Focus); QAccessible::updateAccessibility(&event); diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index eb93e461c02..4cf39b3bb57 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -1091,9 +1091,6 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e QAccessibleEvent focusEvent(q, QAccessible::Focus); focusEvent.setChild(actionIndex); QAccessible::updateAccessibility(&focusEvent); - QAccessibleEvent selectionEvent(q, QAccessible::Selection); - focusEvent.setChild(actionIndex); - QAccessible::updateAccessibility(&selectionEvent); } #endif action->showStatusText(topCausedWidget()); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 03ab490823d..729e08c7a58 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -531,9 +531,6 @@ void QMenuBarPrivate::_q_actionHovered() QAccessibleEvent focusEvent(q, QAccessible::Focus); focusEvent.setChild(actionIndex); QAccessible::updateAccessibility(&focusEvent); - QAccessibleEvent selectionEvent(q, QAccessible::Selection); - selectionEvent.setChild(actionIndex); - QAccessible::updateAccessibility(&selectionEvent); } #endif //QT_NO_ACCESSIBILITY } From 8abf98345a200efd59951b61559baf8561c8b53b Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 10 Apr 2014 14:57:29 +0200 Subject: [PATCH 131/180] Accessibility Mac: Make value interface settable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will let VoiceOver announce QLineEdit as editable text. It also implements setting of values for value interfaces (eg sliders). Task-number: QTBUG-38258 Change-Id: Ic30c10abc4dc0c4f3c5fe922ac5b0a4bbf4b1e5f Reviewed-by: Jan Arve Sæther --- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 474e799a113..9afc377d6ae 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -359,6 +359,12 @@ - (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { return iface->state().focusable ? YES : NO; + } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { + if (iface->textInterface() && iface->state().editable) + return YES; + if (iface->valueInterface()) + return YES; + return NO; } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { return iface->textInterface() ? YES : NO; } @@ -372,6 +378,14 @@ - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { if (QAccessibleActionInterface *action = iface->actionInterface()) action->doAction(QAccessibleActionInterface::setFocusAction()); + } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { + if (iface->textInterface()) { + QString text = QString::fromNSString((NSString *)value); + iface->setText(QAccessible::Value, text); + } else if (QAccessibleValueInterface *valueIface = iface->valueInterface()) { + double val = [value doubleValue]; + valueIface->setCurrentValue(val); + } } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { NSRange range = [value rangeValue]; From 57f8fba4cb4eec4794310e5c58e7a27435335560 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 10 Apr 2014 17:43:51 +0200 Subject: [PATCH 132/180] Accessibility Mac: implement min/max value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes QProgressBar reading by VoiceOver. Task-number: QTBUG-38272 Change-Id: I549fbebe1aff599e53b14685c1bde6c9fb98aa21 Reviewed-by: Jan Arve Sæther --- .../cocoa/qcocoaaccessibilityelement.mm | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 9afc377d6ae..dd3b9f53dbe 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -168,6 +168,14 @@ - (NSArray *)accessibilityAttributeNames { // TODO: multi-selection: NSAccessibilitySelectedTextRangesAttribute, } + if (iface->valueInterface()) { + [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects: + NSAccessibilityMinValueAttribute, + NSAccessibilityMaxValueAttribute, + nil + ]]; + } + return [attributes autorelease]; } @@ -191,6 +199,19 @@ - (id)parentElement { return [QCocoaAccessibleElement elementWithId: parentId]; } + +- (id) minValueAttribute:(QAccessibleInterface*)iface { + if (QAccessibleValueInterface *val = iface->valueInterface()) + return [NSNumber numberWithDouble: val->minimumValue().toDouble()]; + return nil; +} + +- (id) maxValueAttribute:(QAccessibleInterface*)iface { + if (QAccessibleValueInterface *val = iface->valueInterface()) + return [NSNumber numberWithDouble: val->maximumValue().toDouble()]; + return nil; +} + - (id)accessibilityAttributeValue:(NSString *)attribute { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); if (!iface) { @@ -272,6 +293,10 @@ - (id)accessibilityAttributeValue:(NSString *)attribute { return [NSNumber numberWithInt: textBeforeCursor.count(QLatin1Char('\n'))]; } return nil; + } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) { + return [self minValueAttribute:iface]; + } else if ([attribute isEqualToString:NSAccessibilityMaxValueAttribute]) { + return [self maxValueAttribute:iface]; } return nil; From 4ba57a059038f109ae81887be9e903cb8487b6f8 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 28 Jan 2013 15:07:18 +0100 Subject: [PATCH 133/180] Use showNormal() instead of show() in QToolTip. Even on platforms that use the QPlatformIntegration::StyleHint ShowIsFullScreen we do not want to show tool tips fullscreen which would happen if we just call show(). This is also required to fix somewhat random crashes on QNX when browsing a website and hovering links that would trigger a tooltip to be shown. There, we could end up with nested calls to QToolTip::showText when the tooltip was shown full-screen. Since QToolTip is not reentrant that can lead to crashes since QTipLabel::instance could be deleted/invalidated inbetween. Change-Id: I335fcd10cb6d4cffeb622ed8e0caf17f6413d62d Reviewed-by: Rafael Roquetto Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qtooltip.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 5aea55e196a..2b43fd7f6d5 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -512,9 +512,9 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons else if (QApplication::isEffectEnabled(Qt::UI_AnimateTooltip)) qScrollEffect(QTipLabel::instance); else - QTipLabel::instance->show(); + QTipLabel::instance->showNormal(); #else - QTipLabel::instance->show(); + QTipLabel::instance->showNormal(); #endif } } From 68d83cabaee62c6651d04cdf64c48f5d1b463bdb Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 25 Apr 2014 08:25:23 +0200 Subject: [PATCH 134/180] Fixed target path condition for font deployment Change-Id: I49568f5780af30753e68a6487afdc6c8f3b67214 Reviewed-by: Andrew Knight Reviewed-by: Oswald Buddenhagen --- mkspecs/features/winrt/font_deployment.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/winrt/font_deployment.prf b/mkspecs/features/winrt/font_deployment.prf index 36db5b7cace..8fe4ea4c15a 100644 --- a/mkspecs/features/winrt/font_deployment.prf +++ b/mkspecs/features/winrt/font_deployment.prf @@ -43,7 +43,7 @@ if(!build_pass:equals(TEMPLATE, "vcapp")) { !isEmpty(FONTS):equals(TEMPLATE, "app") { fonts.files = $$BUILD_DIR/fonts/* - isEmpty($$target.path) { + isEmpty(target.path) { fonts.path = $$OUT_PWD/fonts } else { fonts.path = $$target.path/fonts From 379042b84c74988ef5cadfe592aa202a2ebf9c61 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 25 Apr 2014 08:26:12 +0200 Subject: [PATCH 135/180] winphone: Fixed font deployment for Visual Studio projects Instead of collecting all files from the "fonts" directory to deploy them to the phone, we only collect files which are mentioned in the FONTS variable. Otherwise fonts that were copied to the fonts directory earlier (due to FONTS being unset (default fonts) or set to another set of fonts) will also be deployed as part of the project. Change-Id: I24c77e154a9f2ec75e88d487c056b0be46e17e87 Reviewed-by: Andrew Knight Reviewed-by: Oswald Buddenhagen --- mkspecs/features/winrt/font_deployment.prf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/winrt/font_deployment.prf b/mkspecs/features/winrt/font_deployment.prf index 8fe4ea4c15a..c767d5bc1ac 100644 --- a/mkspecs/features/winrt/font_deployment.prf +++ b/mkspecs/features/winrt/font_deployment.prf @@ -54,7 +54,9 @@ if(!build_pass:equals(TEMPLATE, "vcapp")) { } !isEmpty(FONTS):winphone:equals(TEMPLATE, "vcapp"):build_pass { - fonts.files = $$OUT_PWD/fonts/* + for (FONT, FONTS) { + fonts.files += $$OUT_PWD/fonts/$$basename(FONT) + } fonts.path = fonts DEPLOYMENT += fonts } From c7ed644fd1979b5a8c29fae1005d8a70801fab14 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 1 Apr 2014 18:27:59 +0200 Subject: [PATCH 136/180] QMenu: Add support for QWidgetAction on Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The implementation follows a similar logic as in Qt 4 making sure we properly interface with the QPA backend. We also make sure to delay moving the action widget to the QPA menu until it's about to show. We still don't support moving the action widget back from QPA world into Qt, as explained in the QWidgetAction documentation. Task-number: QTBUG-19840 Change-Id: I47f6359b0806f967d80c67fbb1f36c3d5ec8603e Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig --- src/widgets/widgets/qmenu.cpp | 38 ++++++++++++++++++++++++++++++-- src/widgets/widgets/qmenu.h | 1 + src/widgets/widgets/qmenu_mac.mm | 19 ++++++++++++++++ src/widgets/widgets/qmenu_p.h | 4 ++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 4cf39b3bb57..403ebe7f497 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -50,6 +50,9 @@ #include "qlayout.h" #include "qpainter.h" #include +#ifdef Q_OS_OSX +#include "qmacnativewidget_mac.h" +#endif #include "qapplication.h" #include "qdesktopwidget.h" #ifndef QT_NO_ACCESSIBILITY @@ -163,7 +166,7 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu) platformMenu = menu; if (!platformMenu.isNull()) { - QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow())); + QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SLOT(_q_platformMenuAboutToShow())); QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide())); } } @@ -1104,6 +1107,8 @@ void QMenuPrivate::_q_actionTriggered() Q_Q(QMenu); if (QAction *action = qobject_cast(q->sender())) { QPointer actionGuard = action; + if (platformMenu && widgetItems.value(action)) + platformMenu->dismiss(); emit q->triggered(action); if (!activationRecursionGuard && actionGuard) { //in case the action has not been activated by the mouse @@ -1134,6 +1139,24 @@ void QMenuPrivate::_q_actionHovered() } } +void QMenuPrivate::_q_platformMenuAboutToShow() +{ + Q_Q(QMenu); + +#ifdef Q_OS_OSX + if (platformMenu) + Q_FOREACH (QAction *action, q->actions()) + if (QWidget *widget = widgetItems.value(const_cast(action))) + if (widget->parent() == q) { + QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast(action)); + moveWidgetToPlatformItem(widget, menuItem); + platformMenu->syncMenuItem(menuItem); + } +#endif + + emit q->aboutToShow(); +} + bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos) { //determines if the mouse has moved (ie its initial position has @@ -2996,8 +3019,19 @@ void QMenu::actionEvent(QActionEvent *e) if (e->action() == d->currentAction) d->currentAction = 0; if (QWidgetAction *wa = qobject_cast(e->action())) { - if (QWidget *widget = d->widgetItems.value(wa)) + if (QWidget *widget = d->widgetItems.value(wa)) { +#ifdef Q_OS_OSX + QWidget *p = widget->parentWidget(); + if (p != this && qobject_cast(p)) { + // This widget was reparented into a native Mac view + // (see QMenuPrivate::moveWidgetToPlatformItem). + // Reset the parent and delete the native widget. + widget->setParent(this); + p->deleteLater(); + } +#endif wa->releaseWidget(widget); + } } d->widgetItems.remove(e->action()); } diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 8a8eaf3baeb..fef7903278e 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -195,6 +195,7 @@ private Q_SLOTS: Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered()) Q_PRIVATE_SLOT(d_func(), void _q_actionHovered()) Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed()) + Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow()) protected: QMenu(QMenuPrivate &dd, QWidget* parent = 0); diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index 41c4481b740..5e304d058b9 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -44,6 +44,8 @@ #include "qmenu.h" #include "qmenubar.h" +#include "qmenubar_p.h" +#include "qmacnativewidget_mac.h" #include #include @@ -115,6 +117,23 @@ \sa QMenu:setAsDockMenu() */ +void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item) +{ + QMacNativeWidget *container = new QMacNativeWidget; + QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater())); + container->resize(widget->sizeHint()); + widget->setParent(container); + + NSView *containerView = container->nativeView(); + QWindow *containerWindow = container->windowHandle(); + Qt::WindowFlags wf = containerWindow->flags(); + containerWindow->setFlags(wf | Qt::SubWindow); + [(NSView *)widget->winId() setAutoresizingMask:NSViewWidthSizable]; + + item->setNativeContents((WId)containerView); + container->show(); +} + #endif //QT_NO_MENU #ifndef QT_NO_MENUBAR diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 9d9851af64c..71bf33e1cee 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -110,6 +110,9 @@ class QMenuPrivate : public QWidgetPrivate void init(); void setPlatformMenu(QPlatformMenu *menu); void syncPlatformMenu(); +#ifdef Q_OS_OSX + void moveWidgetToPlatformItem(QWidget *w, QPlatformMenuItem* item); +#endif static QMenuPrivate *get(QMenu *m) { return m->d_func(); } int scrollerHeight() const; @@ -223,6 +226,7 @@ class QMenuPrivate : public QWidgetPrivate void _q_actionTriggered(); void _q_actionHovered(); + void _q_platformMenuAboutToShow(); bool hasMouseMoved(const QPoint &globalPos); From d032ff63885bd7faa7ec3a6066024fdb08248ffc Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 16 Apr 2014 19:20:16 +0200 Subject: [PATCH 137/180] QNX: Don't create a platform window for a desktop widget As I understand it the QDesktopWidget does only serve the purpose of returning the screen size and number. It does not need a real platform window. This removes some overhead, because a desktop widget is always created. Change-Id: I8c0d86bbb46b1f32094fda1592df795af6bb423f Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxrasterwindow.cpp | 5 ++++- src/plugins/platforms/qnx/qqnxwindow.cpp | 15 +++++++++++---- src/plugins/platforms/qnx/qqnxwindow.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp index eb9fac540f7..ead6e73a872 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp @@ -64,10 +64,13 @@ QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context, bo initWindow(); // Set window usage + if (window->type() == Qt::Desktop) + return; + const int val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE; const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &val); if (result != 0) - qFatal("QQnxEglWindow: failed to set window alpha usage, errno=%d", errno); + qFatal("QQnxRasterWindow: failed to set window alpha usage, errno=%d", errno); } void QQnxRasterWindow::post(const QRegion &dirty) diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index d7256b08aa8..5a405f95779 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -174,7 +174,7 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW // indication that we want to create a child window and join that window group. const QVariant windowGroup = window->property("qnxInitialWindowGroup"); - if (window->type() == Qt::CoverWindow || window->type() == Qt::Desktop) { + if (window->type() == Qt::CoverWindow) { // Cover windows have to be top level to be accessible to window delegate (i.e. navigator) // Desktop windows also need to be toplevel because they are not // supposed to be part of the window hierarchy tree @@ -189,10 +189,13 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW m_isTopLevel = !needRootWindow || !platformScreen->rootWindow(); } + if (window->type() == Qt::Desktop) // A desktop widget does not need a libscreen window + return; + if (m_isTopLevel) { Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext), "Could not create top level window"); // Creates an application window - if (window->type() != Qt::CoverWindow && window->type() != Qt::Desktop) { + if (window->type() != Qt::CoverWindow) { if (needRootWindow) platformScreen->setRootWindow(this); } @@ -245,7 +248,8 @@ void QQnxWindow::setGeometry(const QRect &rect) if (shouldMakeFullScreen()) newGeometry = screen()->geometry(); - setGeometryHelper(newGeometry); + if (window()->type() != Qt::Desktop) + setGeometryHelper(newGeometry); if (isExposed()) QWindowSystemInterface::handleExposeEvent(window(), newGeometry); @@ -285,7 +289,7 @@ void QQnxWindow::setVisible(bool visible) { qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "visible =" << visible; - if (m_visible == visible) + if (m_visible == visible || window()->type() == Qt::Desktop) return; // The first time through we join a window group if appropriate. @@ -668,6 +672,9 @@ void QQnxWindow::setRotation(int rotation) void QQnxWindow::initWindow() { + if (window()->type() == Qt::Desktop) + return; + // Alpha channel is always pre-multiplied if present int val = SCREEN_PRE_MULTIPLIED_ALPHA; Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val), diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index 9a2006396f2..94df9033360 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -75,7 +75,7 @@ friend class QQnxScreen; bool isExposed() const; - WId winId() const { return (WId)m_window; } + WId winId() const { return window()->type() == Qt::Desktop ? -1 : (WId)m_window; } screen_window_t nativeHandle() const { return m_window; } void setBufferSize(const QSize &size); From ff776214698ee8a0d4b5fa819af412d363611cb2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 25 Apr 2014 13:27:06 +0200 Subject: [PATCH 138/180] Windows: Reject focus-in caused by reparenting Windows. Calling WinAPI SetParent() causes the window to be activated, which is not desired for native child widgets. Task-number: QTBUG-32867 Change-Id: Idf61931bc425a043a4b7a98eec9ae122e234dc37 Reviewed-by: Andy Shaw --- src/plugins/platforms/windows/qwindowscontext.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index c210303e1e3..ead29556b74 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1063,6 +1063,15 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et, modalWindow->requestActivate(); return; } + // QTBUG-32867: Invoking WinAPI SetParent() can cause focus-in for the + // window which is not desired for native child widgets. + if (platformWindow->testFlag(QWindowsWindow::WithinSetParent)) { + QWindow *currentFocusWindow = QGuiApplication::focusWindow(); + if (currentFocusWindow && currentFocusWindow != platformWindow->window()) { + currentFocusWindow->requestActivate(); + return; + } + } nextActiveWindow = platformWindow->window(); } else { // Focus out: Is the next window known and different From 4ff4935ed49650141dc6cd788bf774cfc7ea945c Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 22 Apr 2014 16:57:42 +0200 Subject: [PATCH 139/180] Document setUniformValue limitations wrt non square matrices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-37012 Change-Id: Ife4f16eef22090ae4f6fdc24b69a45142a10d9c9 Reviewed-by: Jørgen Lind Reviewed-by: Gunnar Sletta --- src/gui/opengl/qopenglshaderprogram.cpp | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index bfde2704461..58cb60ed92c 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -2236,6 +2236,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& v Sets the uniform variable at \a location in the current context to a 2x3 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat2x3, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec3. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value) @@ -2251,6 +2255,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value Sets the uniform variable called \a name in the current context to a 2x3 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat2x3, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec3. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value) @@ -2262,6 +2270,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& v Sets the uniform variable at \a location in the current context to a 2x4 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat2x4, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec4. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value) @@ -2277,6 +2289,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value Sets the uniform variable called \a name in the current context to a 2x4 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat2x4, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec4. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value) @@ -2288,6 +2304,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& v Sets the uniform variable at \a location in the current context to a 3x2 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat3x2, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec2. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value) @@ -2303,6 +2323,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value Sets the uniform variable called \a name in the current context to a 3x2 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat3x2, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec2. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value) @@ -2340,6 +2364,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& v Sets the uniform variable at \a location in the current context to a 3x4 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat3x4, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec4. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value) @@ -2355,6 +2383,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value Sets the uniform variable called \a name in the current context to a 3x4 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat3x4, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec4. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value) @@ -2366,6 +2398,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& v Sets the uniform variable at \a location in the current context to a 4x2 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat4x2, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec2. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value) @@ -2381,6 +2417,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value Sets the uniform variable called \a name in the current context to a 4x2 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat4x2, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec2. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value) @@ -2392,6 +2432,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& v Sets the uniform variable at \a location in the current context to a 4x3 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat4x3, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec3. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value) @@ -2407,6 +2451,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value Sets the uniform variable called \a name in the current context to a 4x3 matrix \a value. + \note This function is not aware of non square matrix support, + that is, GLSL types like mat4x3, that is present in modern OpenGL + versions. Instead, it treats the uniform as an array of vec3. + \sa setAttributeValue() */ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value) From ca85cc620e5f88a088813daa2929f73bb189b61e Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 17 Apr 2014 14:26:24 +0200 Subject: [PATCH 140/180] remove superfluous include Change-Id: Ie6f52595b84d1383dc64b016dbff9eebe6a5539e Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipewriter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index daa80687340..daad5427058 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qwindowspipewriter_p.h" -#include QT_BEGIN_NAMESPACE From 3e596ffa009168e48a27a3d2d27d0b3e3a471524 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Wed, 23 Apr 2014 14:05:31 +0200 Subject: [PATCH 141/180] QNX: Do not crash if physical screen size is not set If the QQNX_PHYSICAL_SCREEN_SIZE is not set or set incorrectly the application exits with a qFatal. This patch replaces the qFatal with a qWarning and sets the physical screen size to 15cm x 9cm. Change-Id: I9e1a36414289c9e9676ef550eac5c1d7be974553 Reviewed-by: Bernd Weimer Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxscreen.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 2707f14db24..9ba0f5cd2e3 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -97,9 +97,9 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) { const int envHeight = envPhySizeStrList.size() == 2 ? envPhySizeStrList[1].toInt() : -1; if (envWidth <= 0 || envHeight <= 0) { - qFatal("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format " - "\"width,height\" in mm, with width, height > 0. " - "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90"); + qWarning("QQnxScreen: The value of QQNX_PHYSICAL_SCREEN_SIZE must be in the format " + "\"width,height\" in mm, with width, height > 0. Defaulting to 150x90. " + "Example: QQNX_PHYSICAL_SCREEN_SIZE=150,90"); return QSize(150, 90); } @@ -114,8 +114,8 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) { return defSize; #else if (primaryScreen) - qFatal("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. " - "Could not determine physical screen size."); + qWarning("QQnxScreen: QQNX_PHYSICAL_SCREEN_SIZE variable not set. " + "Could not determine physical screen size. Defaulting to 150x90."); return QSize(150, 90); #endif } From a2ad5cf1aadd5a3bec09595be7e8611abab31bb6 Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Wed, 23 Apr 2014 18:47:54 +0200 Subject: [PATCH 142/180] Fix build error when targeting Blackberry Playbook The emitSignals() slot is only implemented/used in the file qqnxfiledialoghelper_bb10.cpp, not in <...>_playbook.cpp. Change-Id: I068e843be74ec9639d889b87caa016c8506ec905 Reviewed-by: Robin Burchell Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxfiledialoghelper.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h index e83fc445d6b..83af966a00c 100644 --- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h +++ b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h @@ -88,7 +88,9 @@ class QQnxFileDialogHelper : public QPlatformFileDialogHelper void dialogClosed(); private Q_SLOTS: +#if !defined(Q_OS_BLACKBERRY_TABLET) void emitSignals(); +#endif private: void setNameFilter(const QString &filter); From 3e6e70bddd84536deaae69421d05785ae6ce28cd Mon Sep 17 00:00:00 2001 From: Israel Lins Albuquerque Date: Tue, 15 Apr 2014 17:37:18 -0300 Subject: [PATCH 143/180] [QSqlQuery] misbehavior of seek in special query positions When QSqlQuery::at() == QSql::BeforeFirstRow and seek(1, true) (seek to next record) is called the expected result is go to first row. When QSqlQuery::at() == QSql::AfterLastRow and seek(-1, true) (seek to previous record) is called the expected result is go to last row. But in all cases the first and last are skipped. Change-Id: I584138b3d397ce1c790bf89688ee92289a99611c Reviewed-by: Mark Brand --- src/sql/kernel/qsqlquery.cpp | 25 +++++++++++++------ .../sql/kernel/qsqlquery/tst_qsqlquery.cpp | 20 +++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp index b08f6bc8ef1..6b13eb02ed4 100644 --- a/src/sql/kernel/qsqlquery.cpp +++ b/src/sql/kernel/qsqlquery.cpp @@ -511,12 +511,23 @@ const QSqlResult* QSqlQuery::result() const \list - \li If the result is currently positioned before the first record or - on the first record, and \a index is negative, there is no change, - and false is returned. + \li If the result is currently positioned before the first record and: + \list + \li \a index is negative or zero, there is no change, and false is + returned. + \li \a index is positive, an attempt is made to position the result + at absolute position \a index - 1, following the sames rule for non + relative seek, above. + \endlist - \li If the result is currently located after the last record, and \a - index is positive, there is no change, and false is returned. + \li If the result is currently positioned after the last record and: + \list + \li \a index is positive or zero, there is no change, and false is + returned. + \li \a index is negative, an attempt is made to position the result + at \a index + 1 relative position from last record, following the + rule below. + \endlist \li If the result is currently located somewhere in the middle, and the relative offset \a index moves the result below zero, the result @@ -549,7 +560,7 @@ bool QSqlQuery::seek(int index, bool relative) switch (at()) { // relative seek case QSql::BeforeFirstRow: if (index > 0) - actualIdx = index; + actualIdx = index - 1; else { return false; } @@ -557,7 +568,7 @@ bool QSqlQuery::seek(int index, bool relative) case QSql::AfterLastRow: if (index < 0) { d->sqlResult->fetchLast(); - actualIdx = at() + index; + actualIdx = at() + index + 1; } else { return false; } diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 55cb67eed9a..301c7bca514 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -1247,6 +1247,26 @@ void tst_QSqlQuery::seek() QVERIFY( q.seek( 0 ) ); QCOMPARE( q.at(), 0 ); QCOMPARE( q.value( 0 ).toInt(), 1 ); + + QVERIFY(!q.seek(QSql::BeforeFirstRow)); + QCOMPARE(q.at(), int(QSql::BeforeFirstRow)); + QVERIFY(q.seek(1, true)); + QCOMPARE(q.at(), 0); + QCOMPARE(q.value(0).toInt(), 1); + + qint32 count = 1; + while (q.next()) ++count; + + QCOMPARE(q.at(), int(QSql::AfterLastRow)); + + if (!q.isForwardOnly()) { + QVERIFY(q.seek(-1, true)); + QCOMPARE(q.at(), count - 1); + QCOMPARE(q.value(0).toInt(), count); + } else { + QVERIFY(!q.seek(-1, true)); + QCOMPARE(q.at(), int(QSql::AfterLastRow)); + } } void tst_QSqlQuery::seekForwardOnlyQuery() From 049fa03c2f8c52e88bf5c5d205beddc92784c0c2 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 23 Apr 2014 08:33:33 +0200 Subject: [PATCH 144/180] Check the right object's height in qCompare for QImage and QPixmap. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes http://www.viva64.com/en/b/0251/, Typo No. 3 and 4 Change-Id: Icbd33534dbf424e00e4c351ae5ee0e3daa99e7b9 Reviewed-by: Jørgen Lind --- src/testlib/qtest_gui.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index a9ac7777c3e..7c68b0fd776 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -98,7 +98,7 @@ inline bool qCompare(QImage const &t1, QImage const &t2, } if (t1Null && t2Null) return compare_helper(true, 0, 0, 0, actual, expected, file, line); - if (t1.width() != t2.width() || t2.height() != t2.height()) { + if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QImages differ in size.\n" " Actual (%s): %dx%d\n" " Expected (%s): %dx%d", @@ -132,7 +132,7 @@ inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, c } if (t1Null && t2Null) return compare_helper(true, 0, 0, 0, actual, expected, file, line); - if (t1.width() != t2.width() || t2.height() != t2.height()) { + if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QPixmaps differ in size.\n" " Actual (%s): %dx%d\n" " Expected (%s): %dx%d", From d7d12bc1eb8ddb9b3f5055099fda7f6a2cea03b3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Apr 2014 14:56:18 +0200 Subject: [PATCH 145/180] Fix crash when accessing QFileDialog::selectedFiles() before widgets exist. Discovered while investigating: Task-number: QTBUG-38414 Change-Id: I764195254ba4b54c86079c6e8ef750d6249960d9 Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 4 ++-- .../widgets/dialogs/qfiledialog/tst_qfiledialog.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 80e8d152ff2..00ff3a2eaff 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.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 QtWidgets module of the Qt Toolkit. @@ -1255,7 +1255,7 @@ QStringList QFileDialog::selectedFiles() const QStringList files; foreach (const QUrl &file, d->userSelectedFiles()) files.append(file.toLocalFile()); - if (files.isEmpty()) { + if (files.isEmpty() && d->usingWidgets()) { const FileMode fm = fileMode(); if (fm != ExistingFile && fm != ExistingFiles) files.append(d->rootIndex().data(QFileSystemModel::FilePathRole).toString()); diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index de8528216d9..e856c2efc5c 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.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 test suite of the Qt Toolkit. @@ -147,6 +147,7 @@ private slots: void clearLineEdit(); void enableChooseButton(); void widgetlessNativeDialog(); + void selectedFilesWithoutWidgets(); void trailingDotsAndSpaces(); #ifdef Q_OS_UNIX #ifdef QT_BUILD_INTERNAL @@ -1326,6 +1327,14 @@ void tst_QFiledialog::widgetlessNativeDialog() QVERIFY(!button); } +void tst_QFiledialog::selectedFilesWithoutWidgets() +{ + // Test for a crash when widgets are not instantiated yet. + QFileDialog fd; + fd.setAcceptMode(QFileDialog::AcceptOpen); + QVERIFY(fd.selectedFiles().size() >= 0); +} + void tst_QFiledialog::trailingDotsAndSpaces() { #ifndef Q_OS_WIN From c0b75d3e6b744245795e2fea3482df4848fd2ff7 Mon Sep 17 00:00:00 2001 From: Steven Ceuppens Date: Mon, 21 Apr 2014 21:07:22 +0200 Subject: [PATCH 146/180] Update AddressBook Example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding parent to QDialog As proposed on qt-project.org forum: http://qt-project.org/forums/viewthread/41686/ Change-Id: Ib66d24e4afd0be803a1080c37bc6c0a189844786 Reviewed-by: Sze Howe Koh Reviewed-by: Jędrzej Nowacki --- examples/widgets/tutorials/addressbook/part5/addressbook.cpp | 2 +- examples/widgets/tutorials/addressbook/part6/addressbook.cpp | 2 +- examples/widgets/tutorials/addressbook/part7/addressbook.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/widgets/tutorials/addressbook/part5/addressbook.cpp b/examples/widgets/tutorials/addressbook/part5/addressbook.cpp index ca2f72e9e1a..a1005d69121 100644 --- a/examples/widgets/tutorials/addressbook/part5/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part5/addressbook.cpp @@ -73,7 +73,7 @@ AddressBook::AddressBook(QWidget *parent) previousButton->setEnabled(false); //! [instantiating FindDialog] - dialog = new FindDialog; + dialog = new FindDialog(this); //! [instantiating FindDialog] connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); diff --git a/examples/widgets/tutorials/addressbook/part6/addressbook.cpp b/examples/widgets/tutorials/addressbook/part6/addressbook.cpp index 2ced8e24046..536853590b7 100644 --- a/examples/widgets/tutorials/addressbook/part6/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part6/addressbook.cpp @@ -80,7 +80,7 @@ AddressBook::AddressBook(QWidget *parent) //! [tooltip 2] saveButton->setEnabled(false); - dialog = new FindDialog; + dialog = new FindDialog(this); connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); diff --git a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp index 2060d97d2fc..ba42cd4c938 100644 --- a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp @@ -80,7 +80,7 @@ AddressBook::AddressBook(QWidget *parent) exportButton->setToolTip(tr("Export as vCard")); exportButton->setEnabled(false); - dialog = new FindDialog; + dialog = new FindDialog(this); connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); From 62a436cf3be540e225b20191baeb6d1350e4619e Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 25 Apr 2014 19:19:03 +0200 Subject: [PATCH 147/180] Fix QFileDialog::viewMode() when using a native file dialog. It should return the view mode that was set in setViewMode() and stored in the options. Change-Id: Iaaa94a201a25baa251446688bf5bdaca5cf3373b Reviewed-by: Mark Gaiser Reviewed-by: Dominik Haumann Reviewed-by: Friedemann Kleint Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 00ff3a2eaff..ecbd9480ff5 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1600,7 +1600,7 @@ QFileDialog::ViewMode QFileDialog::viewMode() const { Q_D(const QFileDialog); if (!d->usingWidgets()) - return QFileDialog::List; + return static_cast(d->options->viewMode()); return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail); } From 386292837bf5f6bcb502bd3fa68cb2a4e9498b1b Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 22 Apr 2014 17:40:58 +0200 Subject: [PATCH 148/180] Add press action to QAccessibleCombobox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VoiceOver expects press to open the combobox. Task-number: QTBUG-37922 Change-Id: Iee7b7974db097e4e2444202c703bd587e1576fe0 Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/complexwidgets.cpp | 6 +++--- tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index b1df6d816a8..5f3b6b4bd64 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -315,19 +315,19 @@ QString QAccessibleComboBox::text(QAccessible::Text t) const QStringList QAccessibleComboBox::actionNames() const { - return QStringList(showMenuAction()); + return QStringList() << showMenuAction() << pressAction(); } QString QAccessibleComboBox::localizedActionDescription(const QString &actionName) const { - if (actionName == showMenuAction()) + if (actionName == showMenuAction() || actionName == pressAction()) return QComboBox::tr("Open the combo box selection popup"); return QString(); } void QAccessibleComboBox::doAction(const QString &actionName) { - if (actionName == showMenuAction()) { + if (actionName == showMenuAction() || actionName == pressAction()) { if (comboBox()->view()->isVisible()) { comboBox()->hidePopup(); } else { diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index fcc5581bead..1cc79f643aa 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -3283,7 +3283,7 @@ void tst_QAccessibility::comboBoxTest() QVERIFY(!combo.view()->isVisible()); QVERIFY(iface->actionInterface()); - QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction()); + QCOMPARE(iface->actionInterface()->actionNames(), QStringList() << QAccessibleActionInterface::showMenuAction() << QAccessibleActionInterface::pressAction()); iface->actionInterface()->doAction(QAccessibleActionInterface::showMenuAction()); QTRY_VERIFY(combo.view()->isVisible()); From 9f6a0300a5ab5996a97b27bc8ada55f41e3ca517 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 28 Apr 2014 16:16:34 +0200 Subject: [PATCH 149/180] Observe case insensitive file systems in QFileDialog::selectFile(). When stripping the root path from a file name that cannot be found in the model, use case sensitive comparison depending on file system. Task-number: QTBUG-38162 Change-Id: I28e28973fca2da35a5768fdd00cc258b9669a15a Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 60 ++++++++++++------- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 37 ++++++++++++ 2 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index ecbd9480ff5..bb8cdec8963 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -71,6 +71,7 @@ extern bool qt_priv_ptr_valid; #endif #if defined(Q_OS_UNIX) #include +#include // for pathconf() on OS X #elif defined(Q_OS_WIN) # include #endif @@ -1018,6 +1019,44 @@ QUrl QFileDialog::directoryUrl() const return QUrl::fromLocalFile(directory().absolutePath()); } +// FIXME Qt 5.4: Use upcoming QVolumeInfo class to determine this information? +static inline bool isCaseSensitiveFileSystem(const QString &path) +{ + Q_UNUSED(path) +#if defined(Q_OS_WIN) + // Return case insensitive unconditionally, even if someone has a case sensitive + // file system mounted, wrongly capitalized drive letters will cause mismatches. + return false; +#elif defined(Q_OS_OSX) + return pathconf(QFile::encodeName(path).constData(), _PC_CASE_SENSITIVE); +#else + return true; +#endif +} + +// Determine the file name to be set on the line edit from the path +// passed to selectFile() in mode QFileDialog::AcceptSave. +static inline QString fileFromPath(const QString &rootPath, QString path) +{ + if (!QFileInfo(path).isAbsolute()) + return path; + if (path.startsWith(rootPath, isCaseSensitiveFileSystem(rootPath) ? Qt::CaseSensitive : Qt::CaseInsensitive)) + path.remove(0, rootPath.size()); + + if (path.isEmpty()) + return path; + + if (path.at(0) == QDir::separator() +#ifdef Q_OS_WIN + //On Windows both cases can happen + || path.at(0) == QLatin1Char('/') +#endif + ) { + path.remove(0, 1); + } + return path; +} + /*! Selects the given \a filename in the file dialog. @@ -1049,28 +1088,9 @@ void QFileDialog::selectFile(const QString &filename) } QModelIndex index = d->model->index(filename); - QString file; - if (!index.isValid()) { - // save as dialog where we want to input a default value - QString text = filename; - if (QFileInfo(filename).isAbsolute()) { - QString current = d->rootPath(); - text.remove(current); - if (text.at(0) == QDir::separator() -#ifdef Q_OS_WIN - //On Windows both cases can happen - || text.at(0) == QLatin1Char('/') -#endif - ) - text = text.remove(0,1); - } - file = text; - } else { - file = index.data().toString(); - } d->qFileDialogUi->listView->selectionModel()->clear(); if (!isVisible() || !d->lineEdit()->hasFocus()) - d->lineEdit()->setText(file); + d->lineEdit()->setText(index.isValid() ? index.data().toString() : fileFromPath(d->rootPath(), filename)); } /*! diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index e856c2efc5c..047df0d3f26 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,7 @@ #include #if defined(Q_OS_UNIX) +#include // for pathconf() on OS X #ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE extern Q_GUI_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0); @@ -79,6 +81,19 @@ QT_END_NAMESPACE #endif #endif +static inline bool isCaseSensitiveFileSystem(const QString &path) +{ + Q_UNUSED(path) +#if defined(Q_OS_MAC) + return pathconf(QFile::encodeName(path).constData(), _PC_CASE_SENSITIVE); +#elif defined(Q_OS_WIN) + return false; +#else + return true; +#endif +} + + class QNonNativeFileDialog : public QFileDialog { Q_OBJECT @@ -130,6 +145,7 @@ private slots: void selectFile_data(); void selectFile(); void selectFiles(); + void selectFileWrongCaseSaveAs(); void selectFilter(); void viewMode(); void proxymodel(); @@ -882,6 +898,27 @@ void tst_QFiledialog::selectFile() fd.reset(); // Ensure the file dialog let's go of the temporary file for "temp". } +void tst_QFiledialog::selectFileWrongCaseSaveAs() +{ + const QString home = QDir::homePath(); + if (isCaseSensitiveFileSystem(home)) + QSKIP("This test is intended for case-insensitive file systems only."); + // QTBUG-38162: when passing a wrongly capitalized path to selectFile() + // on a case-insensitive file system, the line edit should only + // contain the file name ("c:\PRogram files\foo.txt" -> "foo.txt"). + const QString fileName = QStringLiteral("foo.txt"); + const QString path = home + QLatin1Char('/') + fileName; + QString wrongCasePath = path; + for (int c = 0; c < wrongCasePath.size(); c += 2) + wrongCasePath[c] = wrongCasePath.at(c).isLower() ? wrongCasePath.at(c).toUpper() : wrongCasePath.at(c).toLower(); + QNonNativeFileDialog fd(0, "QTBUG-38162", wrongCasePath); + fd.setAcceptMode(QFileDialog::AcceptSave); + fd.selectFile(wrongCasePath); + const QLineEdit *lineEdit = fd.findChild("fileNameEdit"); + QVERIFY(lineEdit); + QCOMPARE(lineEdit->text().compare(fileName, Qt::CaseInsensitive), 0); +} + void tst_QFiledialog::selectFiles() { QTemporaryDir tempDir; From 4833e5080c75a1f52a3040db5118fea5701d930e Mon Sep 17 00:00:00 2001 From: Timur Artikov Date: Thu, 17 Apr 2014 10:31:39 +0700 Subject: [PATCH 150/180] Allow to control animations frame rate from a custom QAnimationDriver Don't use time from the global timer (QUnifiedTimer::time.elapsed()) for animations updating when an user overrides QAnimationDriver::elapsed() Task-number: QTBUG-38390 Change-Id: Ic1470b43d8bbc0ee0a2bbb87f7173f97ba03f852 Reviewed-by: Michael Brasser Reviewed-by: Gunnar Sletta --- src/corelib/animation/qabstractanimation.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f7bb1e91bd7..95d7713cfe7 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -253,8 +253,9 @@ QUnifiedTimer *QUnifiedTimer::instance() void QUnifiedTimer::maybeUpdateAnimationsToCurrentTime() { - if (time.elapsed() - lastTick > 50) - updateAnimationTimers(driver->elapsed()); + qint64 elapsed = driver->elapsed(); + if (elapsed - lastTick > 50) + updateAnimationTimers(elapsed); } void QUnifiedTimer::updateAnimationTimers(qint64 currentTick) @@ -263,7 +264,7 @@ void QUnifiedTimer::updateAnimationTimers(qint64 currentTick) if(insideTick) return; - qint64 totalElapsed = currentTick >= 0 ? currentTick : time.elapsed(); + qint64 totalElapsed = currentTick >= 0 ? currentTick : driver->elapsed(); // ignore consistentTiming in case the pause timer is active qint64 delta = (consistentTiming && !pauseTimer.isActive()) ? From eaffcab287347badbf44e26416f5c2136101e1d2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 3 Apr 2014 14:58:03 -0700 Subject: [PATCH 151/180] Doc: add info about the -perf benchmark switch to QtTest's manual Change-Id: I923dcf4f59db8281800950684fdd6dcc6715508e Reviewed-by: Jerome Pasion --- src/testlib/doc/src/qttestlib-manual.qdoc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 13654972ec8..4125e63ddc3 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -315,12 +315,15 @@ \row \li CPU tick counter \li -tickcounter \li Windows, Mac OS X, Linux, many UNIX-like systems. - \row \li Valgrind Callgrind - \li -callgrind - \li Linux (if installed) \row \li Event Counter \li -eventcounter \li All platforms + \row \li Valgrind Callgrind + \li -callgrind + \li Linux (if installed) + \row \li Linux Perf + \li -perf + \li Linux \endtable In short, walltime is always available but requires many repetitions to @@ -335,6 +338,16 @@ that were received by the event loop before they are sent to their corresponding targets (this might include non-Qt events). + The Linux Performance Monitoring solution is available only on Linux and + provides many different counters, which can be selected by passing an + additional option \c {-perfcounter countername}, such as \c {-perfcounter + cache-misses}, \c {-perfcounter branch-misses}, or \c {-perfcounter + l1d-load-misses}. The default counter is \c {cpu-cycles}. The full list of + counters can be obtained by running any benchmark executable with the + option \c -perfcounterlist. + + Note that using the performance counter may require enabling access to non-privileged applications. + \note Depending on the device configuration, tick counters on the Windows CE platform may not be as fine-grained, compared to other platforms. Devices that do not support high-resolution timers default to From 774082e2ee2b9d7f290b84c3a483cc7710bbe8d4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 23 Apr 2014 07:36:01 -0700 Subject: [PATCH 152/180] Doc: QSize::isValid does >= 0 instead of > 0 comparisons The member function documentation was correct, just the class description was off. Task-number: QTBUG-38535 Change-Id: I55dded9d5ea79d93ce4984911acbeec8bbe6884a Reviewed-by: Martin Smith --- src/corelib/tools/qsize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp index b53eced2986..c9a6ffa03a2 100644 --- a/src/corelib/tools/qsize.cpp +++ b/src/corelib/tools/qsize.cpp @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE width and height can be swapped using the transpose() function. The isValid() function determines if a size is valid (a valid size - has both width and height greater than zero). The isEmpty() + has both width and height greater than or equal to zero). The isEmpty() function returns \c true if either of the width and height is less than, or equal to, zero, while the isNull() function returns \c true only if both the width and the height is zero. From 81fde3a976dec66b0c3eeb006033c0369752e386 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 28 Apr 2014 08:32:17 +0300 Subject: [PATCH 153/180] Direct2D QPA: Speed up widget painting By only starting/ending drawing once in the backing store, we can avoid multiple start/ends and thus flushes of the direct2d device context. This can potentially be much faster with some drivers when many widgets that draw to the same backing store need to redraw. Because starts/ends of QWindowsDirect2DDeviceContext are already refcounted this works out of the box. Change-Id: Ib48edceef6a1041ae0509587c77ac0caa8b29fc6 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- .../direct2d/qwindowsdirect2dbackingstore.cpp | 10 ++++++++++ .../platforms/direct2d/qwindowsdirect2dbackingstore.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp index 079ad6f1278..e4ce81bd24c 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp @@ -75,6 +75,16 @@ QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore() { } +void QWindowsDirect2DBackingStore::beginPaint(const QRegion &) +{ + platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->begin(); +} + +void QWindowsDirect2DBackingStore::endPaint() +{ + platformPixmap(m_pixmap.data())->bitmap()->deviceContext()->end(); +} + QPaintDevice *QWindowsDirect2DBackingStore::paintDevice() { return m_pixmap.data(); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h index 9776d234e8a..fc6802aaa22 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h @@ -58,6 +58,9 @@ class QWindowsDirect2DBackingStore : public QPlatformBackingStore QWindowsDirect2DBackingStore(QWindow *window); ~QWindowsDirect2DBackingStore(); + void beginPaint(const QRegion &); + void endPaint(); + QPaintDevice *paintDevice() Q_DECL_OVERRIDE; void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; From 195c070adf22f829697976ec8dbbfb3b5ec93305 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Mon, 28 Apr 2014 12:59:46 +0300 Subject: [PATCH 154/180] Direct2D QPA: Correctly set active state in paint engine Change-Id: I4eea073ad11ba8684212258b344c1f237598a9c5 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint --- src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 1e7c1752521..8d775e5a9da 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -874,6 +874,7 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev) D2D_TAG(D2DDebugDrawInitialStateTag); + setActive(true); return true; } From 2d019ddc93c8139950c92ba09a3234f12462d024 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 22 Apr 2014 12:57:37 +0200 Subject: [PATCH 155/180] iOS: scroll screen after hiding keyboard programatically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the keyboard is told to hide, we resign first responder. If this is done programatically on touch press, this will make the "hide keyboard gesture" receive a touchesCancelled instead of a touchesEnded. Since we didn't catch this from before, the gesture was left in a mixed state causing the screen not to scroll when later showing the keyboard. Change-Id: I70ed59710128a912097cd5bfbdd8f49b20b7934c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 9a2c55f7f24..8be3846e069 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -229,6 +229,13 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event [super touchesEnded:touches withEvent:event]; } +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + m_touchPressWhileKeyboardVisible = NO; + [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO]; + [super touchesCancelled:touches withEvent:event]; +} + - (void)touchesEndedPostDelivery { // Do some clean-up _after_ touchEnd has been delivered to QUIView From eb211d74cc3dbf991093ad2e799370f006de8198 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 28 Apr 2014 11:26:29 +0300 Subject: [PATCH 156/180] Add missing QT_NO_NETWORKPROXY guards around HTTP connect statements Without these, a spew of connection warnings will occur when using HTTP on Qt builds with QT_NO_NETWORKPROXY. Change-Id: I330f6d98d1abdbadc57768dc48b8fab0ee1f6655 Reviewed-by: Oliver Wolff Reviewed-by: Peter Hartmann --- src/network/access/qhttpthreaddelegate.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index e03dcb8eadc..76107d31109 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -352,8 +352,10 @@ void QHttpThreadDelegate::startRequest() connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), this, SLOT(synchronousAuthenticationRequiredSlot(QHttpNetworkRequest,QAuthenticator*))); +#ifndef QT_NO_NETWORKPROXY connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*))); +#endif // Don't care about ignored SSL errors for now in the synchronous HTTP case. } else if (!synchronous) { @@ -373,8 +375,10 @@ void QHttpThreadDelegate::startRequest() // Connect the reply signals that we can directly forward connect(httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)), this, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*))); +#ifndef QT_NO_NETWORKPROXY connect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); +#endif } connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)), @@ -706,9 +710,11 @@ void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNet a->setPassword(credential.password); } +#ifndef QT_NO_NETWORKPROXY // Disconnect this connection now since we only want to ask the authentication cache once. QObject::disconnect(httpReply, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(synchronousProxyAuthenticationRequiredSlot(QNetworkProxy,QAuthenticator*))); +#endif } #endif From f1eefd6cf99b2784b10390b7accf6bbe49245906 Mon Sep 17 00:00:00 2001 From: parihaaraka Date: Fri, 14 Jun 2013 22:38:43 +0400 Subject: [PATCH 157/180] Fix PSQL column's metadata Fixed libpq's PQfmod() interpretation inside QPSQLResult::record() Task-number: QTBUG-12477 Change-Id: I0e4c94ca1b06fd6a8e5b5702235cdd6d9736f8bf Reviewed-by: Andy Shaw Reviewed-by: Mark Brand --- src/sql/drivers/psql/qsql_psql.cpp | 31 ++++++++++--- .../sql/kernel/qsqlquery/tst_qsqlquery.cpp | 44 +++++++++++++++++++ 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index c052e4c2e7f..722595ad527 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -104,6 +104,11 @@ #define QXIDOID 28 #define QCIDOID 29 +#define QBITOID 1560 +#define QVARBITOID 1562 + +#define VARHDRSZ 4 + /* This is a compile time switch - if PQfreemem is declared, the compiler will use that one, otherwise it'll run in this template */ template @@ -533,17 +538,33 @@ QSqlRecord QPSQLResult::record() const f.setName(QString::fromUtf8(PQfname(d->result, i))); else f.setName(QString::fromLocal8Bit(PQfname(d->result, i))); - f.setType(qDecodePSQLType(PQftype(d->result, i))); + int ptype = PQftype(d->result, i); + f.setType(qDecodePSQLType(ptype)); int len = PQfsize(d->result, i); int precision = PQfmod(d->result, i); - // swap length and precision if length == -1 - if (len == -1 && precision > -1) { - len = precision - 4; + + switch (ptype) { + case QNUMERICOID: + if (precision != -1) { + len = (precision >> 16); + precision = ((precision - VARHDRSZ) & 0xffff); + } + break; + case QBITOID: + case QVARBITOID: + len = precision; precision = -1; + break; + default: + if (len == -1 && precision >= VARHDRSZ) { + len = precision - VARHDRSZ; + precision = -1; + } } + f.setLength(len); f.setPrecision(precision); - f.setSqlType(PQftype(d->result, i)); + f.setSqlType(ptype); info.append(f); } return info; diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 301c7bca514..824f042ffcb 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -195,6 +195,9 @@ private slots: void task_233829_data() { generic_data("QPSQL"); } void task_233829(); + void QTBUG_12477_data() { generic_data("QPSQL"); } + void QTBUG_12477(); + void sqlServerReturn0_data() { generic_data(); } void sqlServerReturn0(); @@ -3012,6 +3015,47 @@ void tst_QSqlQuery::task_233829() QVERIFY_SQL(q,exec()); } +void tst_QSqlQuery::QTBUG_12477() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + if (!db.driverName().startsWith("QPSQL")) + QSKIP("PostgreSQL specific test"); + + QSqlQuery q(db); + QVERIFY_SQL(q, exec("SELECT 1::bit, '10101010000111101101'::varbit, " + "'10101111011'::varbit(15), '22222.20'::numeric(16,2), " + "'333333'::numeric(18), '444444'::numeric")); + QVERIFY_SQL(q, next()); + QSqlRecord r = q.record(); + QSqlField f; + + f = r.field(0); + QCOMPARE(f.length(), 1); + QCOMPARE(f.precision(), -1); + + f = r.field(1); + QCOMPARE(f.length(), -1); + QCOMPARE(f.precision(), -1); + + f = r.field(2); + QCOMPARE(f.length(), 15); + QCOMPARE(f.precision(), -1); + + f = r.field(3); + QCOMPARE(f.length(), 16); + QCOMPARE(f.precision(), 2); + + f = r.field(4); + QCOMPARE(f.length(), 18); + QCOMPARE(f.precision(), 0); + + f = r.field(5); + QCOMPARE(f.length(), -1); + QCOMPARE(f.precision(), -1); +} + void tst_QSqlQuery::sqlServerReturn0() { QFETCH( QString, dbName ); From 159465536f0dd1a373f0c67e5530f9af6ccec433 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 24 Apr 2014 13:49:21 +0200 Subject: [PATCH 158/180] Allow building against static ICU libs also on Unix For dynamic builds of ICU, libicudata is an implicit dependency. Anyhow, it doesn't harm to explicitly link against it, either. So let's do this everywhere ... Task-number: QTBUG-38445 Change-Id: I420ba096e2ce5e1b8d81814ffb4aa7b300143b01 Reviewed-by: Thiago Macieira --- config.tests/unix/icu/icu.pro | 5 +++-- src/corelib/tools/tools.pri | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config.tests/unix/icu/icu.pro b/config.tests/unix/icu/icu.pro index 2c1b431f929..16267ff827b 100644 --- a/config.tests/unix/icu/icu.pro +++ b/config.tests/unix/icu/icu.pro @@ -1,6 +1,7 @@ SOURCES = icu.cpp CONFIG += console CONFIG -= qt dylib + win32 { CONFIG(static, static|shared) { CONFIG(debug, debug|release) { @@ -9,8 +10,8 @@ win32 { LIBS += -lsicuin -lsicuuc -lsicudt } } else { - LIBS += -licuin -licuuc + LIBS += -licuin -licuuc -licudt } } else { - LIBS += -licui18n -licuuc + LIBS += -licui18n -licuuc -licudata } diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 863cf034395..57a95910608 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -163,10 +163,10 @@ contains(QT_CONFIG,icu) { LIBS_PRIVATE += -lsicuin -lsicuuc -lsicudt } } else { - LIBS_PRIVATE += -licuin -licuuc + LIBS_PRIVATE += -licuin -licuuc -licudt } } else { - LIBS_PRIVATE += -licui18n -licuuc + LIBS_PRIVATE += -licui18n -licuuc -licudata } } else: win32 { SOURCES += tools/qcollator_win.cpp From 818eae42cbc291f79d21748408773c0d412ef8a4 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 29 Apr 2014 12:42:54 +0200 Subject: [PATCH 159/180] make use of QDir::NoDotAndDotDot Change-Id: Ib4bdc0d4051fed25dec7dc030658b4d0822a37bd Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 10 ++++------ qmake/generators/projectgenerator.cpp | 18 ++++++++---------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 3870d1ef0dd..0e3e058c7b8 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -370,7 +370,8 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString regex.remove(0, dir.length()); } if(real_dir.isEmpty() || exists(real_dir)) { - QStringList files = QDir(real_dir).entryList(QStringList(regex)); + QStringList files = QDir(real_dir).entryList(QStringList(regex), + QDir::NoDotAndDotDot | QDir::AllEntries); if(files.isEmpty()) { debug_msg(1, "%s:%d Failure to find %s in vpath (%s)", __FILE__, __LINE__, @@ -383,8 +384,6 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString l.removeAt(val_it); QString a; for(int i = (int)files.count()-1; i >= 0; i--) { - if(files[i] == "." || files[i] == "..") - continue; a = real_dir + files[i]; if(!(flags & VPATH_NoFixify)) a = fileFixify(a); @@ -1324,7 +1323,8 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) continue; } QString local_dirstr = Option::fixPathToLocalOS(dirstr, true); - QStringList files = QDir(local_dirstr).entryList(QStringList(filestr)); + QStringList files = QDir(local_dirstr).entryList(QStringList(filestr), + QDir::NoDotAndDotDot | QDir::AllEntries); if (installConfigValues.contains("no_check_exist") && files.isEmpty()) { QString dst_file = filePrefixRoot(root, dst_dir); QString cmd; @@ -1346,8 +1346,6 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) } for(int x = 0; x < files.count(); x++) { QString file = files[x]; - if(file == "." || file == "..") //blah - continue; uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false)))); QFileInfo fi(fileInfo(dirstr + file)); QString dst_file = filePrefixRoot(root, fileFixify(dst_dir, FileFixifyAbsolute, false)); diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 3cd5a22a33d..299ca52457c 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -137,12 +137,9 @@ ProjectGenerator::init() regex = regex.right(regex.length() - (s+1)); } if (Option::recursive) { - QStringList entries = QDir(dir).entryList(QDir::Dirs); - for(int i = 0; i < (int)entries.count(); i++) { - if(entries[i] != "." && entries[i] != "..") { - dirs.append(dir + entries[i] + QDir::separator() + regex); - } - } + QStringList entries = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); + for (int i = 0; i < entries.count(); i++) + dirs.append(dir + entries[i] + QDir::separator() + regex); } QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regex)); for(int i = 0; i < (int)files.count(); i++) { @@ -192,10 +189,10 @@ ProjectGenerator::init() } } if (Option::recursive) { - QStringList dirs = QDir(newdir).entryList(QDir::Dirs); + QStringList dirs = QDir(newdir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); for(int i = 0; i < (int)dirs.count(); i++) { QString nd = fileFixify(newdir + QDir::separator() + dirs[i]); - if(dirs[i] != "." && dirs[i] != ".." && !knownDirs.contains(nd, Qt::CaseInsensitive)) + if (!knownDirs.contains(nd, Qt::CaseInsensitive)) knownDirs.append(nd); } } @@ -207,12 +204,13 @@ ProjectGenerator::init() dir = regx.left(s+1); regx = regx.right(regx.length() - (s+1)); } - QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx), QDir::Dirs); + QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx), + QDir::Dirs | QDir::NoDotAndDotDot); ProStringList &subdirs = v["SUBDIRS"]; for(int i = 0; i < (int)files.count(); i++) { QString newdir(dir + files[i]); QFileInfo fi(fileInfo(newdir)); - if(fi.fileName() != "." && fi.fileName() != "..") { + { newdir = fileFixify(newdir); if(exists(fi.filePath() + QDir::separator() + fi.fileName() + Option::pro_ext) && !subdirs.contains(newdir)) { From 03fc60debf6baaec95ecfbde0b5910e30274402b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 29 Apr 2014 14:17:33 +0200 Subject: [PATCH 160/180] remove pointless checks for "." and ".." Change-Id: Id2b1353a73012461c594319f9d1341bccef85ecc Reviewed-by: Oswald Buddenhagen --- qmake/generators/projectgenerator.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 299ca52457c..05fdcb320d0 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -111,10 +111,8 @@ ProjectGenerator::init() dir += Option::dir_sep; if (Option::recursive) { QStringList files = QDir(dir).entryList(QDir::Files); - for(int i = 0; i < (int)files.count(); i++) { - if(files[i] != "." && files[i] != "..") - dirs.append(dir + files[i] + QDir::separator() + builtin_regex); - } + for (int i = 0; i < files.count(); i++) + dirs.append(dir + files[i] + QDir::separator() + builtin_regex); } regex = builtin_regex; } else { @@ -183,8 +181,7 @@ ProjectGenerator::init() nd += QDir::separator(); nd += profiles[i]; fileFixify(nd); - if(profiles[i] != "." && profiles[i] != ".." && - !subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd)) + if (!subdirs.contains(nd, Qt::CaseInsensitive) && !out_file.endsWith(nd)) subdirs.append(nd); } } From 090124eab6f184abbe9be04f4bc1a9eee5285207 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 28 Feb 2014 21:36:13 -0800 Subject: [PATCH 161/180] Remove duplicate symbol name: QTest::currentAppName It's declared in qtestcase.h as a function, so let's not declare the one in qtestresult.cpp as a static variable. None of the variables in qtestresult.cpp need to be in the QTest namespace, but we don't need to change them now. Change-Id: If6cc34642fdfe3ccda3b8cea7d053ead0db9ccbd Reviewed-by: Olivier Goffart --- src/testlib/qtestresult.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index a9abca0ef82..859f6743cd3 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -51,6 +51,8 @@ #include #include +static const char *currentAppName = 0; + QT_BEGIN_NAMESPACE namespace QTest @@ -64,8 +66,6 @@ namespace QTest static const char *expectFailComment = 0; static int expectFailMode = 0; - - static const char *currentAppName = 0; } void QTestResult::reset() @@ -322,12 +322,12 @@ bool QTestResult::skipCurrentTest() void QTestResult::setCurrentAppName(const char *appName) { - QTest::currentAppName = appName; + ::currentAppName = appName; } const char *QTestResult::currentAppName() { - return QTest::currentAppName; + return ::currentAppName; } QT_END_NAMESPACE From 0edb21df154cd2469ba91ea95c8c6464d1140c8d Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Tue, 29 Apr 2014 16:14:19 +0300 Subject: [PATCH 162/180] Direct2D QPA: Pixel-align aliased drawing Aliased drawing has so far not been perfectly pixel aligned, resulting in less than stellar output in some instances. Although a little hacky, adding 0.5 to all coordinates when in aliased mode fixes things up nicely. There doesn't appear to be a better way to get d2d to cooperate as we would like it to. Change-Id: I10ee494d2f576bfd0eca6d4429095a3726c0bf14 Reviewed-by: Risto Avila Reviewed-by: Andrew Knight --- .../platforms/direct2d/qwindowsdirect2dpaintengine.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 8d775e5a9da..0c3618132d7 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -89,6 +89,11 @@ enum ClipType { LayerClip }; +// Since d2d is a float-based system we need to be able to snap our drawing to whole pixels. +// Applying the magical aliasing offset to coordinates will do so, just make sure that +// aliased painting is turned on on the d2d device context. +static const qreal MAGICAL_ALIASING_OFFSET = 0.5; + #define D2D_TAG(tag) d->dc()->SetTags(tag, tag) Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); @@ -184,8 +189,11 @@ class Direct2DPathGeometryWriter private: D2D1_POINT_2F adjusted(const QPointF &point) { + static const QPointF adjustment(MAGICAL_ALIASING_OFFSET, + MAGICAL_ALIASING_OFFSET); + if (m_roundCoordinates) - return to_d2d_point_2f(point.toPoint()); + return to_d2d_point_2f(point + adjustment); else return to_d2d_point_2f(point); } From 7c12cd0ebb465b6d0714a22d5630872e600be654 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 29 Apr 2014 09:47:24 +0300 Subject: [PATCH 163/180] Windows Phone: add language control to the package manifest This allows the developer to provide a list of languages to the manifest by listing them in WINRT_MANIFEST.languages. It also allows setting the default language with WINRT_MANIFEST.default_language. Task-number: QTBUG-38557 Change-Id: I5cb94c9f45146e3068d0833b9e669dc17dca14b2 Reviewed-by: Oliver Wolff --- .../manifests/8.0/WMAppManifest.xml.in | 2 +- mkspecs/features/winrt/package_manifest.prf | 15 +++++++++++++++ qmake/doc/src/qmake-manual.qdoc | 7 +++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in index 5efb9c7b06d..18d37cf7fce 100644 --- a/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in +++ b/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in @@ -1,6 +1,6 @@ - + $${WINRT_MANIFEST.languages} " + + WINRT_MANIFEST.languages = \ + $$join(MANIFEST_LANGUAGES, $$INDENT, \ + "$$escape_expand(\\r\\n) $$INDENT", \ + "$$escape_expand(\\r\\n) ") + } + # Capabilities are given as a string list and may change with the configuration (network, sensors, etc.) WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities) WINRT_MANIFEST.capabilities_device = $$unique(WINRT_MANIFEST.capabilities_device) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 91629ec9ddc..8032b08d6f7 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2411,6 +2411,9 @@ \li capabilities_device \li Specifies device capabilities to add to the capability list (location, webcam, and so on). This option is not available on Windows Phone. + \row + \li default_language + \li The default language code of the application. Defaults to "en". \row \li dependencies \li Specifies dependencies required by the package. @@ -2437,6 +2440,10 @@ \li identity \li The unique ID of the app. Defaults to reusing the existing generated manifest's UUID, or generates a new UUID if none is present. + \row + \li languages + \li A list of additional language codes supported by the application. This list + is empty by default. \row \li logo_large \li Large logo image file. Default provided by the mkspec. From fd644f3bd0eee59a9cacfd0dd51a620c31c8e87d Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 2 Apr 2014 20:51:55 +0200 Subject: [PATCH 164/180] Improve accessibility event failure output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simpler code and more information ;) Change-Id: I5ca6b2ee88e51dbbd3ec2f08c4ea79bc11b649fa Reviewed-by: Jan Arve Sæther --- src/testlib/qtestaccessible.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h index f27651c3ad3..ef6f61bd82d 100644 --- a/src/testlib/qtestaccessible.h +++ b/src/testlib/qtestaccessible.h @@ -253,12 +253,10 @@ class QTestAccessibility { QString rc; QDebug str = QDebug(&rc).nospace(); - str << "Event " << needle->object() << ", type: " - << needle->type() << ", child: " << needle->child() - << " not found at head of event list of size " << haystack.size() << " :"; + str << "Event " << *needle + << " not found at head of event list of size " << haystack.size() << " :"; Q_FOREACH (const QAccessibleEvent *e, haystack) - str << ' ' << e->object() << ", type: " - << e->type() << ", child: " << e->child(); + str << ' ' << *e; return rc; } From 92d289aba8207d2e95ff4117660f619e497f93e8 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 29 Apr 2014 14:15:42 +0200 Subject: [PATCH 165/180] Widgets going "undercover" should also undercover the QWindow Sometimes Qt wants to hide a widget without calling setVisible(false). This is usually done by setting the widgets geometry outside the parents clip rect (and usually by setting its y coordinate to a sufficiently negative y coordinate). QSplitter uses this when it needs to collapse its children. Previously the QWindow was just moved straight above the QWidget it was hosted in. Task-number: QTBUG-38475 Change-Id: I154dd4d13f108c3d34c64eadb41dd6b477dc5c4e Reviewed-by: Friedemann Kleint Reviewed-by: Gunnar Sletta --- src/widgets/kernel/qwindowcontainer.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index 4618e1c91d6..1770e60c2e1 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 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 QtWidgets module of the Qt Toolkit. @@ -72,7 +72,14 @@ class QWindowContainerPrivate : public QWidgetPrivate void updateGeometry() { Q_Q(QWindowContainer); - if (usesNativeWidgets) + if (q->geometry().bottom() <= 0 || q->geometry().right() <= 0) + /* Qt (e.g. QSplitter) sometimes prefer to hide a widget by *not* calling + setVisible(false). This is often done by setting its coordinates to a sufficiently + negative value so that its clipped outside the parent. Since a QWindow is not clipped + to widgets in general, it needs to be dealt with as a special case. + */ + window->setGeometry(q->geometry()); + else if (usesNativeWidgets) window->setGeometry(q->rect()); else window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size())); From 7e14e69fd5bf76a87c7d79f9d9eef4e76ae83768 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 30 Apr 2014 10:46:20 +0200 Subject: [PATCH 166/180] Stabilize tst_QAbstractItemView::task250754_fontChange(). Increase window size when verifying that the scrollbar disappears when using a small font on Windows 8.1 Change-Id: I7d4520bc5882d8ccd59db3f5bff7e9d6d68a4827 Reviewed-by: Oliver Wolff --- .../itemviews/qabstractitemview/tst_qabstractitemview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 83c45826459..daca1d15164 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -1257,7 +1257,7 @@ void tst_QAbstractItemView::task250754_fontChange() tree.setModel(m); tree.setHeaderHidden(true); // The header is (in certain styles) dpi dependent - w.resize(160, 300); // Minimum width for windows with frame on Windows 8 + w.resize(160, 350); // Minimum width for windows with frame on Windows 8 centerOnScreen(&w); moveCursorAway(&w); w.showNormal(); From 91ef3966bd7921a059d9828d26c228877ab351e2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 22 Apr 2014 13:27:10 +0200 Subject: [PATCH 167/180] fix list of cached module variables makes configure -fully-process less broken. Change-Id: I7d22898b1e6994eb46359afca3fc4ad08e334946 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen Reviewed-by: Martin Jansa --- mkspecs/features/qt_module_pris.prf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index f31bc38c755..aba720238f2 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -177,9 +177,8 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri include($$mod_work_pfx/qt_lib_$${pri}.pri) for(mod, mods_to_load) { for(var, $$list(VERSION MAJOR_VERSION MINOR_VERSION PATCH_VERSION \ - name depends module_config CONFIG DEFINES sources \ + name depends run_depends plugin_types module_config CONFIG DEFINES \ includes bins libs libexecs plugins imports qml \ - rpath_link \ )):defined(QT.$${mod}.$$var, var):cache(QT.$${mod}.$$var, transient) } cache(QT_MODULES, transient) From bc563a02b2a7fde1f93c1746a1de3a4ab749e763 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 21:58:20 +0200 Subject: [PATCH 168/180] don't create a trailing space when PLUGIN_EXTENDS is empty Change-Id: Ia6a11721419e043bc08e38b5e6c6dfd71315eca2 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_plugin.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf index 52567eaff07..b012278bde3 100644 --- a/mkspecs/features/qt_plugin.prf +++ b/mkspecs/features/qt_plugin.prf @@ -38,7 +38,7 @@ CONFIG(static, static|shared) { !build_pass { MODULE_PRI_CONT = \ "QT_PLUGIN.$${MODULE}.TYPE = $$PLUGIN_TYPE" \ - "QT_PLUGIN.$${MODULE}.EXTENDS = $$PLUGIN_EXTENDS" \ + "QT_PLUGIN.$${MODULE}.EXTENDS =$$join(PLUGIN_EXTENDS, " ", " ")" \ "QT_PLUGIN.$${MODULE}.CLASS_NAME = $$PLUGIN_CLASS_NAME" \ "QT_PLUGINS += $$MODULE" write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.") From 5c05534a63f3ce97530b3827533ba9a0f4e2d57c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 29 Apr 2014 19:24:00 +0200 Subject: [PATCH 169/180] fix qtmain's .prl file not being used at some point we stopped adding the qtmain's library path before its respective -l flag, which lead to qmake being unable to resolve the library location and thus ignoring its prl file. Change-Id: I390a31f8ac2877d3823dfd2787b2cc8c696b0ec0 Reviewed-by: Friedemann Kleint Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/win32/windows.prf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/features/win32/windows.prf b/mkspecs/features/win32/windows.prf index 6d8289d949e..f19a42b7e26 100644 --- a/mkspecs/features/win32/windows.prf +++ b/mkspecs/features/win32/windows.prf @@ -7,6 +7,8 @@ contains(TEMPLATE, ".*app"){ qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) { isEqual(entryLib, -lqtmain): { + !contains(QMAKE_DEFAULT_LIBDIRS, $$QT.core.libs): \ + QMAKE_LIBS += -L$$QT.core.libs CONFIG(debug, debug|release): QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX}d else: QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX} } else { From e5024c219fffa972e087a684bacef240082dca82 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 29 Apr 2014 20:15:21 +0200 Subject: [PATCH 170/180] untangle use of system vs. shell path(-list) semantics "system" refers to the system's native shell, which is what qmake's system() invokes, and whose convention by far most commands invoked from a makefile will need. "shell" refers to the shell invoked by make, which diverges from the system shell only when qmake/mingw32-make is called from an msys shell. its conventions need to be used for anything the shell itself does (e.g., assembling env variables, but also command line argument unquoting) and the commands the mkspec sets according to the shell (e.g., QMAKE_MOVE). Change-Id: I0000aa9417c199cf8a810619d31ded24bb0675f9 Reviewed-by: Joerg Bornemann --- mkspecs/features/default_post.prf | 4 ++-- mkspecs/features/incredibuild_xge.prf | 2 +- mkspecs/features/java.prf | 2 +- mkspecs/features/qt_functions.prf | 2 +- mkspecs/features/testcase.prf | 2 +- mkspecs/features/win32/windeployqt.prf | 6 +++--- qtbase.pro | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index 938670b2a8b..6fb140b252d 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -83,8 +83,8 @@ silent { breakpad { load(resolve_target) - DEBUGFILENAME = $$shell_quote($$shell_path($$QMAKE_RESOLVED_TARGET)) - PROJECTPATH = $$shell_quote($$shell_path($$OUT_PWD)) + DEBUGFILENAME = $$shell_quote($$system_path($$QMAKE_RESOLVED_TARGET)) + PROJECTPATH = $$shell_quote($$system_path($$OUT_PWD)) !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t) QMAKE_POST_LINK = $$QMAKE_POST_LINK$$quote($${QT_BREAKPAD_ROOT_PATH}$${QMAKE_DIR_SEP}qtbreakpadsymbols $$DEBUGFILENAME $$PROJECTPATH) diff --git a/mkspecs/features/incredibuild_xge.prf b/mkspecs/features/incredibuild_xge.prf index b43ecf28097..75c7a9a75b4 100644 --- a/mkspecs/features/incredibuild_xge.prf +++ b/mkspecs/features/incredibuild_xge.prf @@ -3,6 +3,6 @@ contains(TEMPLATE, "vc.*") { EOC = $$escape_expand(\\r\\h) for(xge, INCREDIBUILD_XGE) { - $${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$shell_path($${xge}.output) $$EOC $$eval($${xge}.commands) + $${xge}.commands = Rem IncrediBuild_AllowRemote $$EOC Rem IncrediBuild_OutputFile $$system_path($${xge}.output) $$EOC $$eval($${xge}.commands) } } diff --git a/mkspecs/features/java.prf b/mkspecs/features/java.prf index eeaafcc883e..790724cec9c 100644 --- a/mkspecs/features/java.prf +++ b/mkspecs/features/java.prf @@ -44,7 +44,7 @@ CONFIG += plugin no_plugin_name_prefix javac.input = JAVASOURCES javac.output = $$CLASS_DIR javac.CONFIG += combine -javac.commands = javac -source 6 -target 6 -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$shell_path($$join(JAVACLASSPATH, $$QMAKE_DIRLIST_SEP))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN} +javac.commands = javac -source 6 -target 6 -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$system_path($$join(JAVACLASSPATH, $$DIRLIST_SEP))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN} # Force rebuild every time, because we don't know the paths of the destination files # as they depend on the code. javac.depends = FORCE diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 1dacfedd028..64b9fee3615 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -210,7 +210,7 @@ defineTest(qtPrepareTool) { $$1$$3 = $$system_path($$eval($$1)) qtAddTargetEnv($$1$$3, QT_TOOL.$${2}.depends, system) } - $$1 = $$shell_path($$eval($$1)) + $$1 = $$system_path($$eval($$1)) qtAddTargetEnv($$1, QT_TOOL.$${2}.depends, ) } diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index 40ec7cff303..6656d1b8986 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -22,7 +22,7 @@ debug_and_release:debug_and_release_target { } !isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD,^\\./?): \ - check.commands = cd $$system_path($$TESTRUN_CWD) && + check.commands = cd $$shell_path($$TESTRUN_CWD) && # Allow for a custom test runner script check.commands += $(TESTRUNNER) diff --git a/mkspecs/features/win32/windeployqt.prf b/mkspecs/features/win32/windeployqt.prf index f49df47ffef..22253f6299d 100644 --- a/mkspecs/features/win32/windeployqt.prf +++ b/mkspecs/features/win32/windeployqt.prf @@ -3,9 +3,9 @@ qtPrepareTool(QMAKE_WINDEPLOYQT, windeployqt) build_pass { load(resolve_target) - isEmpty(WINDEPLOYQT_OPTIONS): WINDEPLOYQT_OPTIONS = -qmldir $$shell_quote($$shell_path($$_PRO_FILE_PWD_)) - WINDEPLOYQT_TARGET = $$shell_quote($$shell_path($$QMAKE_RESOLVED_TARGET)) - WINDEPLOYQT_OUTPUT = $$shell_quote($$shell_path($$dirname(QMAKE_RESOLVED_TARGET)/$$basename(TARGET).windeployqt)) + isEmpty(WINDEPLOYQT_OPTIONS): WINDEPLOYQT_OPTIONS = -qmldir $$shell_quote($$system_path($$_PRO_FILE_PWD_)) + WINDEPLOYQT_TARGET = $$shell_quote($$system_path($$QMAKE_RESOLVED_TARGET)) + WINDEPLOYQT_OUTPUT = $$shell_quote($$system_path($$dirname(QMAKE_RESOLVED_TARGET)/$$basename(TARGET).windeployqt)) windeployqt.target = windeployqt windeployqt.commands = $$QMAKE_WINDEPLOYQT $$WINDEPLOYQT_OPTIONS -list target $$WINDEPLOYQT_TARGET > $$WINDEPLOYQT_OUTPUT diff --git a/qtbase.pro b/qtbase.pro index ed6fc394cb4..d6861cf09fb 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -87,7 +87,7 @@ INSTALLS += syncqt # qtPrepareTool() to find the non-installed syncqt. prefix_build|!equals(PWD, $$OUT_PWD) { - cmd = perl -w $$shell_path($$PWD/bin/syncqt.pl) + cmd = perl -w $$system_path($$PWD/bin/syncqt.pl) TOOL_PRI = $$OUT_PWD/mkspecs/modules/qt_tool_syncqt.pri From f73b9e4af8d410a54ea38385d9f1a0fe99ddedf4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 29 Apr 2014 20:25:43 +0200 Subject: [PATCH 171/180] make QMAKE_DIRLIST_SEP consistent with QMAKE_DIR_SEP that is, make it match the shell used by the make command. this is unlike DIRLIST_SEPARATOR and DIR_SEPARATOR, which always match the actual system shell. Change-Id: I0fb277d75b32be029808623a3b77e1358c4e265e Reviewed-by: Joerg Bornemann --- mkspecs/android-g++/qmake.conf | 1 + mkspecs/common/qcc-base-qnx.conf | 1 + mkspecs/win32-g++/qmake.conf | 1 + 3 files changed, 3 insertions(+) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 44624fcca52..608e64f3d4d 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -26,6 +26,7 @@ contains(QMAKE_HOST.os,Windows) { } else { MINGW_IN_SHELL = 1 QMAKE_DIR_SEP = / + QMAKE_DIRLIST_SEP = : # Because install's ability to set permissions is not relevant on Windows, # and git's msys does not provide it to start with. QMAKE_INSTALL_FILE = cp -f diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf index 0954cfd1ee2..a0a88b96054 100644 --- a/mkspecs/common/qcc-base-qnx.conf +++ b/mkspecs/common/qcc-base-qnx.conf @@ -57,4 +57,5 @@ QMAKE_STRIPFLAGS_LIB += --strip-unneeded equals(QMAKE_HOST.os, Windows) { isEmpty(QMAKE_SH): error("This mkspec requires an MSYS environment.") QMAKE_DIR_SEP = / + QMAKE_DIRLIST_SEP = : } diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 1ac35611f54..830dde97e99 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -93,6 +93,7 @@ QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain !isEmpty(QMAKE_SH) { MINGW_IN_SHELL = 1 QMAKE_DIR_SEP = / + QMAKE_DIRLIST_SEP = : include(../common/shell-unix.conf) # Because install's ability to set permissions is not relevant on Windows, # and git's msys does not provide it to start with. From d52b00e1d3cc60c81b54a89d6da488dc4bbce384 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 29 Apr 2014 20:39:13 +0200 Subject: [PATCH 172/180] fix $$shell_path() for mingw+sh the msys shell expects unix-like paths with drives converted from d:\ to /d/. Change-Id: I09e25ed2c868702e5d7d8b9cc8c04cc13410eeff Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 5ae99bab926..7896688e540 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1064,10 +1064,18 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( evalError(fL1S("shell_path(path) requires one argument.")); } else { QString rstr = args.at(0).toQString(m_tmp1); - if (m_dirSep.startsWith(QLatin1Char('\\'))) + if (m_dirSep.startsWith(QLatin1Char('\\'))) { rstr.replace(QLatin1Char('/'), QLatin1Char('\\')); - else + } else { rstr.replace(QLatin1Char('\\'), QLatin1Char('/')); +#ifdef Q_OS_WIN + // Convert d:/foo/bar to msys-style /d/foo/bar. + if (rstr.length() > 2 && rstr.at(1) == QLatin1Char(':') && rstr.at(2) == QLatin1Char('/')) { + rstr[1] = rstr.at(0); + rstr[0] = QLatin1Char('/'); + } +#endif + } ret << (rstr.isSharedWith(m_tmp1) ? args.at(0) : ProString(rstr).setSource(args.at(0))); } break; From 948fa572de1c6398df03246b7a6c124af312e967 Mon Sep 17 00:00:00 2001 From: Louai Al-Khanji Date: Tue, 29 Apr 2014 16:15:55 +0300 Subject: [PATCH 173/180] Direct2D QPA: Add handlers for individual primitives Directly handling primitives is faster than using the catch-all fill function which converts arbitrary paths into a direct2d geometry. So do so. Change-Id: I71ce73dbe75aa9b61e741c358d8787d0ea48ee46 Reviewed-by: Risto Avila Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 272 ++++++++++++++++-- .../direct2d/qwindowsdirect2dpaintengine.h | 18 ++ 2 files changed, 269 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 0c3618132d7..58c30b6eebc 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -72,8 +72,15 @@ QT_BEGIN_NAMESPACE // http://msdn.microsoft.com/en-us/library/windows/desktop/dd370979(v=vs.85).aspx enum { D2DDebugDrawInitialStateTag = -1, - D2DDebugDrawImageTag = 1, - D2DDebugFillTag, + D2DDebugFillTag = 1, + D2DDebugFillRectTag, + D2DDebugDrawRectsTag, + D2DDebugDrawRectFsTag, + D2DDebugDrawLinesTag, + D2DDebugDrawLineFsTag, + D2DDebugDrawEllipseTag, + D2DDebugDrawEllipseFTag, + D2DDebugDrawImageTag, D2DDebugDrawPixmapTag, D2DDebugDrawStaticTextItemTag, D2DDebugDrawTextItemTag @@ -933,7 +940,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br ensureBrush(brush); - if (!state()->matrix.isAffine() || d->brush.emulate) { + if (emulationRequired(BrushEmulation)) { rasterFill(path, brush); return; } @@ -941,25 +948,13 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br if (!d->brush.brush) return; - if (path.isRect()) { - const qreal * const points = path.points(); - D2D_RECT_F rect = { - points[0], // left - points[1], // top - points[2], // right, - points[5] // bottom - }; - - d->dc()->FillRectangle(rect, d->brush.brush.Get()); - } else { - 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()->FillGeometry(geometry.Get(), d->brush.brush.Get()); + 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()->FillGeometry(geometry.Get(), d->brush.brush.Get()); } void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) @@ -1016,6 +1011,198 @@ void QWindowsDirect2DPaintEngine::transformChanged() d->updateTransform(state()->transform()); } +void QWindowsDirect2DPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugFillRectTag); + + ensureBrush(brush); + + if (emulationRequired(BrushEmulation)) { + QPaintEngineEx::fillRect(rect, brush); + } else { + QRectF r = rect.normalized(); + adjustForAliasing(&r); + + if (d->brush.brush) + d->dc()->FillRectangle(to_d2d_rect_f(rect), d->brush.brush.Get()); + } +} + +void QWindowsDirect2DPaintEngine::drawRects(const QRect *rects, int rectCount) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugDrawRectsTag); + + ensureBrush(); + ensurePen(); + + if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) { + QPaintEngineEx::drawRects(rects, rectCount); + } else { + QRectF rect; + for (int i = 0; i < rectCount; i++) { + rect = rects[i].normalized(); + adjustForAliasing(&rect); + + D2D1_RECT_F d2d_rect = to_d2d_rect_f(rect); + + if (d->brush.brush) + d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get()); + + if (d->pen.brush) + d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + } + } +} + +void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugDrawRectFsTag); + + ensureBrush(); + ensurePen(); + + if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) { + QPaintEngineEx::drawRects(rects, rectCount); + } else { + QRectF rect; + for (int i = 0; i < rectCount; i++) { + rect = rects[i].normalized(); + adjustForAliasing(&rect); + + D2D1_RECT_F d2d_rect = to_d2d_rect_f(rect); + + if (d->brush.brush) + d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get()); + + if (d->pen.brush) + d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + } + } +} + +void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugDrawLinesTag); + + ensurePen(); + + if (emulationRequired(PenEmulation)) { + QPaintEngineEx::drawLines(lines, lineCount); + } else if (d->pen.brush) { + for (int i = 0; i < lineCount; i++) { + QPointF p1 = lines[i].p1(); + QPointF p2 = lines[i].p2(); + + // Match raster engine output + if (p1 == p2 && d->pen.qpen.widthF() <= 1.0) { + fillRect(QRectF(p1, QSizeF(d->pen.qpen.widthF(), d->pen.qpen.widthF())), + d->pen.qpen.brush()); + continue; + } + + adjustForAliasing(&p1); + adjustForAliasing(&p2); + + D2D1_POINT_2F d2d_p1 = to_d2d_point_2f(p1); + D2D1_POINT_2F d2d_p2 = to_d2d_point_2f(p2); + + d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + } + } +} + +void QWindowsDirect2DPaintEngine::drawLines(const QLineF *lines, int lineCount) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugDrawLineFsTag); + + ensurePen(); + + if (emulationRequired(PenEmulation)) { + QPaintEngineEx::drawLines(lines, lineCount); + } else if (d->pen.brush) { + for (int i = 0; i < lineCount; i++) { + QPointF p1 = lines[i].p1(); + QPointF p2 = lines[i].p2(); + + // Match raster engine output + if (p1 == p2 && d->pen.qpen.widthF() <= 1.0) { + fillRect(QRectF(p1, QSizeF(d->pen.qpen.widthF(), d->pen.qpen.widthF())), + d->pen.qpen.brush()); + continue; + } + + adjustForAliasing(&p1); + adjustForAliasing(&p2); + + D2D1_POINT_2F d2d_p1 = to_d2d_point_2f(p1); + D2D1_POINT_2F d2d_p2 = to_d2d_point_2f(p2); + + d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + } + } +} + +void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugDrawEllipseFTag); + + ensureBrush(); + ensurePen(); + + if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) { + QPaintEngineEx::drawEllipse(r); + } else { + QPointF p = r.center(); + adjustForAliasing(&p); + + D2D1_ELLIPSE ellipse = { + to_d2d_point_2f(p), + r.width() / 2.0, + r.height() / 2.0 + }; + + if (d->brush.brush) + d->dc()->FillEllipse(ellipse, d->brush.brush.Get()); + + if (d->pen.brush) + d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + } +} + +void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r) +{ + Q_D(QWindowsDirect2DPaintEngine); + D2D_TAG(D2DDebugDrawEllipseTag); + + ensureBrush(); + ensurePen(); + + if (emulationRequired(BrushEmulation) || emulationRequired(PenEmulation)) { + QPaintEngineEx::drawEllipse(r); + } else { + QPointF p = r.center(); + adjustForAliasing(&p); + + D2D1_ELLIPSE ellipse = { + to_d2d_point_2f(p), + r.width() / 2.0, + r.height() / 2.0 + }; + + if (d->brush.brush) + d->dc()->FillEllipse(ellipse, d->brush.brush.Get()); + + if (d->pen.brush) + d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + } +} + void QWindowsDirect2DPaintEngine::drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags) { @@ -1388,4 +1575,47 @@ void QWindowsDirect2DPaintEngine::rasterFill(const QVectorPath &path, const QBru } } +bool QWindowsDirect2DPaintEngine::emulationRequired(EmulationType type) const +{ + Q_D(const QWindowsDirect2DPaintEngine); + + if (!state()->matrix.isAffine()) + return true; + + switch (type) { + case PenEmulation: + return d->pen.emulate; + break; + case BrushEmulation: + return d->brush.emulate; + break; + } + + return false; +} + +bool QWindowsDirect2DPaintEngine::antiAliasingEnabled() const +{ + return state()->renderHints & QPainter::Antialiasing; +} + +void QWindowsDirect2DPaintEngine::adjustForAliasing(QRectF *rect) +{ + if (!antiAliasingEnabled()) { + rect->adjust(MAGICAL_ALIASING_OFFSET, + MAGICAL_ALIASING_OFFSET, + MAGICAL_ALIASING_OFFSET, + MAGICAL_ALIASING_OFFSET); + } +} + +void QWindowsDirect2DPaintEngine::adjustForAliasing(QPointF *point) +{ + static const QPointF adjustment(MAGICAL_ALIASING_OFFSET, + MAGICAL_ALIASING_OFFSET); + + if (!antiAliasingEnabled()) + (*point) += adjustment; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index 93ccf809e42..badd7a7688a 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -79,6 +79,17 @@ class QWindowsDirect2DPaintEngine : public QPaintEngineEx void renderHintsChanged() Q_DECL_OVERRIDE; void transformChanged() Q_DECL_OVERRIDE; + void fillRect(const QRectF &rect, const QBrush &brush) Q_DECL_OVERRIDE; + + void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE; + void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE; + + void drawLines(const QLine *lines, int lineCount) Q_DECL_OVERRIDE; + void drawLines(const QLineF *lines, int lineCount) Q_DECL_OVERRIDE; + + void drawEllipse(const QRectF &r) Q_DECL_OVERRIDE; + void drawEllipse(const QRect &r) Q_DECL_OVERRIDE; + void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE; void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE; @@ -96,6 +107,13 @@ class QWindowsDirect2DPaintEngine : public QPaintEngineEx void ensurePen(const QPen &pen); void rasterFill(const QVectorPath &path, const QBrush &brush); + + enum EmulationType { PenEmulation, BrushEmulation }; + bool emulationRequired(EmulationType type) const; + + bool antiAliasingEnabled() const; + void adjustForAliasing(QRectF *rect); + void adjustForAliasing(QPointF *point); }; QT_END_NAMESPACE From aef82ebe15d17e1bfe7c915d33d57a7bec6668c2 Mon Sep 17 00:00:00 2001 From: Kati Kankaanpaa Date: Tue, 22 Apr 2014 11:39:55 -0700 Subject: [PATCH 174/180] Fix override cursor issue with QtQuick2ApplicationViewer. If the override cursor was set before QtQuick2ApplicationViewer was shown then the cursor was the default cursor and not the override cursor. The new cursor was applied only if the window was visible and the cursor has been set. Now the cursor is applied also if override cursor is set. Change-Id: I88618c719e43b2802e209bef440461c532d19f48 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- src/gui/kernel/qwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 6dcc3df166a..96ca6df1070 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -455,7 +455,7 @@ void QWindow::setVisible(bool visible) } #ifndef QT_NO_CURSOR - if (visible && d->hasCursor) + if (visible && (d->hasCursor || QGuiApplication::overrideCursor())) d->applyCursor(); #endif d->platformWindow->setVisible(visible); From da888ba53904af75c462af9f753191f25840e51f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 11 Feb 2014 17:49:26 +0100 Subject: [PATCH 175/180] Only query for the theme if it is available in the GTKStyle If the theme is not available then it should not try to use it when getting the file system icon as it will cause a number of messages to be outputted to the console as it is an invalid call. Change-Id: I33003568f6785ee423c4a6e079a6c62c95145cbc Reviewed-by: J-P Nurmi --- src/widgets/styles/qgtkstyle_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp index 2bd978bcb83..2c64225c700 100644 --- a/src/widgets/styles/qgtkstyle_p.cpp +++ b/src/widgets/styles/qgtkstyle_p.cpp @@ -855,7 +855,7 @@ QFont QGtkStylePrivate::getThemeFont() QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info) { QIcon icon; - if (gnome_vfs_init && gnome_icon_lookup_sync) { + if (isThemeAvailable() && gnome_vfs_init && gnome_icon_lookup_sync) { gnome_vfs_init(); GtkIconTheme *theme = gtk_icon_theme_get_default(); QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded(); From 2567b35a5e14a704c3b33c17e4b39a940c033a4e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 29 Apr 2014 13:22:10 -0700 Subject: [PATCH 176/180] Don't set the window title for a Qt::Desktop window (QDesktopWidget) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The desktop doesn't belong to this application, we shouldn't be setting it (assuming it is even possible). On X, for example, it's possible to set the name and you end up with the root window having _NET_WM_NAME pointing to the last application that created a QDesktopWidget. Change-Id: Ib62d0a4d56a4d2a74afc6b33fa607867343e7aba Reviewed-by: Jørgen Lind --- src/gui/kernel/qwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 96ca6df1070..40e9b9723aa 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -743,7 +743,7 @@ void QWindow::setTitle(const QString &title) d->windowTitle = title; changed = true; } - if (d->platformWindow) + if (d->platformWindow && type() != Qt::Desktop) d->platformWindow->setWindowTitle(title); if (changed) emit windowTitleChanged(title); From 637b6e1097500235ca2146ae706b52ed9fc0effc Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Tue, 8 Apr 2014 17:01:01 +0200 Subject: [PATCH 177/180] Ignore the fullscreen state of a QMdiSubWindow On some platforms all windows are by default forced into fullscreen mode when show() is executed. In QMdiSubWindow we cannot handle the fullscreen state and should ignore it. Otherwise the window will be forced in "normal" state and ignore any previously executed geometry changes. Change-Id: I09ce6507a1eac6a0adb3405ca3f423642d30f801 Reviewed-by: Friedemann Kleint Reviewed-by: Marc Mutz Reviewed-by: Bernd Weimer --- src/widgets/widgets/qmdisubwindow.cpp | 7 +++++-- .../widgets/qmdisubwindow/tst_qmdisubwindow.cpp | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index b1adb3f7601..9104074122b 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1676,15 +1676,18 @@ void QMdiSubWindowPrivate::ensureWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMinimized: windowStates &= ~Qt::WindowMaximized; + windowStates &= ~Qt::WindowFullScreen; windowStates &= ~Qt::WindowNoState; break; case Qt::WindowMaximized: windowStates &= ~Qt::WindowMinimized; + windowStates &= ~Qt::WindowFullScreen; windowStates &= ~Qt::WindowNoState; break; case Qt::WindowNoState: windowStates &= ~Qt::WindowMinimized; windowStates &= ~Qt::WindowMaximized; + windowStates &= ~Qt::WindowFullScreen; break; default: break; @@ -2732,7 +2735,7 @@ bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event) showMinimized(); else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized)) showMaximized(); - else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized))) + else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen))) showNormal(); break; } @@ -3005,7 +3008,7 @@ void QMdiSubWindow::changeEvent(QEvent *changeEvent) d->setMinimizeMode(); else if (!(oldState & Qt::WindowMaximized) && (newState & Qt::WindowMaximized)) d->setMaximizeMode(); - else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized))) + else if (!(newState & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen))) d->setNormalMode(); if (d->isActive) diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp index 268638a5045..ffc3e3b67db 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp +++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp @@ -206,6 +206,7 @@ private slots: void task_233197(); void task_226929(); void styleChange(); + void testFullScreenState(); }; void tst_QMdiSubWindow::initTestCase() @@ -2007,6 +2008,19 @@ void tst_QMdiSubWindow::styleChange() QCOMPARE(spy.count(), 0); } +void tst_QMdiSubWindow::testFullScreenState() +{ + QMdiArea mdiArea; + mdiArea.showMaximized(); + + QMdiSubWindow *subWindow = mdiArea.addSubWindow(new QWidget); + subWindow->setGeometry(0, 0, 300, 300); + subWindow->showFullScreen(); // QMdiSubWindow does not support the fullscreen state. This call + // should be equivalent to setVisible(true) (and not showNormal()) + QVERIFY(QTest::qWaitForWindowExposed(&mdiArea)); + QCOMPARE(subWindow->size(), QSize(300, 300)); +} + QTEST_MAIN(tst_QMdiSubWindow) #include "tst_qmdisubwindow.moc" From 721543e46484524f509e21e6bfe483e5b57bc4be Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 10 Apr 2014 17:10:27 +0200 Subject: [PATCH 178/180] QNX: Fix QLineEdit autotest Change-Id: I84c386a146dd484db844fa93165b28e19e4cefd7 Reviewed-by: Sergio Ahumada Reviewed-by: Bernd Weimer --- tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 077e1aa1dfe..36f14cb1baa 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -1322,7 +1322,7 @@ void tst_QLineEdit::undo_keypressevents_data() // unselect any current selection keys.addKeyClick(Qt::Key_Right); -#ifdef Q_OS_WIN //Mac has a specialcase to handle jumping to the end of a selection +#if defined Q_OS_WIN || defined Q_OS_QNX //Windows and QNX do not jump to the beginning of the selection keys.addKeyClick(Qt::Key_Left); #endif @@ -3206,7 +3206,7 @@ void tst_QLineEdit::leftKeyOnSelectedText() QCOMPARE(testWidget->cursorPosition(), 2); QCOMPARE(testWidget->selectedText(), QString("23")); QTest::keyClick(testWidget, Qt::Key_Left); -#ifdef Q_OS_WIN +#if defined Q_OS_WIN || defined Q_OS_QNX QCOMPARE(testWidget->cursorPosition(), 1); #else // Selection is cleared ands cursor remains at position 2. From a006ede6e785b288d6955490217a6da46e62a7b5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 29 Apr 2014 19:29:59 +0200 Subject: [PATCH 179/180] Mac style: Get proper ThemeButtonKind for QDateTimeEdit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When it gets 'calendarPopup' set, that is. The reason lies, indirectly, in the extra margins we add to QComboBoxes and other QPushButtons in the Mac style. However, these extra margins do not apply to spinboxes, which is what QDateTimeEdit is. In particular, this causes Designer to show QDateTimeEdit at the wrong size when it's not in a layout. Task-number: QTBUG-38615 Change-Id: I3dd52e10db8c8970a6dc40b39fbe29dd86167daa Reviewed-by: Jake Petroules Reviewed-by: J-P Nurmi Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 30 +++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index d35dd16f85a..42262e66a9a 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1345,12 +1345,30 @@ bool qt_mac_buttonIsRenderedFlat(const QPushButton *pushButton, const QStyleOpti // an extra check here before using the mini and small buttons. int h = combo->rect.size().height(); if (combo->editable){ - if (h < 21) - bdi->kind = kThemeComboBoxMini; - else if (h < 26) - bdi->kind = kThemeComboBoxSmall; - else - bdi->kind = kThemeComboBox; + if (qobject_cast(widget)) { + // Except when, you know, we get a QDateTimeEdit with calendarPopup + // enabled. And then things get weird, basically because it's a + // transvestite spinbox with editable combobox tendencies. Meaning + // that it wants to look a combobox, except that it isn't one, so it + // doesn't get all those extra free margins around. (Don't know whose + // idea those margins were, but now it looks like we're stuck with + // them forever). So anyway, the height threshold should be smaller + // in this case, or the style gets confused when it needs to render + // or return any subcontrol size of the poor thing. + if (h < 9) + bdi->kind = kThemeComboBoxMini; + else if (h < 22) + bdi->kind = kThemeComboBoxSmall; + else + bdi->kind = kThemeComboBox; + } else { + if (h < 21) + bdi->kind = kThemeComboBoxMini; + else if (h < 26) + bdi->kind = kThemeComboBoxSmall; + else + bdi->kind = kThemeComboBox; + } } else { // Even if we specify that we want the kThemePopupButton, Carbon // will use the kThemePopupButtonSmall if the size matches. So we From beb7258a56b6ec76531b73cc07ee30132a3f548f Mon Sep 17 00:00:00 2001 From: Kurt Pattyn Date: Tue, 15 Apr 2014 09:57:15 +0200 Subject: [PATCH 180/180] Add default case to switch statements When compiling with the -Wswitch-default flag, the compiler spits warnings for the moc generated files. In certain development environments (e.g. where MISRA rules have to be followed) every switch statement needs to have a default case. Unfortunately the moc generated files contain switch statements without default case. This patch adds a default statement to all switch statements that are generated by the moc compiler. Change-Id: I8f3d81e3463fce4d3abf2ea5d0fa8727a7d9ba2e Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- src/tools/moc/generator.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index d831edfef01..a67ea05956e 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -983,6 +983,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n", propindex, p.type.constData(), prefix.constData(), p.member.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } @@ -1031,6 +1032,7 @@ void Generator::generateMetacall() fprintf(out, " break;\n"); } } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } @@ -1054,6 +1056,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: %s%s; break;\n", propindex, prefix.constData(), p.reset.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } fprintf(out, @@ -1072,6 +1075,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.designable.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } fprintf(out, @@ -1090,6 +1094,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.scriptable.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } fprintf(out, @@ -1108,6 +1113,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.stored.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } fprintf(out, @@ -1126,6 +1132,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.editable.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } fprintf(out, @@ -1145,6 +1152,7 @@ void Generator::generateMetacall() fprintf(out, " case %d: *_b = %s; break;\n", propindex, p.user.constData()); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); } fprintf(out, @@ -1226,6 +1234,7 @@ void Generator::generateStaticMetacall() fprintf(out, ");\n"); fprintf(out, " if (_a[0]) *reinterpret_cast(_a[0]) = _r; } break;\n"); } + fprintf(out, " default: break;\n"); fprintf(out, " }\n"); fprintf(out, " }"); needElse = true;