diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index 5f91ce5e3d7..3b67dd61c7e 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -403,6 +403,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths, const QString absolutePath = isDir ? fileInfo.absoluteFilePath() : fileInfo.absolutePath(); const uint flags = isDir ? (FILE_NOTIFY_CHANGE_DIR_NAME + | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_FILE_NAME) : (FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index f37edfc9671..581df9242cb 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -118,7 +118,7 @@ public: int remainingTime(int timerId) final; - void wakeUp() final; + void wakeUp() override; void interrupt() final; void flush() override; diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index fb8f5a5efcc..a3a4921690d 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -463,10 +463,10 @@ QT_BEGIN_NAMESPACE \c{\xHHHH} with more than 2 digits. A pattern like \c{\x2022} neeeds to be ported to \c{\x{2022}}, or it will match a space (\c{0x20}) followed by the string \c{"22"}. In general, it is highly recommended to always use - curly braces with the \c{\\x} escape, no matter the amount of digits + curly braces with the \c{\x} escape, no matter the amount of digits specified. - \li A 0-to-n quantification like \c{{,n}} needs to be ported to c{{0,n}} to + \li A 0-to-n quantification like \c{{,n}} needs to be ported to \c{{0,n}} to preserve semantics. Otherwise, a pattern such as \c{\d{,3}} would actually match a digit followed by the exact string \c{"{,3}"}. diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 5788f000a1d..720c3e98c78 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -5123,21 +5123,25 @@ bool QString::endsWith(QChar c, Qt::CaseSensitivity cs) const } /*! - Returns \c true if the string only contains uppercase letters, - otherwise returns \c false. + Returns \c true if the string is uppercase, that is, it's identical + to its toUpper() folding. + + Note that this does \e not mean that the string does not contain + lowercase letters (some lowercase letters do not have a uppercase + folding; they are left unchanged by toUpper()). + For more information, refer to the Unicode standard, section 3.13. + \since 5.12 - \sa QChar::isUpper(), isLower() + \sa QChar::toUpper(), isLower() */ bool QString::isUpper() const { - if (isEmpty()) - return false; + QStringIterator it(*this); - const QChar *d = data(); - - for (int i = 0, max = size(); i < max; ++i) { - if (!d[i].isUpper()) + while (it.hasNext()) { + uint uc = it.nextUnchecked(); + if (qGetProp(uc)->cases[QUnicodeTables::UpperCase].diff) return false; } @@ -5145,21 +5149,25 @@ bool QString::isUpper() const } /*! - Returns \c true if the string only contains lowercase letters, - otherwise returns \c false. + Returns \c true if the string is lowercase, that is, it's identical + to its toLower() folding. + + Note that this does \e not mean that the string does not contain + uppercase letters (some uppercase letters do not have a lowercase + folding; they are left unchanged by toLower()). + For more information, refer to the Unicode standard, section 3.13. + \since 5.12 - \sa QChar::isLower(), isUpper() + \sa QChar::toLower(), isUpper() */ bool QString::isLower() const { - if (isEmpty()) - return false; + QStringIterator it(*this); - const QChar *d = data(); - - for (int i = 0, max = size(); i < max; ++i) { - if (!d[i].isLower()) + while (it.hasNext()) { + uint uc = it.nextUnchecked(); + if (qGetProp(uc)->cases[QUnicodeTables::LowerCase].diff) return false; } diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 680c69a978f..ffd5b04276c 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -605,8 +605,13 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME The following parameters are available for \c {-platform windows}: \list + \li \c {altgr}, detect the key \c {AltGr} found on some keyboards as + Qt::GroupSwitchModifier (since Qt 5.12). \li \c {dialogs=[xp|none]}, \c xp uses XP-style native dialogs and \c none disables them. + + \li \c {dpiawareness=[0|1|2} Sets the DPI awareness of the process + (see \l{High DPI Displays}, since Qt 5.4). \li \c {fontengine=freetype}, uses the FreeType font engine. \li \c {menus=[native|none]}, controls the use of native menus. @@ -616,10 +621,23 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME provide hover signals. They are mainly intended for Qt Quick. By default, they will be used if the application is not an instance of QApplication or for Qt Quick Controls 2 - applications. + applications (since Qt 5.10). - \li \c {altgr}, detect the key \c {AltGr} found on some keyboards as - Qt::GroupSwitchModifier. + \li \c {nocolorfonts} Turn off DirectWrite Color fonts + (since Qt 5.8). + + \li \c {nodirectwrite} Turn off DirectWrite fonts (since Qt 5.8). + + \li \c {nomousefromtouch} Ignores mouse events synthesized + from touch events by the operating system. + + \li \c {nowmpointer} Switches from Pointer Input Messages handling + to legacy mouse handling (since Qt 5.12). + \li \c {reverse} Activates Right-to-left mode (experimental). + Windows title bars will be shown accordingly in Right-to-left locales + (since Qt 5.13). + \li \c {tabletabsoluterange=} Sets a value for mouse mode detection + of WinTab tablets (Legacy, since Qt 5.3). \endlist The following parameter is available for \c {-platform cocoa} (on macOS): diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp index 98246de0a5e..5c999f455ef 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp @@ -62,6 +62,9 @@ QT_BEGIN_NAMESPACE +// Clang does not consider __declspec(nothrow) as nothrow +QT_WARNING_DISABLE_CLANG("-Wmicrosoft-exception-spec") + // Convert from design units to logical pixels #define DESIGN_TO_LOGICAL(DESIGN_UNIT_VALUE) \ QFixed::fromReal((qreal(DESIGN_UNIT_VALUE) / qreal(m_unitsPerEm)) * fontDef.pixelSize) diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp index 41355d72aef..d89cd78b285 100644 --- a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp +++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp @@ -33,6 +33,14 @@ #include +#if (__EMSCRIPTEN_major__ > 1 || __EMSCRIPTEN_minor__ > 38 || __EMSCRIPTEN_minor__ == 38 && __EMSCRIPTEN_tiny__ >= 22) +# define EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD +#endif + +#ifdef EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD +#include +#endif + class QWasmEventDispatcherPrivate : public QEventDispatcherUNIXPrivate { @@ -179,3 +187,18 @@ void QWasmEventDispatcher::doMaintainTimers() emscripten_async_call(callback, this, toWaitDuration); m_currentTargetTime = newTargetTime; } + +void QWasmEventDispatcher::wakeUp() +{ +#ifdef EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD + if (!emscripten_is_main_runtime_thread()) + emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, (void*)(&QWasmEventDispatcher::mainThreadWakeUp), this); +#endif + QEventDispatcherUNIX::wakeUp(); +} + +void QWasmEventDispatcher::mainThreadWakeUp(void *eventDispatcher) +{ + emscripten_resume_main_loop(); // Service possible requestUpdate Calls + static_cast(eventDispatcher)->processEvents(QEventLoop::AllEvents); +} diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.h b/src/plugins/platforms/wasm/qwasmeventdispatcher.h index 5300b3de73a..f72d92ce079 100644 --- a/src/plugins/platforms/wasm/qwasmeventdispatcher.h +++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.h @@ -51,6 +51,8 @@ public: protected: bool processEvents(QEventLoop::ProcessEventsFlags flags) override; void doMaintainTimers(); + void wakeUp() override; + static void mainThreadWakeUp(void *eventDispatcher); private: bool m_hasMainLoop = false; diff --git a/src/plugins/platforms/windows/qwindowscombase.h b/src/plugins/platforms/windows/qwindowscombase.h index 45cba9c68bf..bb4b2953956 100644 --- a/src/plugins/platforms/windows/qwindowscombase.h +++ b/src/plugins/platforms/windows/qwindowscombase.h @@ -107,6 +107,9 @@ private: ULONG m_ref; }; +// Clang does not consider __declspec(nothrow) as nothrow +QT_WARNING_DISABLE_CLANG("-Wmicrosoft-exception-spec") + QT_END_NAMESPACE #endif // QWINDOWSCOMBASE_H diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index cdd1f6361e5..7d88601e543 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -34,6 +34,9 @@ #include #include #include +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#include +#endif /* All tests need to run in temporary directories not used * by the application to avoid non-deterministic failures on Windows @@ -79,6 +82,9 @@ private slots: void signalsEmittedAfterFileMoved(); void watchUnicodeCharacters(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + void watchDirectoryAttributeChanges(); +#endif private: QString m_tempDirPattern; @@ -813,5 +819,27 @@ void tst_QFileSystemWatcher::watchUnicodeCharacters() QTRY_COMPARE(changedSpy.count(), 1); } +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +void tst_QFileSystemWatcher::watchDirectoryAttributeChanges() +{ + QTemporaryDir temporaryDirectory(m_tempDirPattern); + QVERIFY2(temporaryDirectory.isValid(), qPrintable(temporaryDirectory.errorString())); + + QDir testDir(temporaryDirectory.path()); + const QString subDir(QString::fromLatin1("attrib_test")); + QVERIFY(testDir.mkdir(subDir)); + testDir = QDir(temporaryDirectory.path() + QDir::separator() + subDir); + + QFileSystemWatcher watcher; + QVERIFY(watcher.addPath(temporaryDirectory.path())); + FileSystemWatcherSpy changedSpy(&watcher, FileSystemWatcherSpy::SpyOnDirectoryChanged); + QCOMPARE(changedSpy.count(), 0); + QVERIFY(SetFileAttributes(reinterpret_cast(testDir.absolutePath().utf16()), FILE_ATTRIBUTE_HIDDEN) != 0); + QTRY_COMPARE(changedSpy.count(), 1); + QVERIFY(SetFileAttributes(reinterpret_cast(testDir.absolutePath().utf16()), FILE_ATTRIBUTE_NORMAL) != 0); + QTRY_COMPARE(changedSpy.count(), 2); +} +#endif + QTEST_MAIN(tst_QFileSystemWatcher) #include "tst_qfilesystemwatcher.moc" diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index f86fbc59882..9cb76a0130e 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -459,8 +459,8 @@ private slots: void trimmed(); void toUpper(); void toLower(); - void isUpper(); - void isLower(); + void isLower_isUpper_data(); + void isLower_isUpper(); void toCaseFolded(); void rightJustified(); void leftJustified(); @@ -2313,44 +2313,83 @@ void tst_QString::toLower() #endif // icu } -void tst_QString::isUpper() +void tst_QString::isLower_isUpper_data() { - QVERIFY(!QString().isUpper()); - QVERIFY(!QString("").isUpper()); - QVERIFY(QString("TEXT").isUpper()); - QVERIFY(!QString("text").isUpper()); - QVERIFY(!QString("Text").isUpper()); - QVERIFY(!QString("tExt").isUpper()); - QVERIFY(!QString("teXt").isUpper()); - QVERIFY(!QString("texT").isUpper()); - QVERIFY(!QString("TExt").isUpper()); - QVERIFY(!QString("teXT").isUpper()); - QVERIFY(!QString("tEXt").isUpper()); - QVERIFY(!QString("tExT").isUpper()); - QVERIFY(!QString("@ABYZ[").isUpper()); - QVERIFY(!QString("@abyz[").isUpper()); - QVERIFY(!QString("`ABYZ{").isUpper()); - QVERIFY(!QString("`abyz{").isUpper()); + QTest::addColumn("string"); + QTest::addColumn("isLower"); + QTest::addColumn("isUpper"); + + int row = 0; + QTest::addRow("lower-and-upper-%02d", row++) << QString() << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString(" ") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("123") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("@123$#") << true << true; + QTest::addRow("lower-and-upper-%02d", row++) << QString("π„žπ„΄π†β™«") << true << true; // Unicode Block 'Musical Symbols' + // not foldable + QTest::addRow("lower-and-upper-%02d", row++) << QString("πšŠπš‹πšŒπšπšŽ") << true << true; // MATHEMATICAL MONOSPACE SMALL A, ... E + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝙖,𝙗,π™˜,𝙙,π™š") << true << true; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E + QTest::addRow("lower-and-upper-%02d", row++) << QString("π—”π—•π—–π——π—˜") << true << true; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A, ... E + QTest::addRow("lower-and-upper-%02d", row++) << QString("𝐀,𝐁,𝐂,𝐃,𝐄") << true << true; // MATHEMATICAL BOLD CAPITAL A, ... E + + row = 0; + QTest::addRow("only-lower-%02d", row++) << QString("text") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("Γ aa") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("øæß") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("text ") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString(" text") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("hello, world!") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("123@abyz[") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("`abyz{") << true << false; + QTest::addRow("only-lower-%02d", row++) << QString("a𝙖a|b𝙗b|cπ™˜c|d𝙙d|eπ™še") << true << false; // MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A, ... E + QTest::addRow("only-lower-%02d", row++) << QString("𐐨") << true << false; // DESERET SMALL LETTER LONG I + // uppercase letters, not foldable + QTest::addRow("only-lower-%02d", row++) << QString("text𝗔text") << true << false; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A + + row = 0; + QTest::addRow("only-upper-%02d", row++) << QString("TEXT") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("Γ€AA") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("Γ˜Γ†αΊž") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("TEXT ") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString(" TEXT") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("HELLO, WORLD!") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("123@ABYZ[") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("`ABYZ{") << false << true; + QTest::addRow("only-upper-%02d", row++) << QString("A𝐀A|B𝐁B|C𝐂C|D𝐃D|E𝐄E") << false << true; // MATHEMATICAL BOLD CAPITAL A, ... E + QTest::addRow("only-upper-%02d", row++) << QString("𐐀") << false << true; // DESERET CAPITAL LETTER LONG I + // lowercase letters, not foldable + QTest::addRow("only-upper-%02d", row++) << QString("TEXT𝚊TEXT") << false << true; // MATHEMATICAL MONOSPACE SMALL A + + row = 0; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("Text") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("tExt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("teXt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("texT") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("TExt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("teXT") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("tEXt") << false << false; + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("tExT") << false << false; + // not foldable + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("TEXT𝚊text") << false << false; // MATHEMATICAL MONOSPACE SMALL A + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("text𝗔TEXT") << false << false; // MATHEMATICAL SANS-SERIF BOLD CAPITAL A + // titlecase, foldable + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("abcLjdef") << false << false; // LATIN CAPITAL LETTER L WITH SMALL LETTER J + QTest::addRow("not-lower-nor-upper-%02d", row++) << QString("ABCLjDEF") << false << false; // LATIN CAPITAL LETTER L WITH SMALL LETTER J } -void tst_QString::isLower() +void tst_QString::isLower_isUpper() { - QVERIFY(!QString().isLower()); - QVERIFY(!QString("").isLower()); - QVERIFY(QString("text").isLower()); - QVERIFY(!QString("Text").isLower()); - QVERIFY(!QString("tExt").isLower()); - QVERIFY(!QString("teXt").isLower()); - QVERIFY(!QString("texT").isLower()); - QVERIFY(!QString("TExt").isLower()); - QVERIFY(!QString("teXT").isLower()); - QVERIFY(!QString("tEXt").isLower()); - QVERIFY(!QString("tExT").isLower()); - QVERIFY(!QString("TEXT").isLower()); - QVERIFY(!QString("@ABYZ[").isLower()); - QVERIFY(!QString("@abyz[").isLower()); - QVERIFY(!QString("`ABYZ{").isLower()); - QVERIFY(!QString("`abyz{").isLower()); + QFETCH(QString, string); + QFETCH(bool, isLower); + QFETCH(bool, isUpper); + + QCOMPARE(string.isLower(), isLower); + QCOMPARE(string.toLower() == string, isLower); + QVERIFY(string.toLower().isLower()); + + QCOMPARE(string.isUpper(), isUpper); + QCOMPARE(string.toUpper() == string, isUpper); + QVERIFY(string.toUpper().isUpper()); } void tst_QString::toCaseFolded()