From a9cbddf4739f3cfabd38367b5f872fe2c1a3814c Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 9 Apr 2014 13:26:57 +0200 Subject: 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 0274ed8201..de6c6585e9 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -134,6 +134,8 @@ public: void interrupt(); void flush(); + bool event(QEvent *); + friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; @@ -163,7 +165,6 @@ public: // 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 495a54cac4..e0ce9f9648 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -734,13 +734,25 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) 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 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() runLoopTimerRef(0), blockSendPostedEvents(false), currentExecIsNSAppRun(false), - modalSessionOnNSAppRun(false), nsAppRunCalledByQt(false), cleanupModalSessionsNeeded(false), processEventsCalled(0), @@ -908,14 +919,6 @@ void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info) // 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(); -- cgit v1.2.3 From 20c4b797a162e5b13abafe183773019ea874811f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 4 Mar 2014 10:21:29 +0100 Subject: 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 ed376fe923..d90e2f5163 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) -- cgit v1.2.3 From 9216bfbcb18c61429b6cdbe7ecf2e9e16c9cdaf7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 3 Mar 2014 19:29:19 +0100 Subject: 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 b30caf4289..e17ff2b249 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. */ -- cgit v1.2.3 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: 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 0b9683a3ef..93462e7ea1 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -639,8 +639,12 @@ static QTouchDevice *touchDevice = 0; 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]; -- cgit v1.2.3 From 3a4bd21db55a6c08ad0a8e09be0699085c7c4b59 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 9 Apr 2014 07:27:21 +0200 Subject: 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 18342d0138..c8eb15a7f7 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 01bedb4a3a..0a504657a3 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} */ /*! -- cgit v1.2.3 From ef77c16cb00ef3788e58da8b35cb91eaf2eaa591 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 10 Apr 2014 13:50:01 +0300 Subject: 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 + .../auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 44 +++++++--------------- .../qtextscriptengine/tst_qtextscriptengine.cpp | 16 ++++++++ 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/configure b/configure index 89c2318d82..a1b006b4ea 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 35950c709b..967ba24fcf 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 56d6711dc6..d0482d77e2 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 c4db669695..5dfb025510 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 -- cgit v1.2.3 From 0ec07b68ad34e135451dd5291732bf73d297ba0c Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 10 Apr 2014 13:50:53 +0300 Subject: 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 +--------- .../qtextscriptengine/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 fac795051a..fc36d07a4a 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 967ba24fcf..34788dc4dc 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -122,20 +122,9 @@ private: 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 5dfb025510..74eb58670b 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)); -- cgit v1.2.3 From 6977700bed929c7f1a20192d07a06abc2fdca278 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 10 Apr 2014 15:51:56 +0200 Subject: 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 c183deb3b8..f78d3bcc4e 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; } -- cgit v1.2.3 From 94742faeceb44fd2d8131b12480e59b699b0ac6f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 12 Apr 2014 10:01:50 -0700 Subject: 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 950647004a..1f82425459 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 -- cgit v1.2.3 From 070e1637ebe3ee899d44b92c948e2e148c237e03 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 11 Apr 2014 13:26:48 -0700 Subject: 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 1f82425459..e93201f102 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 -- cgit v1.2.3 From 387f75c39bfad4439a6bd013089c2cd216cda5ea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Apr 2014 10:41:55 -0700 Subject: 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 e93201f102..dd880d8ede 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 -- cgit v1.2.3 From fb7da5cc8c13bbf9a134306c1d290d34373687b0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 11 Apr 2014 12:09:59 +0200 Subject: 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 ++++ src/plugins/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 a994c51c7d..13a0280baf 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -454,6 +454,10 @@ public: 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 d80b49ccbb..d7b3c75aee 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 5a2002f1d4..ad7e99bd49 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1778,6 +1778,9 @@ public: 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 -- cgit v1.2.3 From 454ebcac45a170abdc67ac08ea04a4efb8c586ad Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 15 Apr 2014 16:49:08 +0200 Subject: 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 843a6edce1..94c77302dd 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, -- cgit v1.2.3 From ffc0e68a167cca112f05b310c3db2d564f444712 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 15 Apr 2014 14:51:37 +0200 Subject: 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 7d997d7d8b..d505c30aa6 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 -- cgit v1.2.3 From a08b5201c15a2fb13afd2cb28fe138e3e3439051 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Mon, 14 Apr 2014 14:12:00 +0200 Subject: 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 3240ec4a20..1039c88e8d 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 \ -- cgit v1.2.3 From c99f909bedad3f590c92deeeefa02e4e74029c1c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Apr 2014 11:51:02 +0200 Subject: 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 a2bd938666..677899950c 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('/'); -- cgit v1.2.3 From fec19027a508f7f6b7711d844b0f5a42bb0d4e83 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 12 Apr 2014 03:45:28 +0300 Subject: 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 ++++++--- src/plugins/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 1432dfdcd9..940d75614c 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 51961014d9..734f645e65 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; -- cgit v1.2.3 From 3f9ad1efd61c76fe0671d28aac9e4886951856ec Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 11 Apr 2014 13:46:48 +0200 Subject: 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 --- src/plugins/platforms/android/qandroidinputcontext.cpp | 14 +++++++++++++- src/plugins/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 3324d9ba49..12005d8fce 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 f7b29a855f..3ce141ae15 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -95,6 +95,7 @@ public: bool isComposing() const; void clear(); + void setFocusObject(QObject *object); //---------------// jboolean beginBatchEdit(); @@ -136,6 +137,7 @@ private: QMetaObject::Connection m_updateCursorPosConnection; bool m_blockUpdateSelection; int m_batchEditNestingLevel; + QObject *m_focusObject; }; QT_END_NAMESPACE -- cgit v1.2.3 From 839c54e070727540570b5994908d461bb7bb4dfd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 9 Apr 2014 15:46:26 +0200 Subject: 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 28fb23d57b..3f6c6d1256 100644 --- a/src/plugins/platforms/ios/quiview_textinput.mm +++ b/src/plugins/platforms/ios/quiview_textinput.mm @@ -473,6 +473,8 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables); 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]; } -- cgit v1.2.3 From 8b0fd78caa8e257757d3eb84732e38cf735b2136 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Thu, 10 Apr 2014 17:12:20 +0300 Subject: 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 a12636778e..bdc3463b9f 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 -- cgit v1.2.3 From 7aac93b6ce4e88c8e47c4b2cd8c283daeac5cdb3 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 10 Apr 2014 11:49:48 +0200 Subject: 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 7382d63a06..dbca05037b 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 eb2c98e1f5..af536fa927 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 03c12200d5..de1de39db2 100644 --- a/src/gui/opengl/qopenglfunctions.h +++ b/src/gui/opengl/qopenglfunctions.h @@ -407,9 +407,6 @@ public: 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 -- cgit v1.2.3 From 4dbef58c3d2a63f59c5ae32ba9dc47a2a9157474 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 15 Apr 2014 18:14:08 +0200 Subject: 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 7eecd3d84d..f79eaf197d 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 345b8d82ad..06dd623368 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 df11ea9b14..90af617e87 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); -- cgit v1.2.3 From d449c0e0e4e39606e0421090b9356c46bc29030c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 22 Jan 2014 14:17:31 +0100 Subject: 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 bdedc9d75f..ab71fe9081 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*))); -- cgit v1.2.3 From dcfd36c2686bcbd56b6a0295640e228f76d7bf1d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 16 Apr 2014 19:35:17 +0200 Subject: 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 a1b006b4ea..1b839c1456 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 5968a8a4ff..418b124a85 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 b32ba91c07..6dd3eaab3c 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 d149511218..fe2caa2efa 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: 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 12005d8fce..02fda19d76 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 -- cgit v1.2.3 From 4e4b2d67010f1fc90a0227c36adab56a3e1ce679 Mon Sep 17 00:00:00 2001 From: John Layt Date: Wed, 16 Apr 2014 15:47:14 +0100 Subject: 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 9ff7c4766a..33a11cc079 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -143,11 +143,11 @@ QT_USE_NAMESPACE 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); } } -- cgit v1.2.3 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: 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 33a11cc079..ef3e88be39 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -160,13 +160,13 @@ QT_USE_NAMESPACE 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 @@ QT_USE_NAMESPACE 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())) -- cgit v1.2.3 From 078c71ac8f0c74e06e0d81ea1a5a44126abc27b6 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 22 Apr 2014 12:43:28 +0300 Subject: 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 --- src/network/socket/qnativesocketengine_winrt.cpp | 319 ++++++++++++++--------- src/network/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 4b2d1c372e..db1d3dc96b 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 @@ public: return S_OK; } - QNativeSocketEngine *engine() const - { - return m_engine; - } - - void setEngine(QNativeSocketEngine *engine) - { - m_engine = engine; - } - ComPtr inputStream() const { return m_stream; @@ -190,13 +183,33 @@ public: private: QByteArray m_bytes; UINT32 m_length; - QPointer 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 b5be5fa830..ec2e1b3ad4 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 @@ public: 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 @@ private: 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 -- cgit v1.2.3 From 878da15f2cfadf249a355b33d31f7937078ea174 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 22 Apr 2014 09:14:39 +0300 Subject: 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 --- .../src/libGLESv2/renderer/d3d11/Renderer11.cpp | 47 ++++++++ .../src/libGLESv2/renderer/d3d11/Renderer11.h | 15 +++ ...WinRT-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 2de477b3bc..e70727c65e 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 a8a722c56c..773fc26db1 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 0000000000..bf2a1ad363 --- /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 + -- cgit v1.2.3 From c97edb25796487c719376dd73c365603bcd68782 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Tue, 22 Apr 2014 08:51:40 +0300 Subject: 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 2e38f81499..583441f396 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; } -- cgit v1.2.3 From aeb0d58782cb75fa70ffc1b08422a0a44129e4b6 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 18 Apr 2014 15:51:51 +0300 Subject: 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 266effb66a..1955758fca 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -358,6 +358,9 @@ public: 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 2d9a42957e..359d0c49e5 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -954,6 +954,9 @@ public: 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; } } -- cgit v1.2.3 From 1cb0cd9e7a381636455bb147f93cc0c7cc92565f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 22 Apr 2014 12:01:05 +0200 Subject: 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 364e19e68e..3366262ef0 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 -- cgit v1.2.3 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: 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 1b839c1456..601d84ab93 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. -- cgit v1.2.3