From 700ea0af687d90ef98d3e9bee57e164174cce4e4 Mon Sep 17 00:00:00 2001 From: Frederik Schwarzer Date: Fri, 28 Oct 2016 11:39:34 +0200 Subject: QMainWindow: fix wording in apidoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5cb44bed7e946574eb3e08ff51948f901b2bb78c Reviewed-by: Topi Reiniö --- src/widgets/widgets/qmainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index e454e3e991..aefd028305 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -320,7 +320,7 @@ void QMainWindowPrivate::init() direction. Two dock widgets may also be stacked on top of each other. A - QTabBar is then used to select which of the widgets that should be + QTabBar is then used to select which of the widgets should be displayed. We give an example of how to create and add dock widgets to a -- cgit v1.2.1 From 1df45820d4ccbb67b9ad0f3eed167342f2917cf8 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 23 Sep 2016 14:20:16 +0200 Subject: doc: Document two undocumented functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change provides missing documentation for two member functions of QString. QString QString::fromUtf16(const char16_t *str, int size) QString QString::fromUcs4(const char32_t *str, int size) Change-Id: I94a9437a457062e49e4457f5876e4d7c31fff24c Reviewed-by: André Hartmann Reviewed-by: Topi Reiniö --- src/corelib/tools/qstring.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b7f83e4b9d..645d213d82 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4818,6 +4818,39 @@ QString QString::fromUtf16(const ushort *unicode, int size) return QUtf16::convertToUnicode((const char *)unicode, size*2, 0); } +/*! + \fn QString QString::fromUtf16(const char16_t *str, int size) + \since 5.3 + + Returns a QString initialized with the first \a size characters + of the Unicode string \a str (ISO-10646-UTF-16 encoded). + + If \a size is -1 (default), \a str must be terminated + with a 0. + + This function checks for a Byte Order Mark (BOM). If it is missing, + host byte order is assumed. + + This function is slow compared to the other Unicode conversions. + Use QString(const QChar *, int) or QString(const QChar *) if possible. + + QString makes a deep copy of the Unicode data. + + \sa utf16(), setUtf16(), fromStdU16String() +*/ + +/*! + \fn QString QString::fromUcs4(const char32_t *str, int size) + \since 5.3 + + Returns a QString initialized with the first \a size characters + of the Unicode string \a str (ISO-10646-UCS-4 encoded). + + If \a size is -1 (default), \a str must be terminated + with a 0. + + \sa toUcs4(), fromUtf16(), utf16(), setUtf16(), fromWCharArray(), fromStdU32String() +*/ /*! \since 4.2 -- cgit v1.2.1 From c34d289c449dc8624f31bade882d6f808dae20a1 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Wed, 12 Oct 2016 13:35:37 +0300 Subject: Fix building when lex source refers to a file generated by yacc Scan lex and yacc sources for dependencies as if they were C source code, which is close enough to reality. This will unfortunately result in the generated source files depending on the generated headers, while it should have been the object files created from these sources which have that dependency. But qmake cannot do better, and this is good enough. Task-number: QTBUG-56507 Change-Id: Ic3e1941bf2e2820bfddf99deba854e1e82f83669 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/lex.prf | 1 + mkspecs/features/yacc.prf | 1 + 2 files changed, 2 insertions(+) diff --git a/mkspecs/features/lex.prf b/mkspecs/features/lex.prf index 16d3a6aa94..7d8325bedb 100644 --- a/mkspecs/features/lex.prf +++ b/mkspecs/features/lex.prf @@ -5,6 +5,7 @@ { lex.name = Lex ${QMAKE_FILE_IN} lex.input = LEXSOURCES + lex.dependency_type = TYPE_C lex_included { lex.CONFIG += no_link } else { diff --git a/mkspecs/features/yacc.prf b/mkspecs/features/yacc.prf index e78dd8cbb3..72cb5c2f3a 100644 --- a/mkspecs/features/yacc.prf +++ b/mkspecs/features/yacc.prf @@ -35,6 +35,7 @@ yacc_impl.name = source for ${QMAKE_FILE_IN} yacc_impl.input = YACCSOURCES yacc_impl.variable_out = GENERATED_SOURCES + yacc_impl.dependency_type = TYPE_C yacc_impl.commands = $$escape_expand(\\n) # We don't want any commands where, but if command is empty no rules are created yacc_impl.depends = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_H)} # Make sure we depend on the step above yacc_impl.output = $${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_MOD_YACC}$${first(QMAKE_EXT_CPP)} # Faked output from this step, output really created in step above -- cgit v1.2.1 From 99cebe717c5d92567a9ee1ca284b7c243ad38c68 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 31 Oct 2016 10:25:45 +0100 Subject: Update bookmarks in the XML bookmarks examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update URLs in jennifer.xbel and remove frank.xbel, which has too many outdated URLs Change-Id: I8cbc1e3988f45230f849e68202780c76cf4353d9 Reviewed-by: Topi Reiniö --- examples/xml/dombookmarks/frank.xbel | 230 ----------------------------- examples/xml/dombookmarks/jennifer.xbel | 62 +++----- examples/xml/saxbookmarks/frank.xbel | 230 ----------------------------- examples/xml/saxbookmarks/jennifer.xbel | 62 +++----- examples/xml/streambookmarks/frank.xbel | 230 ----------------------------- examples/xml/streambookmarks/jennifer.xbel | 62 +++----- 6 files changed, 57 insertions(+), 819 deletions(-) delete mode 100644 examples/xml/dombookmarks/frank.xbel delete mode 100644 examples/xml/saxbookmarks/frank.xbel delete mode 100644 examples/xml/streambookmarks/frank.xbel diff --git a/examples/xml/dombookmarks/frank.xbel b/examples/xml/dombookmarks/frank.xbel deleted file mode 100644 index 2fd5c2e09d..0000000000 --- a/examples/xml/dombookmarks/frank.xbel +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Literate Programming - - Synopsis of Literate Programming - - - Literate Programming: Propaganda and Tools - - - Literate Programming by Henrik Turbell - - - Literate Programming Library - - - Literate Programming Basics - - - Literate Programming Overview - - - POD is not Literate Programming - - - Computers That We Can Count On - - - Literate Programming - Issues and Problems - - - Literate Programming - Wiki Pages - - - What is well-commented code? - - - Bibliography on literate programming - A searchable bibliography - - - Program comprehension and code reading bibliography - - - Elucidative Programming - - - AVL Trees (TexiWeb) - - - Literate Programming on Wikiverse - - - Physically Based Rendering: From Theory to Implementation - - - - Useful C++ Links - - STL - - STL Reference Documentation - - - STL Tutorial - - - STL Reference - - - - Qt - - Qt 2.3 Reference - - - Qt 3.3 Reference - - - Qt 4.0 Reference - - - Qt Home Page - - - - IOStreams - - IO Stream Library - - - Binary I/O - - - I/O Stream FAQ - - - - gdb - - GDB Tutorial - - - Debugging with GDB - - - GDB Quick Reference Page (PDF) (Handy) - - - - Classes and Constructors - - Constructor FAQ - - - Organizing Classes - - - - - Software Documentation or System Documentation - - The Almighty Thud - - - Microsoft Coding Techniques and Programming Practices - - - Software and Documentation - - - The Source Code is the Design - - - What is Software Design? - - - How To Write Unmaintainable Code - - - Self Documenting Program Code Remains a Distant Goal - - - Place Tab A in Slot B - - - UML Reference Card - - - - TeX Resources - - The TeX User's Group - - - MikTeX website - - - MetaPost website - - - HEVEA is a quite complete and fast LATEX to HTML translator - - - - Portable Document Format (PDF) - - Adobe - The postscript and PDF standards - - - Reference Manual Portable Document Format - - - Adobe Acrobat Software Development Kit - - - - Literature Sites - - Guide to Special Collections (Columbia University) - - - Literary Criticism on the Web from the Internet Public Library - - - Victorian Web. - - - Voice of the Shuttle. - - - Modernist Journals Project - - - Museum of American Poetics - - - Modern American Poetry - - - FindArticles.com - - - Literary History - - - Literary Encyclopedia - - - - The University of California Press - - - Wright American Fiction, 1851-1875 - - - Documenting the American South: Beginnings to 1920 - - - Electronic Text Center at the University of Virginia - - - The Schomburg Center for Research in Black Culture - - - Alex Catalogue of Electronic Texts. - - - diff --git a/examples/xml/dombookmarks/jennifer.xbel b/examples/xml/dombookmarks/jennifer.xbel index 74b7f1519f..2501c118af 100644 --- a/examples/xml/dombookmarks/jennifer.xbel +++ b/examples/xml/dombookmarks/jennifer.xbel @@ -3,60 +3,42 @@ Qt Resources - + + Qt home page + + Qt Partners - - Training Partners - - - Consultants and System Integrators - - - Technology Partners - - - Value Added Resellers (VARs) - - + + + Training + + + Qt 5 documentation + + + Frequently Asked Questions + Community Resources + + Qt Centre + QtForum.org - + The Independent Qt Tutorial - - French PROG.Qt - German Qt Forum Korean Qt Community Site - + Russian Qt Forum - - Digitalfanatics: The QT 4 Resource Center - - - QtQuestions - - - Qt Quarterly - - - Qt home page - - - Qt 4.0 documentation - - - Frequently Asked Questions - Online Dictionaries @@ -73,9 +55,6 @@ OneLook Dictionary Search - - The New English-German Dictionary - TU Chemnitz German-English Dictionary @@ -86,8 +65,5 @@ Dictionnaire de l'Académie Française - - Dictionnaire des synonymes - diff --git a/examples/xml/saxbookmarks/frank.xbel b/examples/xml/saxbookmarks/frank.xbel deleted file mode 100644 index 2fd5c2e09d..0000000000 --- a/examples/xml/saxbookmarks/frank.xbel +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Literate Programming - - Synopsis of Literate Programming - - - Literate Programming: Propaganda and Tools - - - Literate Programming by Henrik Turbell - - - Literate Programming Library - - - Literate Programming Basics - - - Literate Programming Overview - - - POD is not Literate Programming - - - Computers That We Can Count On - - - Literate Programming - Issues and Problems - - - Literate Programming - Wiki Pages - - - What is well-commented code? - - - Bibliography on literate programming - A searchable bibliography - - - Program comprehension and code reading bibliography - - - Elucidative Programming - - - AVL Trees (TexiWeb) - - - Literate Programming on Wikiverse - - - Physically Based Rendering: From Theory to Implementation - - - - Useful C++ Links - - STL - - STL Reference Documentation - - - STL Tutorial - - - STL Reference - - - - Qt - - Qt 2.3 Reference - - - Qt 3.3 Reference - - - Qt 4.0 Reference - - - Qt Home Page - - - - IOStreams - - IO Stream Library - - - Binary I/O - - - I/O Stream FAQ - - - - gdb - - GDB Tutorial - - - Debugging with GDB - - - GDB Quick Reference Page (PDF) (Handy) - - - - Classes and Constructors - - Constructor FAQ - - - Organizing Classes - - - - - Software Documentation or System Documentation - - The Almighty Thud - - - Microsoft Coding Techniques and Programming Practices - - - Software and Documentation - - - The Source Code is the Design - - - What is Software Design? - - - How To Write Unmaintainable Code - - - Self Documenting Program Code Remains a Distant Goal - - - Place Tab A in Slot B - - - UML Reference Card - - - - TeX Resources - - The TeX User's Group - - - MikTeX website - - - MetaPost website - - - HEVEA is a quite complete and fast LATEX to HTML translator - - - - Portable Document Format (PDF) - - Adobe - The postscript and PDF standards - - - Reference Manual Portable Document Format - - - Adobe Acrobat Software Development Kit - - - - Literature Sites - - Guide to Special Collections (Columbia University) - - - Literary Criticism on the Web from the Internet Public Library - - - Victorian Web. - - - Voice of the Shuttle. - - - Modernist Journals Project - - - Museum of American Poetics - - - Modern American Poetry - - - FindArticles.com - - - Literary History - - - Literary Encyclopedia - - - - The University of California Press - - - Wright American Fiction, 1851-1875 - - - Documenting the American South: Beginnings to 1920 - - - Electronic Text Center at the University of Virginia - - - The Schomburg Center for Research in Black Culture - - - Alex Catalogue of Electronic Texts. - - - diff --git a/examples/xml/saxbookmarks/jennifer.xbel b/examples/xml/saxbookmarks/jennifer.xbel index d37b8224df..2501c118af 100644 --- a/examples/xml/saxbookmarks/jennifer.xbel +++ b/examples/xml/saxbookmarks/jennifer.xbel @@ -3,60 +3,42 @@ Qt Resources - + + Qt home page + + Qt Partners - - Training Partners - - - Consultants and System Integrators - - - Technology Partners - - - Value Added Resellers (VARs) - - + + + Training + + + Qt 5 documentation + + + Frequently Asked Questions + Community Resources + + Qt Centre + QtForum.org - + The Independent Qt Tutorial - - French PROG.Qt - German Qt Forum Korean Qt Community Site - + Russian Qt Forum - - Digitalfanatics: The QT 4 Resource Center - - - QtQuestions - - - Qt Quarterly - - - qt home page - - - Qt 4.0 documentation - - - Frequently Asked Questions - Online Dictionaries @@ -73,9 +55,6 @@ OneLook Dictionary Search - - The New English-German Dictionary - TU Chemnitz German-English Dictionary @@ -86,8 +65,5 @@ Dictionnaire de l'Académie Française - - Dictionnaire des synonymes - diff --git a/examples/xml/streambookmarks/frank.xbel b/examples/xml/streambookmarks/frank.xbel deleted file mode 100644 index 2fd5c2e09d..0000000000 --- a/examples/xml/streambookmarks/frank.xbel +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Literate Programming - - Synopsis of Literate Programming - - - Literate Programming: Propaganda and Tools - - - Literate Programming by Henrik Turbell - - - Literate Programming Library - - - Literate Programming Basics - - - Literate Programming Overview - - - POD is not Literate Programming - - - Computers That We Can Count On - - - Literate Programming - Issues and Problems - - - Literate Programming - Wiki Pages - - - What is well-commented code? - - - Bibliography on literate programming - A searchable bibliography - - - Program comprehension and code reading bibliography - - - Elucidative Programming - - - AVL Trees (TexiWeb) - - - Literate Programming on Wikiverse - - - Physically Based Rendering: From Theory to Implementation - - - - Useful C++ Links - - STL - - STL Reference Documentation - - - STL Tutorial - - - STL Reference - - - - Qt - - Qt 2.3 Reference - - - Qt 3.3 Reference - - - Qt 4.0 Reference - - - Qt Home Page - - - - IOStreams - - IO Stream Library - - - Binary I/O - - - I/O Stream FAQ - - - - gdb - - GDB Tutorial - - - Debugging with GDB - - - GDB Quick Reference Page (PDF) (Handy) - - - - Classes and Constructors - - Constructor FAQ - - - Organizing Classes - - - - - Software Documentation or System Documentation - - The Almighty Thud - - - Microsoft Coding Techniques and Programming Practices - - - Software and Documentation - - - The Source Code is the Design - - - What is Software Design? - - - How To Write Unmaintainable Code - - - Self Documenting Program Code Remains a Distant Goal - - - Place Tab A in Slot B - - - UML Reference Card - - - - TeX Resources - - The TeX User's Group - - - MikTeX website - - - MetaPost website - - - HEVEA is a quite complete and fast LATEX to HTML translator - - - - Portable Document Format (PDF) - - Adobe - The postscript and PDF standards - - - Reference Manual Portable Document Format - - - Adobe Acrobat Software Development Kit - - - - Literature Sites - - Guide to Special Collections (Columbia University) - - - Literary Criticism on the Web from the Internet Public Library - - - Victorian Web. - - - Voice of the Shuttle. - - - Modernist Journals Project - - - Museum of American Poetics - - - Modern American Poetry - - - FindArticles.com - - - Literary History - - - Literary Encyclopedia - - - - The University of California Press - - - Wright American Fiction, 1851-1875 - - - Documenting the American South: Beginnings to 1920 - - - Electronic Text Center at the University of Virginia - - - The Schomburg Center for Research in Black Culture - - - Alex Catalogue of Electronic Texts. - - - diff --git a/examples/xml/streambookmarks/jennifer.xbel b/examples/xml/streambookmarks/jennifer.xbel index 74b7f1519f..2501c118af 100644 --- a/examples/xml/streambookmarks/jennifer.xbel +++ b/examples/xml/streambookmarks/jennifer.xbel @@ -3,60 +3,42 @@ Qt Resources - + + Qt home page + + Qt Partners - - Training Partners - - - Consultants and System Integrators - - - Technology Partners - - - Value Added Resellers (VARs) - - + + + Training + + + Qt 5 documentation + + + Frequently Asked Questions + Community Resources + + Qt Centre + QtForum.org - + The Independent Qt Tutorial - - French PROG.Qt - German Qt Forum Korean Qt Community Site - + Russian Qt Forum - - Digitalfanatics: The QT 4 Resource Center - - - QtQuestions - - - Qt Quarterly - - - Qt home page - - - Qt 4.0 documentation - - - Frequently Asked Questions - Online Dictionaries @@ -73,9 +55,6 @@ OneLook Dictionary Search - - The New English-German Dictionary - TU Chemnitz German-English Dictionary @@ -86,8 +65,5 @@ Dictionnaire de l'Académie Française - - Dictionnaire des synonymes - -- cgit v1.2.1 From dcedce51a62ae9519d8e85c004c2f93159be8751 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Tue, 1 Nov 2016 11:35:02 +0100 Subject: Include intrin.h header when using MSVC Fixes the build with MSVC15 Change-Id: I7f22938583775bb3f0767d50cf59a43cab95eede Reviewed-by: Friedemann Kleint --- src/corelib/tools/qalgorithms.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h index ffa3082d5e..b22c5e219c 100644 --- a/src/corelib/tools/qalgorithms.h +++ b/src/corelib/tools/qalgorithms.h @@ -36,6 +36,10 @@ #include +#if defined(Q_CC_MSVC) && _MSC_VER > 1500 +#include +#endif + QT_BEGIN_NAMESPACE QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") -- cgit v1.2.1 From c5010107221ce1ba8dd08f2067c7921389baa96b Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Fri, 21 Oct 2016 19:41:44 +0100 Subject: Mention QDialog::setSizeGripEnabled() in QSizeGrip's docs The same way it also mentions QStatusBar. Change-Id: Ic084466310c989d1a79ba5ba21d6784acaa38e6e Reviewed-by: Martin Smith --- src/widgets/widgets/qsizegrip.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp index b2ffef2a5a..5cacff7e0d 100644 --- a/src/widgets/widgets/qsizegrip.cpp +++ b/src/widgets/widgets/qsizegrip.cpp @@ -178,9 +178,12 @@ Qt::Corner QSizeGripPrivate::corner() const Put this widget anywhere in a widget tree and the user can use it to resize the top-level window or any widget with the Qt::SubWindow flag set. Generally, this should be in the lower right-hand corner. + Note that QStatusBar already uses this widget, so if you have a status bar (e.g., you are using QMainWindow), then you don't need - to use this widget explicitly. + to use this widget explicitly. The same goes for QDialog, for which + you can just call \l {QDialog::setSizeGripEnabled()} + {QDialog::setSizeGripEnabled()}. On some platforms the size grip automatically hides itself when the window is shown full screen or maximised. -- cgit v1.2.1 From b5fc085e712815bcd465370f88d1df8179b538e3 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Wed, 2 Nov 2016 10:40:37 +0100 Subject: Add QPixmapIconEngine::pixmap pointer check Dereference after null check (FORWARD_NULL)5. var_deref_op: Dereferencing null pointer pe. pe pointer it's being checked at the beginning of the function so it implies pe might be null. Coverity-Id: 11106 Change-Id: Ie88b27877a46cdd20a317fb5e21c3fdec1b99dda Reviewed-by: Edward Welbourne --- src/gui/image/qicon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 3531be412e..5098955825 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -294,7 +294,7 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St QString key = QLatin1String("qt_") % HexString(pm.cacheKey()) - % HexString(pe->mode) + % HexString(pe ? pe->mode : QIcon::Normal) % HexString(QGuiApplication::palette().cacheKey()) % HexString(actualSize.width()) % HexString(actualSize.height()); -- cgit v1.2.1 From 5f6c0418fe911b7afe34153b16b3f00839354afd Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 1 Nov 2016 14:54:16 +0100 Subject: winrt: Fixed assignment of readOrigin in readDatagram Change-Id: I0455b6526b8bacd30622698e0a497fa2da3932ba Reviewed-by: David Faure --- src/network/socket/qnativesocketengine_winrt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index b6a739d1b8..920b8e2cb1 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -641,7 +641,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea QByteArray readOrigin; // Do not read the whole datagram. Put the rest of it back into the "queue" if (maxlen < datagram.data.length()) { - QByteArray readOrigin = datagram.data.left(maxlen); + readOrigin = datagram.data.left(maxlen); datagram.data = datagram.data.remove(0, maxlen); d->pendingDatagrams.prepend(datagram); } else { -- cgit v1.2.1 From ca4d93d85ee446c5e30ec8e7814651e45cbf1218 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 12 Nov 2015 10:14:51 -0800 Subject: Stop unloading plugins in QPluginLoader and QFactoryLoader QPluginLoader hasn't unloaded in its destructor since Qt 5.0, but we missed the equivalent code in QFactoryLoader (which bypasses QPluginLoader). Besides, QPluginLoader::unload() was still doing unloading, which it won't anymore. Not unloading plugins is Qt's policy, as decided during the 5.0 development process and reaffirmed now in 5.6. This is due to static data in plugins leaking out and remaining in use past the unloading of the plugin, causing crashes. This does not affect QLibrary and QLibrary::unload(). Those are meant for non-Qt loadable modules, so unloading them may be safe. Task-number: QTBUG-49061 Discussed-on: http://lists.qt-project.org/pipermail/development/2015-November/023681.html Change-Id: I461e9fc7199748faa187ffff1416070f138df8db (cherry picked from commit 494376f980e96339b6f1eff7c41336ca4d853065) Discussed-again-on: http://lists.qt-project.org/pipermail/development/2016-October/027476.html Reviewed-by: Lars Knoll --- src/corelib/plugin/qfactoryloader.cpp | 6 ++++-- src/corelib/plugin/qpluginloader.cpp | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index dcf1b1a81d..b6558f5834 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -208,10 +208,12 @@ void QFactoryLoader::update() ++keyUsageCount; } } - if (keyUsageCount || keys.isEmpty()) + if (keyUsageCount || keys.isEmpty()) { + library->setLoadHints(QLibrary::PreventUnloadHint); // once loaded, don't unload d->libraryList += library; - else + } else { library->release(); + } } } #else diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 37f2368413..0ea8280fef 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -148,6 +148,7 @@ QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent) : QObject(parent), d(0), did_load(false) { setFileName(fileName); + setLoadHints(QLibrary::PreventUnloadHint); } /*! @@ -342,7 +343,7 @@ static QString locatePlugin(const QString& fileName) void QPluginLoader::setFileName(const QString &fileName) { #if defined(QT_SHARED) - QLibrary::LoadHints lh; + QLibrary::LoadHints lh = QLibrary::PreventUnloadHint; if (d) { lh = d->loadHints(); d->release(); @@ -391,7 +392,7 @@ Q_GLOBAL_STATIC(StaticPluginList, staticPluginList) \brief Give the load() function some hints on how it should behave. You can give hints on how the symbols in the plugin are - resolved. By default, none of the hints are set. + resolved. By default since Qt 5.7, QLibrary::PreventUnloadHint is set. See the documentation of QLibrary::loadHints for a complete description of how this property works. -- cgit v1.2.1 From 9e53a91e99accae299ff7b4cc0a9c3675606d688 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 21 Oct 2016 18:28:55 +0200 Subject: Fix tiling on a width over 2048 The blend_tiled_argb and blend_tiled_rgb565 was not correctly handling widths larger than the buffer size. This patch adds the same pattern used in blend_tiled_generic, which worked correctly. Change-Id: Ie22c2a21d96cb0477cd0990bf01451ab907a4768 Task-number: QTBUG-56364 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qdrawhelper.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 39ff4142b8..c0a662b002 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4509,8 +4509,10 @@ static void blend_tiled_argb(int count, const QSpan *spans, void *userData) uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; op.func(dest, src, l, coverage); x += l; + sx += l; length -= l; - sx = 0; + if (sx >= image_width) + sx = 0; } ++spans; } @@ -4568,7 +4570,9 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) memcpy(dest, src, l * sizeof(quint16)); length -= l; tx += l; - sx = 0; + sx += l; + if (sx >= image_width) + sx = 0; } // Now use the rasterBuffer as the source of the texture, @@ -4601,8 +4605,10 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx; blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha); x += l; + sx += l; length -= l; - sx = 0; + if (sx >= image_width) + sx = 0; } } } -- cgit v1.2.1 From 1a1a0e31590a5a7f360a86de5c34a2aec8e17157 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 3 Nov 2016 12:06:43 +0300 Subject: GTK+ dialogs: Get rid of deprecated GtkStock usage GtkStock has been deprecated since GTK+ 3.10, and is removed in GTK+ 4. Use the standard button names provided by Qt instead. Change-Id: I55e8452178544b4a9ebf5c75b70f4c5c56c047f4 Reviewed-by: J-P Nurmi --- src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp index c2a116b03c..ba88af917d 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qgtk3dialoghelpers.h" +#include "qgtk3theme.h" #include #include @@ -56,6 +57,11 @@ QT_BEGIN_NAMESPACE +static const char *standardButtonText(int button) +{ + return QGtk3Theme::defaultStandardButtonText(button).toUtf8(); +} + class QGtk3Dialog : public QWindow { Q_OBJECT @@ -237,8 +243,10 @@ QGtk3FileDialogHelper::QGtk3FileDialogHelper() { d.reset(new QGtk3Dialog(gtk_file_chooser_dialog_new("", 0, GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, NULL))); + standardButtonText(QPlatformDialogHelper::Cancel), GTK_RESPONSE_CANCEL, + standardButtonText(QPlatformDialogHelper::Ok), GTK_RESPONSE_OK, + NULL))); + connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted())); connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject())); @@ -435,9 +443,9 @@ void QGtk3FileDialogHelper::applyOptions() if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) gtk_button_set_label(GTK_BUTTON(acceptButton), opts->labelText(QFileDialogOptions::Accept).toUtf8()); else if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) - gtk_button_set_label(GTK_BUTTON(acceptButton), GTK_STOCK_OPEN); + gtk_button_set_label(GTK_BUTTON(acceptButton), standardButtonText(QPlatformDialogHelper::Open)); else - gtk_button_set_label(GTK_BUTTON(acceptButton), GTK_STOCK_SAVE); + gtk_button_set_label(GTK_BUTTON(acceptButton), standardButtonText(QPlatformDialogHelper::Save)); } GtkWidget *rejectButton = gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_CANCEL); @@ -445,7 +453,7 @@ void QGtk3FileDialogHelper::applyOptions() if (opts->isLabelExplicitlySet(QFileDialogOptions::Reject)) gtk_button_set_label(GTK_BUTTON(rejectButton), opts->labelText(QFileDialogOptions::Reject).toUtf8()); else - gtk_button_set_label(GTK_BUTTON(rejectButton), GTK_STOCK_CANCEL); + gtk_button_set_label(GTK_BUTTON(rejectButton), standardButtonText(QPlatformDialogHelper::Cancel)); } } -- cgit v1.2.1 From cf4e7575cad8975442191160723d766b48a9623f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 31 Oct 2016 23:57:36 -0700 Subject: Fix GCC warning about ODR violation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two enums called "Operator" qdrawhelper_p.h:201:8: warning: type ‘struct Operator’ violates the C++ One Definition Rule [-Wodr] qopengl.cpp:138:6: note: a different type is defined in another translation unit Change-Id: I09100678ff4443e6be06fffd1482da1f636614b7 Reviewed-by: Marc Mutz --- src/gui/opengl/qopengl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 3dedd7d7be..9f48d82c9d 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -129,9 +129,6 @@ QDebug operator<<(QDebug d, const QOpenGLConfig::Gpu &g) return d; } -enum Operator { NotEqual, LessThan, LessEqualThan, Equals, GreaterThan, GreaterEqualThan }; -static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; - static inline QString valueKey() { return QStringLiteral("value"); } static inline QString opKey() { return QStringLiteral("op"); } static inline QString versionKey() { return QStringLiteral("version"); } @@ -169,6 +166,9 @@ static inline bool contains(const QJsonArray &haystack, const QString &needle) } namespace { +enum Operator { NotEqual, LessThan, LessEqualThan, Equals, GreaterThan, GreaterEqualThan }; +static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; + // VersionTerm describing a version term consisting of number and operator // found in os.version and driver_version. struct VersionTerm { -- cgit v1.2.1 From 4b6784b49c6dcf0add9ec0cbb4ad97cd191c2aa3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Sep 2016 14:07:59 -0700 Subject: Stop using readdir_r: glibc deprecated it and it's not a good idea MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POSIX does not require that readdir() be reentrant even for operations on different dirent objects, but all implementations (according to the glibc documentation) already do that. Moreover, it's not a good idea to use readdir_r since the buffer space is limited by the caller, so certain file names may be too long (ENAMETOOLONG) -- we had a workaround for QNX, but for no other OS. According to the glibc documentation, it is expected that POSIX will mark readdir_r obsolete and instead require some form of reentrancy for readdir. This commit makes everyone use readdir instead. The macros in qplatformdefs.h are left behind in case someone else is using them. With glibc 2.24, we started getting: qplatformdefs.h:150:35: warning: ‘int readdir_r(DIR*, dirent*, dirent**)’ is deprecated [-Wdeprecated-declarations] qfilesystemiterator_unix.cpp:112:17: note: in expansion of macro ‘QT_READDIR_R’ Task-number: QTBUG-56088 Change-Id: I33dc971f005a4848bb8ffffd14749b4082f62e69 Reviewed-by: Edward Welbourne Reviewed-by: James McDonnell --- src/corelib/io/qfilesystemengine.cpp | 4 +-- src/corelib/io/qfilesystemiterator_p.h | 8 ------ src/corelib/io/qfilesystemiterator_unix.cpp | 38 ----------------------------- 3 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 02aa2ff4b7..055ff3600b 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -216,7 +216,7 @@ bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) return false; } -#if defined(QT_EXT_QNX_READDIR_R) +#if defined(_DEXTRA_FIRST) static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32) { statBuf64->st_mode = statBuf32.st_mode; @@ -281,7 +281,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) { -#if defined(QT_EXT_QNX_READDIR_R) +#if defined(_DEXTRA_FIRST) knownFlagsMask = 0; entryFlags = 0; for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry); diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 119068a648..51dfe65f57 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -87,14 +87,6 @@ private: #else QT_DIR *dir; QT_DIRENT *dirEntry; -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R) - // for readdir_r - QScopedPointer mt_file; -#if defined(QT_EXT_QNX_READDIR_R) - // for _readdir_r - size_t direntSize; -#endif -#endif int lastError; #endif diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 6f094bd3b2..7d0e910188 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -46,9 +46,6 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi : nativePath(entry.nativeFilePath()) , dir(0) , dirEntry(0) -#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R) - , direntSize(0) -#endif , lastError(0) { Q_UNUSED(filters) @@ -58,32 +55,8 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi if ((dir = QT_OPENDIR(nativePath.constData())) == 0) { lastError = errno; } else { - if (!nativePath.endsWith('/')) nativePath.append('/'); - -#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) || defined(QT_EXT_QNX_READDIR_R) - // ### Race condition; we should use fpathconf and dirfd(). - size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX); - if (maxPathName == size_t(-1)) - maxPathName = FILENAME_MAX; - maxPathName += sizeof(QT_DIRENT) + 1; - - QT_DIRENT *p = reinterpret_cast(::malloc(maxPathName)); - Q_CHECK_PTR(p); - - mt_file.reset(p); -#if defined(QT_EXT_QNX_READDIR_R) - direntSize = maxPathName; - - // Include extra stat information in the readdir() call (d_stat member of - // dirent_extra_stat). This is used in QFileSystemMetaData::fillFromDirEnt() to - // avoid extra stat() calls when iterating over directories - int flags = dircntl(dir, D_GETFLAG) | D_FLAG_STAT | D_FLAG_FILTER; - if (dircntl(dir, D_SETFLAG, flags) == -1) - lastError = errno; -#endif -#endif } } @@ -98,18 +71,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa if (!dir) return false; -#if defined(QT_EXT_QNX_READDIR_R) - lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize); - if (lastError) - return false; -#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) - lastError = QT_READDIR_R(dir, mt_file.data(), &dirEntry); - if (lastError) - return false; -#else - // ### add local lock to prevent breaking reentrancy dirEntry = QT_READDIR(dir); -#endif // _POSIX_THREAD_SAFE_FUNCTIONS if (dirEntry) { fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath()); -- cgit v1.2.1 From 15df60239d2dd3b0f0844e3ec8c91300fb7a4b67 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 2 Nov 2016 09:37:42 +0100 Subject: Fix OOM crashes for huge json documents Check all places where we reallocate our internal data structure and return a DocumentTooLarge parse error if we can't get enough memory. Change-Id: I006d0170d941837220c7dad0508571b68e2cbfd7 Reviewed-by: Edward Welbourne Reviewed-by: Kati Kankaanpaa Reviewed-by: Simon Hausmann --- src/corelib/json/qjsonparser.cpp | 79 ++++++++++++++++++++++++++++++++++++---- src/corelib/json/qjsonparser_p.h | 4 ++ 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index b8a628fdcc..c7b16d5ec9 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -385,6 +385,8 @@ bool Parser::parseObject() } int objectOffset = reserveSpace(sizeof(QJsonPrivate::Object)); + if (objectOffset < 0) + return false; BEGIN << "parseObject pos=" << objectOffset << current << json; ParsedObject parsedObject(this, objectOffset); @@ -417,6 +419,9 @@ bool Parser::parseObject() if (parsedObject.offsets.size()) { int tableSize = parsedObject.offsets.size()*sizeof(uint); table = reserveSpace(tableSize); + if (table < 0) + return false; + #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN memcpy(data + table, parsedObject.offsets.constData(), tableSize); #else @@ -446,6 +451,8 @@ bool Parser::parseObject() bool Parser::parseMember(int baseOffset) { int entryOffset = reserveSpace(sizeof(QJsonPrivate::Entry)); + if (entryOffset < 0) + return false; BEGIN << "parseMember pos=" << entryOffset; bool latin1; @@ -469,6 +476,42 @@ bool Parser::parseMember(int baseOffset) return true; } +namespace { + struct ValueArray { + static const int prealloc = 128; + ValueArray() : data(stackValues), alloc(prealloc), size(0) {} + ~ValueArray() { if (data != stackValues) free(data); } + + inline bool grow() { + alloc *= 2; + if (data == stackValues) { + QJsonPrivate::Value *newValues = static_cast(malloc(alloc*sizeof(QJsonPrivate::Value))); + if (!newValues) + return false; + memcpy(newValues, data, size*sizeof(QJsonPrivate::Value)); + data = newValues; + } else { + data = static_cast(realloc(data, alloc*sizeof(QJsonPrivate::Value))); + if (!data) + return false; + } + return true; + } + bool append(const QJsonPrivate::Value &v) { + if (alloc == size && !grow()) + return false; + data[size] = v; + ++size; + return true; + } + + QJsonPrivate::Value stackValues[prealloc]; + QJsonPrivate::Value *data; + int alloc; + int size; + }; +} + /* array = begin-array [ value *( value-separator value ) ] end-array */ @@ -482,8 +525,10 @@ bool Parser::parseArray() } int arrayOffset = reserveSpace(sizeof(QJsonPrivate::Array)); + if (arrayOffset < 0) + return false; - QVarLengthArray values; + ValueArray values; if (!eatSpace()) { lastError = QJsonParseError::UnterminatedArray; @@ -496,7 +541,10 @@ bool Parser::parseArray() QJsonPrivate::Value val; if (!parseValue(&val, arrayOffset)) return false; - values.append(val); + if (!values.append(val)) { + lastError = QJsonParseError::DocumentTooLarge; + return false; + } char token = nextToken(); if (token == EndArray) break; @@ -510,20 +558,22 @@ bool Parser::parseArray() } } - DEBUG << "size =" << values.size(); + DEBUG << "size =" << values.size; int table = arrayOffset; // finalize the object - if (values.size()) { - int tableSize = values.size()*sizeof(QJsonPrivate::Value); + if (values.size) { + int tableSize = values.size*sizeof(QJsonPrivate::Value); table = reserveSpace(tableSize); - memcpy(data + table, values.constData(), tableSize); + if (table < 0) + return false; + memcpy(data + table, values.data, tableSize); } QJsonPrivate::Array *a = (QJsonPrivate::Array *)(data + arrayOffset); a->tableOffset = table - arrayOffset; a->size = current - arrayOffset; a->is_object = false; - a->length = values.size(); + a->length = values.size; DEBUG << "current=" << current; END; @@ -732,6 +782,8 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) } int pos = reserveSpace(sizeof(double)); + if (pos < 0) + return false; qToLittleEndian(ui, reinterpret_cast(data + pos)); if (current - baseOffset >= Value::MaxSize) { lastError = QJsonParseError::DocumentTooLarge; @@ -850,6 +902,9 @@ bool Parser::parseString(bool *latin1) // try to write out a latin1 string int stringPos = reserveSpace(2); + if (stringPos < 0) + return false; + BEGIN << "parse string stringPos=" << stringPos << json; while (json < end) { uint ch = 0; @@ -872,6 +927,8 @@ bool Parser::parseString(bool *latin1) break; } int pos = reserveSpace(1); + if (pos < 0) + return false; DEBUG << " " << ch << (char)ch; data[pos] = (uchar)ch; } @@ -887,6 +944,8 @@ bool Parser::parseString(bool *latin1) // write string length *(QJsonPrivate::qle_ushort *)(data + stringPos) = ushort(current - outStart - sizeof(ushort)); int pos = reserveSpace((4 - current) & 3); + if (pos < 0) + return false; while (pos & 3) data[pos++] = 0; END; @@ -916,10 +975,14 @@ bool Parser::parseString(bool *latin1) } if (QChar::requiresSurrogates(ch)) { int pos = reserveSpace(4); + if (pos < 0) + return false; *(QJsonPrivate::qle_ushort *)(data + pos) = QChar::highSurrogate(ch); *(QJsonPrivate::qle_ushort *)(data + pos + 2) = QChar::lowSurrogate(ch); } else { int pos = reserveSpace(2); + if (pos < 0) + return false; *(QJsonPrivate::qle_ushort *)(data + pos) = (ushort)ch; } } @@ -933,6 +996,8 @@ bool Parser::parseString(bool *latin1) // write string length *(QJsonPrivate::qle_int *)(data + stringPos) = (current - outStart - sizeof(int))/2; int pos = reserveSpace((4 - current) & 3); + if (pos < 0) + return false; while (pos & 3) data[pos++] = 0; END; diff --git a/src/corelib/json/qjsonparser_p.h b/src/corelib/json/qjsonparser_p.h index a395c0c92e..82a7899a51 100644 --- a/src/corelib/json/qjsonparser_p.h +++ b/src/corelib/json/qjsonparser_p.h @@ -102,6 +102,10 @@ private: if (current + space >= dataLength) { dataLength = 2*dataLength + space; data = (char *)realloc(data, dataLength); + if (!data) { + lastError = QJsonParseError::DocumentTooLarge; + return -1; + } } int pos = current; current += space; -- cgit v1.2.1 From c0c75b3c2093976bab90dbf1566a02a1d10f2d33 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 28 Oct 2016 15:12:51 +0200 Subject: vcxproj generator: Support the /DEBUG:FASTLINK option of VS 2015 Make qmake understand the /DEBUG:FASTLINK option in QMAKE_LFLAGS, and write the corresponding value correctly to VS 2015 project files. Task-number: QTBUG-55591 Change-Id: I670375ed1523a5ab96bb3cce28635785564edba8 Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msbuild_objectmodel.cpp | 17 ++++++++++++++++- qmake/generators/win32/msvc_objectmodel.cpp | 4 +++- qmake/generators/win32/msvc_objectmodel.h | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 9dbb33ba14..fec181e61f 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1163,6 +1163,21 @@ static inline QString toString(subSystemOption option) return QString(); } +static inline QString toString(triState genDebugInfo, linkerDebugOption option) +{ + switch (genDebugInfo) { + case unset: + break; + case _False: + return "false"; + case _True: + if (option == linkerDebugOptionFastLink) + return "DebugFastLink"; + return "true"; + } + return QString(); +} + static inline QString toString(machineTypeOption option) { switch (option) { @@ -1541,7 +1556,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCLinkerTool &tool) << attrTagS(_EntryPointSymbol, tool.EntryPointSymbol) << attrTagX(_ForceSymbolReferences, tool.ForceSymbolReferences, ";") << attrTagS(_FunctionOrder, tool.FunctionOrder) - << attrTagT(_GenerateDebugInformation, tool.GenerateDebugInformation) + << attrTagS(_GenerateDebugInformation, toString(tool.GenerateDebugInformation, tool.DebugInfoOption)) << attrTagT(_GenerateManifest, tool.GenerateManifest) << attrTagT(_GenerateWindowsMetadata, tool.GenerateWindowsMetadata) << attrTagS(_WindowsMetadataFile, tool.GenerateWindowsMetadata == _True ? tool.WindowsMetadataFile : QString()) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 7fd748e39c..82adc6814c 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1430,8 +1430,10 @@ bool VCLinkerTool::parseOption(const char* option) }else EnableUAC = _True; break; - case 0x3389797: // /DEBUG + case 0x3389797: // /DEBUG[:FASTLINK] GenerateDebugInformation = _True; + if (config->CompilerVersion >= NET2015 && strcmp(option + 7, "FASTLINK") == 0) + DebugInfoOption = linkerDebugOptionFastLink; break; case 0x0033896: // /DEF:filename ModuleDefinitionFile = option+5; diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 7092da3e59..96923ba23d 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -282,6 +282,10 @@ enum inlineExpansionOption { expandAnySuitable, expandDefault // Not useful number, but stops the output }; +enum linkerDebugOption { + linkerDebugOptionNone, + linkerDebugOptionFastLink +}; enum linkIncrementalType { linkIncrementalDefault, linkIncrementalNo, @@ -595,6 +599,7 @@ public: QStringList ForceSymbolReferences; QString FunctionOrder; triState GenerateDebugInformation; + linkerDebugOption DebugInfoOption; triState GenerateMapFile; qlonglong HeapCommitSize; qlonglong HeapReserveSize; -- cgit v1.2.1 From b18a4de8143cba87502ae5737e28eb6a209c6033 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 14 Sep 2016 17:14:32 +0300 Subject: Register Qt::TextFlag with QT_Q_ENUM By some unfortunate oversight, this enum was never registered. Change-Id: I2227ccf294d2cf717187a3dcaaf4cbfacc4ac65d Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qnamespace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index e2b0d30db0..a30344995e 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1679,6 +1679,7 @@ public: QT_Q_ENUM(Orientation) QT_Q_ENUM(DropAction) QT_Q_FLAG(Alignment) + QT_Q_ENUM(TextFlag) QT_Q_FLAG(Orientations) QT_Q_FLAG(DropActions) QT_Q_FLAG(Edges) -- cgit v1.2.1 From 2f5b7157f5a601d9c439f97e56b238758f9672f2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 3 Nov 2016 18:11:01 +0100 Subject: remove dependencies from sync.profile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the CI obtains them from the qt5 super repo nowadays. Change-Id: I146e6a74763f32bee6651f427dd3664a1236ea0e Reviewed-by: Jędrzej Nowacki --- sync.profile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sync.profile b/sync.profile index bba0ff2b2f..8f57593b00 100644 --- a/sync.profile +++ b/sync.profile @@ -58,11 +58,3 @@ my @zlib_headers = ( "zconf.h", "zlib.h" ); @ignore_for_include_check = ( "qsystemdetection.h", "qcompilerdetection.h", "qprocessordetection.h", @zlib_headers, @angle_headers); @ignore_for_qt_begin_namespace_check = ( "qconfig.h", "qconfig-dist.h", "qconfig-large.h", "qconfig-medium.h", "qconfig-minimal.h", "qconfig-small.h", "qfeatures.h", "qatomic_arch.h", "qatomic_windowsce.h", "qt_windows.h", "qatomic_macosx.h", @zlib_headers, @angle_headers); %inject_headers = ( "$basedir/src/corelib/global" => [ "qconfig.h", "qfeatures.h" ] ); -# Module dependencies. -# Every module that is required to build this module should have one entry. -# Each of the module version specifiers can take one of the following values: -# - A specific Git revision. -# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch) -# -%dependencies = ( -); -- cgit v1.2.1 From c5f18284248cf5ad1d07136764d2e4526b176344 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Wed, 2 Nov 2016 12:45:33 +0200 Subject: Fix freetype detection on QNX Pass qtConfLibrary_freetype test even when the .../freetype2 folder is not found, so that freetype and fontconfig config.tests are run. This fixes freetype detection on QNX, since the freetype headers are located in the default .../include folder. Task-number: QTBUG-56861 Change-Id: Ic8d72e6509195acd2d22a70603df850361f07b34 Reviewed-by: James McDonnell Reviewed-by: Oswald Buddenhagen --- src/gui/configure.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/configure.pri b/src/gui/configure.pri index ee5c7730df..aaffa835dc 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -12,7 +12,7 @@ defineTest(qtConfLibrary_freetype) { return(true) } } - return(false) + return(true) } # Check for Direct X SDK (include, lib, and direct shader compiler 'fxc'). -- cgit v1.2.1 From 95d127354887425b616a5087c24b6765b7bf907b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 24 Oct 2016 15:53:06 +0200 Subject: Windows: Don't claim bitmap fonts support all standard sizes We were throwing away important information by claiming that all fonts support all the standard sizes in QFontDatabase on Windows This caused the font dialog to list unsupported sizes for bitmap fonts, unlike the native font dialog. We would also claim to support creating bitmap fonts at unsupported sizes, which would lead to 1. QFontInfo(font).pointSize() would return the requested size, not the actual rendered size. 2. Bitmap fonts created at 64 pixels and higher would be invisible. On Mac, there are no system bitmap fonts, and the use is not very common, but installing some bitmap fonts on the system, it does seem to ignore the sizes supported in the font and just displays the standard list instead, so we keep the current behavior there. [ChangeLog][QtGui][Text] Fixed list of supported sizes for bitmap fonts on Windows. Task-number: QTBUG-56672 Change-Id: Idbec2db9eb3381ab5ddf6259bd2befcba9b93564 Reviewed-by: Lars Knoll --- .../fontdatabases/windows/qwindowsfontdatabase.cpp | 2 +- .../gui/text/qfontdatabase/tst_qfontdatabase.cpp | 28 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index 434aa16d16..ad4dd3c944 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1583,7 +1583,7 @@ QString QWindowsFontDatabase::fontDir() const bool QWindowsFontDatabase::fontsAlwaysScalable() const { - return true; + return false; } void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont) diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index c53792da99..8c26f8a91f 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -67,6 +67,9 @@ private slots: void condensedFontWidth(); void condensedFontMatching(); + void rasterFonts(); + void smoothFonts(); + private: QString m_ledFont; QString m_testFont; @@ -334,5 +337,30 @@ void tst_QFontDatabase::condensedFontMatching() QFontMetrics(tfcBySubfamilyName).width(testString())); } +void tst_QFontDatabase::rasterFonts() +{ + QFont font(QLatin1String("Fixedsys"), 1000); + QFontInfo fontInfo(font); + + if (fontInfo.family() != font.family()) + QSKIP("Fixedsys font not available."); + + QVERIFY(!QFontDatabase().isSmoothlyScalable(font.family())); + QVERIFY(fontInfo.pointSize() != font.pointSize()); +} + +void tst_QFontDatabase::smoothFonts() +{ + QFont font(QLatin1String("Arial"), 1000); + QFontInfo fontInfo(font); + + if (fontInfo.family() != font.family()) + QSKIP("Arial font not available."); + + // Smooth and bitmap scaling are mutually exclusive + QVERIFY(QFontDatabase().isSmoothlyScalable(font.family())); + QVERIFY(!QFontDatabase().isBitmapScalable(font.family())); +} + QTEST_MAIN(tst_QFontDatabase) #include "tst_qfontdatabase.moc" -- cgit v1.2.1 From a07e77a99a916f5ee65511ffade0f087d72bf8bb Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 4 Nov 2016 11:07:54 +0100 Subject: iOS: fix 'incompatible pointer type' compiler warning Change-Id: I01bb7516a3600dd1dbd71dd6989f541494840abc Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiostextresponder.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 6224a6603c..3a888e2bd0 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -619,7 +619,7 @@ - (id)tokenizer { - return [[[UITextInputStringTokenizer alloc] initWithTextInput:id(self)] autorelease]; + return [[[UITextInputStringTokenizer alloc] initWithTextInput:self] autorelease]; } - (UITextPosition *)beginningOfDocument -- cgit v1.2.1 From 91c0afdcbf49939b466a07c0719444c55b6bbe49 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 4 Nov 2016 15:09:00 +0100 Subject: iOS: only build nsphotolibrarysupport for iOS The plugin depends on AssetLibrary.framework, which is only available for iOS. Change-Id: Ic7b3c4ffb4d26808d2120e46593cb4e191e2c10b Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/optional/optional.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/optional/optional.pro b/src/plugins/platforms/ios/optional/optional.pro index 5e3421a025..6b4ae1ef5e 100644 --- a/src/plugins/platforms/ios/optional/optional.pro +++ b/src/plugins/platforms/ios/optional/optional.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS = nsphotolibrarysupport +ios: SUBDIRS = nsphotolibrarysupport -- cgit v1.2.1 From 68a0bd85920e6eb22b69aa5f57f71f3dccb8b286 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 4 Nov 2016 15:17:19 +0100 Subject: iOS, mkspec: only link in qiosnsphotolibrarysupport for iOS The plugin depends on AssetLibrary.framework, which is only available for iOS. Change-Id: I798c87b57881210ced8e4a7399c1e45d130ee357 Reviewed-by: Jake Petroules --- mkspecs/features/uikit/default_post.prf | 8 -------- mkspecs/macx-ios-clang/features/default_post.prf | 9 +++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 mkspecs/macx-ios-clang/features/default_post.prf diff --git a/mkspecs/features/uikit/default_post.prf b/mkspecs/features/uikit/default_post.prf index 8f1c5280b8..6e23e23a6a 100644 --- a/mkspecs/features/uikit/default_post.prf +++ b/mkspecs/features/uikit/default_post.prf @@ -90,11 +90,3 @@ macx-xcode { QMAKE_PCH_ARCHS = $$VALID_ARCHS } - -!xcodebuild:equals(TEMPLATE, app):!isEmpty(QMAKE_INFO_PLIST) { - # Only link in photo library support if Info.plist contains - # NSPhotoLibraryUsageDescription. Otherwise it will be rejected from AppStore. - plist_path = $$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_) - system("/usr/libexec/PlistBuddy -c 'Print NSPhotoLibraryUsageDescription' $$system_quote($$plist_path) &>/dev/null"): \ - QTPLUGIN += qiosnsphotolibrarysupport -} diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf new file mode 100644 index 0000000000..2ed96fc5c7 --- /dev/null +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -0,0 +1,9 @@ +load(default_post) + +!xcodebuild:equals(TEMPLATE, app):!isEmpty(QMAKE_INFO_PLIST) { + # Only link in photo library support if Info.plist contains + # NSPhotoLibraryUsageDescription. Otherwise it will be rejected from AppStore. + plist_path = $$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_) + system("/usr/libexec/PlistBuddy -c 'Print NSPhotoLibraryUsageDescription' $$system_quote($$plist_path) &>/dev/null"): \ + QTPLUGIN += qiosnsphotolibrarysupport +} -- cgit v1.2.1 From 6172ebaf301c42b0c87396a9c6f0816081dddef9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 26 Oct 2016 13:48:37 +0200 Subject: Fix compiler version detection for clang Concatenate the multi line output from clang into one line before parsing it. This got broken in 492d7d14fc. Change-Id: I282d69932c5851f229213d7ef1ca6a78cd56c8c3 Reviewed-by: Friedemann Kleint Reviewed-by: Michal Klocek Reviewed-by: Oswald Buddenhagen --- configure.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.pri b/configure.pri index cdc13ff87c..6d318f63cb 100644 --- a/configure.pri +++ b/configure.pri @@ -225,6 +225,7 @@ defineTest(qtConfTest_buildParts) { defineTest(qtConfTest_checkCompiler) { contains(QMAKE_CXX, ".*clang.*") { qtRunLoggedCommand("$$QMAKE_CXX -v 2>&1", versionstr)|return(false) + versionstr = "$$versionstr" contains(versionstr, "^Apple (clang|LLVM) version .*") { $${1}.compilerDescription = "Apple Clang" $${1}.compilerId = "apple_clang" -- cgit v1.2.1 From eda3184a67c35d9250bad54c36c6d55f8772e43f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 13:24:43 +0100 Subject: fix icpc version detection the regex didn't match the actual output ("icpc (ICC) 17.0.0 20160721"), and the code failed to concatenate the lines (broken in 492d7d14fc, as for clang). but using -dumpversion (as we do for g++) is more elegant anyway, so do it instead. Change-Id: I328bbfab9c08d6e660c3f1ec51554d9f877b8f66 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- configure.pri | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.pri b/configure.pri index 6d318f63cb..b78d075b61 100644 --- a/configure.pri +++ b/configure.pri @@ -242,11 +242,11 @@ defineTest(qtConfTest_checkCompiler) { $${1}.compilerDescription = "GCC" $${1}.compilerId = "gcc" $${1}.compilerVersion = $$version - } else: contains(QMAKE_CXX, ".*icpc" ) { - qtRunLoggedCommand("$$QMAKE_CXX -v", version)|return(false) + } else: contains(QMAKE_CXX, ".*icpc") { + qtRunLoggedCommand("$$QMAKE_CXX -dumpversion", version)|return(false) $${1}.compilerDescription = "ICC" $${1}.compilerId = "icc" - $${1}.compilerVersion = $$replace(version, "icpc version ([0-9.]+).*", "\\1") + $${1}.compilerVersion = $$version } else: msvc { command = $$QMAKE_CXX /EP /nologo $$source $$system_quote($$QMAKE_CONFIG_TESTS_DIR/win/msvc_version.cpp) qtRunLoggedCommand("$$command", version)|return(false) -- cgit v1.2.1 From 890a4d40ecd384ba4f59643374948a6fdddb741a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 13:57:14 +0100 Subject: nuke obsolete comment amends 56ee007b3. Change-Id: Ida4f79ae72f185ce1f4cca9add30e3084da9c5bf Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 6b500c0f3e..bfc460edca 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1552,9 +1552,6 @@ defineTest(qtConfOutput_publicFeature) { } } -# currently this is somewhat inconsistent, as the feature is output to the public pro file, -# whereas the define is being added to the private pro file. -# This should get cleaned up to add to the private pro and header instead. defineTest(qtConfOutput_privateFeature) { name = "$$eval($${1}.name)" isEmpty(name): \ -- cgit v1.2.1 From 66ad9668f3158ab5a0ee8f93fe3ddf062e37967e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 15:15:19 +0100 Subject: fix iteration over a feature's outputs use precalculated path instead of incorrectly assembling it from scratch. it accidentally worked when the features happened to be in the right order, as the iteration variable 'feature' from the calling function was inherited. however, if the feature was accessed via dependency resolution, things blew up. amends 90eee08b3e, which presumably came to be this way due to a missing adjustment to a refactoring. Change-Id: I78b0acc0682cfc27a458df014ce14262a65c6241 Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index bfc460edca..1d7e810cc8 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1182,8 +1182,8 @@ defineTest(qtConfCheckFeature) { $${fpfx}.available = $$result export($${fpfx}.available) - for (i, $${currentConfig}.features.$${feature}.output._KEYS_): \ - qtConfProcessOneOutput($$feature, $$i) + for (i, $${fpfx}.output._KEYS_): \ + qtConfProcessOneOutput($${1}, $$i) return(true) } -- cgit v1.2.1 From 4b1115742ac7be1a1c6bce0e9cac022adc0bdc5c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 16:50:04 +0100 Subject: invert the logic of the c++98 default test this is much more intuitive, and actually produces a sensible result with configure -recheck after a compiler upgrade. Change-Id: Icfa0b85377d9fc014e66490c8ebf6c9236df978e Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- config.tests/common/c++98default/c++98default.cpp | 4 ++-- configure.json | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config.tests/common/c++98default/c++98default.cpp b/config.tests/common/c++98default/c++98default.cpp index 5edcf2d76c..3ff92eda33 100644 --- a/config.tests/common/c++98default/c++98default.cpp +++ b/config.tests/common/c++98default/c++98default.cpp @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#if __cplusplus >= 201103L -#error "compiler uses c++11 or higher by default" +#if __cplusplus < 201103L +#error "compiler does not use c++11 or higher by default" #endif int main(int, char **) {} diff --git a/configure.json b/configure.json index 85ef23a186..0ff808519c 100644 --- a/configure.json +++ b/configure.json @@ -281,8 +281,8 @@ "type": "compile", "test": "common/c++1z" }, - "cxx98default": { - "label": "compiler defaulting to C++98", + "cxx11default": { + "label": "compiler defaulting to C++11 or higher", "type": "compile", "test": "common/c++98default" }, @@ -483,9 +483,9 @@ "condition": "call.crossCompile", "output": [ "publicConfig", "privateConfig" ] }, - "cxx98default": { - "label": "Compiler defaults to C++98", - "condition": "tests.cxx98default", + "cxx11default": { + "label": "Compiler defaults to C++11 or higher", + "condition": "!tests.cxx11default", "output": [ { "type": "publicConfig", "name": "c++11" } ] }, "compiler-flags": { -- cgit v1.2.1 From 2ad4d757546b5bc0ede98af26cb04716ac6662b9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 16:58:20 +0100 Subject: move empty cache() call back to configure.prf the new configure system doesn't use this type of caching. also, it's invoked via qt_parts.prf, which actually has the same call. Change-Id: Ifa1e810e24330b59a1eb9f883eb0500642a212f3 Reviewed-by: Lars Knoll --- mkspecs/features/configure.prf | 4 ++++ mkspecs/features/configure_base.prf | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index f275e3ac06..cc360033d7 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -1,3 +1,7 @@ +# Ensure that a cache is present. If none was found on startup, this will create +# one in the build directory of the project which loads this feature. +cache() + load(configure_base) isEmpty(QMAKE_CONFIG_TESTS_DIR): QMAKE_CONFIG_TESTS_DIR = $$_PRO_FILE_PWD_/config.tests diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf index dc630a3528..cd60cc3cc6 100644 --- a/mkspecs/features/configure_base.prf +++ b/mkspecs/features/configure_base.prf @@ -43,9 +43,5 @@ defineTest(qtRunLoggedCommand) { return(true) } -# Ensure that a cache is present. If none was found on startup, this will create -# one in the build directory of the project which loads this feature. -cache() - QMAKE_CONFIG_LOG = $$dirname(_QMAKE_CACHE_)/config.log write_file($$QMAKE_CONFIG_LOG, "") -- cgit v1.2.1 From 7ac15ab0ffeeb88a156cd5dd935fadcda4a559f9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 17:08:26 +0100 Subject: don't clear config.log unless re-checking it is counterproductive to clear the log when cached test results are used, as that makes it hard to determine how they came to be. -recheck isn't as clear-cut as -recheck-all, as only part of the results is discarded, and we can't reasonably discard only part of the log. i opted for clearing the log entirely, as having both the old and new results in the log would be probably quite confusing. Change-Id: Ibb391f2ba2ea86d73c23365d46cc66ed8a2158d6 Reviewed-by: Lars Knoll --- mkspecs/features/configure.prf | 2 ++ mkspecs/features/configure_base.prf | 1 - mkspecs/features/qt_configure.prf | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index cc360033d7..147d6f178c 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -4,6 +4,8 @@ cache() load(configure_base) +recheck: write_file($$QMAKE_CONFIG_LOG, "") + isEmpty(QMAKE_CONFIG_TESTS_DIR): QMAKE_CONFIG_TESTS_DIR = $$_PRO_FILE_PWD_/config.tests # Try to build the test project in $$QMAKE_CONFIG_TESTS_DIR/$$1 diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf index cd60cc3cc6..4d68affabf 100644 --- a/mkspecs/features/configure_base.prf +++ b/mkspecs/features/configure_base.prf @@ -44,4 +44,3 @@ defineTest(qtRunLoggedCommand) { } QMAKE_CONFIG_LOG = $$dirname(_QMAKE_CACHE_)/config.log -write_file($$QMAKE_CONFIG_LOG, "") diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 1d7e810cc8..810e3106ab 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1729,6 +1729,8 @@ equals(QMAKE_CONFIG_CACHE_USE, none) { "cache.xplatform = $$[QMAKE_XSPEC]" write_file($$QMAKE_CONFIG_CACHE, cont) } +!equals(QMAKE_CONFIG_CACHE_USE, all): \ + write_file($$QMAKE_CONFIG_LOG, "") for (currentConfig, allConfigs) { qtConfSetModuleName() -- cgit v1.2.1 From c804033f3630cc19bde4612a5ec9fe9a897e750c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 17:20:49 +0100 Subject: don't attempt to install the target of header-only modules they have none. Change-Id: I1e5ffa9960c4fac3c708be4820fb40e7909569c8 Reviewed-by: Jake Petroules Reviewed-by: Lars Knoll --- mkspecs/features/qt_module.prf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 954fdb2501..069eec02eb 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -64,7 +64,9 @@ load(qt_build_paths) header_module { TEMPLATE = aux - CONFIG += force_qt # Needed for the headers_clean tests. + CONFIG += \ + force_qt \ # Needed for the headers_clean tests. + qt_no_install_library } else { TEMPLATE = lib } -- cgit v1.2.1 From dfbfc4915ba57294661faaa9596a92fa64893318 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 17:37:31 +0100 Subject: fix handling of -optimized-tools this option makes sense only when the default build is debug (regardless of whether the release build is also enabled), as it overrides the default. Change-Id: I29f87430242a7d8239f13f0b33f6eebe098d9cf7 Reviewed-by: Lars Knoll --- configure.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.json b/configure.json index 0ff808519c..e266fa918c 100644 --- a/configure.json +++ b/configure.json @@ -558,6 +558,7 @@ }, "release_tools": { "label": "Compile tools in release mode", + "autoDetect": "!features.debug", "output": [ "privateFeature", "publicQtConfig" ] }, "simulator_and_device": { @@ -1073,7 +1074,7 @@ or compile needed modules into the library." }, { "type": "note", - "condition": "features.release_tools && (!features.debug || features.debug_and_release)", + "condition": "features.release_tools && !features.debug", "message": "-optimized-tools is not useful in -release mode." }, { -- cgit v1.2.1 From f13b18dc0cf660a1d3419cf21a6e41ba859eeef7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 17:42:56 +0100 Subject: remove redundancy from the build type report with -force-debug-info it's a bit pointless to state "(with debug info)" also for the default build mode. Change-Id: I99563c424752c735a3157776ef4fe5252ebd3900 Reviewed-by: Lars Knoll --- configure.pri | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/configure.pri b/configure.pri index b78d075b61..02bce88d96 100644 --- a/configure.pri +++ b/configure.pri @@ -527,13 +527,16 @@ defineTest(qtConfReport_buildMode) { else: \ release = "release" - $$qtConfEvaluate("features.debug"): \ + $$qtConfEvaluate("features.debug") { build_mode = "debug" - else: \ + raw_build_mode = "debug" + } else { build_mode = $$release + raw_build_mode = "release" + } $$qtConfEvaluate("features.debug_and_release"): \ - build_mode = "debug and $$release; default link: $$build_mode" + build_mode = "debug and $$release; default link: $$raw_build_mode" $$qtConfEvaluate("features.release_tools"): \ build_mode = "$$build_mode; optimized tools" -- cgit v1.2.1 From 6c7f81cac93d32072e64466a713eebfcf5e68807 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 17:58:53 +0100 Subject: don't write "Checking for ..." to config.log the more precise test/library name is already logged. Change-Id: I73d3229a9e20a0024582b18bfe9f2848cab5f4ff Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 810e3106ab..94001dc1d5 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -794,10 +794,8 @@ defineTest(qtLogTestIntro) { label = $$eval($${1}.label) isEmpty(label): return() - msg = "Checking for $${label}... " - log($$msg) + log("Checking for $${label}... ") $$QMAKE_CONFIG_VERBOSE: log("$$escape_expand(\\n)") - write_file($$QMAKE_CONFIG_LOG, msg, append) } defineTest(qtLogTestResult) { -- cgit v1.2.1 From b4979082b89842ee14cfc28639129bd15935bfc8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 2 Nov 2016 18:00:16 +0100 Subject: don't log silent tests to config.log they were already omitted from the console output; there is no need to spam the log with them (their completion was not logged, either). Change-Id: I32c97413d2e6ceb18ee61356855cc6a7fa2222bf Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 94001dc1d5..d5b9c6dc11 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -611,9 +611,7 @@ defineTest(qtConfHandleLibrary) { return() } - qtLogTestIntro($${lpfx}) - msg = "looking for library $${1}" - write_file($$QMAKE_CONFIG_LOG, msg, append) + qtLogTestIntro($${lpfx}, "looking for library $${1}") result = false for (s, $${lpfx}.sources._KEYS_) { @@ -796,6 +794,7 @@ defineTest(qtLogTestIntro) { log("Checking for $${label}... ") $$QMAKE_CONFIG_VERBOSE: log("$$escape_expand(\\n)") + write_file($$QMAKE_CONFIG_LOG, 2, append) } defineTest(qtLogTestResult) { @@ -921,9 +920,7 @@ defineTest(qtRunSingleTest) { qtConfLoadResult($${tpfx}, $$1): \ return() - qtLogTestIntro($${tpfx}) - msg = "executing config test $${1}" - write_file($$QMAKE_CONFIG_LOG, msg, append) + qtLogTestIntro($${tpfx}, "executing config test $${1}") result = false $${call}($${tpfx}): result = true -- cgit v1.2.1 From 25a2717f66006ba020d12c5666f8f45d3ccf8756 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 4 Nov 2016 10:34:58 +0100 Subject: fix debug-only builds on debug-and-release platforms this actually affects only non-framework Darwin builds - debug-only framework builds are impossible, and Windows is always debug-and-release. Change-Id: Ia79dbbefc5750168ebd8967fe4afbe173f55a0d6 Reviewed-by: Erik Verbruggen Reviewed-by: Joerg Bornemann Reviewed-by: Jake Petroules --- mkspecs/features/qt_helper_lib.prf | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index 07e4f48771..99ba0c6877 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -27,6 +27,8 @@ qtConfig(build_all): CONFIG += build_all DESTDIR = $$MODULE_BASE_OUTDIR/lib DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin +THE_TARGET = $$qt5LibraryTarget($$TARGET) + !build_pass { MODULE = $$replace(TARGET, ^qt, ) MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri @@ -35,22 +37,23 @@ DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin MODULE_PRI_CONT = \ "QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \ "QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)" - MODULE_LIBS = -L$$DESTDIR -l$$TARGET debug_and_release { win32: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}d darwin: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}_debug + MODULE_RELEASE_LIBS = -L$$DESTDIR -l$$TARGET MODULE_PRI_CONT += \ "QMAKE_LIBS_$${ucmodule}_DEBUG = $$val_escape(MODULE_DEBUG_LIBS)" \ - "QMAKE_LIBS_$${ucmodule}_RELEASE = $$val_escape(MODULE_LIBS)" + "QMAKE_LIBS_$${ucmodule}_RELEASE = $$val_escape(MODULE_RELEASE_LIBS)" } else { + MODULE_LIBS = -L$$DESTDIR -l$$THE_TARGET MODULE_PRI_CONT += \ "QMAKE_LIBS_$${ucmodule} = $$val_escape(MODULE_LIBS)" } write_file($$MODULE_PRI, MODULE_PRI_CONT)|error() } +TARGET = $$THE_TARGET + # In static builds of Qt, convenience libraries must be installed, # as in this case they are not linked to the final library/plugin. installed|if(!not_installed:qtConfig(static)): load(qt_installs) - -TARGET = $$qt5LibraryTarget($$TARGET) -- cgit v1.2.1 From 146a2eef5fe35acb65ae5fe7b8ebad771cbd448e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 2 Nov 2016 10:14:58 +0100 Subject: Re-add configure option for Direct2D QPA plugin This also allows us to enable auto-detection for it. Change-Id: I7639ab533553f02e691e6f6b8cdd8dff19d91809 Reviewed-by: Oswald Buddenhagen --- config_help.txt | 1 + src/gui/configure.json | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config_help.txt b/config_help.txt index 296bf807d9..5e0d36a41f 100644 --- a/config_help.txt +++ b/config_help.txt @@ -252,6 +252,7 @@ Gui, printing, widget options: -xcb-xlib............. Enable Xcb-Xlib support [auto] Platform backends: + -direct2d .......... Enable Direct2D support [auto] (Windows only) -directfb .......... Enable DirectFB support [no] (Unix only) -eglfs ............. Enable EGLFS support [auto; no on Android and Windows] -gbm ............... Enable backends for GBM [auto] (Linux only) diff --git a/src/gui/configure.json b/src/gui/configure.json index f4e2faf08b..9fb4a971c3 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -9,6 +9,7 @@ "options": { "android-style-assets": "boolean", "angle": "boolean", + "direct2d": "boolean", "directfb": "boolean", "directwrite": "boolean", "egl": "boolean", @@ -446,8 +447,7 @@ }, "direct2d": { "label": "Direct 2D", - "autoDetect": false, - "condition": "config.win32 && libs.direct2d", + "condition": "config.win32 && !config.winrt && libs.direct2d", "output": [ "privateFeature" ] }, "evdev": { -- cgit v1.2.1 From 969bb10eed646313209fcdd9b84605aa98fc88de Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Thu, 3 Nov 2016 08:22:34 +0200 Subject: Enable cross_compile when sysroot is used The crossCompile test checked only if platform and xplatform are different (which is the usual case), but in yocto builds cross compilation is done by setting both platform and xplatform to the same target mkspec and using host tools from -external-hostbindir. Change-Id: Ib4ae3975a52196d9c0ad52b5b5e9ccd7c1bfe883 Reviewed-by: Oswald Buddenhagen --- configure.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.pri b/configure.pri index 02bce88d96..0e6bb6a6f5 100644 --- a/configure.pri +++ b/configure.pri @@ -57,6 +57,7 @@ defineTest(qtConfCommandline_sanitize) { # callbacks defineReplace(qtConfFunc_crossCompile) { + !isEmpty(config.input.sysroot): return(true) spec = $$[QMAKE_SPEC] !equals(spec, $$[QMAKE_XSPEC]): return(true) return(false) -- cgit v1.2.1 From c972c452e2ae2f38ce957eaac1761d8dff265f9b Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 2 Nov 2016 13:12:12 +0100 Subject: winrt: Proper guarding by readMutex Commented its purpose and the guarded members for readMutex. Fixed places where guarded members were accessed without using the mutex. Use QMutexLocker instead of manually (un-)locking the mutex. Task-number: QTBUG-44357 Change-Id: I3049bb0df30f00659dc284c8e30ad7503c11e7c6 Reviewed-by: David Faure --- src/network/socket/qnativesocketengine_winrt.cpp | 13 ++++++++++--- src/network/socket/qnativesocketengine_winrt_p.h | 10 +++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 920b8e2cb1..32fafc2cb0 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -580,6 +580,7 @@ qint64 QNativeSocketEngine::bytesAvailable() const if (d->socketType != QAbstractSocket::TcpSocket) return -1; + QMutexLocker locker(&d->readMutex); return d->readBytes.size() - d->readBytes.pos(); } @@ -592,12 +593,12 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) // There will be a read notification when the socket was closed by the remote host. If that // happens and there isn't anything left in the buffer, we have to return -1 in order to signal // the closing of the socket. + QMutexLocker mutexLocker(&d->readMutex); if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) { close(); return -1; } - QMutexLocker mutexLocker(&d->readMutex); return d->readBytes.read(data, maxlen); } @@ -628,6 +629,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea PacketHeaderOptions) { Q_D(QNativeSocketEngine); + QMutexLocker locker(&d->readMutex); if (d->socketType != QAbstractSocket::UdpSocket || d->pendingDatagrams.isEmpty()) { if (header) header->clear(); @@ -647,6 +649,7 @@ qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea } else { readOrigin = datagram.data; } + locker.unlock(); memcpy(data, readOrigin, qMin(maxlen, qint64(datagram.data.length()))); return readOrigin.length(); } @@ -684,12 +687,14 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QI bool QNativeSocketEngine::hasPendingDatagrams() const { Q_D(const QNativeSocketEngine); + QMutexLocker locker(&d->readMutex); return d->pendingDatagrams.length() > 0; } qint64 QNativeSocketEngine::pendingDatagramSize() const { Q_D(const QNativeSocketEngine); + QMutexLocker locker(&d->readMutex); if (d->pendingDatagrams.isEmpty()) return -1; @@ -1336,7 +1341,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async hr = byteArrayAccess->Buffer(&data); Q_ASSERT_SUCCEEDED(hr); - readMutex.lock(); + QMutexLocker locker(&readMutex); if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset readBytes.close(); if (!readBytes.isOpen()) @@ -1346,7 +1351,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async Q_ASSERT(readBytes.atEnd()); readBytes.write(reinterpret_cast(data), qint64(bufferLength)); readBytes.seek(readPos); - readMutex.unlock(); + locker.unlock(); if (notifyOnRead) emit q->readReady(); @@ -1410,7 +1415,9 @@ HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, I datagram.data.resize(length); hr = reader->ReadBytes(length, reinterpret_cast(datagram.data.data())); RETURN_OK_IF_FAILED("Could not read datagram"); + QMutexLocker locker(&readMutex); pendingDatagrams.append(datagram); + locker.unlock(); if (notifyOnRead) emit q->readReady(); diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index c1fbcf70fa..654bb99d35 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -200,10 +200,18 @@ private: Microsoft::WRL::ComPtr tcpListener; Microsoft::WRL::ComPtr connectOp; Microsoft::WRL::ComPtr> readOp; + + // Protected by readMutex. Written in handleReadyRead (native callback) QBuffer readBytes; - QMutex readMutex; + // In case of TCP readMutex protects readBytes and bytesAvailable. In case of UDP it is + // pendingDatagrams. They are written inside native callbacks (handleReadyRead and + // handleNewDatagrams/putIntoPendingDatagramsList) + mutable QMutex readMutex; + + // Protected by readMutex. Written in handleNewDatagrams/putIntoPendingDatagramsList QList pendingDatagrams; + QList pendingConnections; QList currentConnections; QEventLoop eventLoop; -- cgit v1.2.1 From fe51dbac3d20ef9275dd1a9070f8185dc7705ad9 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 31 Oct 2016 12:57:38 +0100 Subject: winrt: Fix potential memory corruption The timerInfo list might get accessed concurrently and cause references to become dangling. Hence, we need to protect usages with a mutex. According to tests/benchmark there is no impact on performance. Task-number: QTBUG-56756 Change-Id: I4bdffccff70d2dca99f4a39defad438afe571ada Reviewed-by: Oliver Wolff --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 29 +++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index d115a3db2a..4a2e2d887f 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,7 @@ public: private: QHash timerIdToObject; QVector timerInfos; + mutable QMutex timerInfoLock; QHash timerHandleToId; QHash timerIdToHandle; QHash timerIdToCancelHandle; @@ -116,6 +118,7 @@ private: timerIdToObject.insert(id, obj); const quint64 targetTime = qt_msectime() + interval; const WinRTTimerInfo info(id, interval, type, obj, targetTime); + QMutexLocker locker(&timerInfoLock); if (id >= timerInfos.size()) timerInfos.resize(id + 1); timerInfos[id] = info; @@ -124,6 +127,7 @@ private: bool removeTimer(int id) { + QMutexLocker locker(&timerInfoLock); if (id >= timerInfos.size()) return false; @@ -247,14 +251,18 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) if (timerId == INTERRUPT_HANDLE) break; - WinRTTimerInfo &info = d->timerInfos[timerId]; - Q_ASSERT(info.timerId != INVALID_TIMER_ID); + { + QMutexLocker locker(&d->timerInfoLock); - QCoreApplication::postEvent(this, new QTimerEvent(timerId)); + WinRTTimerInfo &info = d->timerInfos[timerId]; + Q_ASSERT(info.timerId != INVALID_TIMER_ID); - // Update timer's targetTime - const quint64 targetTime = qt_msectime() + info.interval; - info.targetTime = targetTime; + QCoreApplication::postEvent(this, new QTimerEvent(timerId)); + + // Update timer's targetTime + const quint64 targetTime = qt_msectime() + info.interval; + info.targetTime = targetTime; + } waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE); } emit awake(); @@ -421,6 +429,7 @@ QList QEventDispatcherWinRT::registeredTime } Q_D(const QEventDispatcherWinRT); + QMutexLocker locker(&d->timerInfoLock); QList timerInfos; foreach (const WinRTTimerInfo &info, d->timerInfos) { if (info.object == object && info.timerId != INVALID_TIMER_ID) @@ -452,6 +461,7 @@ int QEventDispatcherWinRT::remainingTime(int timerId) } Q_D(QEventDispatcherWinRT); + QMutexLocker locker(&d->timerInfoLock); const WinRTTimerInfo timerInfo = d->timerInfos.at(timerId); if (timerInfo.timerId == INVALID_TIMER_ID) { #ifndef QT_NO_DEBUG @@ -500,6 +510,9 @@ bool QEventDispatcherWinRT::event(QEvent *e) case QEvent::Timer: { QTimerEvent *timerEvent = static_cast(e); const int id = timerEvent->timerId(); + + QMutexLocker locker(&d->timerInfoLock); + Q_ASSERT(id < d->timerInfos.size()); WinRTTimerInfo &info = d->timerInfos[id]; Q_ASSERT(info.timerId != INVALID_TIMER_ID); @@ -508,9 +521,13 @@ bool QEventDispatcherWinRT::event(QEvent *e) break; info.inEvent = true; + locker.unlock(); + QTimerEvent te(id); QCoreApplication::sendEvent(d->timerIdToObject.value(id), &te); + locker.relock(); + // The timer might have been removed in the meanwhile if (id >= d->timerInfos.size()) break; -- cgit v1.2.1 From 14805de3d9584157fed9da8f8955446d2292846f Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 7 Nov 2016 21:11:09 +0100 Subject: Fix build with -no-feature-cursor Change-Id: I0644342c56facefab611f981690d0c7a2a460e7e Reviewed-by: Laszlo Agocs --- src/plugins/platforms/vnc/qvnc.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp index f386be193d..a45bb1c19c 100644 --- a/src/plugins/platforms/vnc/qvnc.cpp +++ b/src/plugins/platforms/vnc/qvnc.cpp @@ -533,9 +533,11 @@ void QRfbRawEncoder::write() QVncClientCursor::QVncClientCursor() { +#ifndef QT_NO_CURSOR QWindow *w = QGuiApplication::focusWindow(); QCursor c = w ? w->cursor() : QCursor(Qt::ArrowCursor); changeCursor(&c, 0); +#endif } QVncClientCursor::~QVncClientCursor() @@ -582,10 +584,10 @@ void QVncClientCursor::write(QVncClient *client) const socket->write((const char*)bitmap.scanLine(i), width); } -#ifndef QT_NO_CURSOR void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window) { Q_UNUSED(window); +#ifndef QT_NO_CURSOR const Qt::CursorShape shape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor; if (shape == Qt::BitmapCursor) { @@ -599,6 +601,9 @@ void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window) cursor = *platformImage.image(); hotspot = platformImage.hotspot(); } +#else // !QT_NO_CURSOR + Q_UNUSED(widgetCursor); +#endif for (auto client : clients) client->setDirtyCursor(); } @@ -614,7 +619,6 @@ uint QVncClientCursor::removeClient(QVncClient *client) clients.removeOne(client); return clients.count(); } -#endif QVncServer::QVncServer(QVncScreen *screen, quint16 port) : qvnc_screen(screen) -- cgit v1.2.1 From c6477286525682773ae3739fee53689e225d1b0a Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 7 Nov 2016 21:11:54 +0100 Subject: Fix developer build with -no-feature-cursor Change-Id: I3ec22f212ad68baa788fcea2e7340c2f53bfc8a1 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/xcb/qxcbcursor.cpp | 4 ++-- src/widgets/graphicsview/qgraphicswidget_p.cpp | 3 +++ src/widgets/kernel/qapplication.cpp | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 4de4be43d1..80fe5a2199 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -74,6 +74,8 @@ static PtrXcursorLibraryGetDefaultSize ptrXcursorLibraryGetDefaultSize = 0; static xcb_font_t cursorFont = 0; static int cursorCount = 0; +#ifndef QT_NO_CURSOR + static uint8_t cur_blank_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -276,8 +278,6 @@ static const char * const cursorNames[] = { "link" }; -#ifndef QT_NO_CURSOR - QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c) : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0) { diff --git a/src/widgets/graphicsview/qgraphicswidget_p.cpp b/src/widgets/graphicsview/qgraphicswidget_p.cpp index 4beb64a254..46d2a4c1aa 100644 --- a/src/widgets/graphicsview/qgraphicswidget_p.cpp +++ b/src/widgets/graphicsview/qgraphicswidget_p.cpp @@ -722,6 +722,9 @@ void QGraphicsWidgetPrivate::windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent #ifndef QT_NO_CURSOR if (needsSetCursorCall) q->setCursor(cursorShape); +#else + Q_UNUSED(needsSetCursorCall); + Q_UNUSED(cursorShape); #endif // update buttons if we hover over them windowData->hoveredSubControl = q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &bar, pos.toPoint(), 0); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 89eff898fe..358838b4e9 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2790,6 +2790,8 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget) // Send enter/leave events followed by a mouse move on the entered widget. QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier); sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver); +#else // !QT_NO_CURSOR + Q_UNUSED(widget); #endif // QT_NO_CURSOR } -- cgit v1.2.1 From baebb6aa26799e627bc3be6bf41589cef422bed2 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 27 Sep 2016 11:13:49 +0200 Subject: QVariant to QJsonValue::Null conversion Adds a few missing parts of the conversion from QVariant to QJsonValue after the introduction of the nullptr QVariant. The conversion the other way is already implemented. Change-Id: I8b25dec4b476c4761c5098a60944ff11c36f8bec Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/json/qjsonvalue.cpp | 8 ++++++++ src/corelib/kernel/qvariant.cpp | 1 + tests/auto/corelib/json/tst_qtjson.cpp | 7 ++++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp index 5a906dda7b..4b52014db1 100644 --- a/src/corelib/json/qjsonvalue.cpp +++ b/src/corelib/json/qjsonvalue.cpp @@ -346,6 +346,12 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other) \header \li Source type \li Destination type + \row + \li + \list + \li QMetaType::Nullptr + \endlist + \li QJsonValue::Null \row \li \list @@ -393,6 +399,8 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other) QJsonValue QJsonValue::fromVariant(const QVariant &variant) { switch (variant.userType()) { + case QMetaType::Nullptr: + return QJsonValue(Null); case QVariant::Bool: return QJsonValue(variant.toBool()); case QVariant::Int: diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 72ae3b063f..ccfa7d0d38 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3085,6 +3085,7 @@ bool QVariant::canConvert(int targetTypeId) const if (currentType == QMetaType::QJsonValue) { switch (targetTypeId) { + case QMetaType::Nullptr: case QMetaType::QString: case QMetaType::Bool: case QMetaType::Int: diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 1194260efa..17892b44a2 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -1103,6 +1103,7 @@ void tst_QtJson::fromVariant() jsonObject["string"] = stringValue; jsonObject["array"] = jsonArray_variant; + QCOMPARE(QJsonValue::fromVariant(QVariant::fromValue(nullptr)), QJsonValue(QJsonValue::Null)); QCOMPARE(QJsonValue::fromVariant(QVariant(boolValue)), QJsonValue(boolValue)); QCOMPARE(QJsonValue::fromVariant(QVariant(intValue)), QJsonValue(intValue)); QCOMPARE(QJsonValue::fromVariant(QVariant(uintValue)), QJsonValue(static_cast(uintValue))); @@ -1179,7 +1180,7 @@ void tst_QtJson::toVariantMap() array.append(true); array.append(999.); array.append(QLatin1String("string")); - array.append(QJsonValue()); + array.append(QJsonValue::Null); object.insert("Array", array); map = object.toVariantMap(); @@ -1203,12 +1204,12 @@ void tst_QtJson::toVariantHash() QVERIFY(hash.isEmpty()); object.insert("Key", QString("Value")); - object.insert("null", QJsonValue()); + object.insert("null", QJsonValue::Null); QJsonArray array; array.append(true); array.append(999.); array.append(QLatin1String("string")); - array.append(QJsonValue()); + array.append(QJsonValue::Null); object.insert("Array", array); hash = object.toVariantHash(); -- cgit v1.2.1 From ffe72840a34ed7c99294f29f85828c5d5fad728f Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 1 Nov 2016 13:10:35 +0100 Subject: Only turn off font hinting when scale is != 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KDE will set the screen scale factors to 1 by default. Make sure we don't turn off font hinting in that case. Task-number: QTBUG-56797 Change-Id: Ieab18a7cfe4c1cb7087caab4d881932a4a991bc8 Reviewed-by: Friedemann Kleint Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qhighdpiscaling.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 6846196719..a94ad1e00a 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -332,8 +332,10 @@ static const char scaleFactorProperty[] = "_q_scaleFactor"; */ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor) { - m_screenFactorSet = true; - m_active = true; + if (!qFuzzyCompare(factor, qreal(1))) { + m_screenFactorSet = true; + m_active = true; + } screen->setProperty(scaleFactorProperty, QVariant(factor)); // hack to force re-evaluation of screen geometry -- cgit v1.2.1 From ae8d3d69d68e7f3da1b0f524e12496387aff26ec Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 1 Nov 2016 15:28:17 -0700 Subject: macOS: Clear event dispatcher interrupt state A pending interrupt of a QEventLoop may interfere with native runModal calls, resulting in Cocoa's main event loop to be stopped unexpectedly. After commit 9ab60b9c processEvents() no longer resets the event dispatcher interrupt flag. Add QCocoaEventDispatcher::clearCurrentThreadCocoa EventDispatcherInterruptFlag(). Use it to clear the interrupt state before calling runModal and variants. Work around the inability to use platform API in the print support code. Change-Id: I52f26f99a63cbb46969db42f65b09a3c3119ad15 Task-number: QTBUG-56746 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 2 ++ src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 13 +++++++++++++ src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoanativeinterface.h | 2 ++ src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 6 ++++++ src/printsupport/dialogs/qpagesetupdialog_mac.mm | 5 +++++ src/printsupport/dialogs/qprintdialog_mac.mm | 5 +++++ 9 files changed, 48 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 3c924bec94..474e2cdb19 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -39,6 +39,7 @@ #include #include "qcocoahelpers.h" +#include "qcocoaeventdispatcher.h" #import @@ -318,6 +319,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // close down during the cleanup. qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); + + // Make sure we don't interrupt the runModalForWindow call. + QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag(); + [NSApp runModalForWindow:mColorPanel]; mDialogIsExecuting = false; return (mResultCode == NSOKButton); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 8a2a478a72..569dd3b028 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -125,6 +125,8 @@ public: void interrupt(); void flush(); + static void clearCurrentThreadCocoaEventDispatcherInterruptFlag(); + friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 1cfb3ecff9..09a0e14950 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -960,6 +960,19 @@ void QCocoaEventDispatcher::interrupt() void QCocoaEventDispatcher::flush() { } +// QTBUG-56746: The behavior of processEvents() has been changed to not clear +// the interrupt flag. Use this function to clear it. + void QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag() +{ + QCocoaEventDispatcher *cocoaEventDispatcher = + qobject_cast(QThread::currentThread()->eventDispatcher()); + if (!cocoaEventDispatcher) + return; + QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = + static_cast(QObjectPrivate::get(cocoaEventDispatcher)); + cocoaEventDispatcherPrivate->interrupt = false; +} + QCocoaEventDispatcher::~QCocoaEventDispatcher() { Q_D(QCocoaEventDispatcher); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 4c1b190b9c..71748ae77f 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -45,6 +45,7 @@ #include "qt_mac_p.h" #include "qcocoahelpers.h" #include "qcocoamenubar.h" +#include "qcocoaeventdispatcher.h" #include #include #include @@ -235,6 +236,10 @@ static QString strippedText(QString s) // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // close down during the cleanup. qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); + + // Make sure we don't interrupt the runModal call below. + QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag(); + QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); mReturnCode = [mSavePanel runModal]; QCocoaMenuBar::resetKnownMenuItemsToQt(); diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 5b27dc1da9..eb800afd47 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -43,6 +43,7 @@ #include #include "qcocoahelpers.h" +#include "qcocoaeventdispatcher.h" #import @@ -313,6 +314,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will // close down during the cleanup. qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); + + // Make sure we don't interrupt the runModalForWindow call. + QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag(); + [NSApp runModalForWindow:mFontPanel]; mDialogIsExecuting = false; return (mResultCode == NSOKButton); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index d018c05635..d6786b9274 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -96,6 +96,8 @@ private: */ Q_INVOKABLE QPixmap defaultBackgroundPixmapForQWizard(); + Q_INVOKABLE void clearCurrentThreadCocoaEventDispatcherInterruptFlag(); + // QMacPastebardMime support. The mac pasteboard void pointers are // QMacPastebardMime instances from the cocoa plugin or qtmacextras // These two classes are kept in sync and can be casted between. diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index baee451903..8534c1c6fb 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -38,6 +38,7 @@ #include "qcocoahelpers.h" #include "qcocoaapplication.h" #include "qcocoaintegration.h" +#include "qcocoaeventdispatcher.h" #include #include @@ -193,6 +194,11 @@ QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard() return QPixmap(); } +void QCocoaNativeInterface::clearCurrentThreadCocoaEventDispatcherInterruptFlag() +{ + QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag(); +} + void QCocoaNativeInterface::onAppFocusWindowChanged(QWindow *window) { Q_UNUSED(window); diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm index b86de31883..9c86c5a90e 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm +++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm @@ -127,6 +127,11 @@ void QMacPageSetupDialogPrivate::openCocoaPageLayout(Qt::WindowModality modality QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) alloc] initWithNSPrintInfo:printInfo]; if (modality == Qt::ApplicationModal) { + + // Make sure we don't interrupt the runModalWithPrintInfo call. + (void) QMetaObject::invokeMethod(qApp->platformNativeInterface(), + "clearCurrentThreadCocoaEventDispatcherInterruptFlag"); + int rval = [pageLayout runModalWithPrintInfo:printInfo]; [delegate pageLayoutDidEnd:pageLayout returnCode:rval contextInfo:q]; } else { diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index 030526954d..964b20dac5 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -239,6 +239,11 @@ void QPrintDialogPrivate::openCocoaPrintPanel(Qt::WindowModality modality) if (modality == Qt::ApplicationModal || !q->parentWidget()) { if (modality == Qt::NonModal) qWarning("QPrintDialog is required to be modal on OS X"); + + // Make sure we don't interrupt the runModalWithPrintInfo call. + (void) QMetaObject::invokeMethod(qApp->platformNativeInterface(), + "clearCurrentThreadCocoaEventDispatcherInterruptFlag"); + int rval = [printPanel runModalWithPrintInfo:printInfo]; [delegate printPanelDidEnd:printPanel returnCode:rval contextInfo:q]; } else { -- cgit v1.2.1 From 8f2eb9b43c23b03918c50fa721a47f3ab99e4ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 27 Oct 2016 09:57:54 +0200 Subject: Prevent stale QOpenGLContext fbo pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is logic for clearing the qgl_curent_fbo pointer in release(), but it is not always called, causing the pointer to become stale on QOpenGLFramebufferObject deletion. As a last resort, clear the qgl_curent_fbo pointer on the current context if it’s pointing to the object that is being deleted. Change-Id: I36cca511da295412332193524219e32607ef8261 Task-number: QTBUG-56639 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qopenglcontext_p.h | 2 +- src/gui/opengl/qopenglframebufferobject.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 7c8c698a7d..113b789512 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -258,7 +258,7 @@ public: static QOpenGLContextPrivate *get(QOpenGLContext *context) { - return context->d_func(); + return context ? context->d_func() : Q_NULLPTR; } #if !defined(QT_NO_DEBUG) diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index b1b580f85b..b5fa6b9785 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -949,6 +949,12 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() d->stencil_buffer_guard->free(); if (d->fbo_guard) d->fbo_guard->free(); + + QOpenGLContextPrivate *contextPrv = QOpenGLContextPrivate::get(QOpenGLContext::currentContext()); + if (contextPrv && contextPrv->qgl_current_fbo == this) { + contextPrv->qgl_current_fbo_invalid = true; + contextPrv->qgl_current_fbo = Q_NULLPTR; + } } /*! -- cgit v1.2.1 From 356f5bbac3a66701e958896f8075bbacc90439df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 25 Oct 2016 08:14:21 +0200 Subject: Cocoa: Make child window cursors work correctly The existing cursor logic had a couple of issues: - It made the faulty assumption that we could not use the NSWindow invalidateCursorRectsForView API for child NSViews. - It used NSWindow invalidateCursorRectsForView and NSView resetCursorRects. This API has been replaced by the more general NSTrackingArea API. - It did not implement falling back to the parent window cursor if the current window has no cursor set. Document that QWindow cursors work the same way as QWidget cursors in that a QWindow with no set cursor will fall back to the parent window cursor. Change the cocoa platform code to use NSTrackingArea exclusively and implement NSView cursorUpdate which sets the cursor. Handle immediate change on QWindow:: setCursor() manually. Add QWindow::effectiveWindowCursor() and applyEffectiveWindowCursor() which finds the correct window cursor. Add a manual test for the child window, child widget, and QWidget::createWindowChild cases. Task-number: QTBUG-33479 Task-number: QTBUG-52023 Change-Id: I0370e11bbadb2da95e8632e61be6228ec2cd5e9d Reviewed-by: Timur Pocheptsov --- src/gui/kernel/qwindow.cpp | 3 + src/plugins/platforms/cocoa/qcocoacursor.mm | 9 +- src/plugins/platforms/cocoa/qcocoawindow.h | 2 + src/plugins/platforms/cocoa/qcocoawindow.mm | 60 ++++++--- src/plugins/platforms/cocoa/qnsview.h | 1 - src/plugins/platforms/cocoa/qnsview.mm | 19 +-- tests/manual/qcursor/childwidget/childwidget.pro | 6 + tests/manual/qcursor/childwidget/main.cpp | 92 ++++++++++++++ tests/manual/qcursor/childwindow/childwindow.pro | 5 + tests/manual/qcursor/childwindow/main.cpp | 91 ++++++++++++++ .../childwindowcontainer/childwindowcontainer.pro | 6 + tests/manual/qcursor/childwindowcontainer/main.cpp | 138 +++++++++++++++++++++ tests/manual/qcursor/qcursor.pro | 2 +- 13 files changed, 395 insertions(+), 39 deletions(-) create mode 100644 tests/manual/qcursor/childwidget/childwidget.pro create mode 100644 tests/manual/qcursor/childwidget/main.cpp create mode 100644 tests/manual/qcursor/childwindow/childwindow.pro create mode 100644 tests/manual/qcursor/childwindow/main.cpp create mode 100644 tests/manual/qcursor/childwindowcontainer/childwindowcontainer.pro create mode 100644 tests/manual/qcursor/childwindowcontainer/main.cpp diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 2ff19f5175..c7ad10a46f 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2462,6 +2462,9 @@ void QWindowPrivate::_q_clearAlert() See the \l{Qt::CursorShape}{list of predefined cursor objects} for a range of useful shapes. + If no cursor has been set, or after a call to unsetCursor(), the + parent window's cursor is used. + By default, the cursor has the Qt::ArrowCursor shape. Some underlying window implementations will reset the cursor if it diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 8e38181c29..a4c291c14a 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -55,7 +55,7 @@ QCocoaCursor::~QCocoaCursor() void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) { - NSCursor * cocoaCursor = convertCursor(cursor); + NSCursor *cocoaCursor = convertCursor(cursor); if (QPlatformWindow * platformWindow = window->handle()) static_cast(platformWindow)->setWindowCursor(cocoaCursor); @@ -77,9 +77,12 @@ void QCocoaCursor::setPos(const QPoint &position) CFRelease(e); } -NSCursor *QCocoaCursor::convertCursor(QCursor * cursor) +NSCursor *QCocoaCursor::convertCursor(QCursor *cursor) { - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + if (cursor == Q_NULLPTR) + return 0; + + const Qt::CursorShape newShape = cursor->shape(); NSCursor *cocoaCursor; // Check for a suitable built-in NSCursor first: diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 9cf6328281..bf28f83540 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -236,6 +236,8 @@ public: void setMenubar(QCocoaMenuBar *mb); QCocoaMenuBar *menubar() const; + NSCursor *effectiveWindowCursor() const; + void applyEffectiveWindowCursor(); void setWindowCursor(NSCursor *cursor); void registerTouch(bool enable); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 977a5ae657..a18d93b89e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1645,31 +1645,53 @@ QCocoaMenuBar *QCocoaWindow::menubar() const return m_menubar; } -void QCocoaWindow::setWindowCursor(NSCursor *cursor) +// Finds the effective cursor for this window by walking up the +// ancestor chain (including this window) until a set cursor is +// found. Returns nil if there is not set cursor. +NSCursor *QCocoaWindow::effectiveWindowCursor() const { - // This function is called (via QCocoaCursor) by Qt to set - // the cursor for this window. It can be called for a window - // that is not currenly under the mouse pointer (for example - // for a popup window.) Qt expects the set cursor to "stick": - // it should be accociated with the window until a different - // cursor is set. - if (m_windowCursor != cursor) { - [m_windowCursor release]; - m_windowCursor = [cursor retain]; - } - // Use the built in cursor rect API if the QCocoaWindow has a NSWindow. - // Othervise, set the cursor if this window is under the mouse. In - // this case QNSView::cursorUpdate will set the cursor as the pointer - // moves. - if (m_nsWindow && m_qtView) { - [m_nsWindow invalidateCursorRectsForView : m_qtView]; + if (m_windowCursor) + return m_windowCursor; + if (!parent()) + return nil; + return static_cast(parent())->effectiveWindowCursor(); +} + +// Applies the cursor as returned by effectiveWindowCursor(), handles +// the special no-cursor-set case by setting the arrow cursor. +void QCocoaWindow::applyEffectiveWindowCursor() +{ + NSCursor *effectiveCursor = effectiveWindowCursor(); + if (effectiveCursor) { + [effectiveCursor set]; } else { - if (m_windowUnderMouse) - [cursor set]; + // We wold like to _unset_ the cursor here; but there is no such + // API. Fall back to setting the default arrow cursor. + [[NSCursor arrowCursor] set]; } } +void QCocoaWindow::setWindowCursor(NSCursor *cursor) +{ + if (m_windowCursor == cursor) + return; + + // Setting a cursor in a foregin view is not supported. + if (!m_qtView) + return; + + [m_windowCursor release]; + m_windowCursor = cursor; + [m_windowCursor retain]; + + // The installed view tracking area (see QNSView updateTrackingAreas) will + // handle cursor updates on mouse enter/leave. Handle the case where the + // mouse is on the this window by changing the cursor immediately. + if (m_windowUnderMouse) + applyEffectiveWindowCursor(); +} + void QCocoaWindow::registerTouch(bool enable) { m_registerTouchCount += enable ? 1 : -1; diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 2d4ad7aad3..9d2b54a321 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -118,7 +118,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)mouseMovedImpl:(NSEvent *)theEvent; - (void)mouseEnteredImpl:(NSEvent *)theEvent; - (void)mouseExitedImpl:(NSEvent *)theEvent; -- (void)cursorUpdateImpl:(NSEvent *)theEvent; - (void)rightMouseDown:(NSEvent *)theEvent; - (void)rightMouseDragged:(NSEvent *)theEvent; - (void)rightMouseUp:(NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index c67bcfd23b..1ad9b5f327 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -120,7 +120,7 @@ static bool _q_dontOverrideCtrlLMB = false; - (void)cursorUpdate:(NSEvent *)theEvent { - [view cursorUpdateImpl:theEvent]; + [self cursorUpdate:theEvent]; } @end @@ -924,21 +924,10 @@ QT_WARNING_POP [self addTrackingArea:m_trackingArea]; } --(void)cursorUpdateImpl:(NSEvent *)theEvent -{ - Q_UNUSED(theEvent) - // Set the cursor manually if there is no NSWindow. - if (!m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor) - [m_platformWindow->m_windowCursor set]; - else - [super cursorUpdate:theEvent]; -} - --(void)resetCursorRects +- (void)cursorUpdate:(NSEvent *)theEvent { - // Use the cursor rect API if there is a NSWindow - if (m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor) - [self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor]; + Q_UNUSED(theEvent); + m_platformWindow->applyEffectiveWindowCursor(); } - (void)mouseMovedImpl:(NSEvent *)theEvent diff --git a/tests/manual/qcursor/childwidget/childwidget.pro b/tests/manual/qcursor/childwidget/childwidget.pro new file mode 100644 index 0000000000..9ca41c5b4f --- /dev/null +++ b/tests/manual/qcursor/childwidget/childwidget.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = childwidget +INCLUDEPATH += . +QT += widgets + +SOURCES += main.cpp diff --git a/tests/manual/qcursor/childwidget/main.cpp b/tests/manual/qcursor/childwidget/main.cpp new file mode 100644 index 0000000000..4447c87210 --- /dev/null +++ b/tests/manual/qcursor/childwidget/main.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +class CursorWidget : public QWidget +{ +public: + CursorWidget(QCursor cursor, QColor color) + :m_cursor(cursor) + ,m_color(color) + { + if (cursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(cursor); + } + + void paintEvent(QPaintEvent *e) + { + QPainter p(this); + p.fillRect(e->rect(), m_color); + } + + void mousePressEvent(QMouseEvent *) + { + // Toggle cursor + QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor; + if (newCursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(newCursor); + } + +private: + QCursor m_cursor; + QColor m_color; +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + // Test child widgets (one of which is native) with set cursors. + // Click window to toggle cursor. + + CursorWidget w1((QCursor(Qt::SizeVerCursor)), QColor(Qt::blue).darker()); + w1.resize(200, 200); + w1.show(); + + CursorWidget w2((QCursor(Qt::OpenHandCursor)), QColor(Qt::red).darker()); + w2.setParent(&w1); + w2.setGeometry(0, 0, 100, 100); + w2.show(); + + CursorWidget w3((QCursor(Qt::IBeamCursor)), QColor(Qt::green).darker()); + w3.winId(); + w3.setParent(&w1); + w3.setGeometry(100, 100, 100, 100); + w3.show(); + + return app.exec(); +} diff --git a/tests/manual/qcursor/childwindow/childwindow.pro b/tests/manual/qcursor/childwindow/childwindow.pro new file mode 100644 index 0000000000..194536a91a --- /dev/null +++ b/tests/manual/qcursor/childwindow/childwindow.pro @@ -0,0 +1,5 @@ +TEMPLATE = app +TARGET = childwindow +INCLUDEPATH += . + +SOURCES += main.cpp diff --git a/tests/manual/qcursor/childwindow/main.cpp b/tests/manual/qcursor/childwindow/main.cpp new file mode 100644 index 0000000000..5fc293dfcf --- /dev/null +++ b/tests/manual/qcursor/childwindow/main.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +class CursorWindow : public QRasterWindow +{ +public: + CursorWindow(QCursor cursor, QColor color) + :m_cursor(cursor) + ,m_color(color) + { + if (cursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(cursor); + } + + void paintEvent(QPaintEvent *e) + { + QPainter p(this); + p.fillRect(e->rect(), m_color); + } + + void mousePressEvent(QMouseEvent *) + { + // Toggle cursor + QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor; + if (newCursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(newCursor); + } + +private: + QCursor m_cursor; + QColor m_color; +}; + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + // Test child windows with set cursors. Create parent window and + // two child windows. Click window to toggle cursor. + + CursorWindow w1((QCursor(Qt::SizeVerCursor)), QColor(Qt::blue).darker()); + w1.resize(200, 200); + w1.show(); + + CursorWindow w2((QCursor(Qt::OpenHandCursor)), QColor(Qt::red).darker()); + w2.setParent(&w1); + w2.setGeometry(0, 0, 100, 100); + w2.show(); + + CursorWindow w3((QCursor(Qt::IBeamCursor)), QColor(Qt::green).darker()); + w3.setParent(&w1); + w3.setGeometry(100, 100, 100, 100); + w3.show(); + + return app.exec(); +} diff --git a/tests/manual/qcursor/childwindowcontainer/childwindowcontainer.pro b/tests/manual/qcursor/childwindowcontainer/childwindowcontainer.pro new file mode 100644 index 0000000000..2233ce4a63 --- /dev/null +++ b/tests/manual/qcursor/childwindowcontainer/childwindowcontainer.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = childwindowcontainer +INCLUDEPATH += . +QT += widgets + +SOURCES += main.cpp diff --git a/tests/manual/qcursor/childwindowcontainer/main.cpp b/tests/manual/qcursor/childwindowcontainer/main.cpp new file mode 100644 index 0000000000..d440133a42 --- /dev/null +++ b/tests/manual/qcursor/childwindowcontainer/main.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +class CursorWindow : public QRasterWindow +{ +public: + CursorWindow(QCursor cursor, QColor color) + :m_cursor(cursor) + ,m_color(color) + { + if (cursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(cursor); + } + + void paintEvent(QPaintEvent *e) + { + QPainter p(this); + p.fillRect(e->rect(), m_color); + } + + void mousePressEvent(QMouseEvent *) + { + // Toggle cursor + QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor; + if (newCursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(newCursor); + } + +private: + QCursor m_cursor; + QColor m_color; +}; + +class CursorWidget : public QWidget +{ +public: + CursorWidget(QCursor cursor, QColor color) + :m_cursor(cursor) + ,m_color(color) + { + if (cursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(cursor); + } + + void paintEvent(QPaintEvent *e) + { + QPainter p(this); + p.fillRect(e->rect(), m_color); + } + + void mousePressEvent(QMouseEvent *) + { + // Toggle cursor + QCursor newCursor = (cursor().shape() == m_cursor.shape()) ? QCursor() : m_cursor; + if (newCursor.shape() == Qt::ArrowCursor) + unsetCursor(); + else + setCursor(newCursor); + } + +private: + QCursor m_cursor; + QColor m_color; +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + { + // Create top-level windowContainer with window. Setting the cursor + // for the container should set the cursor for the window as well. + // Setting the cursor for the window overrides the cursor for the + // container. The example starts out with a window cursor; click + // to fall back to the container cursor. + CursorWindow *w1 = new CursorWindow(QCursor(Qt::OpenHandCursor), QColor(Qt::red).darker()); + QWidget* container = QWidget::createWindowContainer(w1); + container->resize(200, 200); + container->setCursor(Qt::PointingHandCursor); + container->show(); + } + + { + // Similar to above, but with a top-level QWiget + CursorWidget *w1 = new CursorWidget(QCursor(Qt::IBeamCursor), QColor(Qt::green).darker()); + w1->resize(200, 200); + + CursorWindow *w2 = new CursorWindow(QCursor(Qt::OpenHandCursor), QColor(Qt::red).darker()); + QWidget* container = QWidget::createWindowContainer(w2); + container->winId(); // must make the container native, otherwise setCursor + // sets the cursor on a QWindowContainerClassWindow which + // is outside the QWindow hierarchy (macOS). + container->setParent(w1); + container->setCursor(Qt::PointingHandCursor); + container->setGeometry(0, 0, 100, 100); + + w1->show(); + } + + return app.exec(); +} diff --git a/tests/manual/qcursor/qcursor.pro b/tests/manual/qcursor/qcursor.pro index 0b5c2b1945..c6617b8e89 100644 --- a/tests/manual/qcursor/qcursor.pro +++ b/tests/manual/qcursor/qcursor.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs -SUBDIRS = allcursors grab_override qcursorhighdpi +SUBDIRS = allcursors childwidget childwindow childwindowcontainer grab_override qcursorhighdpi -- cgit v1.2.1 From d7bcdc3a442b99c2caebd4cfd38de67e14090e05 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 2 Nov 2016 16:45:41 +0100 Subject: QStyleHelper::uniqueName(): Improve palette pixmap cache key Use QDataStream to obtain cache key for a palettes that are different from the default QPalette. This results in unique keys for palettes created from QStyleSheetStyle's render rules. Task-number: QTBUG-56743 Change-Id: Icbfe165f705ef3e1c9e88cfc9dca88ff1d1e81e6 Reviewed-by: Andy Shaw --- src/widgets/styles/qstylehelper.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index 6602b58a9d..960695e9df 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -43,6 +43,8 @@ #include "qstylehelper_p.h" #include +#include +#include QT_BEGIN_NAMESPACE @@ -56,7 +58,6 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize & QString tmp = key % HexString(option->state) % HexString(option->direction) % HexString(complexOption ? uint(complexOption->activeSubControls) : 0u) - % HexString(option->palette.cacheKey()) % HexString(size.width()) % HexString(size.height()); @@ -67,6 +68,25 @@ QString uniqueName(const QString &key, const QStyleOption *option, const QSize & % QLatin1Char(spinBox->frame ? '1' : '0'); ; } #endif // QT_NO_SPINBOX + + // QTBUG-56743, try to create a palette cache key reflecting the value, + // as leaks may occur in conjunction with QStyleSheetStyle/QRenderRule modifying + // palettes when using QPalette::cacheKey() + if (option->palette != QGuiApplication::palette()) { + tmp.append(QLatin1Char('P')); +#ifndef QT_NO_DATASTREAM + QByteArray key; + key.reserve(5120); // Observed 5040B for a serialized palette on 64bit + { + QDataStream str(&key, QIODevice::WriteOnly); + str << option->palette; + } + const QByteArray sha1 = QCryptographicHash::hash(key, QCryptographicHash::Sha1).toHex(); + tmp.append(QString::fromLatin1(sha1)); +#else // QT_NO_DATASTREAM + tmp.append(QString::number(option->palette.cacheKey(), 16)); +#endif // !QT_NO_DATASTREAM + } return tmp; } -- cgit v1.2.1 From aa7e764058cb820c86341c91360976b6bddfd4da Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 4 Nov 2016 12:38:50 +0100 Subject: MinGW: Explicitly define NTDDI_VERSION Define NTDDI_VERSION, just like _WIN32_WINNT, to be Windows Vista. Usually NTDDI_VERSION is automatically set by MinGW headers to the value that matches _WIN32_WINNT. However, for precompiled headers the inclusion order is that _WIN32_WINNT is set _after_ the relevant MinGW header is parsed, so this can fail. The alternative would be to set _WIN32_WINNT via a compiler flag, e.g. in the mkspecs. Change-Id: Id59e7083f0d3e00491b54e87647c6c9fabb99795 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/global/qt_windows.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/global/qt_windows.h b/src/corelib/global/qt_windows.h index 7b95501c08..bc48104edc 100644 --- a/src/corelib/global/qt_windows.h +++ b/src/corelib/global/qt_windows.h @@ -53,6 +53,9 @@ # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x600 # endif +# ifndef NTDDI_VERSION +# define NTDDI_VERSION 0x06000000 +# endif #endif #ifndef NOMINMAX -- cgit v1.2.1 From aa73a7026fd8093a340b20dacba7b10e5ffa03ac Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 2 Nov 2016 13:58:54 +0100 Subject: QStandardPaths: Replace deprecated Win32 SHGetSpecialFolderPath SHGetSpecialFolderPath is declared 'unsupported' by Microsoft, and has problems with non-ASCII characters. Replace it by the newer SHGetKnownFolderPath. To fix compilation with MinGW, we have to link in libuuid also in the bootstrapped tools. The alternative is redefining all GUID's (like we did for FOLDERID_Downloads), which is arguably less elegant. Task-number: QTBUG-50570 Change-Id: If99be559bc72de3734ae1fa4d50f960659739898 Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- src/corelib/io/qstandardpaths_win.cpp | 77 ++++++++++++----------------------- src/tools/bootstrap/bootstrap.pro | 5 ++- 2 files changed, 31 insertions(+), 51 deletions(-) diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 38c63553ea..94beed0c1f 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -47,17 +47,10 @@ #include #endif -const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; - #include #include #include -#ifndef CSIDL_MYMUSIC -#define CSIDL_MYMUSIC 13 -#define CSIDL_MYVIDEO 14 -#endif - #ifndef QT_NO_STANDARDPATHS QT_BEGIN_NAMESPACE @@ -108,47 +101,31 @@ static inline void appendTestMode(QString &path) path += QLatin1String("/qttest"); } -// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath() -static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) +// Map QStandardPaths::StandardLocation to KNOWNFOLDERID of SHGetKnownFolderPath() +static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type) { - static const int clsids[] = { - CSIDL_DESKTOPDIRECTORY, // DesktopLocation - CSIDL_PERSONAL, // DocumentsLocation - CSIDL_FONTS, // FontsLocation - CSIDL_PROGRAMS, // ApplicationsLocation - CSIDL_MYMUSIC, // MusicLocation - CSIDL_MYVIDEO, // MoviesLocation - CSIDL_MYPICTURES, // PicturesLocation - -1, -1, // TempLocation/HomeLocation - CSIDL_LOCAL_APPDATA, // AppLocalDataLocation ("Local" path), AppLocalDataLocation = DataLocation - -1, // CacheLocation - CSIDL_LOCAL_APPDATA, // GenericDataLocation ("Local" path) - -1, // RuntimeLocation - CSIDL_LOCAL_APPDATA, // ConfigLocation ("Local" path) - -1, -1, // DownloadLocation/GenericCacheLocation - CSIDL_LOCAL_APPDATA, // GenericConfigLocation ("Local" path) - CSIDL_APPDATA, // AppDataLocation ("Roaming" path) - CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path) + static const GUID folderIds[] = { + FOLDERID_Desktop, // DesktopLocation + FOLDERID_Documents, // DocumentsLocation + FOLDERID_Fonts, // FontsLocation + FOLDERID_Programs, // ApplicationsLocation + FOLDERID_Music, // MusicLocation + FOLDERID_Videos, // MoviesLocation + FOLDERID_Pictures, // PicturesLocation + GUID(), GUID(), // TempLocation/HomeLocation + FOLDERID_LocalAppData, // AppLocalDataLocation ("Local" path), AppLocalDataLocation = DataLocation + GUID(), // CacheLocation + FOLDERID_LocalAppData, // GenericDataLocation ("Local" path) + GUID(), // RuntimeLocation + FOLDERID_LocalAppData, // ConfigLocation ("Local" path) + GUID(), GUID(), // DownloadLocation/GenericCacheLocation + FOLDERID_LocalAppData, // GenericConfigLocation ("Local" path) + FOLDERID_RoamingAppData,// AppDataLocation ("Roaming" path) + FOLDERID_LocalAppData, // AppConfigLocation ("Local" path) }; - Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); - return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1; -}; - -// Convenience for SHGetSpecialFolderPath(). -static QString sHGetSpecialFolderPath(int clsid, QStandardPaths::StandardLocation type, bool warn = false) -{ - QString result; - wchar_t path[MAX_PATH]; - if (Q_LIKELY(clsid >= 0 && SHGetSpecialFolderPath(0, path, clsid, FALSE))) { - result = convertCharArray(path); - } else { - if (warn) { - qErrnoWarning("SHGetSpecialFolderPath() failed for standard location \"%s\", clsid=0x%x.", - qPrintable(displayName(type)), clsid); - } - } - return result; + Q_STATIC_ASSERT(sizeof(folderIds) / sizeof(folderIds[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); + return size_t(type) < sizeof(folderIds) / sizeof(folderIds[0]) ? folderIds[type] : GUID(); } // Convenience for SHGetKnownFolderPath(). @@ -178,7 +155,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) QString result; switch (type) { case DownloadLocation: - result = sHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, type); + result = sHGetKnownFolderPath(FOLDERID_Downloads, type); if (result.isEmpty()) result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); break; @@ -187,7 +164,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache // location for everyone. Most applications seem to be using a // cache directory located in their AppData directory - result = sHGetSpecialFolderPath(writableSpecialFolderClsid(AppLocalDataLocation), type, /* warn */ true); + result = sHGetKnownFolderPath(writableSpecialFolderId(AppLocalDataLocation), type, /* warn */ true); if (!result.isEmpty()) { appendTestMode(result); appendOrganizationAndApp(result); @@ -196,7 +173,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) break; case GenericCacheLocation: - result = sHGetSpecialFolderPath(writableSpecialFolderClsid(GenericDataLocation), type, /* warn */ true); + result = sHGetKnownFolderPath(writableSpecialFolderId(GenericDataLocation), type, /* warn */ true); if (!result.isEmpty()) { appendTestMode(result); result += QLatin1String("/cache"); @@ -213,7 +190,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) break; default: - result = sHGetSpecialFolderPath(writableSpecialFolderClsid(type), type, /* warn */ isConfigLocation(type)); + result = sHGetKnownFolderPath(writableSpecialFolderId(type), type, /* warn */ isConfigLocation(type)); if (!result.isEmpty() && isConfigLocation(type)) { appendTestMode(result); if (!isGenericConfigLocation(type)) @@ -233,7 +210,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) // type-specific handling goes here if (isConfigLocation(type)) { - QString programData = sHGetSpecialFolderPath(CSIDL_COMMON_APPDATA, type); + QString programData = sHGetKnownFolderPath(FOLDERID_ProgramData, type); if (!programData.isEmpty()) { if (!isGenericConfigLocation(type)) appendOrganizationAndApp(programData); diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 0e0a617f2b..d51f9e98a4 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -134,7 +134,10 @@ macx { include(../../3rdparty/zlib_dependency.pri) } -win32:LIBS += -luser32 -lole32 -ladvapi32 -lshell32 +win32 { + LIBS += -luser32 -lole32 -ladvapi32 -lshell32 + mingw: LIBS += -luuid +} load(qt_module) -- cgit v1.2.1 From b5fa247102c610d8ed4c1d88a7f1ea685b96c91f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 3 Nov 2016 11:17:14 +0100 Subject: QStandardPaths: Do not check whether path exists (Windows) It's arguably better to return a non-existing location than no location at all. This makes it in line with the documentation for e.g. QStandardPaths::writableLocation that says Note: The storage location returned can be a directory that does not exist; i.e., it may need to be created by the system or the user. Finally, this was also the behavior of code that used SHGetSpecialFolderPath before. Change-Id: I5ee44747a38434535610e45a4d303b36ef79d42a Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- src/corelib/io/qstandardpaths_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 94beed0c1f..a64bde6fb4 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -138,7 +138,7 @@ static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardL reinterpret_cast(QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath")); LPWSTR path; - if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, 0, 0, &path)))) { + if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, KF_FLAG_DONT_VERIFY, 0, &path)))) { result = convertCharArray(path); CoTaskMemFree(path); } else { -- cgit v1.2.1 From ed7f77071dcca996a8c8147fd66344090666e60c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 5 Aug 2016 10:12:12 +0200 Subject: Replace custom type traits with std one's Remove most type traits from qtypetraits.h, but keep the custom implementation of is_signed/is_unsigned. This gets rid of BSD-3 licensed code from Google in a public header (hugh!). The custom implementations for is_signed/is_unsigned are kept because the implementations in gcc's standard headers do not work as we expect for enums - both is_signed and is_unsigned always returns false there - see also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59027 [ChangeLog][QtCore][General] Qt now relies on type traits from the C++ standard library. Change-Id: I3f2188b46949f04ca4482a6ac9afd3482103f0e1 Reviewed-by: Thiago Macieira --- src/corelib/global/qflags.h | 2 +- src/corelib/global/qglobal.h | 3 +- src/corelib/global/qisenum.h | 3 +- src/corelib/global/qnumeric_p.h | 4 +- src/corelib/global/qtypeinfo.h | 7 +- src/corelib/global/qtypetraits.h | 450 +-------------------- src/corelib/kernel/qmetatype.h | 9 +- src/corelib/kernel/qobject.h | 12 +- src/corelib/kernel/qpointer.h | 2 +- src/corelib/kernel/qtimer.h | 8 +- src/corelib/kernel/qvariant_p.h | 10 +- src/corelib/thread/qmutex.cpp | 3 +- src/corelib/tools/qbytearray_p.h | 3 +- src/corelib/tools/qhash.h | 2 +- src/corelib/tools/qlist.h | 4 +- src/corelib/tools/qmap.h | 7 +- src/corelib/tools/qsharedpointer_impl.h | 2 +- src/corelib/tools/qstringalgorithms_p.h | 4 +- src/testlib/qtestcase.h | 3 +- src/widgets/graphicsview/qgraphicsitem.h | 4 +- src/widgets/styles/qstyleoption.h | 8 +- src/widgets/widgets/qmenu.h | 4 +- src/widgets/widgets/qtoolbar.h | 4 +- tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 5 +- .../tools/qhashfunctions/tst_qhashfunctions.cpp | 3 +- 25 files changed, 58 insertions(+), 508 deletions(-) diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index a6bd37c33f..f85fc705b4 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -102,7 +102,7 @@ public: // the definition below is too complex for qdoc typedef int Int; #else - typedef typename QtPrivate::if_< + typedef typename std::conditional< QtPrivate::is_unsigned::value, unsigned int, signed int diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 1bcd30e0b3..99be82f8c3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -42,6 +42,7 @@ #define QGLOBAL_H #ifdef __cplusplus +# include # include #endif @@ -963,7 +964,7 @@ public: // - if there was a break inside the inner loop, it will exit with control still // set to 1; in that case, the outer loop will invert it to 0 and will exit too #define Q_FOREACH(variable, container) \ -for (QForeachContainer::type> _container_((container)); \ +for (QForeachContainer::type> _container_((container)); \ _container_.control && _container_.i != _container_.e; \ ++_container_.i, _container_.control ^= 1) \ for (variable = *_container_.i; _container_.control; _container_.control = 0) diff --git a/src/corelib/global/qisenum.h b/src/corelib/global/qisenum.h index 0a4d44619c..185db5e45f 100644 --- a/src/corelib/global/qisenum.h +++ b/src/corelib/global/qisenum.h @@ -55,8 +55,7 @@ #endif #ifndef Q_IS_ENUM -# include -# define Q_IS_ENUM(x) QtPrivate::is_enum::value +# define Q_IS_ENUM(x) std::is_enum::value #endif // shut up syncqt diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index ef40a45dc4..23fcf340f1 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -172,7 +172,7 @@ static inline bool qt_is_finite(float f) // Unsigned overflow math // namespace { -template inline typename QtPrivate::QEnableIf::value, bool>::Type +template inline typename QtPrivate::QEnableIf::value, bool>::Type add_overflow(T v1, T v2, T *r) { // unsigned additions are well-defined @@ -180,7 +180,7 @@ add_overflow(T v1, T v2, T *r) return v1 > T(v1 + v2); } -template inline typename QtPrivate::QEnableIf::value, bool>::Type +template inline typename QtPrivate::QEnableIf::value, bool>::Type mul_overflow(T v1, T v2, T *r) { // use the next biggest type diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index e709050011..cdc85ab1d0 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -38,12 +38,13 @@ ** ****************************************************************************/ -#include #include #ifndef QTYPEINFO_H #define QTYPEINFO_H +#include + QT_BEGIN_NAMESPACE /* @@ -60,7 +61,7 @@ class QTypeInfo public: enum { isPointer = false, - isIntegral = QtPrivate::is_integral::value, + isIntegral = std::is_integral::value, isComplex = true, isStatic = true, isRelocatable = Q_IS_ENUM(T), @@ -247,7 +248,7 @@ public: \ isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \ isLarge = (sizeof(TYPE)>sizeof(void*)), \ isPointer = false, \ - isIntegral = QtPrivate::is_integral< TYPE >::value, \ + isIntegral = std::is_integral< TYPE >::value, \ isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0), \ sizeOf = sizeof(TYPE) \ }; \ diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index c311303e27..b664dd3a3e 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -37,451 +37,28 @@ ** ****************************************************************************/ -// BEGIN Google Code - -// Copyright (c) 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// ---- -// -// This code is compiled directly on many platforms, including client -// platforms like Windows, Mac, and embedded systems. Before making -// any changes here, make sure that you're not breaking any platforms. -// -// Define a small subset of tr1 type traits. The traits we define are: -// is_integral -// is_floating_point -// is_pointer -// is_enum -// is_reference -// is_const -// is_volatile -// is_pod -// has_trivial_constructor -// has_trivial_copy -// has_trivial_assign -// has_trivial_destructor -// is_signed -// is_unsigned -// remove_const -// remove_volatile -// remove_cv -// remove_reference -// add_reference -// remove_pointer -// is_same -// is_convertible -// We can add more type traits as required. - -// Changes from the original implementation: -// - Move base types from template_util.h directly into this header. -// - Use Qt macros for long long type differences on Windows. -// - Enclose in QtPrivate namespace. - #include "QtCore/qglobal.h" #ifndef QTYPETRAITS_H #define QTYPETRAITS_H -#include // For pair - QT_BEGIN_NAMESPACE namespace QtPrivate { -// Types small_ and big_ are guaranteed such that sizeof(small_) < -// sizeof(big_) -typedef char small_; - -struct big_ { - char dummy[2]; -}; - -// Identity metafunction. -template -struct identity_ { - typedef T type; -}; - -// integral_constant, defined in tr1, is a wrapper for an integer -// value. We don't really need this generality; we could get away -// with hardcoding the integer type to bool. We use the fully -// general integer_constant for compatibility with tr1. - -template -struct integral_constant { - static const T value = v; - typedef T value_type; - typedef integral_constant type; -}; - -template const T integral_constant::value; - - -// Abbreviations: true_type and false_type are structs that represent boolean -// true and false values. Also define the boost::mpl versions of those names, -// true_ and false_. -typedef integral_constant true_type; -typedef integral_constant false_type; -typedef true_type true_; -typedef false_type false_; - -// if_ is a templatized conditional statement. -// if_ is a compile time evaluation of cond. -// if_<>::type contains A if cond is true, B otherwise. -template -struct if_{ - typedef A type; -}; - -template -struct if_ { - typedef B type; -}; - - -// type_equals_ is a template type comparator, similar to Loki IsSameType. -// type_equals_::value is true iff "A" is the same type as "B". // -// New code should prefer base::is_same, defined in base/type_traits.h. -// It is functionally identical, but is_same is the standard spelling. -template -struct type_equals_ : public false_ { -}; - -template -struct type_equals_ : public true_ { -}; - -// and_ is a template && operator. -// and_::value evaluates "A::value && B::value". -template -struct and_ : public integral_constant { -}; - -// or_ is a template || operator. -// or_::value evaluates "A::value || B::value". -template -struct or_ : public integral_constant { -}; - -template struct is_integral; -template struct is_floating_point; -template struct is_pointer; -// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) -// is_enum uses is_convertible, which is not available on MSVC. -template struct is_enum; -#endif -template struct is_reference; -template struct is_pod; -template struct has_trivial_constructor; -template struct has_trivial_copy; -template struct has_trivial_assign; -template struct has_trivial_destructor; -template struct remove_const; -template struct remove_volatile; -template struct remove_cv; -template struct remove_reference; -template struct add_reference; -template struct remove_pointer; -template struct is_same; -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) -template struct is_convertible; -#endif - -// is_integral is false except for the built-in integer types. A -// cv-qualified type is integral if and only if the underlying type is. -template struct is_integral : false_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -#if defined(_MSC_VER) -// wchar_t is not by default a distinct type from unsigned short in -// Microsoft C. -// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx -template<> struct is_integral<__wchar_t> : true_type { }; -#else -template<> struct is_integral : true_type { }; -#endif -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -#if defined(Q_OS_WIN) && !defined(Q_CC_GNU) -template<> struct is_integral<__int64> : true_type { }; -template<> struct is_integral : true_type { }; -#else -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -#endif -template struct is_integral : is_integral { }; -template struct is_integral : is_integral { }; -template struct is_integral : is_integral { }; -#if defined (Q_COMPILER_UNICODE_STRINGS) -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -#endif - -// is_floating_point is false except for the built-in floating-point types. -// A cv-qualified type is integral if and only if the underlying type is. -template struct is_floating_point : false_type { }; -template<> struct is_floating_point : true_type { }; -template<> struct is_floating_point : true_type { }; -template<> struct is_floating_point : true_type { }; -template struct is_floating_point - : is_floating_point { }; -template struct is_floating_point - : is_floating_point { }; -template struct is_floating_point - : is_floating_point { }; - -// is_pointer is false except for pointer types. A cv-qualified type (e.g. -// "int* const", as opposed to "int const*") is cv-qualified if and only if -// the underlying type is. -template struct is_pointer : false_type { }; -template struct is_pointer : true_type { }; -template struct is_pointer : is_pointer { }; -template struct is_pointer : is_pointer { }; -template struct is_pointer : is_pointer { }; - -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) - -namespace internal { - -template struct is_class_or_union { - template static small_ tester(void (U::*)()); - template static big_ tester(...); - static const bool value = sizeof(tester(0)) == sizeof(small_); -}; - -// is_convertible chokes if the first argument is an array. That's why -// we use add_reference here. -template struct is_enum_impl - : is_convertible::type, int> { }; - -template struct is_enum_impl : false_type { }; - -} // namespace internal - -// Specified by TR1 [4.5.1] primary type categories. - -// Implementation note: +// define custom is_signed, is_unsigned that also works with enum's // -// Each type is either void, integral, floating point, array, pointer, -// reference, member object pointer, member function pointer, enum, -// union or class. Out of these, only integral, floating point, reference, -// class and enum types are potentially convertible to int. Therefore, -// if a type is not a reference, integral, floating point or class and -// is convertible to int, it's a enum. Adding cv-qualification to a type -// does not change whether it's an enum. -// -// Is-convertible-to-int check is done only if all other checks pass, -// because it can't be used with some types (e.g. void or classes with -// inaccessible conversion operators). -template struct is_enum - : internal::is_enum_impl< - is_same::value || - is_integral::value || - is_floating_point::value || - is_reference::value || - internal::is_class_or_union::value, - T> { }; - -template struct is_enum : is_enum { }; -template struct is_enum : is_enum { }; -template struct is_enum : is_enum { }; - -#endif - -// is_reference is false except for reference types. -template struct is_reference : false_type {}; -template struct is_reference : true_type {}; - -// Specified by TR1 [4.5.3] Type Properties -template struct is_const : false_type {}; -template struct is_const : true_type {}; -template struct is_volatile : false_type {}; -template struct is_volatile : true_type {}; - -// We can't get is_pod right without compiler help, so fail conservatively. -// We will assume it's false except for arithmetic types, enumerations, -// pointers and cv-qualified versions thereof. Note that std::pair -// is not a POD even if T and U are PODs. -template struct is_pod - : integral_constant::value || - is_floating_point::value || -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) - // is_enum is not available on MSVC. - is_enum::value || -#endif - is_pointer::value)> { }; -template struct is_pod : is_pod { }; -template struct is_pod : is_pod { }; -template struct is_pod : is_pod { }; - - -// We can't get has_trivial_constructor right without compiler help, so -// fail conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial -// constructors. (3) array of a type with a trivial constructor. -// (4) const versions thereof. -template struct has_trivial_constructor : is_pod { }; -template struct has_trivial_constructor > - : integral_constant::value && - has_trivial_constructor::value)> { }; -template struct has_trivial_constructor - : has_trivial_constructor { }; -template struct has_trivial_constructor - : has_trivial_constructor { }; - -// We can't get has_trivial_copy right without compiler help, so fail -// conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial copy -// constructors. (3) array of a type with a trivial copy constructor. -// (4) const versions thereof. -template struct has_trivial_copy : is_pod { }; -template struct has_trivial_copy > - : integral_constant::value && - has_trivial_copy::value)> { }; -template struct has_trivial_copy - : has_trivial_copy { }; -template struct has_trivial_copy : has_trivial_copy { }; - -// We can't get has_trivial_assign right without compiler help, so fail -// conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial copy -// constructors. (3) array of a type with a trivial assign constructor. -template struct has_trivial_assign : is_pod { }; -template struct has_trivial_assign > - : integral_constant::value && - has_trivial_assign::value)> { }; -template struct has_trivial_assign - : has_trivial_assign { }; - -// We can't get has_trivial_destructor right without compiler help, so -// fail conservatively. We will assume it's false except for: (1) types -// for which is_pod is true. (2) std::pair of types with trivial -// destructors. (3) array of a type with a trivial destructor. -// (4) const versions thereof. -template struct has_trivial_destructor : is_pod { }; -template struct has_trivial_destructor > - : integral_constant::value && - has_trivial_destructor::value)> { }; -template struct has_trivial_destructor - : has_trivial_destructor { }; -template struct has_trivial_destructor - : has_trivial_destructor { }; - -// Specified by TR1 [4.7.1] -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type; }; -template struct remove_volatile { typedef T type; }; -template struct remove_volatile { typedef T type; }; -template struct remove_cv { - typedef typename remove_const::type>::type type; -}; - - -// Specified by TR1 [4.7.2] Reference modifications. -template struct remove_reference { typedef T type; }; -template struct remove_reference { typedef T type; }; - -template struct add_reference { typedef T& type; }; -template struct add_reference { typedef T& type; }; - -// Specified by TR1 [4.7.4] Pointer modifications. -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { - typedef T type; }; - -// Specified by TR1 [4.6] Relationships between types -template struct is_same : public false_type { }; -template struct is_same : public true_type { }; - -// Specified by TR1 [4.6] Relationships between types -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) -namespace internal { - -// This class is an implementation detail for is_convertible, and you -// don't need to know how it works to use is_convertible. For those -// who care: we declare two different functions, one whose argument is -// of type To and one with a variadic argument list. We give them -// return types of different size, so we can use sizeof to trick the -// compiler into telling us which function it would have chosen if we -// had called it with an argument of type From. See Alexandrescu's -// _Modern C++ Design_ for more details on this sort of trick. - -template -struct ConvertHelper { - static small_ Test(To); - static big_ Test(...); - static From Create(); -}; -} // namespace internal - -// Inherits from true_type if From is convertible to To, false_type otherwise. -template -struct is_convertible - : integral_constant::Test( - internal::ConvertHelper::Create())) - == sizeof(small_)> { -}; -#endif - -// END Google Code // a metafunction to invert an integral_constant: template struct not_ - : integral_constant {}; - -// same, with a bool argument: -template -struct not_c - : integral_constant {}; + : std::integral_constant {}; // Checks whether a type is unsigned (T must be convertible to unsigned int): template struct is_unsigned - : integral_constant {}; + : std::integral_constant {}; // Checks whether a type is signed (T must be convertible to int): template @@ -512,27 +89,6 @@ Q_STATIC_ASSERT((!is_unsigned::value)); Q_STATIC_ASSERT((!is_signed::value)); Q_STATIC_ASSERT(( is_signed::value)); -template struct is_default_constructible; - -template<> struct is_default_constructible -{ -protected: - template struct test { typedef char type; }; -public: - static bool const value = false; -}; -template<> struct is_default_constructible<>::test { typedef double type; }; - -template struct is_default_constructible : is_default_constructible<> -{ -private: - template static typename test::type sfinae(U*); - template static char sfinae(...); -public: - static bool const value = sizeof(sfinae(0)) > 1; -}; - - } // namespace QtPrivate QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 9e2a5bf75d..29e60b0eb5 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -46,7 +46,6 @@ #include #include #include -#include #ifndef QT_NO_QOBJECT #include #endif @@ -887,7 +886,7 @@ private: // is void* to avoid overloads conflicts. We do it by injecting unaccessible Dummy // type as part of the overload signature. struct Dummy {}; - typedef typename QtPrivate::if_::value, Dummy, value_type>::type value_type_OR_Dummy; + typedef typename std::conditional::value, Dummy, value_type>::type value_type_OR_Dummy; public: static void assign(void **ptr, const value_type_OR_Dummy *iterator ) { @@ -1092,7 +1091,7 @@ struct QSequentialIterableConvertFunctor } namespace QtMetaTypePrivate { -template::value> +template::value> struct AssociativeContainerAccessor { static const typename T::key_type& getKey(const typename T::const_iterator &it) @@ -1106,7 +1105,7 @@ struct AssociativeContainerAccessor } }; -template >::value> +template >::value> struct StlStyleAssociativeContainerAccessor; template @@ -1787,7 +1786,7 @@ template struct QMetaTypeIdQObject { enum { - Defined = QtPrivate::is_default_constructible::value + Defined = std::is_default_constructible::value }; static int qt_metatype_id() diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 3cec9802dc..69b70ad6ec 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -155,14 +155,14 @@ public: template inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { - typedef typename QtPrivate::remove_cv::type>::type ObjType; + typedef typename std::remove_cv::type>::type ObjType; return static_cast(qt_qFindChild_helper(this, aName, ObjType::staticMetaObject, options)); } template inline QList findChildren(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { - typedef typename QtPrivate::remove_cv::type>::type ObjType; + typedef typename std::remove_cv::type>::type ObjType; QList list; qt_qFindChildren_helper(this, aName, ObjType::staticMetaObject, reinterpret_cast *>(&list), options); @@ -173,7 +173,7 @@ public: template inline QList findChildren(const QRegExp &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { - typedef typename QtPrivate::remove_cv::type>::type ObjType; + typedef typename std::remove_cv::type>::type ObjType; QList list; qt_qFindChildren_helper(this, re, ObjType::staticMetaObject, reinterpret_cast *>(&list), options); @@ -185,7 +185,7 @@ public: template inline QList findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { - typedef typename QtPrivate::remove_cv::type>::type ObjType; + typedef typename std::remove_cv::type>::type ObjType; QList list; qt_qFindChildren_helper(this, re, ObjType::staticMetaObject, reinterpret_cast *>(&list), options); @@ -493,7 +493,7 @@ inline QT_DEPRECATED QList qFindChildren(const QObject *o, const QRegExp &re) template inline T qobject_cast(QObject *object) { - typedef typename QtPrivate::remove_cv::type>::type ObjType; + typedef typename std::remove_cv::type>::type ObjType; Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro::Value, "qobject_cast requires the type to have a Q_OBJECT macro"); return static_cast(ObjType::staticMetaObject.cast(object)); @@ -502,7 +502,7 @@ inline T qobject_cast(QObject *object) template inline T qobject_cast(const QObject *object) { - typedef typename QtPrivate::remove_cv::type>::type ObjType; + typedef typename std::remove_cv::type>::type ObjType; Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro::Value, "qobject_cast requires the type to have a Q_OBJECT macro"); return static_cast(ObjType::staticMetaObject.cast(object)); diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index b5c17ad394..b2b3cda4ab 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -52,7 +52,7 @@ class QVariant; template class QPointer { - Q_STATIC_ASSERT_X(!QtPrivate::is_pointer::value, "QPointer's template type must not be a pointer type"); + Q_STATIC_ASSERT_X(!std::is_pointer::value, "QPointer's template type must not be a pointer type"); template struct TypeSelector diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 4f934d0367..96c7efd8f5 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -119,14 +119,14 @@ public: // singleShot to a functor or function pointer (without context) template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && - !QtPrivate::is_same::value, void>::Type + !std::is_same::value, void>::Type singleShot(Duration interval, Func1 slot) { singleShot(interval, defaultTypeFor(interval), nullptr, slot); } template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && - !QtPrivate::is_same::value, void>::Type + !std::is_same::value, void>::Type singleShot(Duration interval, Qt::TimerType timerType, Func1 slot) { singleShot(interval, timerType, nullptr, slot); @@ -134,14 +134,14 @@ public: // singleShot to a functor or function pointer (with context) template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && - !QtPrivate::is_same::value, void>::Type + !std::is_same::value, void>::Type singleShot(Duration interval, QObject *context, Func1 slot) { singleShot(interval, defaultTypeFor(interval), context, slot); } template static inline typename QtPrivate::QEnableIf::IsPointerToMemberFunction && - !QtPrivate::is_same::value, void>::Type + !std::is_same::value, void>::Type singleShot(Duration interval, Qt::TimerType timerType, QObject *context, Func1 slot) { //compilation error if the slot has arguments. diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index d01f386032..ec87e20656 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -66,7 +66,7 @@ struct QVariantIntegrator { static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data) && ((QTypeInfoQuery::isRelocatable) || Q_IS_ENUM(T)); - typedef QtPrivate::integral_constant CanUseInternalSpace_t; + typedef std::integral_constant CanUseInternalSpace_t; }; Q_STATIC_ASSERT(QVariantIntegrator::CanUseInternalSpace); Q_STATIC_ASSERT(QVariantIntegrator::CanUseInternalSpace); @@ -118,28 +118,28 @@ private: }; template -inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::true_type) +inline void v_construct_helper(QVariant::Private *x, const T &t, std::true_type) { new (&x->data) T(t); x->is_shared = false; } template -inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::false_type) +inline void v_construct_helper(QVariant::Private *x, const T &t, std::false_type) { x->data.shared = new QVariantPrivateSharedEx(t); x->is_shared = true; } template -inline void v_construct_helper(QVariant::Private *x, QtPrivate::true_type) +inline void v_construct_helper(QVariant::Private *x, std::true_type) { new (&x->data) T(); x->is_shared = false; } template -inline void v_construct_helper(QVariant::Private *x, QtPrivate::false_type) +inline void v_construct_helper(QVariant::Private *x, std::false_type) { x->data.shared = new QVariantPrivateSharedEx; x->is_shared = true; diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 366413e82e..6e0fa4eedb 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -48,7 +48,6 @@ #include "qelapsedtimer.h" #include "qthread.h" #include "qmutex_p.h" -#include "qtypetraits.h" #ifndef QT_LINUX_FUTEX #include "private/qfreelist_p.h" @@ -77,7 +76,7 @@ public: // written to by the thread that first owns 'mutex'; // read during attempts to acquire ownership of 'mutex' from any other thread: - QAtomicPointer::type> owner; + QAtomicPointer::type> owner; // only ever accessed from the thread that owns 'mutex': uint count; diff --git a/src/corelib/tools/qbytearray_p.h b/src/corelib/tools/qbytearray_p.h index 0824611d99..6ebff739cd 100644 --- a/src/corelib/tools/qbytearray_p.h +++ b/src/corelib/tools/qbytearray_p.h @@ -52,14 +52,13 @@ // #include -#include #include "qtools_p.h" QT_BEGIN_NAMESPACE enum { // Define as enum to force inlining. Don't expose MaxAllocSize in a public header. - MaxByteArraySize = MaxAllocSize - sizeof(QtPrivate::remove_pointer::type) + MaxByteArraySize = MaxAllocSize - sizeof(std::remove_pointer::type) }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 6a2d7bdd11..d58c3c5733 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -764,7 +764,7 @@ Q_INLINE_TEMPLATE typename QHash::iterator QHash::insert(const K return iterator(createNode(h, akey, avalue, node)); } - if (!QtPrivate::is_same::value) + if (!std::is_same::value) (*node)->value = avalue; return iterator(*node); } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index c7f27abdd6..c0a92aaa10 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -125,10 +125,10 @@ class QList { public: struct MemoryLayout - : QtPrivate::if_< + : std::conditional< QTypeInfo::isStatic || QTypeInfo::isLarge, QListData::IndirectLayout, - typename QtPrivate::if_< + typename std::conditional< sizeof(T) == sizeof(void*), QListData::ArrayCompatibleLayout, QListData::InlineWithPaddingLayout diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index baa10b7a95..96ce787446 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -44,7 +44,6 @@ #include #include #include -#include #ifdef Q_MAP_DEBUG #include @@ -130,15 +129,15 @@ struct QMapNode : public QMapNodeBase { callDestructorIfNecessary(key); callDestructorIfNecessary(value); - doDestroySubTree(QtPrivate::integral_constant::isComplex || QTypeInfo::isComplex>()); + doDestroySubTree(std::integral_constant::isComplex || QTypeInfo::isComplex>()); } QMapNode *lowerBound(const Key &key); QMapNode *upperBound(const Key &key); private: - void doDestroySubTree(QtPrivate::false_type) {} - void doDestroySubTree(QtPrivate::true_type) + void doDestroySubTree(std::false_type) {} + void doDestroySubTree(std::true_type) { if (left) leftNode()->destroySubTree(); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index a0c22c9179..5738413bfb 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -464,7 +464,7 @@ private: template inline void enableSharedFromThis(const QEnableSharedFromThis *ptr) { - ptr->initializeFromSharedPointer(constCast::type>()); + ptr->initializeFromSharedPointer(constCast::type>()); } inline void enableSharedFromThis(...) {} diff --git a/src/corelib/tools/qstringalgorithms_p.h b/src/corelib/tools/qstringalgorithms_p.h index d7127517e0..c5470bc7ad 100644 --- a/src/corelib/tools/qstringalgorithms_p.h +++ b/src/corelib/tools/qstringalgorithms_p.h @@ -60,8 +60,8 @@ template struct QStringAlgorithms { typedef typename StringType::value_type Char; typedef typename StringType::size_type size_type; - typedef typename QtPrivate::remove_cv::type NakedStringType; - static const bool isConst = QtPrivate::is_const::value; + typedef typename std::remove_cv::type NakedStringType; + static const bool isConst = std::is_const::value; static inline bool isSpace(char ch) { return ascii_isspace(ch); } static inline bool isSpace(QChar ch) { return ch.isSpace(); } diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 045431fcaf..c3ccfc3f8c 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -312,7 +311,7 @@ namespace QTest template inline void addColumn(const char *name, T * = 0) { - typedef QtPrivate::is_same QIsSameTConstChar; + typedef std::is_same QIsSameTConstChar; Q_STATIC_ASSERT_X(!QIsSameTConstChar::value, "const char* is not allowed as a test data format."); addColumnInternal(qMetaTypeId(), name); } diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h index 59656f5b0b..36f8aac124 100644 --- a/src/widgets/graphicsview/qgraphicsitem.h +++ b/src/widgets/graphicsview/qgraphicsitem.h @@ -1024,14 +1024,14 @@ private: template inline T qgraphicsitem_cast(QGraphicsItem *item) { - typedef typename QtPrivate::remove_cv::type>::type Item; + typedef typename std::remove_cv::type>::type Item; return int(Item::Type) == int(QGraphicsItem::Type) || (item && int(Item::Type) == item->type()) ? static_cast(item) : 0; } template inline T qgraphicsitem_cast(const QGraphicsItem *item) { - typedef typename QtPrivate::remove_cv::type>::type Item; + typedef typename std::remove_cv::type>::type Item; return int(Item::Type) == int(QGraphicsItem::Type) || (item && int(Item::Type) == item->type()) ? static_cast(item) : 0; } diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h index 9679411402..0e76d53eea 100644 --- a/src/widgets/styles/qstyleoption.h +++ b/src/widgets/styles/qstyleoption.h @@ -665,7 +665,7 @@ protected: template T qstyleoption_cast(const QStyleOption *opt) { - typedef typename QtPrivate::remove_cv::type>::type Opt; + typedef typename std::remove_cv::type>::type Opt; if (opt && opt->version >= Opt::Version && (opt->type == Opt::Type || int(Opt::Type) == QStyleOption::SO_Default || (int(Opt::Type) == QStyleOption::SO_Complex @@ -677,7 +677,7 @@ T qstyleoption_cast(const QStyleOption *opt) template T qstyleoption_cast(QStyleOption *opt) { - typedef typename QtPrivate::remove_cv::type>::type Opt; + typedef typename std::remove_cv::type>::type Opt; if (opt && opt->version >= Opt::Version && (opt->type == Opt::Type || int(Opt::Type) == QStyleOption::SO_Default || (int(Opt::Type) == QStyleOption::SO_Complex @@ -728,7 +728,7 @@ public: template T qstyleoption_cast(const QStyleHintReturn *hint) { - typedef typename QtPrivate::remove_cv::type>::type Opt; + typedef typename std::remove_cv::type>::type Opt; if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast(hint); @@ -738,7 +738,7 @@ T qstyleoption_cast(const QStyleHintReturn *hint) template T qstyleoption_cast(QStyleHintReturn *hint) { - typedef typename QtPrivate::remove_cv::type>::type Opt; + typedef typename std::remove_cv::type>::type Opt; if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast(hint); diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index bcbd0a95c4..5d218ac1ba 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -98,7 +98,7 @@ public: #else // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) template - inline typename QtPrivate::QEnableIf::value + inline typename QtPrivate::QEnableIf::value && QtPrivate::IsPointerToTypeDerivedFromQObject::Value, QAction *>::Type addAction(const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) { @@ -126,7 +126,7 @@ public: } // addAction(QIcon, QString): Connect to a QObject slot / functor or function pointer (with context) template - inline typename QtPrivate::QEnableIf::value + inline typename QtPrivate::QEnableIf::value && QtPrivate::IsPointerToTypeDerivedFromQObject::Value, QAction *>::Type addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) { diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h index d361513bbf..0ea4d4afeb 100644 --- a/src/widgets/widgets/qtoolbar.h +++ b/src/widgets/widgets/qtoolbar.h @@ -116,7 +116,7 @@ public: #else // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) template - inline typename QtPrivate::QEnableIf::value + inline typename QtPrivate::QEnableIf::value && QtPrivate::IsPointerToTypeDerivedFromQObject::Value, QAction *>::Type addAction(const QString &text, const Obj *object, Func1 slot) { @@ -134,7 +134,7 @@ public: } // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) template - inline typename QtPrivate::QEnableIf::value + inline typename QtPrivate::QEnableIf::value && QtPrivate::IsPointerToTypeDerivedFromQObject::Value, QAction *>::Type addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot) { diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 9b92a4ff15..ff0497b69e 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -28,7 +28,6 @@ #include -#include #include #include @@ -376,8 +375,8 @@ void tst_QGlobal::isEnum() #define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true) #define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false) #else -#define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true && QtPrivate::is_enum::value == true) -#define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false && QtPrivate::is_enum::value == false) +#define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true && std::is_enum::value == true) +#define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false && std::is_enum::value == false) #endif QVERIFY(IS_ENUM_TRUE(isEnum_B_Byte)); diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp index 1a70ac5e75..0c890eafbc 100644 --- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp +++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp @@ -29,7 +29,6 @@ #include #include -#include #include #include @@ -197,7 +196,7 @@ void tst_QHashFunctions::range() { // verify that the input iterator category suffices: std::stringstream sstream; - Q_STATIC_ASSERT((QtPrivate::is_same::iterator_category>::value)); + Q_STATIC_ASSERT((std::is_same::iterator_category>::value)); std::copy(ints, ints + numInts, std::ostream_iterator(sstream, " ")); sstream.seekg(0); std::istream_iterator it(sstream), end; -- cgit v1.2.1 From 92805a0e9c488e47280e93f65e5378818e340ad1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 7 Nov 2016 11:23:21 +0100 Subject: Fix EGL break on Debian X32 Change to QT_POINTER_SIZE instead of Q_PROCESSOR_WORDSIZE. The latter is 8 due to targeting 64-bit, but pointers are 32-bit still in such builds. For the condition in question it is the pointer size that matters. Task-number: QTBUG-56686 Change-Id: I96c203cae91ceb8404606de605c4fdb1a02a9d5f Reviewed-by: Dmitry Shachnev Reviewed-by: Thiago Macieira --- src/platformsupport/eglconvenience/qt_egl_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/eglconvenience/qt_egl_p.h b/src/platformsupport/eglconvenience/qt_egl_p.h index 615ee4b80a..b1495c9f9d 100644 --- a/src/platformsupport/eglconvenience/qt_egl_p.h +++ b/src/platformsupport/eglconvenience/qt_egl_p.h @@ -83,7 +83,7 @@ struct QtEglConverter { return v; } }; -#if Q_PROCESSOR_WORDSIZE > 4 +#if QT_POINTER_SIZE > 4 template <> struct QtEglConverter { -- cgit v1.2.1 From e25f2392eb4a208449c3aa53196c81583dba08dc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 11 Oct 2016 00:43:29 +0200 Subject: QGraphicsWidget: add missing break statement to switch in event() If the QEvent::GraphicsSceneMousePress case falls through, it does so because d->hasDecoration() == false or the virtual call to windowFrameEvent() returned false. It falls through to the case for QEvent::GraphicsSceneMouseMove, etc, which ensures d->windowData and then checks hasDecoration() again, with some other conditions on top, and calls the same virtual function, windowFrameEvent(), with the same arguments again. Now, it could, theoretically, be possible that that second call would, due to the presence of a windowData that wasn't there before, return true when before it did return false. But the only modification to *this between the calls to windowFrameEvent() is the potential allocation of d->windowData, which, if actually effected, will have d->windowData->grabbedSection == Qt::NoSection, hence windowFrameEvent() won't even be called a second time It is therefore safe to assume that a break was intended here, so add it. Discovered independently be GCC 7 and Coverity. Coverity-Id: 11149 Change-Id: Id708a1689ed0f0c914622e388c456ea4576fda02 Reviewed-by: Edward Welbourne --- src/widgets/graphicsview/qgraphicswidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index 125174627d..5a4f96a2aa 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -1449,6 +1449,7 @@ bool QGraphicsWidget::event(QEvent *event) case QEvent::GraphicsSceneMousePress: if (d->hasDecoration() && windowFrameEvent(event)) return true; + break; case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseRelease: case QEvent::GraphicsSceneMouseDoubleClick: -- cgit v1.2.1 From ef36fd02178482cd312ea551303856ef563421af Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 8 Oct 2016 16:41:46 +0200 Subject: QGraphicsSceneBspTreeIndex: fix misleading code in event() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old code employed a switch statement to filter timer events, but fell unconditionally through to the default case of calling QObject::event(). The final return statement following the switch is thus dead code. Fix by turning the switch into an if and returning QObject::event() unconditionally afterwards, which much better describes the intent of the code, and also fixes the GCC 7 warning about implicit fall- through in the switch (which wasn't implicit to a human, but GCC's comment-reading-capabilities are somewhat limited at this point). Change-Id: I6756a65b3679a446d09fd721dfd0adc24fdf7772 Reviewed-by: Sérgio Martins Reviewed-by: Edward Welbourne --- src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp index ce43b1332d..9916591ffa 100644 --- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -691,8 +691,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics bool QGraphicsSceneBspTreeIndex::event(QEvent *event) { Q_D(QGraphicsSceneBspTreeIndex); - switch (event->type()) { - case QEvent::Timer: + if (event->type() == QEvent::Timer) { if (d->indexTimerId && static_cast(event)->timerId() == d->indexTimerId) { if (d->restartIndexTimer) { d->restartIndexTimer = false; @@ -701,11 +700,8 @@ bool QGraphicsSceneBspTreeIndex::event(QEvent *event) d->_q_updateIndex(); } } - // Fallthrough intended - support timers in subclasses. - default: - return QObject::event(event); } - return true; + return QObject::event(event); } QT_END_NAMESPACE -- cgit v1.2.1 From b559b5646359e6fd9c208c29b7524352784e6177 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 10 Oct 2016 20:27:36 +0200 Subject: QFontconfigDatabase: remove 200 unneeded relocations Same change as in QColor (d38f86e50b01c6dd60f5a97355031e08d6a47d18). No text and data reduction numbers (ubsan build). Change-Id: I7280a511e785c9442a3a6a1ed55e10011ce0a84e Reviewed-by: Edward Welbourne --- .../fontconfig/qfontconfigdatabase.cpp | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 1c2c3288a0..71236227de 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -110,7 +110,7 @@ static inline int stretchFromFcWidth(int fcwidth) return qtstretch; } -static const char *specialLanguages[] = { +static const char specialLanguages[][6] = { "", // Unknown "", // Inherited "", // Common @@ -244,12 +244,12 @@ static const char *specialLanguages[] = { "", // OldHungarian "" // SignWriting }; -Q_STATIC_ASSERT(sizeof(specialLanguages) / sizeof(const char *) == QChar::ScriptCount); +Q_STATIC_ASSERT(sizeof specialLanguages / sizeof *specialLanguages == QChar::ScriptCount); // this could become a list of all languages used for each writing // system, instead of using the single most common language. -static const char *languageForWritingSystem[] = { - 0, // Any +static const char languageForWritingSystem[][6] = { + "", // Any "en", // Latin "el", // Greek "ru", // Cyrillic @@ -279,25 +279,25 @@ static const char *languageForWritingSystem[] = { "ja", // Japanese "ko", // Korean "vi", // Vietnamese - 0, // Symbol + "", // Symbol "sga", // Ogham "non", // Runic "man" // N'Ko }; -Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount); +Q_STATIC_ASSERT(sizeof languageForWritingSystem / sizeof *languageForWritingSystem == QFontDatabase::WritingSystemsCount); #if FC_VERSION >= 20297 // Newer FontConfig let's us sort out fonts that report certain scripts support, // but no open type tables for handling them correctly. // Check the reported script presence in the FC_CAPABILITY's "otlayout:" section. -static const char *capabilityForWritingSystem[] = { - 0, // Any - 0, // Latin - 0, // Greek - 0, // Cyrillic - 0, // Armenian - 0, // Hebrew - 0, // Arabic +static const char capabilityForWritingSystem[][5] = { + "", // Any + "", // Latin + "", // Greek + "", // Cyrillic + "", // Armenian + "", // Hebrew + "", // Arabic "syrc", // Syriac "thaa", // Thaana "deva", // Devanagari @@ -310,20 +310,20 @@ static const char *capabilityForWritingSystem[] = { "knda", // Kannada "mlym", // Malayalam "sinh", // Sinhala - 0, // Thai - 0, // Lao + "", // Thai + "", // Lao "tibt", // Tibetan "mymr", // Myanmar - 0, // Georgian + "", // Georgian "khmr", // Khmer - 0, // SimplifiedChinese - 0, // TraditionalChinese - 0, // Japanese - 0, // Korean - 0, // Vietnamese - 0, // Symbol - 0, // Ogham - 0, // Runic + "", // SimplifiedChinese + "", // TraditionalChinese + "", // Japanese + "", // Korean + "", // Vietnamese + "", // Symbol + "", // Ogham + "", // Runic "nko " // N'Ko }; Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount); @@ -425,7 +425,7 @@ static void populateFromPattern(FcPattern *pattern) FcLangResult langRes = FcLangSetHasLang(langset, lang); if (langRes != FcLangDifferentLang) { #if FC_VERSION >= 20297 - if (capabilityForWritingSystem[j] != Q_NULLPTR && requiresOpenType(j)) { + if (*capabilityForWritingSystem[j] && requiresOpenType(j)) { if (cap == Q_NULLPTR) capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); if (capRes == FcResultMatch && strstr(reinterpret_cast(cap), capabilityForWritingSystem[j]) == 0) -- cgit v1.2.1 From e649eac69a3220be7654ce6428185c83cd885db2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 4 Nov 2016 10:52:36 +0100 Subject: Direct2D QPA: Add #include directives for MinGW D2D support has been partially added to recent versions of MinGW, which one day could make compiling the plugin possible. Change-Id: I53f91c483d3b900698f4424cb6a72f626e32e60b Reviewed-by: Louai Al-Khanji --- src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h index 97715ad050..34225bba9a 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h @@ -46,6 +46,13 @@ #include #include +#ifdef Q_CC_MINGW +# include +# include +# include +# include +# include +#endif // Q_CC_MINGW #include QT_BEGIN_NAMESPACE -- cgit v1.2.1 From b64fc69d1c8a54ee311ea115c5c01823b0868d18 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 8 Nov 2016 15:33:51 +0100 Subject: Fix compiler warning/error with clang 3.6 Clang warns about self assignment, so use the same mechanism as Q_UNUSED for HB_UNUSED. Change-Id: I0894c72fb0936074b15198053464f5bc4b8991d4 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/harfbuzz/src/harfbuzz-impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-impl.h b/src/3rdparty/harfbuzz/src/harfbuzz-impl.h index 5f430498c4..f98594ac91 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-impl.h +++ b/src/3rdparty/harfbuzz/src/harfbuzz-impl.h @@ -59,7 +59,7 @@ HB_BEGIN_HEADER #endif #ifndef HB_UNUSED -# define HB_UNUSED(arg) ((arg) = (arg)) +# define HB_UNUSED(arg) ((void)(arg)) #endif #define HB_LIKELY(cond) (cond) -- cgit v1.2.1 From 0383d0be33c7ede2104b7225c9af13104cbef85d Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 9 Nov 2016 07:50:14 +0100 Subject: winrt: Do not copy into a reference The intention has probably been to reset a reference, which is not required. Task-number: QTBUG-56756 Change-Id: I1ef44b6c9b8365ac5c8d48234137e518558e9398 Reviewed-by: Oliver Wolff --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index 4a2e2d887f..8d4fbfd8e4 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -532,7 +532,6 @@ bool QEventDispatcherWinRT::event(QEvent *e) if (id >= d->timerInfos.size()) break; - info = d->timerInfos[id]; if (info.timerId == INVALID_TIMER_ID) break; -- cgit v1.2.1 From c83ba01f7bc542368973f3f24dfb59c6052dd78a Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 9 Nov 2016 07:51:25 +0100 Subject: winrt: remove superfluous code We do not need to check for an invalid timer id, as this can only happen if the above check is already true. Hence, this was doing the same check twice. Task-number: QTBUG-56756 Change-Id: Icca9b26c32ce88eab76dd02c6c10b24af07bfad7 Reviewed-by: Oliver Wolff --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index 8d4fbfd8e4..6126ff0e5d 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -532,9 +532,6 @@ bool QEventDispatcherWinRT::event(QEvent *e) if (id >= d->timerInfos.size()) break; - if (info.timerId == INVALID_TIMER_ID) - break; - if (info.interval == 0 && info.inEvent) { // post the next zero timer event as long as the timer was not restarted QCoreApplication::postEvent(this, new QTimerEvent(id)); -- cgit v1.2.1 From 9de3b15d07dcf1be5ff7b26e2e7987ed8e91a0ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= Date: Mon, 7 Nov 2016 09:40:34 +0100 Subject: QLabel: take DPR of QMovie in account when calculating sizeHint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QLabel already does that for QPixmap, so just do the same for QMovie's current pixmap. Task-number: QTBUG-48157 Change-Id: I7b26460f778e56ff017a5efd433f8929f30e4b41 Reviewed-by: Friedemann Kleint Reviewed-by: Morten Johan Sørvig --- src/widgets/widgets/qlabel.cpp | 1 + tests/auto/widgets/widgets/qlabel/red@2x.png | Bin 0 -> 105 bytes tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp | 24 +++++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 tests/auto/widgets/widgets/qlabel/red@2x.png diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index a07a964595..34b75cb550 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -579,6 +579,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const #ifndef QT_NO_MOVIE } else if (movie && !movie->currentPixmap().isNull()) { br = movie->currentPixmap().rect(); + br.setSize(br.size() / movie->currentPixmap().devicePixelRatio()); #endif } else if (isTextLabel) { int align = QStyle::visualAlignment(textDirection(), QFlag(this->align)); diff --git a/tests/auto/widgets/widgets/qlabel/red@2x.png b/tests/auto/widgets/widgets/qlabel/red@2x.png new file mode 100644 index 0000000000..4a843e744f Binary files /dev/null and b/tests/auto/widgets/widgets/qlabel/red@2x.png differ diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index d76dbf6b46..2b2756fef3 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -101,6 +101,9 @@ private Q_SLOTS: void taskQTBUG_7902_contextMenuCrash(); #endif + void taskQTBUG_48157_dprPixmap(); + void taskQTBUG_48157_dprMovie(); + private: QLabel *testWidget; QPointer test_box; @@ -546,5 +549,26 @@ void tst_QLabel::taskQTBUG_7902_contextMenuCrash() } #endif +void tst_QLabel::taskQTBUG_48157_dprPixmap() +{ + QLabel label; + QPixmap pixmap; + pixmap.load(QFINDTESTDATA(QStringLiteral("red@2x.png"))); + QCOMPARE(pixmap.devicePixelRatio(), 2.0); + label.setPixmap(pixmap); + QCOMPARE(label.sizeHint(), pixmap.rect().size() / pixmap.devicePixelRatio()); +} + +void tst_QLabel::taskQTBUG_48157_dprMovie() +{ + QLabel label; + QMovie movie; + movie.setFileName(QFINDTESTDATA(QStringLiteral("red@2x.png"))); + movie.start(); + QCOMPARE(movie.currentPixmap().devicePixelRatio(), 2.0); + label.setMovie(&movie); + QCOMPARE(label.sizeHint(), movie.currentPixmap().size() / movie.currentPixmap().devicePixelRatio()); +} + QTEST_MAIN(tst_QLabel) #include "tst_qlabel.moc" -- cgit v1.2.1 From 5c3b16706ff30c38258df0e98e071bf8ae6a1460 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 8 Aug 2016 09:05:53 +0200 Subject: Remove compiler-specific implementations of Q_IS_ENUM Since the macro is now just a wrapper for std::is_enum, its use is also deprecated. [ChangeLog][QtCore][Global] Q_IS_ENUM is deprecated. Use std::is_enum<>::value instead. Change-Id: I09b9f4559c02c81f338cace927873318f2acafde Reviewed-by: Thiago Macieira --- src/corelib/global/qisenum.h | 17 +--- src/corelib/global/qtypeinfo.h | 6 +- src/corelib/kernel/qmetatype.h | 3 +- src/corelib/kernel/qvariant_p.h | 2 +- tests/auto/corelib/global/qglobal/tst_qglobal.cpp | 95 ---------------------- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 2 +- 6 files changed, 7 insertions(+), 118 deletions(-) diff --git a/src/corelib/global/qisenum.h b/src/corelib/global/qisenum.h index 185db5e45f..8f784ef6e3 100644 --- a/src/corelib/global/qisenum.h +++ b/src/corelib/global/qisenum.h @@ -42,21 +42,8 @@ #ifndef QISENUM_H #define QISENUM_H -#ifndef Q_IS_ENUM -# if defined(Q_CC_GNU) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) -# define Q_IS_ENUM(x) __is_enum(x) -# elif defined(Q_CC_MSVC) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER >=140050215) -# define Q_IS_ENUM(x) __is_enum(x) -# elif defined(Q_CC_CLANG) -# if __has_extension(is_enum) -# define Q_IS_ENUM(x) __is_enum(x) -# endif -# endif -#endif - -#ifndef Q_IS_ENUM -# define Q_IS_ENUM(x) std::is_enum::value -#endif +// Use of Q_IS_ENUM is deprecated since 5.8 +#define Q_IS_ENUM(x) std::is_enum::value // shut up syncqt QT_BEGIN_NAMESPACE diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index cdc85ab1d0..8aa5cb4fb4 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -38,13 +38,11 @@ ** ****************************************************************************/ -#include +#include #ifndef QTYPEINFO_H #define QTYPEINFO_H -#include - QT_BEGIN_NAMESPACE /* @@ -64,7 +62,7 @@ public: isIntegral = std::is_integral::value, isComplex = true, isStatic = true, - isRelocatable = Q_IS_ENUM(T), + isRelocatable = std::is_enum::value, isLarge = (sizeof(T)>sizeof(void*)), isDummy = false, //### Qt6: remove sizeOf = sizeof(T) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 29e60b0eb5..e64812b3ae 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -45,7 +45,6 @@ #include #include #include -#include #ifndef QT_NO_QOBJECT #include #endif @@ -1635,7 +1634,7 @@ namespace QtPrivate { | (IsSharedPointerToTypeDerivedFromQObject::Value ? QMetaType::SharedPointerToQObject : 0) | (IsWeakPointerToTypeDerivedFromQObject::Value ? QMetaType::WeakPointerToQObject : 0) | (IsTrackingPointerToTypeDerivedFromQObject::Value ? QMetaType::TrackingPointerToQObject : 0) - | (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0) + | (std::is_enum::value ? QMetaType::IsEnumeration : 0) | (IsGadgetHelper::Value ? QMetaType::IsGadget : 0) }; }; diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index ec87e20656..bf88def438 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -65,7 +65,7 @@ template struct QVariantIntegrator { static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data) - && ((QTypeInfoQuery::isRelocatable) || Q_IS_ENUM(T)); + && ((QTypeInfoQuery::isRelocatable) || std::is_enum::value); typedef std::integral_constant CanUseInternalSpace_t; }; Q_STATIC_ASSERT(QVariantIntegrator::CanUseInternalSpace); diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index ff0497b69e..bb6ec1c8e7 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -48,7 +48,6 @@ private slots: void qConstructorFunction(); void qCoreAppStartupFunction(); void qCoreAppStartupFunctionRestart(); - void isEnum(); void qAlignOf(); void integerForSize(); void qprintable(); @@ -365,100 +364,6 @@ public: enum AnEnum {}; }; -#if defined (Q_COMPILER_CLASS_ENUM) -enum class isEnum_G : qint64 {}; -#endif - -void tst_QGlobal::isEnum() -{ -#if defined (Q_CC_MSVC) -#define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true) -#define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false) -#else -#define IS_ENUM_TRUE(x) (Q_IS_ENUM(x) == true && std::is_enum::value == true) -#define IS_ENUM_FALSE(x) (Q_IS_ENUM(x) == false && std::is_enum::value == false) -#endif - - QVERIFY(IS_ENUM_TRUE(isEnum_B_Byte)); - QVERIFY(IS_ENUM_TRUE(const isEnum_B_Byte)); - QVERIFY(IS_ENUM_TRUE(volatile isEnum_B_Byte)); - QVERIFY(IS_ENUM_TRUE(const volatile isEnum_B_Byte)); - - QVERIFY(IS_ENUM_TRUE(isEnum_B_Short)); - QVERIFY(IS_ENUM_TRUE(const isEnum_B_Short)); - QVERIFY(IS_ENUM_TRUE(volatile isEnum_B_Short)); - QVERIFY(IS_ENUM_TRUE(const volatile isEnum_B_Short)); - - QVERIFY(IS_ENUM_TRUE(isEnum_B_Int)); - QVERIFY(IS_ENUM_TRUE(const isEnum_B_Int)); - QVERIFY(IS_ENUM_TRUE(volatile isEnum_B_Int)); - QVERIFY(IS_ENUM_TRUE(const volatile isEnum_B_Int)); - - QVERIFY(IS_ENUM_TRUE(isEnum_F::AnEnum)); - QVERIFY(IS_ENUM_TRUE(const isEnum_F::AnEnum)); - QVERIFY(IS_ENUM_TRUE(volatile isEnum_F::AnEnum)); - QVERIFY(IS_ENUM_TRUE(const volatile isEnum_F::AnEnum)); - - QVERIFY(IS_ENUM_FALSE(void)); - QVERIFY(IS_ENUM_FALSE(isEnum_B_Byte &)); - QVERIFY(IS_ENUM_FALSE(isEnum_B_Byte[1])); - QVERIFY(IS_ENUM_FALSE(const isEnum_B_Byte[1])); - QVERIFY(IS_ENUM_FALSE(isEnum_B_Byte[])); - QVERIFY(IS_ENUM_FALSE(int)); - QVERIFY(IS_ENUM_FALSE(float)); - QVERIFY(IS_ENUM_FALSE(isEnum_A)); - QVERIFY(IS_ENUM_FALSE(isEnum_A *)); - QVERIFY(IS_ENUM_FALSE(const isEnum_A)); - QVERIFY(IS_ENUM_FALSE(isEnum_C)); - QVERIFY(IS_ENUM_FALSE(isEnum_D)); - QVERIFY(IS_ENUM_FALSE(isEnum_E)); - QVERIFY(IS_ENUM_FALSE(void())); - QVERIFY(IS_ENUM_FALSE(void(*)())); - QVERIFY(IS_ENUM_FALSE(int isEnum_A::*)); - QVERIFY(IS_ENUM_FALSE(void (isEnum_A::*)())); - - QVERIFY(IS_ENUM_FALSE(size_t)); - QVERIFY(IS_ENUM_FALSE(bool)); - QVERIFY(IS_ENUM_FALSE(wchar_t)); - - QVERIFY(IS_ENUM_FALSE(char)); - QVERIFY(IS_ENUM_FALSE(unsigned char)); - QVERIFY(IS_ENUM_FALSE(short)); - QVERIFY(IS_ENUM_FALSE(unsigned short)); - QVERIFY(IS_ENUM_FALSE(int)); - QVERIFY(IS_ENUM_FALSE(unsigned int)); - QVERIFY(IS_ENUM_FALSE(long)); - QVERIFY(IS_ENUM_FALSE(unsigned long)); - - QVERIFY(IS_ENUM_FALSE(qint8)); - QVERIFY(IS_ENUM_FALSE(quint8)); - QVERIFY(IS_ENUM_FALSE(qint16)); - QVERIFY(IS_ENUM_FALSE(quint16)); - QVERIFY(IS_ENUM_FALSE(qint32)); - QVERIFY(IS_ENUM_FALSE(quint32)); - QVERIFY(IS_ENUM_FALSE(qint64)); - QVERIFY(IS_ENUM_FALSE(quint64)); - - QVERIFY(IS_ENUM_FALSE(void *)); - QVERIFY(IS_ENUM_FALSE(int *)); - -#if defined (Q_COMPILER_UNICODE_STRINGS) - QVERIFY(IS_ENUM_FALSE(char16_t)); - QVERIFY(IS_ENUM_FALSE(char32_t)); -#endif - -#if defined (Q_COMPILER_CLASS_ENUM) - // Strongly type class enums are not handled by the - // fallback type traits implementation. Any compiler - // supported by Qt that supports C++0x class enums - // should also support the __is_enum intrinsic. - QVERIFY(Q_IS_ENUM(isEnum_G)); -#endif - -#undef IS_ENUM_TRUE -#undef IS_ENUM_FALSE -} - struct Empty {}; template struct AlignmentInStruct { T dummy; }; diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index caceda86be..7d9f56ef38 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -712,7 +712,7 @@ void tst_QMetaType::flags_data() << bool(!QTypeInfo::isStatic) \ << bool(QTypeInfo::isComplex) \ << bool(QtPrivate::IsPointerToTypeDerivedFromQObject::Value) \ - << bool(Q_IS_ENUM(RealType)); + << bool(std::is_enum::value); QT_FOR_EACH_STATIC_CORE_CLASS(ADD_METATYPE_TEST_ROW) QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW) QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW) -- cgit v1.2.1 From 615270a3008cfc1314a3c983b7e69006dc4184b4 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 8 Aug 2016 09:41:57 +0200 Subject: Rename QtPrivate::is_[un]signed to QtPrivate::Is[Un]signedEnum Any other use than for enums should use std::is_[un]signed. Make this explicit by renaming the type traits. Change-Id: I494158563c95c710e710d0d337f4e547006df171 Reviewed-by: Thiago Macieira --- src/corelib/global/qflags.h | 2 +- src/corelib/global/qtypetraits.h | 41 +++++++++++++------------ tests/auto/corelib/global/qflags/tst_qflags.cpp | 8 ++--- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index f85fc705b4..b871c90c9d 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -103,7 +103,7 @@ public: typedef int Int; #else typedef typename std::conditional< - QtPrivate::is_unsigned::value, + QtPrivate::QIsUnsignedEnum::value, unsigned int, signed int >::type Int; diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index b664dd3a3e..9773db919b 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -47,7 +47,8 @@ QT_BEGIN_NAMESPACE namespace QtPrivate { // -// define custom is_signed, is_unsigned that also works with enum's +// Define QIsUnsignedEnum, QIsSignedEnum - +// std::is_signed, std::is_unsigned does not work for enum's // // a metafunction to invert an integral_constant: @@ -57,37 +58,37 @@ struct not_ // Checks whether a type is unsigned (T must be convertible to unsigned int): template -struct is_unsigned +struct QIsUnsignedEnum : std::integral_constant {}; // Checks whether a type is signed (T must be convertible to int): template -struct is_signed - : not_< is_unsigned > {}; +struct QIsSignedEnum + : not_< QIsUnsignedEnum > {}; -Q_STATIC_ASSERT(( is_unsigned::value)); -Q_STATIC_ASSERT((!is_unsigned::value)); +Q_STATIC_ASSERT(( QIsUnsignedEnum::value)); +Q_STATIC_ASSERT((!QIsUnsignedEnum::value)); -Q_STATIC_ASSERT((!is_signed::value)); -Q_STATIC_ASSERT(( is_signed::value)); +Q_STATIC_ASSERT((!QIsSignedEnum::value)); +Q_STATIC_ASSERT(( QIsSignedEnum::value)); -Q_STATIC_ASSERT(( is_unsigned::value)); -Q_STATIC_ASSERT((!is_unsigned::value)); +Q_STATIC_ASSERT(( QIsUnsignedEnum::value)); +Q_STATIC_ASSERT((!QIsUnsignedEnum::value)); -Q_STATIC_ASSERT((!is_signed::value)); -Q_STATIC_ASSERT(( is_signed::value)); +Q_STATIC_ASSERT((!QIsSignedEnum::value)); +Q_STATIC_ASSERT(( QIsSignedEnum::value)); -Q_STATIC_ASSERT(( is_unsigned::value)); -Q_STATIC_ASSERT((!is_unsigned::value)); +Q_STATIC_ASSERT(( QIsUnsignedEnum::value)); +Q_STATIC_ASSERT((!QIsUnsignedEnum::value)); -Q_STATIC_ASSERT((!is_signed::value)); -Q_STATIC_ASSERT(( is_signed::value)); +Q_STATIC_ASSERT((!QIsSignedEnum::value)); +Q_STATIC_ASSERT(( QIsSignedEnum::value)); -Q_STATIC_ASSERT(( is_unsigned::value)); -Q_STATIC_ASSERT((!is_unsigned::value)); +Q_STATIC_ASSERT(( QIsUnsignedEnum::value)); +Q_STATIC_ASSERT((!QIsUnsignedEnum::value)); -Q_STATIC_ASSERT((!is_signed::value)); -Q_STATIC_ASSERT(( is_signed::value)); +Q_STATIC_ASSERT((!QIsSignedEnum::value)); +Q_STATIC_ASSERT(( QIsSignedEnum::value)); } // namespace QtPrivate diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 10902b6f55..634d9a2df3 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -134,11 +134,11 @@ void tst_QFlags::signedness() // underlying type is implementation-defined, we need to allow for // a different signedness, so we only check that the relative // signedness of the types matches: - Q_STATIC_ASSERT((QtPrivate::is_unsigned::value == - QtPrivate::is_unsigned::value)); + Q_STATIC_ASSERT((QtPrivate::QIsUnsignedEnum::value == + QtPrivate::QIsUnsignedEnum::value)); - Q_STATIC_ASSERT((QtPrivate::is_signed::value == - QtPrivate::is_signed::value)); + Q_STATIC_ASSERT((QtPrivate::QIsSignedEnum::value == + QtPrivate::QIsSignedEnum::value)); } #if defined(Q_COMPILER_CLASS_ENUM) -- cgit v1.2.1 From a160fd52a1e121dfb237bfcddc305caa896df7dc Mon Sep 17 00:00:00 2001 From: Steve Schilz Date: Fri, 6 May 2016 09:31:03 -0700 Subject: Documentation: Specify units for QTextDocument::pageSize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parameter in setPageSize is QSizeF. Without a specified unit it is hard to know what to use as input. Units depend upon the underlying paint device Change-Id: If001b3e9587d6085cc18017680fa20396e936adb Reviewed-by: Edward Welbourne Reviewed-by: Topi Reiniö Reviewed-by: Nico Vertriest Reviewed-by: Steve Schilz --- src/gui/text/qtextdocument.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 6cccf417c7..baadc068d5 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1760,6 +1760,10 @@ QTextBlock QTextDocument::lastBlock() const \property QTextDocument::pageSize \brief the page size that should be used for laying out the document + The units are determined by the underlying paint device. The size is + measured in logical pixels when painting to the screen, and in points + (1/72 inch) when painting to a printer. + By default, for a newly-created, empty document, this property contains an undefined size. -- cgit v1.2.1 From 8ee65cd1f25d8a78b6cdba3e6ab6fa031468693c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 7 Nov 2016 12:29:12 +0100 Subject: Correct a Q_CHECK_PTR()'s parameter Someone cut-and-pasted but forgot one of the changes. Change-Id: I647dc8117ebfe8ce3d4b26d468b80c15d4e533e8 Reviewed-by: Thiago Macieira --- src/corelib/xml/qxmlstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index ef7d454dca..6ad06eaed6 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -880,7 +880,7 @@ inline void QXmlStreamReaderPrivate::reallocateStack() sym_stack = reinterpret_cast (realloc(sym_stack, stack_size * sizeof(Value))); Q_CHECK_PTR(sym_stack); state_stack = reinterpret_cast (realloc(state_stack, stack_size * sizeof(int))); - Q_CHECK_PTR(sym_stack); + Q_CHECK_PTR(state_stack); } -- cgit v1.2.1 From ef744f2163a22960a04a4c524fece0ec40b2534d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 8 Nov 2016 15:34:10 +0100 Subject: Avoid clang warnings about unused return values Change-Id: Iebec7fb425a92199592cb3ea92190dd0bb5deabd Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 7b711e197b..e57d9aa1e0 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -162,7 +162,7 @@ static ProcessInfo *tryAllocateInSection(Header *header, ProcessInfo entries[], } /* there isn't an available entry, undo our increment */ - ffd_atomic_add_fetch(&header->busyCount, -1, FFD_ATOMIC_RELAXED); + (void)ffd_atomic_add_fetch(&header->busyCount, -1, FFD_ATOMIC_RELAXED); return NULL; } @@ -267,7 +267,7 @@ static void freeInfo(Header *header, ProcessInfo *entry) entry->deathPipe = -1; entry->pid = 0; - ffd_atomic_add_fetch(&header->busyCount, -1, FFD_ATOMIC_RELEASE); + (void)ffd_atomic_add_fetch(&header->busyCount, -1, FFD_ATOMIC_RELEASE); assert(header->busyCount >= 0); } -- cgit v1.2.1 From 7d3b291c2252bb737845b923e86c5dbcc9e5ec72 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 9 Nov 2016 10:45:12 +0100 Subject: winrt: Switch default screen image format No need to specify a format with alpha for the screen. Comparing to Windows, Format_ARGB32_Premultiplied was only set in the constructor, but never actually during runtime as detection enforces eith RGB32 or RGB16. Change-Id: I4c2fabbab0d14ee296f9b7e43b02de8a9836d5bb Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index e8e869c04f..6d4edcc8dc 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -625,7 +625,7 @@ int QWinRTScreen::depth() const QImage::Format QWinRTScreen::format() const { - return QImage::Format_ARGB32_Premultiplied; + return QImage::Format_RGB32; } QSizeF QWinRTScreen::physicalSize() const -- cgit v1.2.1 From eedf8f28e014bb3de6bbaec173d10e03e1792bc4 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 3 Nov 2016 15:28:28 +0100 Subject: Doc: update SQL examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - screenshot: remove OS-dependent part of window - \image --> \borderedimage Change-Id: I3eb98595e5c2eb254d3857e4c81dfedac8b7939e Reviewed-by: Topi Reiniö --- examples/sql/doc/images/books-demo.png | Bin 29155 -> 14782 bytes examples/sql/doc/images/cachedtable-example.png | Bin 15908 -> 6912 bytes examples/sql/doc/images/drilldown-example.png | Bin 9092 -> 6612 bytes examples/sql/doc/images/masterdetail-example.png | Bin 104228 -> 66419 bytes examples/sql/doc/images/querymodel-example.png | Bin 30882 -> 17656 bytes .../doc/images/relationaltablemodel-example.png | Bin 10188 -> 5556 bytes examples/sql/doc/images/sql-widget-mapper.png | Bin 13040 -> 4777 bytes examples/sql/doc/images/sqlbrowser-demo.png | Bin 20671 -> 12742 bytes examples/sql/doc/images/tablemodel-example.png | Bin 20904 -> 14361 bytes .../doc/images/widgetmapper-sql-mapping-table.png | Bin 39681 -> 11701 bytes .../sql/doc/images/widgetmapper-sql-mapping.png | Bin 60265 -> 17593 bytes examples/sql/doc/src/books.qdoc | 2 +- examples/sql/doc/src/cachedtable.qdoc | 2 +- examples/sql/doc/src/drilldown.qdoc | 2 +- examples/sql/doc/src/masterdetail.qdoc | 2 +- examples/sql/doc/src/querymodel.qdoc | 2 +- examples/sql/doc/src/relationaltablemodel.qdoc | 2 +- examples/sql/doc/src/sqlbrowser.qdoc | 2 +- examples/sql/doc/src/sqlwidgetmapper.qdoc | 6 +++--- examples/sql/doc/src/tablemodel.qdoc | 2 +- 20 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/sql/doc/images/books-demo.png b/examples/sql/doc/images/books-demo.png index 5bcc20b478..77b3b308c9 100644 Binary files a/examples/sql/doc/images/books-demo.png and b/examples/sql/doc/images/books-demo.png differ diff --git a/examples/sql/doc/images/cachedtable-example.png b/examples/sql/doc/images/cachedtable-example.png index db770dfdf2..ca72aa4fed 100644 Binary files a/examples/sql/doc/images/cachedtable-example.png and b/examples/sql/doc/images/cachedtable-example.png differ diff --git a/examples/sql/doc/images/drilldown-example.png b/examples/sql/doc/images/drilldown-example.png index fed51d3629..39a4117637 100644 Binary files a/examples/sql/doc/images/drilldown-example.png and b/examples/sql/doc/images/drilldown-example.png differ diff --git a/examples/sql/doc/images/masterdetail-example.png b/examples/sql/doc/images/masterdetail-example.png index bc282b7a78..6bf19f3b55 100644 Binary files a/examples/sql/doc/images/masterdetail-example.png and b/examples/sql/doc/images/masterdetail-example.png differ diff --git a/examples/sql/doc/images/querymodel-example.png b/examples/sql/doc/images/querymodel-example.png index 908d500e1f..b425997878 100644 Binary files a/examples/sql/doc/images/querymodel-example.png and b/examples/sql/doc/images/querymodel-example.png differ diff --git a/examples/sql/doc/images/relationaltablemodel-example.png b/examples/sql/doc/images/relationaltablemodel-example.png index 44fc858562..e6a1b58096 100644 Binary files a/examples/sql/doc/images/relationaltablemodel-example.png and b/examples/sql/doc/images/relationaltablemodel-example.png differ diff --git a/examples/sql/doc/images/sql-widget-mapper.png b/examples/sql/doc/images/sql-widget-mapper.png index dfa64aba9e..51b5d759b8 100644 Binary files a/examples/sql/doc/images/sql-widget-mapper.png and b/examples/sql/doc/images/sql-widget-mapper.png differ diff --git a/examples/sql/doc/images/sqlbrowser-demo.png b/examples/sql/doc/images/sqlbrowser-demo.png index 101ec5a0a3..6a5635d183 100644 Binary files a/examples/sql/doc/images/sqlbrowser-demo.png and b/examples/sql/doc/images/sqlbrowser-demo.png differ diff --git a/examples/sql/doc/images/tablemodel-example.png b/examples/sql/doc/images/tablemodel-example.png index 3ae2a8c05c..17478e07cc 100644 Binary files a/examples/sql/doc/images/tablemodel-example.png and b/examples/sql/doc/images/tablemodel-example.png differ diff --git a/examples/sql/doc/images/widgetmapper-sql-mapping-table.png b/examples/sql/doc/images/widgetmapper-sql-mapping-table.png index 98734b34b6..0360207249 100644 Binary files a/examples/sql/doc/images/widgetmapper-sql-mapping-table.png and b/examples/sql/doc/images/widgetmapper-sql-mapping-table.png differ diff --git a/examples/sql/doc/images/widgetmapper-sql-mapping.png b/examples/sql/doc/images/widgetmapper-sql-mapping.png index 88718c6a8b..994cef8402 100644 Binary files a/examples/sql/doc/images/widgetmapper-sql-mapping.png and b/examples/sql/doc/images/widgetmapper-sql-mapping.png differ diff --git a/examples/sql/doc/src/books.qdoc b/examples/sql/doc/src/books.qdoc index 3a145f04ac..f65daed372 100644 --- a/examples/sql/doc/src/books.qdoc +++ b/examples/sql/doc/src/books.qdoc @@ -34,7 +34,7 @@ The Books example shows how Qt's SQL classes can be used with the model/view framework to create rich user interfaces for information stored in a database. - \image books-demo.png + \borderedimage books-demo.png Information about a collection of books is held in a database. The books are catalogued by author, title, genre, and year of publication. Although each of diff --git a/examples/sql/doc/src/cachedtable.qdoc b/examples/sql/doc/src/cachedtable.qdoc index 7db35f13bd..2db80f9c8e 100644 --- a/examples/sql/doc/src/cachedtable.qdoc +++ b/examples/sql/doc/src/cachedtable.qdoc @@ -34,7 +34,7 @@ caching any changes to the data until the user explicitly submits them using a push button. - \image cachedtable-example.png + \borderedimage cachedtable-example.png The example consists of a single class, \c TableEditor, which is a custom dialog widget that allows the user to modify data stored in diff --git a/examples/sql/doc/src/drilldown.qdoc b/examples/sql/doc/src/drilldown.qdoc index f7a00722de..1fcac41eeb 100644 --- a/examples/sql/doc/src/drilldown.qdoc +++ b/examples/sql/doc/src/drilldown.qdoc @@ -34,7 +34,7 @@ well as submit changes, using the QSqlRelationalTableModel and QDataWidgetMapper classes. - \image drilldown-example.png Screenshot of the Drill Down Example + \borderedimage drilldown-example.png Screenshot of the Drill Down Example When running the example application, a user can retrieve information about each item by clicking the corresponding image. diff --git a/examples/sql/doc/src/masterdetail.qdoc b/examples/sql/doc/src/masterdetail.qdoc index 6f733fbae7..033dd41f72 100644 --- a/examples/sql/doc/src/masterdetail.qdoc +++ b/examples/sql/doc/src/masterdetail.qdoc @@ -40,5 +40,5 @@ the database and the associated XML file using the API provided by the Qt SQL and Qt XML modules, respectively. - \image masterdetail-example.png + \borderedimage masterdetail-example.png */ diff --git a/examples/sql/doc/src/querymodel.qdoc b/examples/sql/doc/src/querymodel.qdoc index a089402005..4f14975234 100644 --- a/examples/sql/doc/src/querymodel.qdoc +++ b/examples/sql/doc/src/querymodel.qdoc @@ -34,5 +34,5 @@ data obtained from a SQL query, using a model that encapsulates the query and table views to display the results. - \image querymodel-example.png + \borderedimage querymodel-example.png */ diff --git a/examples/sql/doc/src/relationaltablemodel.qdoc b/examples/sql/doc/src/relationaltablemodel.qdoc index 43c069709c..95648cdc78 100644 --- a/examples/sql/doc/src/relationaltablemodel.qdoc +++ b/examples/sql/doc/src/relationaltablemodel.qdoc @@ -33,5 +33,5 @@ \brief The Relational Table Model example shows how to use table views with a relational model to visualize the relations between items in a database. - \image relationaltablemodel-example.png + \borderedimage relationaltablemodel-example.png */ diff --git a/examples/sql/doc/src/sqlbrowser.qdoc b/examples/sql/doc/src/sqlbrowser.qdoc index fa442de3e3..6eeb2376f3 100644 --- a/examples/sql/doc/src/sqlbrowser.qdoc +++ b/examples/sql/doc/src/sqlbrowser.qdoc @@ -33,5 +33,5 @@ \brief The SQL Browser example shows how a data browser can be used to visualize the results of SQL statements on a live database. - \image sqlbrowser-demo.png + \borderedimage sqlbrowser-demo.png */ diff --git a/examples/sql/doc/src/sqlwidgetmapper.qdoc b/examples/sql/doc/src/sqlwidgetmapper.qdoc index 42e14672c9..a0fc26a642 100644 --- a/examples/sql/doc/src/sqlwidgetmapper.qdoc +++ b/examples/sql/doc/src/sqlwidgetmapper.qdoc @@ -33,7 +33,7 @@ \brief The SQL Widget Mapper example shows how to use a map information from a database to widgets on a form. - \image sql-widget-mapper.png + \borderedimage sql-widget-mapper.png In the \l{Combo Widget Mapper Example}, we showed how to use a named mapping between a widget mapper and a QComboBox widget with a special @@ -74,7 +74,7 @@ including values for the address types that correspond to the address types are stored in a separate table. - \image widgetmapper-sql-mapping-table.png + \borderedimage widgetmapper-sql-mapping-table.png We create an "addresstype" table containing the identifiers used in the "person" table and the corresponding strings: @@ -93,7 +93,7 @@ used wherever the "typeid" is presented to the user. (See the QSqlRelationalTableModel::setRelation() documentation for details.) - \image widgetmapper-sql-mapping.png + \borderedimage widgetmapper-sql-mapping.png The constructor of the \c Window class can be explained in three parts. In the first part, we set up the model used to hold the data, then we set diff --git a/examples/sql/doc/src/tablemodel.qdoc b/examples/sql/doc/src/tablemodel.qdoc index 3c39ca7cd5..66d1801508 100644 --- a/examples/sql/doc/src/tablemodel.qdoc +++ b/examples/sql/doc/src/tablemodel.qdoc @@ -33,5 +33,5 @@ \brief The Table Model example shows how to use a specialized SQL table model with table views to edit information in a database. - \image tablemodel-example.png + \borderedimage tablemodel-example.png */ -- cgit v1.2.1 From 49680fe0bbc9330bb92d985636690b5214f4f3b0 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 12 Oct 2016 15:43:28 +0200 Subject: Fix misspelled QT_NO_ features Change-Id: I77ca4139cb8437b781f082195bf4c92034f55512 Reviewed-by: Marc Mutz Reviewed-by: Lars Knoll --- src/corelib/kernel/qcoreapplication.cpp | 2 +- src/widgets/graphicsview/qgraphicstransform_p.h | 2 +- src/widgets/kernel/qwidget.cpp | 2 +- src/widgets/widgets/qmdisubwindow_p.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index a4a4e50f10..3796df5614 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2048,7 +2048,7 @@ QString QCoreApplication::translate(const char *context, const char *sourceText, return ret; } -#endif //QT_NO_TRANSLATE +#endif //QT_NO_TRANSLATION // Makes it possible to point QCoreApplication to a custom location to ensure // the directory is added to the patch, and qt.conf and deployed plugins are diff --git a/src/widgets/graphicsview/qgraphicstransform_p.h b/src/widgets/graphicsview/qgraphicstransform_p.h index 39f7ab5487..38dbd51c2e 100644 --- a/src/widgets/graphicsview/qgraphicstransform_p.h +++ b/src/widgets/graphicsview/qgraphicstransform_p.h @@ -77,6 +77,6 @@ public: QT_END_NAMESPACE -#endif //QT_NO_GRAPHCISVIEW +#endif //QT_NO_GRAPHICSVIEW #endif // QGRAPHICSTRANSFORM_P_H diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index dc04bfb632..8ca79bbb3c 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5535,7 +5535,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP return; } } -#endif //QT_NO_GRAFFICSEFFECT +#endif //QT_NO_GRAPHICSEFFECT const bool alsoOnScreen = flags & DrawPaintOnScreen; const bool recursive = flags & DrawRecursive; diff --git a/src/widgets/widgets/qmdisubwindow_p.h b/src/widgets/widgets/qmdisubwindow_p.h index 46a8e99d0a..650d3b0bfb 100644 --- a/src/widgets/widgets/qmdisubwindow_p.h +++ b/src/widgets/widgets/qmdisubwindow_p.h @@ -211,7 +211,7 @@ public: Qt::FocusReason focusInReason; OperationInfoMap operationMap; QPointer systemMenu; -#ifndef QT_NO_ACTIONS +#ifndef QT_NO_ACTION QPointer actions[NumWindowStateActions]; #endif QMdiSubWindow::SubWindowOptions options; -- cgit v1.2.1 From f7a7b9796e70b22f302018d6fdbf89cd0c40a321 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 12 Oct 2016 12:31:00 +0200 Subject: Make QT_NO_HIGHDPI a proper feature Change-Id: Ia82f25f9bedfde77aeb711cb089ce3e0f95d0e59 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/gui/configure.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/configure.json b/src/gui/configure.json index 9fb4a971c3..6fba8173b4 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -847,6 +847,12 @@ "condition": "features.library", "output": [ "publicFeature", "feature" ] }, + "highdpiscaling": { + "label": "High DPI Scaling", + "purpose": "Provides automatic scaling of DPI-unaware applications on high-DPI displays.", + "section": "Kernel", + "output": [ "publicFeature", "feature" ] + }, "validator": { "label": "QValidator", "purpose": "Supports validation of input text.", -- cgit v1.2.1 From 9512d97c90cb5f989100b3ce7c258ea5fc2f7829 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 9 Nov 2016 14:36:08 +0100 Subject: Remove a few unnecessary recalculations of hash When we already have the hash-value we can give it to findNode to avoid recalculating it, and if don't need it later, we don't need to request it. Removes around 1% of qHash calls when running QtCreator. Change-Id: I0e5e61e26a407f4ac7e029a3ac13ddd553e4994b Reviewed-by: Thiago Macieira --- src/corelib/tools/qhash.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index d58c3c5733..66b5e75a1a 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -744,7 +744,7 @@ Q_INLINE_TEMPLATE T &QHash::operator[](const Key &akey) Node **node = findNode(akey, &h); if (*node == e) { if (d->willGrow()) - node = findNode(akey, &h); + node = findNode(akey, h); return createNode(h, akey, T(), node)->value; } return (*node)->value; @@ -760,7 +760,7 @@ Q_INLINE_TEMPLATE typename QHash::iterator QHash::insert(const K Node **node = findNode(akey, &h); if (*node == e) { if (d->willGrow()) - node = findNode(akey, &h); + node = findNode(akey, h); return iterator(createNode(h, akey, avalue, node)); } @@ -961,8 +961,7 @@ QPair::iterator, typename QHash::iterator> QHash< template QPair::const_iterator, typename QHash::const_iterator> QHash::equal_range(const Key &akey) const Q_DECL_NOTHROW { - uint h; - Node *node = *findNode(akey, &h); + Node *node = *findNode(akey); const_iterator firstIt = const_iterator(node); if (node != e) { -- cgit v1.2.1 From 15414257b3719f2c302cca26efe40f2b3caa115b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 4 Nov 2016 15:52:32 +0100 Subject: Don't count no-break spaces as trailing spaces No-break-spaces should not be counted in the space data, but rather be treated as any other non-breakable character. We were already taking care of this in the loop we reach if the item starts with a character which isn't whitespace, but there is a second loop for items that begin with whitespace characters. The result of this was that in certain circumstances where you gave the nbsp its own format and made the line wrap, the previous line would count an extra trailing space and it would swallow the first character in its following line. [ChangeLog][QtGui][Text] Fixed a bug where a no-break space would sometimes cause the first character of the containing line to not be displayed. Task-number: QTBUG-56714 Change-Id: Idd760a389052e6de70f6cc397122b217987fa5f2 Reviewed-by: Lars Knoll --- src/gui/text/qtextlayout.cpp | 8 +++-- .../auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 37 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index aca475a581..ac2895aeb3 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1896,11 +1896,15 @@ void QTextLine::layout_helper(int maxGlyphs) ++lbh.glyphCount; if (lbh.checkFullOtherwiseExtend(line)) goto found; - } else if (attributes[lbh.currentPosition].whiteSpace) { + } else if (attributes[lbh.currentPosition].whiteSpace + && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) { lbh.whiteSpaceOrObject = true; - while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace) + while (lbh.currentPosition < end + && attributes[lbh.currentPosition].whiteSpace + && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) { addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount, current, lbh.logClusters, lbh.glyphs); + } if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line. diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index 84d58191c0..22a4276b8e 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -142,6 +142,7 @@ private slots: void xToCursorForLigatures(); void cursorInNonStopChars(); void nbsp(); + void nbspWithFormat(); void noModificationOfInputString(); void superscriptCrash_qtbug53911(); @@ -2266,5 +2267,41 @@ void tst_QTextLayout::superscriptCrash_qtbug53911() qDeleteAll(textLayouts); } +void tst_QTextLayout::nbspWithFormat() +{ + QString s1 = QLatin1String("ABCDEF "); + QString s2 = QLatin1String("GHI"); + QChar nbsp(QChar::Nbsp); + QString s3 = QLatin1String("JKLMNOPQRSTUVWXYZ"); + + QTextLayout layout; + layout.setText(s1 + s2 + nbsp + s3); + + QTextLayout::FormatRange formatRange; + formatRange.start = s1.length() + s2.length(); + formatRange.length = 1; + formatRange.format.setFontUnderline(true); + + QList overrides; + overrides.append(formatRange); + + layout.setAdditionalFormats(overrides); + + layout.beginLayout(); + forever { + QTextLine line = layout.createLine(); + if (!line.isValid()) + break; + line.setLineWidth(1); + } + layout.endLayout(); + + QCOMPARE(layout.lineCount(), 2); + QCOMPARE(layout.lineAt(0).textStart(), 0); + QCOMPARE(layout.lineAt(0).textLength(), s1.length()); + QCOMPARE(layout.lineAt(1).textStart(), s1.length()); + QCOMPARE(layout.lineAt(1).textLength(), s2.length() + 1 + s3.length()); +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" -- cgit v1.2.1 From 95b506cccddcb6d3cba05abe59250862b7ea3999 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Nov 2016 10:33:20 +0100 Subject: fix build with -qt-xcb the include path must be absolute, as otherwise the external module pri will contain a bogus path. amends 9a088e78. Task-number: QTBUG-56934 Change-Id: I701f5778d8c1b5586310b08e7763858460455d63 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/xcb/xcb-static/xcb-static.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro index f3e54813ee..20d8b83e7c 100644 --- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro +++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro @@ -6,7 +6,7 @@ # CONFIG += static -XCB_DIR = ../../../../3rdparty/xcb +XCB_DIR = $$QT_SOURCE_TREE/src/3rdparty/xcb MODULE_INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude INCLUDEPATH += $$XCB_DIR/include/xcb -- cgit v1.2.1 From a192ee0c379cd16512460bc45b1d492078f49aba Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 26 Oct 2016 11:37:24 -0700 Subject: Move WinRT font database to QtFontDatabaseSupport Similar to what we recently did with the Windows font databases. The goal, again, is to add platform font database support for the minimal QPA plugin. Change-Id: Ide5f4ec452c920f169cc31c617cbcf19d8d1764d Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint Reviewed-by: Maurice Kalinowski --- .../fontdatabases/fontdatabases.pro | 4 + .../fontdatabases/winrt/qwinrtfontdatabase.cpp | 491 +++++++++++++++++++++ .../fontdatabases/winrt/qwinrtfontdatabase_p.h | 90 ++++ src/platformsupport/fontdatabases/winrt/winrt.pri | 11 + src/plugins/platforms/winrt/qwinrtfontdatabase.cpp | 491 --------------------- src/plugins/platforms/winrt/qwinrtfontdatabase.h | 79 ---- src/plugins/platforms/winrt/qwinrtintegration.cpp | 2 +- src/plugins/platforms/winrt/winrt.pro | 4 +- 8 files changed, 598 insertions(+), 574 deletions(-) create mode 100644 src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp create mode 100644 src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h create mode 100644 src/platformsupport/fontdatabases/winrt/winrt.pri delete mode 100644 src/plugins/platforms/winrt/qwinrtfontdatabase.cpp delete mode 100644 src/plugins/platforms/winrt/qwinrtfontdatabase.h diff --git a/src/platformsupport/fontdatabases/fontdatabases.pro b/src/platformsupport/fontdatabases/fontdatabases.pro index 7fc4ecc115..9376c3b702 100644 --- a/src/platformsupport/fontdatabases/fontdatabases.pro +++ b/src/platformsupport/fontdatabases/fontdatabases.pro @@ -24,6 +24,10 @@ darwin:!if(watchos:CONFIG(simulator, simulator|device)) { win32:!winrt { include($$PWD/windows/windows.pri) } + + winrt { + include($$PWD/winrt/winrt.pri) + } } load(qt_module) diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp new file mode 100644 index 0000000000..f214184c36 --- /dev/null +++ b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp @@ -0,0 +1,491 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwinrtfontdatabase_p.h" + +#include +#include + +#include +#include +#include +#include +using namespace Microsoft::WRL; + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") + +QDebug operator<<(QDebug d, const QFontDef &def) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "Family=" << def.family << " Stylename=" << def.styleName + << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize + << " styleHint=" << def.styleHint << " weight=" << def.weight + << " stretch=" << def.stretch << " hintingPreference=" + << def.hintingPreference; + return d; +} + +// Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur +static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range) +{ + if (range.first >= 0x0000 && range.last <= 0x007F) + return QFontDatabase::Latin; + if (range.first >= 0x0370 && range.last <= 0x03FF) + return QFontDatabase::Greek; + if (range.first >= 0x0400 && range.last <= 0x04FF) + return QFontDatabase::Cyrillic; + if (range.first >= 0x0530 && range.last <= 0x058F) + return QFontDatabase::Armenian; + if (range.first >= 0x0590 && range.last <= 0x05FF) + return QFontDatabase::Hebrew; + if (range.first >= 0x0600 && range.last <= 0x06FF) + return QFontDatabase::Arabic; + if (range.first >= 0x0700 && range.last <= 0x074F) + return QFontDatabase::Syriac; + if (range.first >= 0x0780 && range.last <= 0x07BF) + return QFontDatabase::Thaana; + if (range.first >= 0x0900 && range.last <= 0x097F) + return QFontDatabase::Devanagari; + if (range.first >= 0x0980 && range.last <= 0x09FF) + return QFontDatabase::Bengali; + if (range.first >= 0x0A00 && range.last <= 0x0A7F) + return QFontDatabase::Gurmukhi; + if (range.first >= 0x0A80 && range.last <= 0x0AFF) + return QFontDatabase::Gujarati; + if (range.first >= 0x0B00 && range.last <= 0x0B7F) + return QFontDatabase::Oriya; + if (range.first >= 0x0B80 && range.last <= 0x0BFF) + return QFontDatabase::Tamil; + if (range.first >= 0x0C00 && range.last <= 0x0C7F) + return QFontDatabase::Telugu; + if (range.first >= 0x0C80 && range.last <= 0x0CFF) + return QFontDatabase::Kannada; + if (range.first >= 0x0D00 && range.last <= 0x0D7F) + return QFontDatabase::Malayalam; + if (range.first >= 0x0D80 && range.last <= 0x0DFF) + return QFontDatabase::Sinhala; + if (range.first >= 0x0E00 && range.last <= 0x0E7F) + return QFontDatabase::Thai; + if (range.first >= 0x0E80 && range.last <= 0x0EFF) + return QFontDatabase::Lao; + if (range.first >= 0x0F00 && range.last <= 0x0FFF) + return QFontDatabase::Tibetan; + if (range.first >= 0x1000 && range.last <= 0x109F) + return QFontDatabase::Myanmar; + if (range.first >= 0x10A0 && range.last <= 0x10FF) + return QFontDatabase::Georgian; + if (range.first >= 0x1780 && range.last <= 0x17FF) + return QFontDatabase::Khmer; + if (range.first >= 0x4E00 && range.last <= 0x9FFF) + return QFontDatabase::SimplifiedChinese; + if (range.first >= 0xAC00 && range.last <= 0xD7AF) + return QFontDatabase::Korean; + if (range.first >= 0x1680 && range.last <= 0x169F) + return QFontDatabase::Ogham; + if (range.first >= 0x16A0 && range.last <= 0x16FF) + return QFontDatabase::Runic; + if (range.first >= 0x07C0 && range.last <= 0x07FF) + return QFontDatabase::Nko; + + return QFontDatabase::Other; +} + +QString QWinRTFontDatabase::fontDir() const +{ + qCDebug(lcQpaFonts) << __FUNCTION__; + QString fontDirectory = QBasicFontDatabase::fontDir(); + if (!QFile::exists(fontDirectory)) { + // Fall back to app directory + fonts, and just app directory after that + const QString applicationDirPath = QCoreApplication::applicationDirPath(); + fontDirectory = applicationDirPath + QLatin1String("/fonts"); + if (!QFile::exists(fontDirectory)) { + if (m_fontFamilies.isEmpty()) + qWarning("No fonts directory found in application package."); + fontDirectory = applicationDirPath; + } + } + return fontDirectory; +} + +QWinRTFontDatabase::~QWinRTFontDatabase() +{ + qCDebug(lcQpaFonts) << __FUNCTION__; + + foreach (IDWriteFontFile *fontFile, m_fonts.keys()) + fontFile->Release(); + + foreach (IDWriteFontFamily *fontFamily, m_fontFamilies) + fontFamily->Release(); +} + +QFont QWinRTFontDatabase::defaultFont() const +{ + return QFont(QStringLiteral("Segoe UI")); +} + +bool QWinRTFontDatabase::fontsAlwaysScalable() const +{ + return true; +} + +void QWinRTFontDatabase::populateFontDatabase() +{ + qCDebug(lcQpaFonts) << __FUNCTION__; + + ComPtr factory; + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory); + if (FAILED(hr)) { + qWarning("Failed to create DirectWrite factory: %s", qPrintable(qt_error_string(hr))); + QBasicFontDatabase::populateFontDatabase(); + return; + } + + ComPtr fontCollection; + hr = factory->GetSystemFontCollection(&fontCollection); + if (FAILED(hr)) { + qWarning("Failed to open system font collection: %s", qPrintable(qt_error_string(hr))); + QBasicFontDatabase::populateFontDatabase(); + return; + } + + int fontFamilyCount = fontCollection->GetFontFamilyCount(); + for (int i = 0; i < fontFamilyCount; ++i) { + ComPtr fontFamily; + hr = fontCollection->GetFontFamily(i, &fontFamily); + if (FAILED(hr)) { + qWarning("Unable to get font family: %s", qPrintable(qt_error_string(hr))); + continue; + } + + ComPtr names; + hr = fontFamily->GetFamilyNames(&names); + if (FAILED(hr)) { + qWarning("Unable to get font family names: %s", qPrintable(qt_error_string(hr))); + continue; + } + quint32 familyNameLength; + hr = names->GetStringLength(0, &familyNameLength); + if (FAILED(hr)) { + qWarning("Unable to get family name length: %s", qPrintable(qt_error_string(hr))); + continue; + } + QVector familyBuffer(familyNameLength + 1); + hr = names->GetString(0, familyBuffer.data(), familyBuffer.size()); + if (FAILED(hr)) { + qWarning("Unable to create font family name: %s", qPrintable(qt_error_string(hr))); + continue; + } + QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength); + + m_fontFamilies.insert(familyName, fontFamily.Detach()); + + registerFontFamily(familyName); + } + + QBasicFontDatabase::populateFontDatabase(); +} + +void QWinRTFontDatabase::populateFamily(const QString &familyName) +{ + qCDebug(lcQpaFonts) << __FUNCTION__ << familyName; + + IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName); + if (!fontFamily) { + qWarning("The font family %s was not found.", qPrintable(familyName)); + return; + } + + bool fontRegistered = false; + const int fontCount = fontFamily->GetFontCount(); + for (int j = 0; j < fontCount; ++j) { + ComPtr font; + HRESULT hr = fontFamily->GetFont(j, &font); + if (FAILED(hr)) { + qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr))); + continue; + } + + // Skip simulated faces + if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) + continue; + + ComPtr baseFontFace; + hr = font->CreateFontFace(&baseFontFace); + if (FAILED(hr)) { + qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr))); + continue; + } + ComPtr fontFace; + hr = baseFontFace.As(&fontFace); + if (FAILED(hr)) { + qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr))); + continue; + } + + // We can't deal with multi-file fonts + quint32 fileCount; + hr = fontFace->GetFiles(&fileCount, NULL); + if (FAILED(hr)) { + qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr))); + continue; + } + if (fileCount != 1) + continue; + + ComPtr informationalStrings; + BOOL exists; + hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER, + &informationalStrings, &exists); + if (FAILED(hr)) { + qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr))); + continue; + } + QString foundryName; + if (exists) { + quint32 length; + hr = informationalStrings->GetStringLength(0, &length); + if (FAILED(hr)) + qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr))); + if (SUCCEEDED(hr)) { + QVector buffer(length + 1); + hr = informationalStrings->GetString(0, buffer.data(), buffer.size()); + if (FAILED(hr)) + qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr))); + if (SUCCEEDED(hr)) + foundryName = QString::fromWCharArray(buffer.data(), length); + } + } + + QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(font->GetWeight()); + + QFont::Style style; + switch (font->GetStyle()) { + default: + case DWRITE_FONT_STYLE_NORMAL: + style = QFont::StyleNormal; + break; + case DWRITE_FONT_STYLE_OBLIQUE: + style = QFont::StyleOblique; + break; + case DWRITE_FONT_STYLE_ITALIC: + style = QFont::StyleItalic; + break; + } + + QFont::Stretch stretch; + switch (font->GetStretch()) { + default: + case DWRITE_FONT_STRETCH_UNDEFINED: + case DWRITE_FONT_STRETCH_NORMAL: + stretch = QFont::Unstretched; + break; + case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: + stretch = QFont::UltraCondensed; + break; + case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: + stretch = QFont::ExtraCondensed; + break; + case DWRITE_FONT_STRETCH_CONDENSED: + stretch = QFont::Condensed; + break; + case DWRITE_FONT_STRETCH_SEMI_CONDENSED: + stretch = QFont::SemiCondensed; + break; + case DWRITE_FONT_STRETCH_SEMI_EXPANDED: + stretch = QFont::SemiExpanded; + break; + case DWRITE_FONT_STRETCH_EXPANDED: + stretch = QFont::Expanded; + break; + case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: + stretch = QFont::ExtraExpanded; + break; + case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: + stretch = QFont::UltraExpanded; + break; + } + + const bool fixedPitch = fontFace->IsMonospacedFont(); + + // Get writing systems from unicode ranges + quint32 actualRangeCount; + hr = fontFace->GetUnicodeRanges(0, nullptr, &actualRangeCount); + Q_ASSERT(hr == E_NOT_SUFFICIENT_BUFFER); + QVector unicodeRanges(actualRangeCount); + hr = fontFace->GetUnicodeRanges(actualRangeCount, unicodeRanges.data(), &actualRangeCount); + if (FAILED(hr)) { + qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr))); + continue; + } + QSupportedWritingSystems writingSystems; + for (quint32 i = 0; i < actualRangeCount; ++i) { + const QFontDatabase::WritingSystem writingSystem = writingSystemFromUnicodeRange(unicodeRanges.at(i)); + writingSystems.setSupported(writingSystem); + } + if (writingSystems.supported(QFontDatabase::SimplifiedChinese)) { + writingSystems.setSupported(QFontDatabase::TraditionalChinese); + writingSystems.setSupported(QFontDatabase::Japanese); + } + if (writingSystems.supported(QFontDatabase::Latin)) + writingSystems.setSupported(QFontDatabase::Vietnamese); + + IDWriteFontFile *fontFile; + hr = fontFace->GetFiles(&fileCount, &fontFile); + if (FAILED(hr)) { + qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr))); + continue; + } + + FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() }; + m_fonts.insert(fontFile, description); + registerFont(familyName, QString(), foundryName, weight, style, stretch, + true, true, 0, fixedPitch, writingSystems, fontFile); + fontRegistered = true; + } + + // Always populate something to avoid an assert + if (!fontRegistered) { + registerFont(familyName, QString(), QString(), QFont::Normal, QFont::StyleNormal, + QFont::Unstretched, false, false, 0, false, QSupportedWritingSystems(), 0); + } +} + +QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) +{ + qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << handle; + + if (!handle) // Happens if a font family population failed + return 0; + + IDWriteFontFile *fontFile = reinterpret_cast(handle); + if (!m_fonts.contains(fontFile)) + return QBasicFontDatabase::fontEngine(fontDef, handle); + + const void *referenceKey; + quint32 referenceKeySize; + HRESULT hr = fontFile->GetReferenceKey(&referenceKey, &referenceKeySize); + if (FAILED(hr)) { + qWarning("Unable to get font file reference key: %s", qPrintable(qt_error_string(hr))); + return 0; + } + + ComPtr loader; + hr = fontFile->GetLoader(&loader); + if (FAILED(hr)) { + qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr))); + return 0; + } + + ComPtr stream; + hr =loader->CreateStreamFromKey(referenceKey, referenceKeySize, &stream); + if (FAILED(hr)) { + qWarning("Unable to get font file stream: %s", qPrintable(qt_error_string(hr))); + return 0; + } + + quint64 fileSize; + hr = stream->GetFileSize(&fileSize); + if (FAILED(hr)) { + qWarning("Unable to get font file size: %s", qPrintable(qt_error_string(hr))); + return 0; + } + + const void *data; + void *context; + hr = stream->ReadFileFragment(&data, 0, fileSize, &context); + if (FAILED(hr)) { + qWarning("Unable to get font file data: %s", qPrintable(qt_error_string(hr))); + return 0; + } + const QByteArray fontData((const char *)data, fileSize); + stream->ReleaseFileFragment(context); + + QFontEngine::FaceId faceId; + const FontDescription description = m_fonts.value(fontFile); + faceId.uuid = description.uuid; + faceId.index = description.index; + const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); + QFontEngineFT::GlyphFormat format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono; + QFontEngineFT *engine = new QFontEngineFT(fontDef); + if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) { + delete engine; + return 0; + } + + return engine; +} + +QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, + QFont::StyleHint styleHint, + QChar::Script script) const +{ + Q_UNUSED(style) + Q_UNUSED(styleHint) + Q_UNUSED(script) + + qCDebug(lcQpaFonts) << __FUNCTION__ << family; + + QStringList result; + if (family == QLatin1String("Helvetica")) + result.append(QStringLiteral("Arial")); + result.append(QBasicFontDatabase::fallbacksForFamily(family, style, styleHint, script)); + return result; +} + +void QWinRTFontDatabase::releaseHandle(void *handle) +{ + qCDebug(lcQpaFonts) << __FUNCTION__ << handle; + + if (!handle) + return; + + IDWriteFontFile *fontFile = reinterpret_cast(handle); + if (m_fonts.contains(fontFile)) { + m_fonts.remove(fontFile); + fontFile->Release(); + return; + } + + QBasicFontDatabase::releaseHandle(handle); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h new file mode 100644 index 0000000000..9559bac0a8 --- /dev/null +++ b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINRTFONTDATABASE_H +#define QWINRTFONTDATABASE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +struct IDWriteFontFile; +struct IDWriteFontFamily; + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) + +struct FontDescription +{ + quint32 index; + QByteArray uuid; +}; + +class QWinRTFontDatabase : public QBasicFontDatabase +{ +public: + QString fontDir() const; + ~QWinRTFontDatabase(); + QFont defaultFont() const Q_DECL_OVERRIDE; + bool fontsAlwaysScalable() const Q_DECL_OVERRIDE; + void populateFontDatabase() Q_DECL_OVERRIDE; + void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; + QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE; + QStringList fallbacksForFamily(const QString &family, QFont::Style style, + QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE; + void releaseHandle(void *handle) Q_DECL_OVERRIDE; +private: + QHash m_fonts; + QHash m_fontFamilies; +}; + +QT_END_NAMESPACE + +#endif // QWINRTFONTDATABASE_H diff --git a/src/platformsupport/fontdatabases/winrt/winrt.pri b/src/platformsupport/fontdatabases/winrt/winrt.pri new file mode 100644 index 0000000000..4875338182 --- /dev/null +++ b/src/platformsupport/fontdatabases/winrt/winrt.pri @@ -0,0 +1,11 @@ +QT *= gui-private + +SOURCES += \ + $$PWD/qwinrtfontdatabase.cpp + +HEADERS += \ + $$PWD/qwinrtfontdatabase_p.h + +DEFINES += __WRL_NO_DEFAULT_LIB__ + +LIBS += $$QMAKE_LIBS_CORE -ldwrite diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp deleted file mode 100644 index d4f2ba1bd6..0000000000 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwinrtfontdatabase.h" - -#include -#include - -#include -#include -#include -#include -using namespace Microsoft::WRL; - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") - -QDebug operator<<(QDebug d, const QFontDef &def) -{ - QDebugStateSaver saver(d); - d.nospace(); - d << "Family=" << def.family << " Stylename=" << def.styleName - << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize - << " styleHint=" << def.styleHint << " weight=" << def.weight - << " stretch=" << def.stretch << " hintingPreference=" - << def.hintingPreference; - return d; -} - -// Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur -static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range) -{ - if (range.first >= 0x0000 && range.last <= 0x007F) - return QFontDatabase::Latin; - if (range.first >= 0x0370 && range.last <= 0x03FF) - return QFontDatabase::Greek; - if (range.first >= 0x0400 && range.last <= 0x04FF) - return QFontDatabase::Cyrillic; - if (range.first >= 0x0530 && range.last <= 0x058F) - return QFontDatabase::Armenian; - if (range.first >= 0x0590 && range.last <= 0x05FF) - return QFontDatabase::Hebrew; - if (range.first >= 0x0600 && range.last <= 0x06FF) - return QFontDatabase::Arabic; - if (range.first >= 0x0700 && range.last <= 0x074F) - return QFontDatabase::Syriac; - if (range.first >= 0x0780 && range.last <= 0x07BF) - return QFontDatabase::Thaana; - if (range.first >= 0x0900 && range.last <= 0x097F) - return QFontDatabase::Devanagari; - if (range.first >= 0x0980 && range.last <= 0x09FF) - return QFontDatabase::Bengali; - if (range.first >= 0x0A00 && range.last <= 0x0A7F) - return QFontDatabase::Gurmukhi; - if (range.first >= 0x0A80 && range.last <= 0x0AFF) - return QFontDatabase::Gujarati; - if (range.first >= 0x0B00 && range.last <= 0x0B7F) - return QFontDatabase::Oriya; - if (range.first >= 0x0B80 && range.last <= 0x0BFF) - return QFontDatabase::Tamil; - if (range.first >= 0x0C00 && range.last <= 0x0C7F) - return QFontDatabase::Telugu; - if (range.first >= 0x0C80 && range.last <= 0x0CFF) - return QFontDatabase::Kannada; - if (range.first >= 0x0D00 && range.last <= 0x0D7F) - return QFontDatabase::Malayalam; - if (range.first >= 0x0D80 && range.last <= 0x0DFF) - return QFontDatabase::Sinhala; - if (range.first >= 0x0E00 && range.last <= 0x0E7F) - return QFontDatabase::Thai; - if (range.first >= 0x0E80 && range.last <= 0x0EFF) - return QFontDatabase::Lao; - if (range.first >= 0x0F00 && range.last <= 0x0FFF) - return QFontDatabase::Tibetan; - if (range.first >= 0x1000 && range.last <= 0x109F) - return QFontDatabase::Myanmar; - if (range.first >= 0x10A0 && range.last <= 0x10FF) - return QFontDatabase::Georgian; - if (range.first >= 0x1780 && range.last <= 0x17FF) - return QFontDatabase::Khmer; - if (range.first >= 0x4E00 && range.last <= 0x9FFF) - return QFontDatabase::SimplifiedChinese; - if (range.first >= 0xAC00 && range.last <= 0xD7AF) - return QFontDatabase::Korean; - if (range.first >= 0x1680 && range.last <= 0x169F) - return QFontDatabase::Ogham; - if (range.first >= 0x16A0 && range.last <= 0x16FF) - return QFontDatabase::Runic; - if (range.first >= 0x07C0 && range.last <= 0x07FF) - return QFontDatabase::Nko; - - return QFontDatabase::Other; -} - -QString QWinRTFontDatabase::fontDir() const -{ - qCDebug(lcQpaFonts) << __FUNCTION__; - QString fontDirectory = QBasicFontDatabase::fontDir(); - if (!QFile::exists(fontDirectory)) { - // Fall back to app directory + fonts, and just app directory after that - const QString applicationDirPath = QCoreApplication::applicationDirPath(); - fontDirectory = applicationDirPath + QLatin1String("/fonts"); - if (!QFile::exists(fontDirectory)) { - if (m_fontFamilies.isEmpty()) - qWarning("No fonts directory found in application package."); - fontDirectory = applicationDirPath; - } - } - return fontDirectory; -} - -QWinRTFontDatabase::~QWinRTFontDatabase() -{ - qCDebug(lcQpaFonts) << __FUNCTION__; - - foreach (IDWriteFontFile *fontFile, m_fonts.keys()) - fontFile->Release(); - - foreach (IDWriteFontFamily *fontFamily, m_fontFamilies) - fontFamily->Release(); -} - -QFont QWinRTFontDatabase::defaultFont() const -{ - return QFont(QStringLiteral("Segoe UI")); -} - -bool QWinRTFontDatabase::fontsAlwaysScalable() const -{ - return true; -} - -void QWinRTFontDatabase::populateFontDatabase() -{ - qCDebug(lcQpaFonts) << __FUNCTION__; - - ComPtr factory; - HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory); - if (FAILED(hr)) { - qWarning("Failed to create DirectWrite factory: %s", qPrintable(qt_error_string(hr))); - QBasicFontDatabase::populateFontDatabase(); - return; - } - - ComPtr fontCollection; - hr = factory->GetSystemFontCollection(&fontCollection); - if (FAILED(hr)) { - qWarning("Failed to open system font collection: %s", qPrintable(qt_error_string(hr))); - QBasicFontDatabase::populateFontDatabase(); - return; - } - - int fontFamilyCount = fontCollection->GetFontFamilyCount(); - for (int i = 0; i < fontFamilyCount; ++i) { - ComPtr fontFamily; - hr = fontCollection->GetFontFamily(i, &fontFamily); - if (FAILED(hr)) { - qWarning("Unable to get font family: %s", qPrintable(qt_error_string(hr))); - continue; - } - - ComPtr names; - hr = fontFamily->GetFamilyNames(&names); - if (FAILED(hr)) { - qWarning("Unable to get font family names: %s", qPrintable(qt_error_string(hr))); - continue; - } - quint32 familyNameLength; - hr = names->GetStringLength(0, &familyNameLength); - if (FAILED(hr)) { - qWarning("Unable to get family name length: %s", qPrintable(qt_error_string(hr))); - continue; - } - QVector familyBuffer(familyNameLength + 1); - hr = names->GetString(0, familyBuffer.data(), familyBuffer.size()); - if (FAILED(hr)) { - qWarning("Unable to create font family name: %s", qPrintable(qt_error_string(hr))); - continue; - } - QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength); - - m_fontFamilies.insert(familyName, fontFamily.Detach()); - - registerFontFamily(familyName); - } - - QBasicFontDatabase::populateFontDatabase(); -} - -void QWinRTFontDatabase::populateFamily(const QString &familyName) -{ - qCDebug(lcQpaFonts) << __FUNCTION__ << familyName; - - IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName); - if (!fontFamily) { - qWarning("The font family %s was not found.", qPrintable(familyName)); - return; - } - - bool fontRegistered = false; - const int fontCount = fontFamily->GetFontCount(); - for (int j = 0; j < fontCount; ++j) { - ComPtr font; - HRESULT hr = fontFamily->GetFont(j, &font); - if (FAILED(hr)) { - qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr))); - continue; - } - - // Skip simulated faces - if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) - continue; - - ComPtr baseFontFace; - hr = font->CreateFontFace(&baseFontFace); - if (FAILED(hr)) { - qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr))); - continue; - } - ComPtr fontFace; - hr = baseFontFace.As(&fontFace); - if (FAILED(hr)) { - qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr))); - continue; - } - - // We can't deal with multi-file fonts - quint32 fileCount; - hr = fontFace->GetFiles(&fileCount, NULL); - if (FAILED(hr)) { - qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr))); - continue; - } - if (fileCount != 1) - continue; - - ComPtr informationalStrings; - BOOL exists; - hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER, - &informationalStrings, &exists); - if (FAILED(hr)) { - qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr))); - continue; - } - QString foundryName; - if (exists) { - quint32 length; - hr = informationalStrings->GetStringLength(0, &length); - if (FAILED(hr)) - qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr))); - if (SUCCEEDED(hr)) { - QVector buffer(length + 1); - hr = informationalStrings->GetString(0, buffer.data(), buffer.size()); - if (FAILED(hr)) - qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr))); - if (SUCCEEDED(hr)) - foundryName = QString::fromWCharArray(buffer.data(), length); - } - } - - QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(font->GetWeight()); - - QFont::Style style; - switch (font->GetStyle()) { - default: - case DWRITE_FONT_STYLE_NORMAL: - style = QFont::StyleNormal; - break; - case DWRITE_FONT_STYLE_OBLIQUE: - style = QFont::StyleOblique; - break; - case DWRITE_FONT_STYLE_ITALIC: - style = QFont::StyleItalic; - break; - } - - QFont::Stretch stretch; - switch (font->GetStretch()) { - default: - case DWRITE_FONT_STRETCH_UNDEFINED: - case DWRITE_FONT_STRETCH_NORMAL: - stretch = QFont::Unstretched; - break; - case DWRITE_FONT_STRETCH_ULTRA_CONDENSED: - stretch = QFont::UltraCondensed; - break; - case DWRITE_FONT_STRETCH_EXTRA_CONDENSED: - stretch = QFont::ExtraCondensed; - break; - case DWRITE_FONT_STRETCH_CONDENSED: - stretch = QFont::Condensed; - break; - case DWRITE_FONT_STRETCH_SEMI_CONDENSED: - stretch = QFont::SemiCondensed; - break; - case DWRITE_FONT_STRETCH_SEMI_EXPANDED: - stretch = QFont::SemiExpanded; - break; - case DWRITE_FONT_STRETCH_EXPANDED: - stretch = QFont::Expanded; - break; - case DWRITE_FONT_STRETCH_EXTRA_EXPANDED: - stretch = QFont::ExtraExpanded; - break; - case DWRITE_FONT_STRETCH_ULTRA_EXPANDED: - stretch = QFont::UltraExpanded; - break; - } - - const bool fixedPitch = fontFace->IsMonospacedFont(); - - // Get writing systems from unicode ranges - quint32 actualRangeCount; - hr = fontFace->GetUnicodeRanges(0, nullptr, &actualRangeCount); - Q_ASSERT(hr == E_NOT_SUFFICIENT_BUFFER); - QVector unicodeRanges(actualRangeCount); - hr = fontFace->GetUnicodeRanges(actualRangeCount, unicodeRanges.data(), &actualRangeCount); - if (FAILED(hr)) { - qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr))); - continue; - } - QSupportedWritingSystems writingSystems; - for (quint32 i = 0; i < actualRangeCount; ++i) { - const QFontDatabase::WritingSystem writingSystem = writingSystemFromUnicodeRange(unicodeRanges.at(i)); - writingSystems.setSupported(writingSystem); - } - if (writingSystems.supported(QFontDatabase::SimplifiedChinese)) { - writingSystems.setSupported(QFontDatabase::TraditionalChinese); - writingSystems.setSupported(QFontDatabase::Japanese); - } - if (writingSystems.supported(QFontDatabase::Latin)) - writingSystems.setSupported(QFontDatabase::Vietnamese); - - IDWriteFontFile *fontFile; - hr = fontFace->GetFiles(&fileCount, &fontFile); - if (FAILED(hr)) { - qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr))); - continue; - } - - FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() }; - m_fonts.insert(fontFile, description); - registerFont(familyName, QString(), foundryName, weight, style, stretch, - true, true, 0, fixedPitch, writingSystems, fontFile); - fontRegistered = true; - } - - // Always populate something to avoid an assert - if (!fontRegistered) { - registerFont(familyName, QString(), QString(), QFont::Normal, QFont::StyleNormal, - QFont::Unstretched, false, false, 0, false, QSupportedWritingSystems(), 0); - } -} - -QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) -{ - qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << handle; - - if (!handle) // Happens if a font family population failed - return 0; - - IDWriteFontFile *fontFile = reinterpret_cast(handle); - if (!m_fonts.contains(fontFile)) - return QBasicFontDatabase::fontEngine(fontDef, handle); - - const void *referenceKey; - quint32 referenceKeySize; - HRESULT hr = fontFile->GetReferenceKey(&referenceKey, &referenceKeySize); - if (FAILED(hr)) { - qWarning("Unable to get font file reference key: %s", qPrintable(qt_error_string(hr))); - return 0; - } - - ComPtr loader; - hr = fontFile->GetLoader(&loader); - if (FAILED(hr)) { - qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr))); - return 0; - } - - ComPtr stream; - hr =loader->CreateStreamFromKey(referenceKey, referenceKeySize, &stream); - if (FAILED(hr)) { - qWarning("Unable to get font file stream: %s", qPrintable(qt_error_string(hr))); - return 0; - } - - quint64 fileSize; - hr = stream->GetFileSize(&fileSize); - if (FAILED(hr)) { - qWarning("Unable to get font file size: %s", qPrintable(qt_error_string(hr))); - return 0; - } - - const void *data; - void *context; - hr = stream->ReadFileFragment(&data, 0, fileSize, &context); - if (FAILED(hr)) { - qWarning("Unable to get font file data: %s", qPrintable(qt_error_string(hr))); - return 0; - } - const QByteArray fontData((const char *)data, fileSize); - stream->ReleaseFileFragment(context); - - QFontEngine::FaceId faceId; - const FontDescription description = m_fonts.value(fontFile); - faceId.uuid = description.uuid; - faceId.index = description.index; - const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); - QFontEngineFT::GlyphFormat format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono; - QFontEngineFT *engine = new QFontEngineFT(fontDef); - if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) { - delete engine; - return 0; - } - - return engine; -} - -QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, - QFont::StyleHint styleHint, - QChar::Script script) const -{ - Q_UNUSED(style) - Q_UNUSED(styleHint) - Q_UNUSED(script) - - qCDebug(lcQpaFonts) << __FUNCTION__ << family; - - QStringList result; - if (family == QLatin1String("Helvetica")) - result.append(QStringLiteral("Arial")); - result.append(QBasicFontDatabase::fallbacksForFamily(family, style, styleHint, script)); - return result; -} - -void QWinRTFontDatabase::releaseHandle(void *handle) -{ - qCDebug(lcQpaFonts) << __FUNCTION__ << handle; - - if (!handle) - return; - - IDWriteFontFile *fontFile = reinterpret_cast(handle); - if (m_fonts.contains(fontFile)) { - m_fonts.remove(fontFile); - fontFile->Release(); - return; - } - - QBasicFontDatabase::releaseHandle(handle); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h deleted file mode 100644 index 8fed4a3fa7..0000000000 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINRTFONTDATABASE_H -#define QWINRTFONTDATABASE_H - -#include -#include - -struct IDWriteFontFile; -struct IDWriteFontFamily; - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) - -struct FontDescription -{ - quint32 index; - QByteArray uuid; -}; - -class QWinRTFontDatabase : public QBasicFontDatabase -{ -public: - QString fontDir() const; - ~QWinRTFontDatabase(); - QFont defaultFont() const Q_DECL_OVERRIDE; - bool fontsAlwaysScalable() const Q_DECL_OVERRIDE; - void populateFontDatabase() Q_DECL_OVERRIDE; - void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; - QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE; - QStringList fallbacksForFamily(const QString &family, QFont::Style style, - QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE; - void releaseHandle(void *handle) Q_DECL_OVERRIDE; -private: - QHash m_fonts; - QHash m_fontFamilies; -}; - -QT_END_NAMESPACE - -#endif // QWINRTFONTDATABASE_H diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 7a0c95e6c1..ffc3bbf077 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -45,7 +45,6 @@ #include "qwinrtinputcontext.h" #include "qwinrtservices.h" #include "qwinrteglcontext.h" -#include "qwinrtfontdatabase.h" #include "qwinrttheme.h" #include "qwinrtclipboard.h" #ifndef QT_NO_DRAGANDDROP @@ -56,6 +55,7 @@ #include #include +#include #include #include #include diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 8fd2a83a16..be2f5ca7e2 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -8,7 +8,7 @@ QT += \ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ -LIBS += $$QMAKE_LIBS_CORE -ldwrite -ld3d11 +LIBS += $$QMAKE_LIBS_CORE -ld3d11 SOURCES = \ main.cpp \ @@ -20,7 +20,6 @@ SOURCES = \ qwinrteventdispatcher.cpp \ qwinrtfiledialoghelper.cpp \ qwinrtfileengine.cpp \ - qwinrtfontdatabase.cpp \ qwinrtinputcontext.cpp \ qwinrtintegration.cpp \ qwinrtmessagedialoghelper.cpp \ @@ -39,7 +38,6 @@ HEADERS = \ qwinrteventdispatcher.h \ qwinrtfiledialoghelper.h \ qwinrtfileengine.h \ - qwinrtfontdatabase.h \ qwinrtinputcontext.h \ qwinrtintegration.h \ qwinrtmessagedialoghelper.h \ -- cgit v1.2.1 From 5cff7d2b679d48a247b4630cb9e3d5b04fab0b55 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 31 Oct 2016 11:54:51 -0700 Subject: QComboBox: Prioritize the model font for popup items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Mac, we use QComboMenuDelegate specifically as item delegate for the popup list. It happens that the order of resolving the font for each item individually would prioritize QComboBox's font instead of whatever the assigned model's FontRole would specify. The fix only requires checking whether FontRole is valid before falling back QComboBox's properties. Change-Id: I7208ad1911b30cc52c826c1884a1e19f5acd9fb4 Task-number: QTBUG-56693 Reviewed-by: Morten Johan Sørvig --- src/widgets/widgets/qcombobox.cpp | 14 ++-- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 74 ++++++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 52e7962109..4358e568bf 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -170,18 +170,18 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt menuOption.menuRect = option.rect; menuOption.rect = option.rect; - // Make sure fonts set on the combo box also overrides the font for the popup menu. - if (mCombo->testAttribute(Qt::WA_SetFont) + // Make sure fonts set on the model or on the combo box, in + // that order, also override the font for the popup menu. + QVariant fontRoleData = index.data(Qt::FontRole); + if (fontRoleData.isValid()) { + menuOption.font = fontRoleData.value(); + } else if (mCombo->testAttribute(Qt::WA_SetFont) || mCombo->testAttribute(Qt::WA_MacSmallSize) || mCombo->testAttribute(Qt::WA_MacMiniSize) || mCombo->font() != qt_app_fonts_hash()->value("QComboBox", QFont())) { menuOption.font = mCombo->font(); } else { - QVariant fontRoleData = index.data(Qt::FontRole); - if (fontRoleData.isValid()) - menuOption.font = fontRoleData.value(); - else - menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font()); + menuOption.font = qt_app_fonts_hash()->value("QComboMenuItem", mCombo->font()); } menuOption.fontMetrics = QFontMetrics(menuOption.font); diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 816fe1faba..edaf033678 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -62,6 +62,7 @@ #include #include #include +#include static inline void setFrameless(QWidget *w) { @@ -160,6 +161,7 @@ private slots: void respectChangedOwnershipOfItemView(); void task_QTBUG_39088_inputMethodHints(); void task_QTBUG_49831_scrollerNotActivated(); + void task_QTBUG_56693_itemFontFromModel(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -3250,5 +3252,77 @@ void tst_QComboBox::task_QTBUG_49831_scrollerNotActivated() } } +class QTBUG_56693_Model : public QStandardItemModel +{ +public: + QTBUG_56693_Model(QObject *parent = Q_NULLPTR) + : QStandardItemModel(parent) + { } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if (role == Qt::FontRole) { + if (index.row() < 5) { + QFont font = QApplication::font(); + font.setItalic(true); + return font; + } else { + return QApplication::font(); + } + } + return QStandardItemModel::data(index, role); + } +}; + +class QTBUG_56693_ProxyStyle : public QProxyStyle +{ +public: + QTBUG_56693_ProxyStyle(QStyle *style) + : QProxyStyle(style), italicItemsNo(0) + { + + } + + void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w = Q_NULLPTR) const override + { + if (element == CE_MenuItem) + if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(opt)) + if (menuItem->font.italic()) + italicItemsNo++; + + baseStyle()->drawControl(element, opt, p, w); + } + + mutable int italicItemsNo; +}; + +void tst_QComboBox::task_QTBUG_56693_itemFontFromModel() +{ + QComboBox box; + if (!qobject_cast(box.itemDelegate())) + QSKIP("Only for combo boxes using QComboMenuDelegate"); + + QTBUG_56693_Model model; + box.setModel(&model); + + QTBUG_56693_ProxyStyle *proxyStyle = new QTBUG_56693_ProxyStyle(box.style()); + box.setStyle(proxyStyle); + box.setFont(QApplication::font()); + + for (int i = 0; i < 10; i++) + box.addItem(QLatin1String("Item ") + QString::number(i)); + + box.show(); + QTest::qWaitForWindowExposed(&box); + box.showPopup(); + QFrame *container = box.findChild(); + QVERIFY(container); + QTest::qWaitForWindowExposed(container); + + QCOMPARE(proxyStyle->italicItemsNo, 5); + + box.hidePopup(); +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" -- cgit v1.2.1 From 5fcda458721c85f7b4209f418b416ffa5c93936e Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 8 Nov 2016 21:45:07 +0100 Subject: Do not guard tslib with evdev That relation is incorrect. We can have tslib support without evdev. Task-number: QTBUG-54998 Change-Id: I2c09bad73210fa4a13000077480c70365d482e2e Reviewed-by: Eirik Aavitsland --- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 14 ++++++++------ src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index c226c0134a..bb62506f33 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -406,15 +406,17 @@ void QEglFSIntegration::createInputHandlers() } #endif -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); - new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); + bool useTslib = false; #ifndef QT_NO_TSLIB - const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); + useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); if (useTslib) new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); - else -#endif // QT_NO_TSLIB +#endif + +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); + new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); + if (!useTslib) new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); #endif } diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index 8c8c8a15ea..3cc0e735ad 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -141,15 +141,17 @@ void QLinuxFbIntegration::createInputHandlers() } #endif -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this); - new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this); + bool useTslib = false; #ifndef QT_NO_TSLIB - const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_FB_TSLIB"); + useTslib = qEnvironmentVariableIntValue("QT_QPA_FB_TSLIB"); if (useTslib) new QTsLibMouseHandler(QLatin1String("TsLib"), QString()); - else -#endif // QT_NO_TSLIB +#endif + +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this); + new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this); + if (!useTslib) new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); #endif } -- cgit v1.2.1 From e8364f9a4b481207ba6822827e143fb31eccfe51 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 27 Oct 2016 11:38:57 +0200 Subject: Enable GL prototypes with recent Khronos headers Recent Khronos headers decided to break the world by guarding all function prototypes with GL_GLEXT_PROTOTYPES which has traditionally been used for extension headers only. Until this gets corrected - see https://lists.freedesktop.org/archives/mesa-dev/2016-September/128654.html - add the define to the config tests and qopengl.h. While 5.7 already has some of the qopengl.h fixes due to an upgraded ANGLE shipping with newer headers, this is a cross-platform issue that will surface everywhere eventually. Therefore we target the full set of fixes to 5.6. This time we also make sure the forced define of GL_GLEXT_PROTOTYPES is removed before including the ext header, thus apps get the ext protos only if they actually requested them. Task-number: QTBUG-56764 Change-Id: Ib2c6d2e7b71b8fb8683424f43e6289e64e4ee46c Reviewed-by: Oliver Wolff Reviewed-by: Andy Nichols --- config.tests/unix/opengldesktop/opengldesktop.cpp | 1 + config.tests/unix/opengles2/opengles2.cpp | 1 + config.tests/unix/opengles3/opengles3.cpp | 1 + src/gui/opengl/qopengl.h | 22 +++++++++++++++++++++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/config.tests/unix/opengldesktop/opengldesktop.cpp b/config.tests/unix/opengldesktop/opengldesktop.cpp index 13e3059364..7ca8764a09 100644 --- a/config.tests/unix/opengldesktop/opengldesktop.cpp +++ b/config.tests/unix/opengldesktop/opengldesktop.cpp @@ -34,6 +34,7 @@ #ifdef __APPLE__ #include #else +#define GL_GLEXT_PROTOTYPES #include #endif diff --git a/config.tests/unix/opengles2/opengles2.cpp b/config.tests/unix/opengles2/opengles2.cpp index b3b9be6d49..81926f3ee4 100644 --- a/config.tests/unix/opengles2/opengles2.cpp +++ b/config.tests/unix/opengles2/opengles2.cpp @@ -34,6 +34,7 @@ #ifdef BUILD_ON_MAC #include #else + #define GL_GLEXT_PROTOTYPES #include #endif diff --git a/config.tests/unix/opengles3/opengles3.cpp b/config.tests/unix/opengles3/opengles3.cpp index 506ac8b19c..80b2323465 100644 --- a/config.tests/unix/opengles3/opengles3.cpp +++ b/config.tests/unix/opengles3/opengles3.cpp @@ -34,6 +34,7 @@ #ifdef BUILD_ON_MAC #include #else + #define GL_GLEXT_PROTOTYPES #include #endif diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index a060949c17..aa0e6394d3 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -89,6 +89,13 @@ typedef void* GLeglImageOES; // applications cannot target ES 3. Therefore QOpenGLFunctions and // friends do everything dynamically and never rely on these macros. +// Some Khronos headers use the ext proto guard in the standard headers as well, +// which is bad. Work it around, but avoid spilling over to the ext header. +# ifndef GL_GLEXT_PROTOTYPES +# define GL_GLEXT_PROTOTYPES +# define QGL_TEMP_GLEXT_PROTO +# endif + # if defined(QT_OPENGL_ES_3_1) # include # elif defined(QT_OPENGL_ES_3) @@ -97,6 +104,11 @@ typedef void* GLeglImageOES; # include #endif +# ifdef QGL_TEMP_GLEXT_PROTO +# undef GL_GLEXT_PROTOTYPES +# undef QGL_TEMP_GLEXT_PROTO +# endif + /* Some GLES2 implementations (like the one on Harmattan) are missing the typedef for GLchar. Work around it here by adding it. The Kkronos headers @@ -117,7 +129,15 @@ typedef char GLchar; # include # else # define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h -# include +// Some Khronos headers use the ext proto guard in the standard headers as well, +// which is bad. Work it around, but avoid spilling over to the ext header. +# ifndef GL_GLEXT_PROTOTYPES +# define GL_GLEXT_PROTOTYPES +# include +# undef GL_GLEXT_PROTOTYPES +# else +# include +# endif # include # endif // Q_OS_MAC #endif // QT_OPENGL_ES_2 -- cgit v1.2.1 From 3c2cb87de2554b9c4f6e2080768fe9ede00aeab3 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 7 Nov 2016 09:54:55 +0100 Subject: xcb: Warn and bail out when even the basic, dummy context fails Do not move on to glGet since the behavior is undefined. Task-number: QTBUG-48986 Change-Id: Ifd279635ed1b8441f92697965d15ae3ecb59a7e3 Reviewed-by: Andy Nichols --- .../platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 9bdedcc830..c2b7a562a9 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -672,8 +672,11 @@ void QGLXContext::queryDummyContext() } QOpenGLContext context; - context.create(); - context.makeCurrent(surface.data()); + if (!context.create() || !context.makeCurrent(surface.data())) { + qWarning("QGLXContext: Failed to create dummy context"); + m_supportsThreading = false; + return; + } m_supportsThreading = true; -- cgit v1.2.1 From 467b15a20c3d6eb611ea5f6ccffd5fc0df81b0c4 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 10 Nov 2016 12:45:49 +0100 Subject: Improve use of QHash to minimize double hashing Avoid looking up by key twice in a row in various locations, but instead using iterators and index lookup. Change-Id: I61a079115199ab9c041ad3a26d36b45ee3f775e0 Reviewed-by: Thiago Macieira --- src/gui/image/qiconloader.cpp | 4 +--- src/gui/image/qpixmapcache.cpp | 19 ++++++++----------- src/gui/kernel/qopenglcontext.cpp | 5 +++-- src/gui/text/qfontengine_ft.cpp | 5 +++-- src/gui/text/qtextformat.cpp | 3 +-- src/gui/text/qtextlayout.cpp | 9 ++++----- .../fontdatabases/windows/qwindowsfontdatabase.cpp | 5 +++-- src/widgets/accessible/itemviews.cpp | 7 +++---- src/widgets/styles/qpixmapstyle.cpp | 6 +++--- 9 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index eda9d6f24e..17d77a07b5 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -383,13 +383,11 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, // Used to protect against potential recursions visited << themeName; - QIconTheme theme = themeList.value(themeName); + QIconTheme &theme = themeList[themeName]; if (!theme.isValid()) { theme = QIconTheme(themeName); if (!theme.isValid()) theme = QIconTheme(fallbackTheme()); - - themeList.insert(themeName, theme); } const QStringList contentDirs = theme.contentDirs(); diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 6d03332367..73448943e1 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -324,26 +324,23 @@ QPixmap *QPMCache::object(const QPixmapCache::Key &key) const bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost) { - QPixmapCache::Key cacheKey; - QPixmapCache::Key oldCacheKey = cacheKeys.value(key); + QPixmapCache::Key &cacheKey = cacheKeys[key]; //If for the same key we add already a pixmap we should delete it - if (oldCacheKey.d) { - QCache::remove(oldCacheKey); - cacheKeys.remove(key); - } + if (cacheKey.d) + QCache::remove(cacheKey); //we create a new key the old one has been removed cacheKey = createKey(); bool success = QCache::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost); if (success) { - cacheKeys.insert(key, cacheKey); if (!theid) { theid = startTimer(flush_time); t = false; } } else { //Insertion failed we released the new allocated key + cacheKeys.remove(key); releaseKey(cacheKey); } return success; @@ -389,12 +386,12 @@ bool QPMCache::replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int bool QPMCache::remove(const QString &key) { - QPixmapCache::Key cacheKey = cacheKeys.value(key); + auto cacheKey = cacheKeys.constFind(key); //The key was not in the cache - if (!cacheKey.d) + if (cacheKey == cacheKeys.constEnd()) return false; - cacheKeys.remove(key); - return QCache::remove(cacheKey); + cacheKeys.erase(cacheKey); + return QCache::remove(cacheKey.value()); } bool QPMCache::remove(const QPixmapCache::Key &key) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 7e5697e5d8..8aea593bf0 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -848,14 +848,15 @@ QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionP // Create object if suitable one not cached QAbstractOpenGLFunctions* funcs = 0; - if (!d->versionFunctions.contains(vp)) { + auto it = d->versionFunctions.constFind(vp); + if (it == d->versionFunctions.constEnd()) { funcs = QOpenGLVersionFunctionsFactory::create(vp); if (funcs) { funcs->setOwningContext(this); d->versionFunctions.insert(vp, funcs); } } else { - funcs = d->versionFunctions.value(vp); + funcs = it.value(); } if (funcs && QOpenGLContext::currentContext() == this) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 09b0475a84..6d575e0e88 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -320,8 +320,9 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) cleanup(); - if (freetypeData->faces.contains(face_id)) - freetypeData->faces.take(face_id); + auto it = freetypeData->faces.constFind(face_id); + if (it != freetypeData->faces.constEnd()) + freetypeData->faces.erase(it); if (freetypeData->faces.isEmpty()) { FT_Done_FreeType(freetypeData->library); diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 8adeb3e659..39fec032dc 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -3409,8 +3409,7 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format) f.d = new QTextFormatPrivate; f.d->resolveFont(defaultFnt); - if (!hashes.contains(hash, idx)) - hashes.insert(hash, idx); + hashes.insert(hash, idx); } QT_CATCH(...) { formats.pop_back(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index f5827bb683..28a5eb6a89 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1059,9 +1059,10 @@ QList QTextLayout::glyphRuns(int from, int length) const QGlyphRun::GlyphRunFlags flags = glyphRun.flags(); QPair key(fontEngine, int(flags)); // merge the glyph runs using the same font - if (glyphRunHash.contains(key)) { - QGlyphRun &oldGlyphRun = glyphRunHash[key]; - + QGlyphRun &oldGlyphRun = glyphRunHash[key]; + if (oldGlyphRun.isEmpty()) { + oldGlyphRun = glyphRun; + } else { QVector indexes = oldGlyphRun.glyphIndexes(); QVector positions = oldGlyphRun.positions(); QRectF boundingRect = oldGlyphRun.boundingRect(); @@ -1073,8 +1074,6 @@ QList QTextLayout::glyphRuns(int from, int length) const oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setPositions(positions); oldGlyphRun.setBoundingRect(boundingRect); - } else { - glyphRunHash[key] = glyphRun; } } } diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index ad4dd3c944..b8d997bc35 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -524,10 +524,11 @@ namespace { const void *key = *reinterpret_cast(fontFileReferenceKey); *fontFileStream = NULL; - if (!m_fontDatas.contains(key)) + auto it = m_fontDatas.constFind(key); + if (it == m_fontDatas.constEnd()) return E_FAIL; - QByteArray fontData = m_fontDatas.value(key); + QByteArray fontData = it.value(); DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); stream->AddRef(); *fontFileStream = stream; diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index 796d13487b..09eba76fbd 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -486,10 +486,9 @@ QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const if (!view()->model()) return 0; - if (childToId.contains(logicalIndex)) { - QAccessible::Id id = childToId.value(logicalIndex); - return QAccessible::accessibleInterface(id); - } + auto id = childToId.constFind(logicalIndex); + if (id != childToId.constEnd()) + return QAccessible::accessibleInterface(id.value()); int vHeader = verticalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0; diff --git a/src/widgets/styles/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp index b51860045d..e973a96a91 100644 --- a/src/widgets/styles/qpixmapstyle.cpp +++ b/src/widgets/styles/qpixmapstyle.cpp @@ -628,10 +628,10 @@ void QPixmapStyle::drawCachedPixmap(QPixmapStyle::ControlDescriptor control, con QPainter *p) const { Q_D(const QPixmapStyle); - if (!d->descriptors.contains(control)) + auto descriptor = d->descriptors.constFind(control); + if (descriptor == d->descriptors.constEnd()) return; - const QPixmapStyleDescriptor &desc = d->descriptors.value(control); - const QPixmap pix = d->getCachedPixmap(control, desc, rect.size()); + const QPixmap pix = d->getCachedPixmap(control, descriptor.value(), rect.size()); Q_ASSERT(!pix.isNull()); p->drawPixmap(rect, pix); } -- cgit v1.2.1 From bfaa8925d5cc0a59cec3f747a8d982ca819f026b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 2 Nov 2016 14:10:47 +0100 Subject: Improve the validation algorithm for binary JSON Add better boundary checks and catch (hopefully all) cases where invalid binary JSON could cause crashes. Change-Id: I206510b7c5e3ba953802a5f46645878e65704ecc Reviewed-by: Edward Welbourne --- src/corelib/json/qjson.cpp | 25 ++++++++------- src/corelib/json/qjson_p.h | 35 ++++++++++++++++----- tests/auto/corelib/json/invalidBinaryData/10.bjson | Bin 0 -> 544 bytes tests/auto/corelib/json/invalidBinaryData/11.bjson | Bin 0 -> 542 bytes tests/auto/corelib/json/invalidBinaryData/12.bjson | Bin 0 -> 506 bytes tests/auto/corelib/json/invalidBinaryData/13.bjson | Bin 0 -> 544 bytes tests/auto/corelib/json/invalidBinaryData/14.bjson | Bin 0 -> 521 bytes tests/auto/corelib/json/invalidBinaryData/15.bjson | Bin 0 -> 536 bytes tests/auto/corelib/json/invalidBinaryData/16.bjson | Bin 0 -> 874 bytes tests/auto/corelib/json/invalidBinaryData/17.bjson | Bin 0 -> 49 bytes tests/auto/corelib/json/invalidBinaryData/18.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/19.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/20.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/21.bjson | Bin 0 -> 552 bytes tests/auto/corelib/json/invalidBinaryData/22.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/23.bjson | Bin 0 -> 533 bytes tests/auto/corelib/json/invalidBinaryData/24.bjson | Bin 0 -> 506 bytes tests/auto/corelib/json/invalidBinaryData/25.bjson | Bin 0 -> 542 bytes tests/auto/corelib/json/invalidBinaryData/26.bjson | Bin 0 -> 628 bytes tests/auto/corelib/json/invalidBinaryData/27.bjson | Bin 0 -> 51 bytes tests/auto/corelib/json/invalidBinaryData/28.bjson | Bin 0 -> 542 bytes tests/auto/corelib/json/invalidBinaryData/29.bjson | Bin 0 -> 544 bytes tests/auto/corelib/json/invalidBinaryData/30.bjson | Bin 0 -> 542 bytes tests/auto/corelib/json/invalidBinaryData/31.bjson | Bin 0 -> 553 bytes tests/auto/corelib/json/invalidBinaryData/32.bjson | Bin 0 -> 536 bytes tests/auto/corelib/json/invalidBinaryData/33.bjson | Bin 0 -> 544 bytes tests/auto/corelib/json/invalidBinaryData/34.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/35.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/36.bjson | Bin 0 -> 524 bytes tests/auto/corelib/json/invalidBinaryData/37.bjson | Bin 0 -> 536 bytes tests/auto/corelib/json/tst_qtjson.cpp | 16 ++++++++++ 31 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 tests/auto/corelib/json/invalidBinaryData/10.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/11.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/12.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/13.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/14.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/15.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/16.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/17.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/18.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/19.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/20.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/21.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/22.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/23.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/24.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/25.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/26.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/27.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/28.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/29.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/30.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/31.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/32.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/33.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/34.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/35.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/36.bjson create mode 100644 tests/auto/corelib/json/invalidBinaryData/37.bjson diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp index c3b58e59a5..c6fff068ce 100644 --- a/src/corelib/json/qjson.cpp +++ b/src/corelib/json/qjson.cpp @@ -129,10 +129,12 @@ bool Data::valid() const return false; bool res = false; - if (header->root()->is_object) - res = static_cast(header->root())->isValid(); + Base *root = header->root(); + int maxSize = alloc - sizeof(Header); + if (root->is_object) + res = static_cast(root)->isValid(maxSize); else - res = static_cast(header->root())->isValid(); + res = static_cast(root)->isValid(maxSize); return res; } @@ -195,9 +197,9 @@ int Object::indexOf(const QString &key, bool *exists) return min; } -bool Object::isValid() const +bool Object::isValid(int maxSize) const { - if (tableOffset + length*sizeof(offset) > size) + if (size > (uint)maxSize || tableOffset + length*sizeof(offset) > size) return false; QString lastKey; @@ -206,8 +208,7 @@ bool Object::isValid() const if (entryOffset + sizeof(Entry) >= tableOffset) return false; Entry *e = entryAt(i); - int s = e->size(); - if (table()[i] + s > tableOffset) + if (!e->isValid(tableOffset - table()[i])) return false; QString key = e->key(); if (key < lastKey) @@ -221,9 +222,9 @@ bool Object::isValid() const -bool Array::isValid() const +bool Array::isValid(int maxSize) const { - if (tableOffset + length*sizeof(offset) > size) + if (size > (uint)maxSize || tableOffset + length*sizeof(offset) > size) return false; for (uint i = 0; i < length; ++i) { @@ -323,12 +324,12 @@ bool Value::isValid(const Base *b) const int s = usedStorage(b); if (!s) return true; - if (s < 0 || offset + s > (int)b->tableOffset) + if (s < 0 || s > (int)b->tableOffset - offset) return false; if (type == QJsonValue::Array) - return static_cast(base(b))->isValid(); + return static_cast(base(b))->isValid(s); if (type == QJsonValue::Object) - return static_cast(base(b))->isValid(); + return static_cast(base(b))->isValid(s); return true; } diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index b7de24d165..c5fd38e640 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -302,12 +302,19 @@ public: String(const char *data) { d = (Data *)data; } struct Data { - qle_int length; + qle_uint length; qle_ushort utf16[1]; }; Data *d; + int byteSize() const { return sizeof(uint) + sizeof(ushort) * d->length; } + bool isValid(int maxSize) const { + // Check byteSize() <= maxSize, avoiding integer overflow + maxSize -= sizeof(uint); + return maxSize >= 0 && uint(d->length) <= maxSize / sizeof(ushort); + } + inline String &operator=(const QString &str) { d->length = str.length(); @@ -376,11 +383,16 @@ public: Latin1String(const char *data) { d = (Data *)data; } struct Data { - qle_short length; + qle_ushort length; char latin1[1]; }; Data *d; + int byteSize() const { return sizeof(ushort) + sizeof(char)*(d->length); } + bool isValid(int maxSize) const { + return byteSize() <= maxSize; + } + inline Latin1String &operator=(const QString &str) { int len = d->length = str.length(); @@ -567,7 +579,7 @@ public: } int indexOf(const QString &key, bool *exists); - bool isValid() const; + bool isValid(int maxSize) const; }; @@ -577,7 +589,7 @@ public: inline Value at(int i) const; inline Value &operator [](int i); - bool isValid() const; + bool isValid(int maxSize) const; }; @@ -631,12 +643,12 @@ public: // key // value data follows key - int size() const { + uint size() const { int s = sizeof(Entry); if (value.latinKey) - s += sizeof(ushort) + qFromLittleEndian(*(ushort *) ((const char *)this + sizeof(Entry))); + s += shallowLatin1Key().byteSize(); else - s += sizeof(uint) + sizeof(ushort)*qFromLittleEndian(*(int *) ((const char *)this + sizeof(Entry))); + s += shallowKey().byteSize(); return alignedSize(s); } @@ -662,6 +674,15 @@ public: return shallowKey().toString(); } + bool isValid(int maxSize) const { + if (maxSize < (int)sizeof(Entry)) + return false; + maxSize -= sizeof(Entry); + if (value.latinKey) + return shallowLatin1Key().isValid(maxSize); + return shallowKey().isValid(maxSize); + } + bool operator ==(const QString &key) const; inline bool operator !=(const QString &key) const { return !operator ==(key); } inline bool operator >=(const QString &key) const; diff --git a/tests/auto/corelib/json/invalidBinaryData/10.bjson b/tests/auto/corelib/json/invalidBinaryData/10.bjson new file mode 100644 index 0000000000..12b29b7aa5 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/10.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/11.bjson b/tests/auto/corelib/json/invalidBinaryData/11.bjson new file mode 100644 index 0000000000..cf2b612111 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/11.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/12.bjson b/tests/auto/corelib/json/invalidBinaryData/12.bjson new file mode 100644 index 0000000000..9c2403350e Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/12.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/13.bjson b/tests/auto/corelib/json/invalidBinaryData/13.bjson new file mode 100644 index 0000000000..db6308b1fd Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/13.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/14.bjson b/tests/auto/corelib/json/invalidBinaryData/14.bjson new file mode 100644 index 0000000000..347da4572c Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/14.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/15.bjson b/tests/auto/corelib/json/invalidBinaryData/15.bjson new file mode 100644 index 0000000000..c6c5558934 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/15.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/16.bjson b/tests/auto/corelib/json/invalidBinaryData/16.bjson new file mode 100644 index 0000000000..ae8b57446d Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/16.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/17.bjson b/tests/auto/corelib/json/invalidBinaryData/17.bjson new file mode 100644 index 0000000000..32f0cc0e23 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/17.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/18.bjson b/tests/auto/corelib/json/invalidBinaryData/18.bjson new file mode 100644 index 0000000000..50c89169eb Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/18.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/19.bjson b/tests/auto/corelib/json/invalidBinaryData/19.bjson new file mode 100644 index 0000000000..b922212f45 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/19.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/20.bjson b/tests/auto/corelib/json/invalidBinaryData/20.bjson new file mode 100644 index 0000000000..c965a0d294 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/20.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/21.bjson b/tests/auto/corelib/json/invalidBinaryData/21.bjson new file mode 100644 index 0000000000..98165ee40c Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/21.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/22.bjson b/tests/auto/corelib/json/invalidBinaryData/22.bjson new file mode 100644 index 0000000000..151f773a81 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/22.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/23.bjson b/tests/auto/corelib/json/invalidBinaryData/23.bjson new file mode 100644 index 0000000000..6eb5269470 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/23.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/24.bjson b/tests/auto/corelib/json/invalidBinaryData/24.bjson new file mode 100644 index 0000000000..c55a2a3e3b Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/24.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/25.bjson b/tests/auto/corelib/json/invalidBinaryData/25.bjson new file mode 100644 index 0000000000..6c619f2ae1 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/25.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/26.bjson b/tests/auto/corelib/json/invalidBinaryData/26.bjson new file mode 100644 index 0000000000..3bf303215a Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/26.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/27.bjson b/tests/auto/corelib/json/invalidBinaryData/27.bjson new file mode 100644 index 0000000000..d2656c2287 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/27.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/28.bjson b/tests/auto/corelib/json/invalidBinaryData/28.bjson new file mode 100644 index 0000000000..6797cf8c40 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/28.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/29.bjson b/tests/auto/corelib/json/invalidBinaryData/29.bjson new file mode 100644 index 0000000000..0645dfc3b2 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/29.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/30.bjson b/tests/auto/corelib/json/invalidBinaryData/30.bjson new file mode 100644 index 0000000000..f77fe1efd0 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/30.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/31.bjson b/tests/auto/corelib/json/invalidBinaryData/31.bjson new file mode 100644 index 0000000000..d9840b6582 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/31.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/32.bjson b/tests/auto/corelib/json/invalidBinaryData/32.bjson new file mode 100644 index 0000000000..1de4cb829f Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/32.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/33.bjson b/tests/auto/corelib/json/invalidBinaryData/33.bjson new file mode 100644 index 0000000000..532a31dc08 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/33.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/34.bjson b/tests/auto/corelib/json/invalidBinaryData/34.bjson new file mode 100644 index 0000000000..f498558eff Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/34.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/35.bjson b/tests/auto/corelib/json/invalidBinaryData/35.bjson new file mode 100644 index 0000000000..8701210755 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/35.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/36.bjson b/tests/auto/corelib/json/invalidBinaryData/36.bjson new file mode 100644 index 0000000000..ef5864e911 Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/36.bjson differ diff --git a/tests/auto/corelib/json/invalidBinaryData/37.bjson b/tests/auto/corelib/json/invalidBinaryData/37.bjson new file mode 100644 index 0000000000..f4dd4ae12f Binary files /dev/null and b/tests/auto/corelib/json/invalidBinaryData/37.bjson differ diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 1665ff696d..f2f9166711 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -103,6 +103,7 @@ private Q_SLOTS: void fromBinary(); void toAndFromBinary_data(); void toAndFromBinary(); + void invalidBinaryData(); void parseNumbers(); void parseStrings(); void parseDuplicateKeys(); @@ -1779,6 +1780,21 @@ void tst_QtJson::toAndFromBinary() QVERIFY(doc == outdoc); } +void tst_QtJson::invalidBinaryData() +{ + QDir dir(testDataDir + "/invalidBinaryData"); + QFileInfoList files = dir.entryInfoList(); + for (int i = 0; i < files.size(); ++i) { + if (!files.at(i).isFile()) + continue; + QFile file(files.at(i).filePath()); + file.open(QIODevice::ReadOnly); + QByteArray bytes = file.readAll(); + QJsonDocument document = QJsonDocument::fromRawData(bytes.constData(), bytes.size()); + QVERIFY(document.isNull()); + } +} + void tst_QtJson::parseNumbers() { { -- cgit v1.2.1 From dffde23a0ae28f05ef2aa9af138f0a82bbfce942 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 9 Nov 2016 10:32:54 +0100 Subject: Fix writing into application directory Tests are not supposed to write into the build/application directory, but rather should output to the temp directory. Change-Id: Idcdf51226a2d547514aea2fbb2054998d8a3437e Reviewed-by: Friedemann Kleint --- tests/auto/gui/image/qpixmap/tst_qpixmap.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index 286f00c111..73da5804eb 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -171,6 +171,7 @@ private: const QString m_prefix; const QString m_convertFromImage; const QString m_loadFromData; + const QTemporaryDir m_tempDir; }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -230,11 +231,11 @@ void tst_QPixmap::initTestCase() QVERIFY(!m_prefix.isEmpty()); QVERIFY(!m_convertFromImage.isEmpty()); QVERIFY(!m_loadFromData.isEmpty()); + QVERIFY2(m_tempDir.isValid(), qPrintable(m_tempDir.errorString())); } void tst_QPixmap::cleanupTestCase() { - QFile::remove(QLatin1String("temp_image.png")); } void tst_QPixmap::swap() @@ -1471,18 +1472,18 @@ void tst_QPixmap::preserveDepth() void tst_QPixmap::loadAsBitmapOrPixmap() { QImage tmp(10, 10, QImage::Format_RGB32); - tmp.save("temp_image.png"); + tmp.save(m_tempDir.path() + "/temp_image.png"); bool ok; // Check that we can load the pixmap as a pixmap and that it then turns into a pixmap - QPixmap pixmap("temp_image.png"); + QPixmap pixmap(m_tempDir.path() + "/temp_image.png"); QVERIFY(!pixmap.isNull()); QVERIFY(pixmap.depth() > 1); QVERIFY(!pixmap.isQBitmap()); pixmap = QPixmap(); - ok = pixmap.load("temp_image.png"); + ok = pixmap.load(m_tempDir.path() + "/temp_image.png"); QVERIFY(ok); QVERIFY(!pixmap.isNull()); QVERIFY(pixmap.depth() > 1); @@ -1490,20 +1491,20 @@ void tst_QPixmap::loadAsBitmapOrPixmap() //now we can try to load it without an extension pixmap = QPixmap(); - ok = pixmap.load("temp_image"); + ok = pixmap.load(m_tempDir.path() + "/temp_image"); QVERIFY(ok); QVERIFY(!pixmap.isNull()); QVERIFY(pixmap.depth() > 1); QVERIFY(!pixmap.isQBitmap()); // The do the same check for bitmaps.. - QBitmap bitmap("temp_image.png"); + QBitmap bitmap(m_tempDir.path() + "/temp_image.png"); QVERIFY(!bitmap.isNull()); QCOMPARE(bitmap.depth(), 1); QVERIFY(bitmap.isQBitmap()); bitmap = QBitmap(); - ok = bitmap.load("temp_image.png"); + ok = bitmap.load(m_tempDir.path() + "/temp_image.png"); QVERIFY(ok); QVERIFY(!bitmap.isNull()); QCOMPARE(bitmap.depth(), 1); -- cgit v1.2.1 From 0038b400530e2459a2aa89576aa245007962a1c9 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 27 Oct 2016 09:09:58 +0200 Subject: Unbreak a couple of configurations Fix compilation with topleveldomain, textodfwriter and cssparser features disabled. Change-Id: I3f061fb09eef36cd640256a46cf77dde85a54d3d Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/io/qurl.cpp | 2 ++ src/gui/painting/painting.pri | 6 +++++- src/gui/text/text.pri | 24 +++++++++++++++++------- src/network/access/qnetworkcookiejar.cpp | 2 ++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index b7762c2ae6..5b34813a71 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -410,7 +410,9 @@ #include "qhash.h" #include "qdir.h" // for QDir::fromNativeSeparators #include "qdatastream.h" +#if QT_CONFIG(topleveldomain) #include "qtldurl_p.h" +#endif #include "private/qipaddress_p.h" #include "qurlquery.h" diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index a61865a0b6..33db1ea0b4 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -65,7 +65,6 @@ SOURCES += \ painting/qcolor.cpp \ painting/qcompositionfunctions.cpp \ painting/qcosmeticstroker.cpp \ - painting/qcssutil.cpp \ painting/qdrawhelper.cpp \ painting/qemulationpaintengine.cpp \ painting/qgammatables.cpp \ @@ -104,6 +103,11 @@ darwin { SOURCES += painting/qcoregraphics.mm } +qtConfig(cssparser) { + SOURCES += \ + painting/qcssutil.cpp +} + SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \ diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index c1c52f2d1a..a15793ec2f 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -32,11 +32,7 @@ HEADERS += \ text/qtextlist.h \ text/qsyntaxhighlighter.h \ text/qtextdocumentwriter.h \ - text/qcssparser_p.h \ text/qtexttable_p.h \ - text/qzipreader_p.h \ - text/qzipwriter_p.h \ - text/qtextodfwriter_p.h \ text/qstatictext_p.h \ text/qstatictext.h \ text/qrawfont.h \ @@ -70,9 +66,6 @@ SOURCES += \ text/qtextlist.cpp \ text/qtextdocumentwriter.cpp \ text/qsyntaxhighlighter.cpp \ - text/qcssparser.cpp \ - text/qzip.cpp \ - text/qtextodfwriter.cpp \ text/qstatictext.cpp \ text/qrawfont.cpp \ text/qglyphrun.cpp \ @@ -93,3 +86,20 @@ qtConfig(harfbuzz)|qtConfig(system-harfbuzz) { SOURCES += text/qharfbuzzng.cpp HEADERS += text/qharfbuzzng_p.h } + +qtConfig(textodfwriter) { + HEADERS += \ + text/qtextodfwriter_p.h \ + text/qzipreader_p.h \ + text/qzipwriter_p.h + SOURCES += \ + text/qtextodfwriter.cpp \ + text/qzip.cpp +} + +qtConfig(cssparser) { + HEADERS += \ + text/qcssparser_p.h + SOURCES += \ + text/qcssparser.cpp +} diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 0540cb740f..232c2b47a5 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -43,7 +43,9 @@ #include "QtNetwork/qnetworkcookie.h" #include "QtCore/qurl.h" #include "QtCore/qdatetime.h" +#if QT_CONFIG(topleveldomain) #include "private/qtldurl_p.h" +#endif QT_BEGIN_NAMESPACE -- cgit v1.2.1 From 2265fbe7c12cbb1f98fad8b4bb878d571427000c Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 12 Oct 2016 17:33:30 +0300 Subject: Remove unused variable in QIconLoader::findIconHelper() Change-Id: Idac0b24631187063445ea5acfd078b2479359d52 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/image/qiconloader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index c7f1f2beb4..8f9f22eb95 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -242,8 +242,6 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, QThemeIconInfo info; Q_ASSERT(!themeName.isEmpty()); - QPixmap pixmap; - // Used to protect against potential recursions visited << themeName; -- cgit v1.2.1 From 1c080465659af269775908bb249159152d563b89 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 8 Nov 2016 15:54:43 +0300 Subject: doc: Remove obsolete note for QWidget::paintEvent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qt_x11_set_global_double_buffer() is dead code since Qt 5. Change-Id: Ie9a33b6f03dc2e39f12bc790292bb0d227f05c44 Reviewed-by: Tor Arne Vestbø --- src/widgets/doc/snippets/code/src_gui_kernel_qwidget.cpp | 8 -------- src/widgets/kernel/qwidget.cpp | 5 ----- 2 files changed, 13 deletions(-) diff --git a/src/widgets/doc/snippets/code/src_gui_kernel_qwidget.cpp b/src/widgets/doc/snippets/code/src_gui_kernel_qwidget.cpp index 53cd907c74..b26f791d37 100644 --- a/src/widgets/doc/snippets/code/src_gui_kernel_qwidget.cpp +++ b/src/widgets/doc/snippets/code/src_gui_kernel_qwidget.cpp @@ -127,11 +127,3 @@ setUpdatesEnabled(false); bigVisualChanges(); setUpdatesEnabled(true); //! [13] - - -//! [14] -... -extern void qt_x11_set_global_double_buffer(bool); -qt_x11_set_global_double_buffer(false); -... -//! [14] diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b2db4e1529..53b39e0394 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9597,11 +9597,6 @@ void QWidget::leaveEvent(QEvent *) Since Qt 4.0, QWidget automatically double-buffers its painting, so there is no need to write double-buffering code in paintEvent() to avoid flicker. - \b{Note for the X11 platform}: It is possible to toggle global double - buffering by calling \c qt_x11_set_global_double_buffer(). For example, - - \snippet code/src_gui_kernel_qwidget.cpp 14 - \note Generally, you should refrain from calling update() or repaint() \b{inside} a paintEvent(). For example, calling update() or repaint() on children inside a paintevent() results in undefined behavior; the child may -- cgit v1.2.1 From 839cae0422be3302ca4a9cbbd7e8482152a7d8c3 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 19 Oct 2016 17:37:00 +0300 Subject: doc: Add missing documentation for QXcbWindowFunctions::setWmWindowRole() Change-Id: I5a457eb19fee011868cdf6d0534713c760fd57d2 Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- .../xcbfunctions/qxcbwindowfunctions.qdoc | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc index b26255553f..8d9c85a5c3 100644 --- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc +++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc @@ -85,6 +85,35 @@ relayed to the function retrieved by QGuiApplication. */ +/*! + \typedef QXcbWindowFunctions::SetWmWindowRole + \since 5.6.2 + + This is the typedef for the function returned by + QGuiApplication::platformFunction when passed the + value returned by setWmWindowRoleIdentifier(). +*/ + +/*! + \fn QByteArray QXcbWindowFunctions::setWmWindowRoleIdentifier() + \since 5.6.2 + + This function returns the byte array that can be used to query + QGuiApplication::platformFunction to retrieve the SetWmWindowRole function. +*/ + +/*! + \fn void QXcbWindowFunctions::setWmWindowRole(QWindow *window, const QByteArray &role) + \since 5.6.2 + + Sets the WM_WINDOW_ROLE property from \role on the corresponding + X11 window. + + This is a convenience function that can be used directly instead + of resolving the function pointer. \a window and \a role will be + relayed to the function retrieved by QGuiApplication. +*/ + /*! \typedef QXcbWindowFunctions::SetWmWindowIconText -- cgit v1.2.1 From 49e3b2f27e86c8f8a0b01334649e7bef2d20fecb Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 4 Nov 2016 13:05:28 +0100 Subject: Disable PCH for qdrawhelper.cpp with GCC 5 Precompiled headers with GCC 5.3.1 causes internal compiler error in qdrawhelper.cpp, so compile this specific file without PCH. Task-number: QTBUG-54154 Change-Id: Id5d9fe99cbeca58a60734510898e4ccb9694c203 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/painting.pri | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 33db1ea0b4..86e35c39f8 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -108,6 +108,12 @@ qtConfig(cssparser) { painting/qcssutil.cpp } +# Causes internal compiler errors with at least GCC 5.3.1: +gcc:equals(QT_GCC_MAJOR_VERSION, 5) { + SOURCES -= painting/qdrawhelper.cpp + NO_PCH_SOURCES += painting/qdrawhelper.cpp +} + SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \ -- cgit v1.2.1 From 468eeca88ea1a398bc15ea156a4b1609dc23a018 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 10 Nov 2016 16:44:50 +0100 Subject: fix showing lgpl in the license prompt the response is lowercased, so an uppercase L would never match. amends c7c7cf636. Change-Id: Idc796ec9a43bfd23452cd758100cbf1fb6fb252b Reviewed-by: Kai Koehne Reviewed-by: Joerg Bornemann --- tools/configure/configureapp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 263cd6e78c..4639709602 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4514,7 +4514,7 @@ bool Configure::showLicense(QString orgLicenseFile) return false; } else { if (dictionary["EDITION"] == "OpenSource") { - if (accept == 'L') + if (accept == 'l') licenseFile = orgLicenseFile + "/LICENSE.LGPL3"; else licenseFile = orgLicenseFile + "/LICENSE.GPL2"; -- cgit v1.2.1 From c214379156e4c75dcfe59cf73d69b912f4293303 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 14 Nov 2016 10:49:35 +0100 Subject: winrt: Fix definition of GL_GLEXT_PROTOTYPES in qwinrtbackingstore We have to make sure that GL_GLEXT_RPOTOTYPES is defined when qplatformbackingstore.h is included. Without the definition glBlitFramebufferANGLE will not be set and compilation might fail. Task-number: QTBUG-57083 Change-Id: I4cacaf4c2851913b3437ebd1f0f2956d0f400553 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/winrt/qwinrtbackingstore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h index ce99718548..41b27debcc 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.h +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h @@ -40,6 +40,7 @@ #ifndef QWINRTBACKINGSTORE_H #define QWINRTBACKINGSTORE_H +#define GL_GLEXT_PROTOTYPES #include #include #include -- cgit v1.2.1 From 8d6522ddd0dcc90e0551f87be9d1a6452f365548 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 10 Nov 2016 09:42:35 +0100 Subject: Freetype: Fix device pixel ratio with large fonts When the dpr scale caused pixel sizes to reach 64 pixels and up, thus triggering the outline drawing fallback, we would render the glyphs at the original size but scale the glyph positions, giving broken rendering. This was because we did not actually pass the matrix to the fallback function when getting the alpha maps. Fixing it revealed a different problem, which was that the bounding box for the glyphs, returned by alphaMapBoundingBox() did not actually apply the transform when outline drawing was enabled. [ChangeLog][QtGui][Text] Fixed rendering of large fonts when a device pixel ratio is set and the Freetype engine is used. Task-number: QTBUG-55856 Change-Id: I03d9066faf0e4346628a4eb630f0dd74a81ef148 Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 91 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 6d575e0e88..c7b932d4ab 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -889,6 +889,42 @@ static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info) || (uchar)(info.height) != info.height; } +static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix) +{ + int l, r, t, b; + FT_Vector vector; + vector.x = *left; + vector.y = *top; + FT_Vector_Transform(&vector, matrix); + l = r = vector.x; + t = b = vector.y; + vector.x = *right; + vector.y = *top; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = *right; + vector.y = *bottom; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = *left; + vector.y = *bottom; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + *left = l; + *right = r; + *top = t; + *bottom = b; +} + QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, @@ -978,10 +1014,19 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.yOff = 0; if ((set && set->outline_drawing) || fetchMetricsOnly) { - int left = FLOOR(slot->metrics.horiBearingX); - int right = CEIL(slot->metrics.horiBearingX + slot->metrics.width); - int top = CEIL(slot->metrics.horiBearingY); - int bottom = FLOOR(slot->metrics.horiBearingY - slot->metrics.height); + int left = slot->metrics.horiBearingX; + int right = slot->metrics.horiBearingX + slot->metrics.width; + int top = slot->metrics.horiBearingY; + int bottom = slot->metrics.horiBearingY - slot->metrics.height; + + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) + transformBoundingBox(&left, &top, &right, &bottom, &matrix); + + left = FLOOR(left); + right = CEIL(right); + bottom = FLOOR(bottom); + top = CEIL(top); + info.x = TRUNC(left); info.y = TRUNC(top); info.width = TRUNC(right - left); @@ -1044,40 +1089,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, int right = slot->metrics.horiBearingX + slot->metrics.width; int top = slot->metrics.horiBearingY; int bottom = slot->metrics.horiBearingY - slot->metrics.height; - if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { - int l, r, t, b; - FT_Vector vector; - vector.x = left; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - l = r = vector.x; - t = b = vector.y; - vector.x = right; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = right; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = left; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - left = l; - right = r; - top = t; - bottom = b; - } + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) + transformBoundingBox(&left, &top, &right, &bottom, &matrix); left = FLOOR(left); right = CEIL(right); bottom = FLOOR(bottom); @@ -1962,7 +1975,7 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const if (!img.isNull()) return img; - return QFontEngine::alphaMapForGlyph(g); + return QFontEngine::alphaMapForGlyph(g, subPixelPosition, t); } QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) -- cgit v1.2.1 From 104e6d0f5427f5ebaab106b1651eb76c4c56df98 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 10 Nov 2016 12:33:39 +0100 Subject: Freetype: Disable outline drawing when drawing to pixmap cache When we are anyway caching the rendered glyphs in a texture, like when doing native text rendering in the scene graph, the outline drawing fallback does not make sense. In fact, when used together with a dpr scale factor, it would cause text to be blurry, since it would first render the QPainterPath at the set pixel size and then scale the image. In practice, there isn't any real clients of the internal outline_drawing property in the Freetype engine anymore, since this is now handled independently of the font engines in the QPaintEngineEx::shouldDrawCachedGlyphs(), but in case we at any point would want to be compatible with the X11 paint engine again, we might as well keep it around. Task-number: QTBUG-55856 Change-Id: Ie090c596fe5cda2b598fa152a488881d50f86d2c Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 16 +++++++++------- src/gui/text/qfontengine_ft_p.h | 8 ++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index c7b932d4ab..de6da88245 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -928,7 +928,8 @@ static inline void transformBoundingBox(int *left, int *top, int *right, int *bo QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, - bool fetchMetricsOnly) const + bool fetchMetricsOnly, + bool disableOutlineDrawing) const { // Q_ASSERT(freetype->lock == 1); @@ -1013,7 +1014,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; - if ((set && set->outline_drawing) || fetchMetricsOnly) { + if ((set && set->outline_drawing && !disableOutlineDrawing) || fetchMetricsOnly) { int left = slot->metrics.horiBearingX; int right = slot->metrics.horiBearingX + slot->metrics.width; int top = slot->metrics.horiBearingY; @@ -1931,10 +1932,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, - bool fetchBoundingBox) + bool fetchBoundingBox, + bool disableOutlineDrawing) { QGlyphSet *glyphSet = loadGlyphSet(t); - if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox) + if (glyphSet != 0 && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox) return 0; Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; @@ -1948,7 +1950,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t); FT_Matrix_Multiply(&ftMatrix, &m); freetype->matrix = m; - glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false); + glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false, disableOutlineDrawing); unlockFace(); } @@ -1964,7 +1966,7 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const { const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono; - Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true); QImage img = alphaMapFromGlyphData(glyph, neededFormat); img = img.copy(); @@ -1985,7 +1987,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co const GlyphFormat neededFormat = Format_A32; - Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true); QImage img = alphaMapFromGlyphData(glyph, neededFormat); img = img.copy(); diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 5ca3721c71..32357d0076 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -272,10 +272,10 @@ private: inline bool isBitmapFont() const { return defaultFormat == Format_Mono; } inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); } - inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false) const - { return loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, subPixelPosition, format, fetchMetricsOnly); } - Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const; - Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false); + inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const + { return loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); } + Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const; + Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false, bool disableOutlineDrawing = false); QGlyphSet *loadGlyphSet(const QTransform &matrix); -- cgit v1.2.1 From 8db556d29919fd0c0ddb23b743cb5e6c218b1ae2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 9 Nov 2016 13:11:31 +0100 Subject: fix $$section()'s bad argument count error message the autotest was also broken, because it was created by pasting the bogus message into the result ... Change-Id: I02b8663b96c7d96cdb3c19639e2213e49fd2bcec Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 3 +-- tests/auto/tools/qmakelib/evaltest.cpp | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 8f3849e6d8..c8208909b6 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -478,8 +478,7 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( int end = -1; if (func_t == E_SECTION) { if (args.count() != 3 && args.count() != 4) { - evalError(fL1S("%1(var) section(var, sep, begin, end) requires" - " three or four arguments.").arg(func.toQString(m_tmp1))); + evalError(fL1S("section(var, sep, begin, end) requires three or four arguments.")); } else { var = args[0]; sep = args.at(1).toQString(); diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index 09482d86d9..3c96c6fb7a 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -1125,8 +1125,8 @@ void tst_qmakelib::addReplaceFunctions(const QString &qindir) QTest::newRow("$$section(): bad number of arguments") << "VAR = $$section(1, 2) \\\n$$section(1, 2, 3, 4, 5)" << "VAR =" - << "##:1: section(var) section(var, sep, begin, end) requires three or four arguments.\n" - "##:2: section(var) section(var, sep, begin, end) requires three or four arguments." + << "##:1: section(var, sep, begin, end) requires three or four arguments.\n" + "##:2: section(var, sep, begin, end) requires three or four arguments." << true; QTest::newRow("$$find()") -- cgit v1.2.1 From 9308b7d618db7f08768b11c17b661853c66005e4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Nov 2016 13:41:27 +0100 Subject: don't create bogus property variants sysroot, spec, and xspec have no /src and /get variants. Change-Id: I8548791f8ea6ba9fd9f10c35f914ed6badbea9d4 Reviewed-by: Joerg Bornemann --- qmake/property.cpp | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/qmake/property.cpp b/qmake/property.cpp index 817ae953d5..b9139d5be1 100644 --- a/qmake/property.cpp +++ b/qmake/property.cpp @@ -46,38 +46,41 @@ static const struct { const char *name; QLibraryInfo::LibraryLocation loc; bool raw; + bool singular; } propList[] = { - { "QT_SYSROOT", QLibraryInfo::SysrootPath, true }, - { "QT_INSTALL_PREFIX", QLibraryInfo::PrefixPath, false }, - { "QT_INSTALL_ARCHDATA", QLibraryInfo::ArchDataPath, false }, - { "QT_INSTALL_DATA", QLibraryInfo::DataPath, false }, - { "QT_INSTALL_DOCS", QLibraryInfo::DocumentationPath, false }, - { "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath, false }, - { "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath, false }, - { "QT_INSTALL_LIBEXECS", QLibraryInfo::LibraryExecutablesPath, false }, - { "QT_INSTALL_BINS", QLibraryInfo::BinariesPath, false }, - { "QT_INSTALL_TESTS", QLibraryInfo::TestsPath, false }, - { "QT_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, false }, - { "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, false }, - { "QT_INSTALL_QML", QLibraryInfo::Qml2ImportsPath, false }, - { "QT_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, false }, - { "QT_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, false }, - { "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, false }, - { "QT_INSTALL_DEMOS", QLibraryInfo::ExamplesPath, false }, // Just backwards compat - { "QT_HOST_PREFIX", QLibraryInfo::HostPrefixPath, true }, - { "QT_HOST_DATA", QLibraryInfo::HostDataPath, true }, - { "QT_HOST_BINS", QLibraryInfo::HostBinariesPath, true }, - { "QT_HOST_LIBS", QLibraryInfo::HostLibrariesPath, true }, - { "QMAKE_SPEC", QLibraryInfo::HostSpecPath, true }, - { "QMAKE_XSPEC", QLibraryInfo::TargetSpecPath, true }, + { "QT_SYSROOT", QLibraryInfo::SysrootPath, true, true }, + { "QT_INSTALL_PREFIX", QLibraryInfo::PrefixPath, false, false }, + { "QT_INSTALL_ARCHDATA", QLibraryInfo::ArchDataPath, false, false }, + { "QT_INSTALL_DATA", QLibraryInfo::DataPath, false, false }, + { "QT_INSTALL_DOCS", QLibraryInfo::DocumentationPath, false, false }, + { "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath, false, false }, + { "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath, false, false }, + { "QT_INSTALL_LIBEXECS", QLibraryInfo::LibraryExecutablesPath, false, false }, + { "QT_INSTALL_BINS", QLibraryInfo::BinariesPath, false, false }, + { "QT_INSTALL_TESTS", QLibraryInfo::TestsPath, false, false }, + { "QT_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, false, false }, + { "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, false, false }, + { "QT_INSTALL_QML", QLibraryInfo::Qml2ImportsPath, false, false }, + { "QT_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, false, false }, + { "QT_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, false, false }, + { "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, false, false }, + { "QT_INSTALL_DEMOS", QLibraryInfo::ExamplesPath, false, false }, // Just backwards compat + { "QT_HOST_PREFIX", QLibraryInfo::HostPrefixPath, true, false }, + { "QT_HOST_DATA", QLibraryInfo::HostDataPath, true, false }, + { "QT_HOST_BINS", QLibraryInfo::HostBinariesPath, true, false }, + { "QT_HOST_LIBS", QLibraryInfo::HostLibrariesPath, true, false }, + { "QMAKE_SPEC", QLibraryInfo::HostSpecPath, true, true }, + { "QMAKE_XSPEC", QLibraryInfo::TargetSpecPath, true, true }, }; QMakeProperty::QMakeProperty() : settings(0) { for (unsigned i = 0; i < sizeof(propList)/sizeof(propList[0]); i++) { QString name = QString::fromLatin1(propList[i].name); - m_values[ProKey(name + "/src")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectiveSourcePaths); - m_values[ProKey(name + "/get")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths); + if (!propList[i].singular) { + m_values[ProKey(name + "/src")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectiveSourcePaths); + m_values[ProKey(name + "/get")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::EffectivePaths); + } QString val = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::FinalPaths); if (!propList[i].raw) { m_values[ProKey(name + "/dev")] = QLibraryInfo::rawLocation(propList[i].loc, QLibraryInfo::DevicePaths); -- cgit v1.2.1 From 4e1d65071b0984fc9570b7328be3142b11b740d2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 10 Nov 2016 16:51:24 +0100 Subject: fix wording issues in license prompt Task-number: QTBUG-42136 Change-Id: Ie4ff1b38af6e7a74490558e80a0e559fee8a5486 Reviewed-by: Kai Koehne --- configure | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 0b8b417bbc..6ebeab30fe 100755 --- a/configure +++ b/configure @@ -3108,14 +3108,14 @@ if [ "$Edition" = "OpenSource" ]; then while true; do if [ "$CFG_ANDROID_STYLE_ASSETS" = "no" ] || [ "$XPLATFORM_ANDROID" = "no" ]; then echo "You are licensed to use this software under the terms of" - echo "the Lesser GNU General Public License (LGPL) versions 2.1." + echo "the GNU Lesser General Public License (LGPL) version 2.1." echo "You are also licensed to use this software under the terms of" - echo "the GNU Lesser General Public License (LGPL) versions 3." + echo "the GNU Lesser General Public License (LGPL) version 3." affix="either" showLGPL2="yes" else echo "You are licensed to use this software under the terms of" - echo "the GNU Lesser General Public License (LGPL) versions 3." + echo "the GNU Lesser General Public License (LGPL) version 3." showLGPL2="no" affix="the" fi @@ -3129,7 +3129,7 @@ if [ "$Edition" = "OpenSource" ]; then echo "Type '3' to view the GNU Lesser General Public License version 3." fi if [ "$showLGPL2" = "yes" ]; then - echo "Type 'L' to view the Lesser GNU General Public License version 2.1." + echo "Type 'L' to view the GNU Lesser General Public License version 2.1." fi echo "Type 'yes' to accept this license offer." echo "Type 'no' to decline this license offer." -- cgit v1.2.1 From 6bfe30a0bf33f300f80f87026177f4da8f54df13 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 10 Nov 2016 17:08:07 +0100 Subject: drop obsolete file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amends 97fcf3bc9 (introduction of official android port). Change-Id: Iaab596559c5d4c825269cbdda77d956c3650fb09 Reviewed-by: Joerg Bornemann Reviewed-by: Jake Petroules Reviewed-by: BogDan Vatra Reviewed-by: Otto Ryynänen --- mkspecs/common/linux-android.conf | 114 -------------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 mkspecs/common/linux-android.conf diff --git a/mkspecs/common/linux-android.conf b/mkspecs/common/linux-android.conf deleted file mode 100644 index fec008cb45..0000000000 --- a/mkspecs/common/linux-android.conf +++ /dev/null @@ -1,114 +0,0 @@ -MAKEFILE_GENERATOR = UNIX -QMAKE_INCREMENTAL_STYLE = sublib - -QMAKE_PLATFORM += android - -include(linux.conf) -include(gcc-base-unix.conf) - -DEFINES += QT_NO_PRINTER QT_NO_PRINTDIALOG -QT_QPA_DEFAULT_PLATFORM = minimal - -NDK_ROOT = $$(ANDROID_NDK_ROOT) -isEmpty(NDK_ROOT): error("$ANDROID_NDK_ROOT is empty, please set it to something like ~/android/ndk-r7c") - -NDK_HOST = $$(ANDROID_NDK_HOST) -isEmpty(NDK_HOST): error("$ANDROID_NDK_HOST is empty, please set it to something like linux-x86 or darwin-x86") - -ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM) -isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = android-5 - -NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) -isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = 4.4.3 - -!contains(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION - -NDK_TOOLCHAIN = $$ANDROID_NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION -NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST - -CONFIG += $$ANDROID_PLATFORM $$ANDROID_TARGET_ARCH -ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ -ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr - -# used to compile platform plugins for android-4 and android-5 -QMAKE_ANDROID_PLATFORM_INCDIR = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/usr/include -QMAKE_ANDROID_PLATFORM_LIBDIR = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/usr/lib - -ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl$$ANDROID_CXXSTL_SUFFIX/gnu-libstdc++/libs/$$ANDROID_TARGET_ARCH -ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl$$ANDROID_CXXSTL_SUFFIX/gnu-libstdc++/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include - -# modifications to g++.conf -QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-gcc - -QMAKE_CFLAGS_WARN_ON = -Wall -Wextra -QMAKE_CFLAGS_WARN_OFF = -Wno-psabi - -QMAKE_CFLAGS_SHLIB = -fPIC -QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -QMAKE_CFLAGS_THREAD = -D_REENTRANT -QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden - -QMAKE_CXX = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-g++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF -QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE -QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG -QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD -QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden - -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_LINK - -# modifications to linux.conf -QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-ar cqs -QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-objcopy -QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-nm -P -QMAKE_STRIP = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-strip -QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-ranlib - -QMAKE_INCDIR = $$ANDROID_PLATFORM_PATH/include $$ANDROID_SOURCES_CXX_STL_INCDIR -QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$ANDROID_PLATFORM_PATH/lib -QMAKE_INCDIR_X11 = -QMAKE_LIBDIR_X11 = -QMAKE_INCDIR_OPENGL = -QMAKE_INCDIR_OPENGL_ES2 = -QMAKE_LIBDIR_OPENGL_ES2 = - -contains(ANDROID_TARGET_ARCH, x86): LIBGCC_PATH_FULL = $$system($$QMAKE_CC -print-libgcc-file-name) - else: LIBGCC_PATH_FULL = $$system($$QMAKE_CC -mthumb-interwork -print-libgcc-file-name) - -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX -QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -L$$dirname(LIBGCC_PATH_FULL) -Wl,-rpath-link=$$ANDROID_PLATFORM_PATH/lib -QMAKE_LFLAGS_APP = -QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared - -contains(NDK_ROOT, ".*r[56].*") { - !contains(ANDROID_PLATFORM, ".*android-[458].*") { - message("Your NDK-version is out-dated. A work-around is enabled. Consider updating your NDK (workarounds are required until r6(a))") - QMAKE_LFLAGS_SHLIB += $$ANDROID_PLATFORM_PATH/lib/crtbegin_so.o $$ANDROID_PLATFORM_PATH/lib/crtend_so.o - } -} - -QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -QMAKE_LFLAGS_SONAME = -QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined -QMAKE_LFLAGS_RPATH = -Wl,-rpath= - -# TODO: -lgnustl_static was -lstdc++, but that leads to undefined reference to -# std::__throw_bad_alloc during configure. -QMAKE_LIBS = -lsupc++ -llog -lz -lm -ldl -lc -lgcc -lgnustl_static -QMAKE_LIBS_X11 = -QMAKE_LIBS_X11SM = -QMAKE_LIBS_QT_THREAD = -QMAKE_LIBS_QT_OPENGL = -QMAKE_LIBS_QTOPIA = -QMAKE_LIBS_THREAD = -QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS - -load(qt_config) - -- cgit v1.2.1 From d91bf00c43736940e4139357e288df6432775a3d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 8 Jun 2016 12:06:29 +0200 Subject: tst_QFileSystemModel::specialFiles(): Remove Windows parts The test created a Windows shortcut (.lnk) and checked on its existence. It was not found in the first test since QFileSystemModel returned the resolved file name (linktarget.txt). When fixing this by querying QFileSystemModel::fileInfo()::fileName(), the 2nd test failed since shortcut files are not considered system files. Amends change 3b093034b638a69b4dc91212d1743638864a1337. Task-number: QTBUG-53890 Task-number: QTBUG-20968 Task-number: QTBUG-29403 Change-Id: Iec58b52532b44d12759eaa6c8d63a8a4dc8d1bc3 Reviewed-by: Joerg Bornemann --- .../dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index af92f0735d..cb0f0b040a 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -1097,6 +1097,10 @@ static QSet fileListUnderIndex(const QFileSystemModel *model, const QMo void tst_QFileSystemModel::specialFiles() { +#ifndef Q_OS_UNIX + QSKIP("Not implemented"); +#endif + QFileSystemModel model; model.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); @@ -1105,23 +1109,8 @@ void tst_QFileSystemModel::specialFiles() // as it will always return a valid index for existing files, // even if the file is not visible with the given filter. -#if defined(Q_OS_UNIX) const QModelIndex rootIndex = model.setRootPath(QStringLiteral("/dev/")); const QString testFileName = QStringLiteral("null"); -#elif defined(Q_OS_WIN) - const QModelIndex rootIndex = model.setRootPath(flatDirTestPath); - - const QString testFileName = QStringLiteral("linkSource.lnk"); - - QFile file(flatDirTestPath + QLatin1String("/linkTarget.txt")); - QVERIFY(file.open(QIODevice::WriteOnly)); - file.close(); - QVERIFY(file.link(flatDirTestPath + '/' + testFileName)); -#else - QSKIP("Not implemented"); - QModelIndex rootIndex; - QString testFileName; -#endif QTRY_VERIFY(fileListUnderIndex(&model, rootIndex).contains(testFileName)); -- cgit v1.2.1 From addf1f45f3e2c37a09ef7f7bab909467c2bf79f7 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 11 Nov 2016 12:34:54 -0800 Subject: qmake: fix installation of asset catalog files This strips leading whitespace from asset catalog filenames, which was causing installation to fail due to incorrectly calculated paths. Task-number: QTBUG-57090 Change-Id: I80db627262f9d58f4403e2d8ab205bef2113992b Reviewed-by: Oswald Buddenhagen --- mkspecs/features/mac/asset_catalogs.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/mac/asset_catalogs.prf b/mkspecs/features/mac/asset_catalogs.prf index 57d93d56d5..87875136c2 100644 --- a/mkspecs/features/mac/asset_catalogs.prf +++ b/mkspecs/features/mac/asset_catalogs.prf @@ -65,7 +65,7 @@ actool_output_files = $$system(\ mkdir -p $$system_quote($$QMAKE_ASSET_CATALOGS_BUILD_PATH) && \ /usr/libexec/PlistBuddy -c \'Print :com.apple.actool.compilation-results:output-files\' \ - /dev/stdin <<< $($${asset_catalog_compiler.commands} 2>/dev/null) | grep \'^ .*$\', lines) + /dev/stdin <<< $($${asset_catalog_compiler.commands} 2>/dev/null) | sed -Ene \'s/^ +//p\', lines) for (output_file, actool_output_files) { !equals(output_file, $$asset_catalog_compiler.target): \ -- cgit v1.2.1 From aeb2768a7c5b23260e6ca0826b844777b9948b6c Mon Sep 17 00:00:00 2001 From: Hannah von Reth Date: Fri, 11 Nov 2016 10:02:34 +0100 Subject: Introduce QMAKE_CD to enable us to cd from one Windows drive to another On Windows cd does not change the drive. So when you are on drive C: and type "cd D:\data" it will change the directory on drive D: but not affect your current working directory. To also change your drive you have to provide the parameter /d on Windows, so "cd /d D:\data" will also change the drive. Task-number: QTBUG-57080 Change-Id: Ib629879534523982eec693cef725f20a535a1a74 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/configure.prf | 2 +- mkspecs/features/ctest_testcase_common.prf | 2 +- mkspecs/features/qt_configure.prf | 4 ++-- mkspecs/features/qt_parts.prf | 2 +- mkspecs/features/spec_post.prf | 2 ++ mkspecs/features/testcase.prf | 2 +- mkspecs/features/uikit/xcodebuild.prf | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 147d6f178c..62eae6d813 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -31,7 +31,7 @@ defineTest(qtCompileTest) { test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$1 test_out_dir = $$shadowed($$test_dir) - test_cmd_base = "cd $$system_quote($$system_path($$test_out_dir)) &&" + test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&" # Disable qmake features which are typically counterproductive for tests qmake_configs = "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\"" diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf index af80fc00a1..8cdad77a78 100644 --- a/mkspecs/features/ctest_testcase_common.prf +++ b/mkspecs/features/ctest_testcase_common.prf @@ -86,7 +86,7 @@ for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) { CMAKE_MODULES_UNDER_TEST = $$join(CMAKE_MODULES_UNDER_TEST, ;) check.commands = \ - $(MKDIR) $$BUILD_DIR && cd $$BUILD_DIR && \ + $(MKDIR) $$BUILD_DIR && $$QMAKE_CD $$BUILD_DIR && \ cmake $$CMAKE_TEST_LOCATION $$CMAKE_GENERATOR \ -DCMAKE_C_COMPILER=$$QMAKE_CC \ -DCMAKE_CXX_COMPILER=$$QMAKE_CXX \ diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index d5b9c6dc11..47772be8de 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -324,7 +324,7 @@ defineTest(qtConfParseCommandLine) { defineReplace(qtConfToolchainSupportsFlag) { test_out_dir = $$shadowed($$QMAKE_CONFIG_TESTS_DIR) - test_cmd_base = "cd $$system_quote($$system_path($$test_out_dir)) &&" + test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&" conftest = "int main() { return 0; }" write_file("$$test_out_dir/conftest.cpp", conftest)|error() @@ -696,7 +696,7 @@ defineTest(qtConfTest_compile) { test_out_dir = $$shadowed($$test_dir) !isEmpty($${1}.pro): \ test_dir = $$test_dir/$$eval($${1}.pro) - test_cmd_base = "cd $$system_quote($$system_path($$test_out_dir)) &&" + test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&" qmake_args = $$qtConfPkgConfigEnv()$$system_quote($$system_path($$QMAKE_QMAKE)) !isEmpty(QMAKE_QTCONF): \ diff --git a/mkspecs/features/qt_parts.prf b/mkspecs/features/qt_parts.prf index 0accef6665..67e218ca73 100644 --- a/mkspecs/features/qt_parts.prf +++ b/mkspecs/features/qt_parts.prf @@ -88,7 +88,7 @@ for (t, tests): \ testdirs = $$unique(testdirs) for (td, testdirs) { t = $$basename(td)-distclean - $${t}.commands = -cd $$shell_path($$td) && $(MAKE) distclean + $${t}.commands = -$$QMAKE_CD $$shell_path($$td) && $(MAKE) distclean QMAKE_EXTRA_TARGETS += $$t DISTCLEAN_DEPS += $$t } diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf index 234189fed1..f87bf3c037 100644 --- a/mkspecs/features/spec_post.prf +++ b/mkspecs/features/spec_post.prf @@ -67,6 +67,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ |isEmpty(QMAKE_SH) { QMAKE_ZIP = zip -r -9 + QMAKE_CD = cd /d QMAKE_COPY = copy /y QMAKE_COPY_FILE = $$QMAKE_COPY QMAKE_COPY_DIR = xcopy /s /q /y /i @@ -87,6 +88,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ QMAKE_TAR = tar -cf QMAKE_GZIP = gzip -9f + QMAKE_CD = cd QMAKE_COPY = cp -f QMAKE_COPY_FILE = $$QMAKE_COPY QMAKE_COPY_DIR = $$QMAKE_COPY -R diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index 83ff177856..c202664c47 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -49,7 +49,7 @@ unix { $${type}.commands += $(TESTARGS) !isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD, ^\\./?): \ - $${type}.commands = cd $$shell_path($$TESTRUN_CWD) && $$eval($${type}.commands) + $${type}.commands = $$QMAKE_CD $$shell_path($$TESTRUN_CWD) && $$eval($${type}.commands) # If the test is marked as insignificant, discard the exit code insignificant_test: $${type}.commands = -$$eval($${type}.commands) diff --git a/mkspecs/features/uikit/xcodebuild.prf b/mkspecs/features/uikit/xcodebuild.prf index df015b583a..a766b9ea5c 100644 --- a/mkspecs/features/uikit/xcodebuild.prf +++ b/mkspecs/features/uikit/xcodebuild.prf @@ -27,7 +27,7 @@ for(arg, QMAKE_ARGS) { cmd = "$$QMAKE_QMAKE $$system_quote($$_PRO_FILE_) -spec macx-xcode $$args" debug(1, "Generating Xcode project in $$OUT_PWD using '$$cmd'") -system("cd $$system_quote($$OUT_PWD) && $$cmd") +system("$$QMAKE_CD $$system_quote($$OUT_PWD) && $$cmd") # Subtargets -- cgit v1.2.1 From 80842959c4f63be930c77da39df7ac386dcaa1d7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 12 Nov 2016 21:01:20 +0100 Subject: Revert "Optimize QJsonObject::operator==" This reverts commit 862fa24179505ef725ff78bb64bdabd54bd00c95, which attempted to optimize QJsonObject::operator== under the assumption that the entries it holds are lexicographically sorted. They should be, because Object::indexOf() finds them by binary search, but apparently both fromJson(), as well as construction through op[] leave (some) entries unsorted. This behavior should be fixed, because other code relies on sorted entries, too, but until the problem is more fully under- stood, revert the patch to unbreak equality comparisons. Task-number: QTBUG-56843 Change-Id: I5b608c16d1bbcb4f01b75ce93bd58b49ff050be2 Reviewed-by: Lars Knoll --- src/corelib/json/qjson_p.h | 2 -- src/corelib/json/qjsonobject.cpp | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index c5fd38e640..5be31ca03f 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -691,8 +691,6 @@ public: bool operator >=(const Entry &other) const; }; -inline bool operator!=(const Entry &lhs, const Entry &rhs) { return !(lhs == rhs); } - inline bool Entry::operator >=(const QString &key) const { if (value.latinKey) diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index f5fd76eac0..b83c8dd19a 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -545,8 +545,8 @@ bool QJsonObject::operator==(const QJsonObject &other) const for (uint i = 0; i < o->length; ++i) { QJsonPrivate::Entry *e = o->entryAt(i); - QJsonPrivate::Entry *oe = other.o->entryAt(i); - if (*e != *oe || QJsonValue(d, o, e->value) != QJsonValue(other.d, other.o, oe->value)) + QJsonValue v(d, o, e->value); + if (other.value(e->key()) != v) return false; } -- cgit v1.2.1 From 6de11782d093dea2e6fe9406fb712706a984ff61 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 11 Nov 2016 09:09:12 +0100 Subject: Allow checking for the existence of modules in configure.json You can now use 'module.gui' to check whether the Qt Gui module exists in the current build of Qt. Task-number: QTBUG-56656 Change-Id: Ic73f162ed0578e07c70e3ec3706f285b6d09a41d Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_configure.prf | 45 +++++++++++++++++++++++++++++++++++---- mkspecs/features/qt_module.prf | 4 ++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 47772be8de..bdf9f21fc9 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -932,6 +932,15 @@ defineTest(qtRunSingleTest) { qtConfSaveResult($${tpfx}, $$1) } +defineTest(qtConfHaveModule) { + module = $$replace(1, -, _) + !isEmpty(QT.$${module}.skip):$$eval(QT.$${module}.skip): \ + return(false) + !isEmpty(QT.$${module}.name): \ + return(true) + return(false) +} + defineReplace(qtConfEvaluate) { isEmpty(1): return(true) @@ -1015,6 +1024,10 @@ defineReplace(qtConfEvaluateSingleExpression) { var = $$replace(e, "^config\.", "") result = false contains(CONFIG, $$var): result = true + } else: contains(e, "^module\..*") { + var = $$replace(e, "^module\.", "") + result = false + qtConfHaveModule($$var): result = true } else: contains(e, "^arch\..*") { var = $$replace(e, "^arch\.", "") result = false @@ -1183,6 +1196,17 @@ defineTest(qtConfCheckFeature) { return(true) } +defineTest(qtConfCheckModuleCondition) { + QT.$${currentModule}.skip = false + !$$qtConfEvaluate($$eval($${currentConfig}.condition)): \ + QT.$${currentModule}.skip = true + export(QT.$${currentModule}.skip) + + # ensure qtConfHaveModule() works + QT.$${currentModule}.name = - + export(QT.$${currentModule}.name) +} + defineTest(qtConfProcessFeatures) { for (feature, $${currentConfig}.features._KEYS_): \ @@ -1758,15 +1782,28 @@ for (currentConfig, allConfigs) { } } - # process all features - qtConfProcessFeatures() + qtConfCheckModuleCondition() + + qtConfHaveModule($$currentModule) { + # process all features + qtConfProcessFeatures() + } else { + qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}.skip", "true") + } # generate files and reports qtConfProcessOutput() - qtConfCreateReport() - qtConfCreateSummary() + qtConfHaveModule($$currentModule) { + qtConfCreateReport() + qtConfCreateSummary() + } else { + QT_CONFIGURE_SKIPPED_MODULES += " $$currentModule" + } } +!isEmpty(QT_CONFIGURE_SKIPPED_MODULES): \ + qtConfAddNote("The following modules are not being compiled in this configuration:" $$QT_CONFIGURE_SKIPPED_MODULES) + # these come from the pri files loaded above. for (p, QMAKE_POST_CONFIGURE): \ eval($$p) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 069eec02eb..31d628596c 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -18,6 +18,10 @@ exists($$OUT_PWD/qt$${MODULE}-config.pri) { CONFIG += generated_privates } +skip = $$eval(QT.$${MODULE}.skip) +isEmpty(skip): skip = false +requires(!$$skip) + # Compile as shared/DLL or static according to the option given to configure # unless overridden. Host builds are always static host_build|staticlib: CONFIG += static -- cgit v1.2.1 From 94f9ee79a65636f1bf96671ad11641b1f6c7421a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 11 Nov 2016 09:13:53 +0100 Subject: Clean up some conditions in our pro files Change qtConfig(opengl(es2)?) to qtConfig(opengl) as that covers the case without any regular expression. Change-Id: I935e3150f87e195e8bd3d0e55b4ed43572b131cf Reviewed-by: Oswald Buddenhagen --- examples/widgets/widgets.pro | 4 +--- src/gui/kernel/kernel.pri | 2 +- src/gui/opengl/opengl.pri | 2 +- src/src.pro | 4 ++-- tests/auto/gui/gui.pro | 2 +- tests/auto/gui/kernel/kernel.pro | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro index 65a96dd718..513ddc91f2 100644 --- a/examples/widgets/widgets.pro +++ b/examples/widgets/widgets.pro @@ -22,11 +22,9 @@ SUBDIRS = \ tutorials \ widgets -qtConfig(opengl(es2)?) { +qtConfig(opengl): \ SUBDIRS += windowcontainer -} -!qtConfig(opengl(es2)?): SUBDIRS -= windowcontainer contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows contains(DEFINES, QT_NO_DRAGANDDROP): SUBDIRS -= draganddrop mac:SUBDIRS += mac diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 3b7e03a0ff..792ca9fbaf 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -139,7 +139,7 @@ SOURCES += \ kernel/qhighdpiscaling.cpp -qtConfig(opengl(es2)?) { +qtConfig(opengl) { HEADERS += \ kernel/qplatformopenglcontext.h \ kernel/qopenglcontext.h \ diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index 2c3cca6b18..712cf144e0 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -3,7 +3,7 @@ qtConfig(opengl): CONFIG += opengl qtConfig(opengles2): CONFIG += opengles2 -qtConfig(opengl(es2)?) { +qtConfig(opengl) { HEADERS += opengl/qopengl.h \ opengl/qopengl_p.h \ diff --git a/src/src.pro b/src/src.pro index 87391eab5b..f19b0bd354 100644 --- a/src/src.pro +++ b/src/src.pro @@ -174,7 +174,7 @@ qtConfig(gui) { src_platformsupport.depends += src_3rdparty_freetype } SUBDIRS += src_gui src_platformsupport src_platformheaders - qtConfig(opengl(es2)?): SUBDIRS += src_openglextensions + qtConfig(opengl): SUBDIRS += src_openglextensions src_plugins.depends += src_gui src_platformsupport src_platformheaders src_testlib.depends += src_gui # if QtGui is enabled, QtTest requires QtGui's headers qtConfig(widgets) { @@ -182,7 +182,7 @@ qtConfig(gui) { TOOLS += src_tools_uic src_plugins.depends += src_widgets src_testlib.depends += src_widgets # if QtWidgets is enabled, QtTest requires QtWidgets's headers - qtConfig(opengl(es2)?) { + qtConfig(opengl) { SUBDIRS += src_opengl src_plugins.depends += src_opengl } diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro index 8d8a2df393..2fd3024afe 100644 --- a/tests/auto/gui/gui.pro +++ b/tests/auto/gui/gui.pro @@ -13,4 +13,4 @@ SUBDIRS = \ util \ itemmodels \ -!qtConfig(opengl(es2)?): SUBDIRS -= qopengl qopenglconfig +!qtConfig(opengl): SUBDIRS -= qopengl qopenglconfig diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 631962ad34..559395a9ae 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -34,6 +34,6 @@ win32:!winrt:qtHaveModule(network): SUBDIRS += noqteventloop !qtHaveModule(network): SUBDIRS -= \ qguieventloop -!qtConfig(opengl(es2)?): SUBDIRS -= qopenglwindow +!qtConfig(opengl): SUBDIRS -= qopenglwindow uikit: SUBDIRS -= qclipboard -- cgit v1.2.1 From c64e4bf6b436c779d9ab03fd6886ab8d27c90235 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 9 Nov 2016 15:02:11 +0100 Subject: Make 'use' entries work across module boundaries 'use' entries in the tests and libraries sections of configure.json files should work acrosss library boundaries, so a test in qtwayland can refer to a library from qtbase. Change-Id: Ide02b9985be427a27982a422ca84a29b23145bcf Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_configure.prf | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index bdf9f21fc9..38305890b5 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -675,13 +675,33 @@ defineTest(qtConfTest_library) { defineTest(qtConfTestPrepare_compile) { for (u, $$list($$eval($${1}.use))) { - !contains($${currentConfig}.libraries._KEYS_, $$u): \ - error("Test $$1 tries to use undeclared library '$$u'") - qtConfHandleLibrary($$u) - lpfx = $${currentConfig}.libraries.$${u} - isEmpty($${lpfx}.source): \ - return(false) - $${1}.literal_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source)) + libConfig = + contains($${currentConfig}.libraries._KEYS_, $$u) { + libConfig = $${currentConfig} + qtConfHandleLibrary($$u) + } else { + for (d, QMAKE_CONFIG_DEPS) { + contains($${d}.libraries._KEYS_, $$u) { + libConfig = $$d + break() + } + } + } + isEmpty(libConfig) { + nu = $$upper($$u) + libs = $$eval(QMAKE_LIBS_$$nu) $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$${nu}_RELEASE) + defines = $$eval(QMAKE_DEFINES_$${nu}) + includes = $$eval(QMAKE_INCDIR_$${nu}) + + isEmpty(libs):isEmpty(defines):isEmpty(includes): \ + error("Test $$1 tries to use undeclared library '$$u'") + $${1}.literal_args += $$system_quote(QMAKE_USE += $$u) + } else { + lpfx = $${libConfig}.libraries.$${u} + isEmpty($${lpfx}.source): \ + return(false) + $${1}.literal_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source)) + } } export($${1}.literal_args) return(true) -- cgit v1.2.1 From 291eba6f8099a0fec8fbd9cf8a1fb67e5c9f4f8d Mon Sep 17 00:00:00 2001 From: Palo Kisa Date: Mon, 7 Nov 2016 18:27:17 +0100 Subject: QClipboard: Fix emitting changed() in XCB In XCB environment the QClipboard::changed() was not delivered if the QClipboard::clear() was issued by other Qt app/process. If the QClipboard::clear() is used, then the owner in xcb_xfixes_selection_notify_event_t is XCB_NONE, so we need make the decission to handle this event by the selection_timestamp and our m_timestamp[mode]. Task-number: QTBUG-56972 Change-Id: If4c486ac02223eac506465cac7ff1a07bd02a187 Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index d44ebae8f7..40abef4e50 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -723,8 +723,10 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve if (mode > QClipboard::Selection) return; - // here we care only about the xfixes events that come from non Qt processes - if (event->owner != XCB_NONE && event->owner != owner()) { + // Note1: Here we care only about the xfixes events that come from other processes. + // Note2: If the QClipboard::clear() is issued, event->owner is XCB_NONE, + // so we check selection_timestamp to not handle our own QClipboard::clear(). + if (event->owner != owner() && event->selection_timestamp > m_timestamp[mode]) { if (!m_xClipboard[mode]) { m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this)); } else { -- cgit v1.2.1 From 246fe271878dbe586b5f3222a78d67dfecd1ca83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 11 Nov 2016 08:01:29 +0100 Subject: Cocoa: Make dictation via speech recognition work Returning NSNotFound from the NSTextInputClient selectedRange implementation when there is no selection prevents dictation from activating (for unknown reasons). Return an empty {0, 0} range instead. Text input methods such as Pinyin still work after this change. [ChangeLog][macOS] Speech to text dictation now works for Qt text input. Change-Id: Ibf1729bdd271e8ed5ce3c9d2a0373c8ab3613d8e Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 1ad9b5f327..50dda52a7b 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1783,9 +1783,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) - (NSRange) selectedRange { - NSRange selectedRange = {NSNotFound, 0}; - selectedRange.location = NSNotFound; - selectedRange.length = 0; + NSRange selectedRange = {0, 0}; QObject *fo = QGuiApplication::focusObject(); if (!fo) -- cgit v1.2.1 From 01c3565d3e484af0451060cdbdfc42f5d10dfb9a Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 13 Oct 2016 09:16:06 +0200 Subject: winrt: Add documentation for verbatim manifest processing Change-Id: I4a2acc6844bd160b3ccdbcea4be1e1fbc1cc266d Reviewed-by: Oliver Wolff --- qmake/doc/src/qmake-manual.qdoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 1cfe4c9979..b6c950cab6 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2595,6 +2595,10 @@ \li capabilities_device \li Specifies device capabilities to add to the capability list (location, webcam, and so on). + \row + \li CONFIG + \li Specifies additional flags for processing the input manifest file. + Currently, \c{verbatim} is the only available option. \row \li default_language \li The default language code of the application. Defaults to "en". @@ -2727,6 +2731,14 @@ WINRT_MANIFEST = someManifest.xml.in \endcode + In case the input manifest file should not be processed and only copied to + the target directory, the verbatim configuration needs to be set. + + \code + WINRT_MANIFEST = someManifest.xml.in + WINRT_MANIFEST.CONFIG += verbatim + \endcode + \note The required image sizes of \e logo_small, \e logo_medium, and \e logo_large depend on the target platform. The general descriptions are overwritten if a description that specifies the size is provided. -- cgit v1.2.1 From c442244907a7246ee1e0cff3827e874d50d6da11 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 27 Oct 2016 09:42:56 +0200 Subject: Fixes for findVersionDirectivePosition() The old code was wrong as it used QString::fromUtf8() to convert the char * array to a QString. This could lead to wrong positions when trying to find the #version directive, as any valid utf8 sequence in a comment before could have lead to wrong offsets compared to the 8 bit data. Fix this and optimize the code at the same time to avoid creating a copy of the data and using QRegularExpression. Also fixes building Qt with -no-feature-regularexpression Change-Id: I2d84875ef59b3a0fb4d8b069bf56f4372c57ccdc Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglshaderprogram.cpp | 81 +++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 61343e5f5a..cd582c5285 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -432,73 +432,84 @@ static QVersionDirectivePosition findVersionDirectivePosition(const char *source { Q_ASSERT(source); - QString working = QString::fromUtf8(source); - // According to the GLSL spec the #version directive must not be // preceded by anything but whitespace and comments. // In order to not get confused by #version directives within a - // multiline comment, we need to run a minimal preprocessor first. + // multiline comment, we need to do some minimal comment parsing + // while searching for the directive. enum { Normal, + StartOfLine, + PreprocessorDirective, CommentStarting, MultiLineComment, SingleLineComment, CommentEnding - } state = Normal; + } state = StartOfLine; - for (QChar *c = working.begin(); c != working.end(); ++c) { + const char *c = source; + while (*c) { switch (state) { + case PreprocessorDirective: + if (*c == ' ' || *c == '\t') + break; + if (!strncmp(c, "version", strlen("version"))) { + // Found version directive + c += strlen("version"); + while (*c && *c != '\n') + ++c; + int splitPosition = c - source + 1; + int linePosition = int(std::count(source, c, '\n')) + 1; + return QVersionDirectivePosition(splitPosition, linePosition); + } else if (*c == '/') + state = CommentStarting; + else if (*c == '\n') + state = StartOfLine; + else + state = Normal; + break; + case StartOfLine: + if (*c == ' ' || *c == '\t') + break; + else if (*c == '#') { + state = PreprocessorDirective; + break; + } + state = Normal; + // fall through case Normal: - if (*c == QLatin1Char('/')) + if (*c == '/') state = CommentStarting; + else if (*c == '\n') + state = StartOfLine; break; case CommentStarting: - if (*c == QLatin1Char('*')) + if (*c == '*') state = MultiLineComment; - else if (*c == QLatin1Char('/')) + else if (*c == '/') state = SingleLineComment; else state = Normal; break; case MultiLineComment: - if (*c == QLatin1Char('*')) + if (*c == '*') state = CommentEnding; - else if (*c == QLatin1Char('#')) - *c = QLatin1Char('_'); break; case SingleLineComment: - if (*c == QLatin1Char('\n')) + if (*c == '\n') state = Normal; - else if (*c == QLatin1Char('#')) - *c = QLatin1Char('_'); break; case CommentEnding: - if (*c == QLatin1Char('/')) { + if (*c == '/') state = Normal; - } else { - if (*c == QLatin1Char('#')) - *c = QLatin1Char('_'); - if (*c != QLatin1Char('*')) - state = MultiLineComment; - } + else if (*c != QLatin1Char('*')) + state = MultiLineComment; break; } + ++c; } - // Search for #version directive - int splitPosition = 0; - int linePosition = 1; - - static const QRegularExpression pattern(QStringLiteral("^\\s*#\\s*version.*(\\n)?"), - QRegularExpression::MultilineOption - | QRegularExpression::OptimizeOnFirstUsageOption); - QRegularExpressionMatch match = pattern.match(working); - if (match.hasMatch()) { - splitPosition = match.capturedEnd(); - linePosition += int(std::count(working.begin(), working.begin() + splitPosition, QLatin1Char('\n'))); - } - - return QVersionDirectivePosition(splitPosition, linePosition); + return QVersionDirectivePosition(0, 1); } /*! -- cgit v1.2.1 From 7d4da559afb62a779b3d90a65fb679cb5433f203 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 28 Oct 2016 14:27:41 +0200 Subject: Remove all Multimedia related configuration options from qtbase They live in qtmultimedia now. Change-Id: I1a2ee8be3efb7c4ee9a29d2a8e3fc1f3eea704fc Reviewed-by: Oswald Buddenhagen --- config.tests/unix/alsa/alsa.pro | 2 - config.tests/unix/alsa/alsatest.cpp | 48 ----------------- config.tests/unix/gstreamer/gstreamer.cpp | 47 ----------------- config.tests/unix/gstreamer/gstreamer.pro | 4 -- config.tests/unix/pulseaudio/pulseaudio.cpp | 56 -------------------- config.tests/unix/pulseaudio/pulseaudio.pro | 2 - config_help.txt | 9 ---- configure.json | 82 ----------------------------- 8 files changed, 250 deletions(-) delete mode 100644 config.tests/unix/alsa/alsa.pro delete mode 100644 config.tests/unix/alsa/alsatest.cpp delete mode 100644 config.tests/unix/gstreamer/gstreamer.cpp delete mode 100644 config.tests/unix/gstreamer/gstreamer.pro delete mode 100644 config.tests/unix/pulseaudio/pulseaudio.cpp delete mode 100644 config.tests/unix/pulseaudio/pulseaudio.pro diff --git a/config.tests/unix/alsa/alsa.pro b/config.tests/unix/alsa/alsa.pro deleted file mode 100644 index 211e9bc899..0000000000 --- a/config.tests/unix/alsa/alsa.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = alsatest.cpp -CONFIG -= qt dylib diff --git a/config.tests/unix/alsa/alsatest.cpp b/config.tests/unix/alsa/alsatest.cpp deleted file mode 100644 index 1b2b141b79..0000000000 --- a/config.tests/unix/alsa/alsatest.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#if SND_LIB_VERSION < 0x1000a // 1.0.10 -#error "Alsa version found too old, require >= 1.0.10" -#endif - -int main(int argc,char **argv) -{ -} - diff --git a/config.tests/unix/gstreamer/gstreamer.cpp b/config.tests/unix/gstreamer/gstreamer.cpp deleted file mode 100644 index 8076458b8b..0000000000 --- a/config.tests/unix/gstreamer/gstreamer.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#define GST_USE_UNSTABLE_API - -#include - -int main(int, char**) -{ - return 0; -} diff --git a/config.tests/unix/gstreamer/gstreamer.pro b/config.tests/unix/gstreamer/gstreamer.pro deleted file mode 100644 index 7b6fbb4d75..0000000000 --- a/config.tests/unix/gstreamer/gstreamer.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES += gstreamer.cpp - -CONFIG -= qt - diff --git a/config.tests/unix/pulseaudio/pulseaudio.cpp b/config.tests/unix/pulseaudio/pulseaudio.cpp deleted file mode 100644 index 7b71567ae5..0000000000 --- a/config.tests/unix/pulseaudio/pulseaudio.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#if !defined(PA_API_VERSION) || PA_API_VERSION-0 != 12 -# error "Incompatible PulseAudio API version" -#endif -#if !PA_CHECK_VERSION(0,9,0) -# error "PulseAudio version too old" -#endif - -int main(int, char **) -{ - const char *headers = pa_get_headers_version(); - const char *library = pa_get_library_version(); - pa_glib_mainloop_new(0); - return (headers - library) * 0; -} diff --git a/config.tests/unix/pulseaudio/pulseaudio.pro b/config.tests/unix/pulseaudio/pulseaudio.pro deleted file mode 100644 index 5e36c0aa81..0000000000 --- a/config.tests/unix/pulseaudio/pulseaudio.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = pulseaudio.cpp -CONFIG -= qt diff --git a/config_help.txt b/config_help.txt index 5e0d36a41f..5725e9213f 100644 --- a/config_help.txt +++ b/config_help.txt @@ -289,12 +289,3 @@ Database options: [all auto] MYSQL_PATH= PSQL_LIBS= SYBASE= SYBASE_LIBS= -sqlite .............. Select used sqlite3 [system/qt] - -Multimedia options: - - -pulseaudio .......... Enable PulseAudio support [auto] - -alsa ................ Enable ALSA support [auto] - -no-gstreamer ........ Disable support for GStreamer - -gstreamer [version] . Enable GStreamer support [auto] - With no parameter, 1.0 is tried first, then 0.10. - -wmf-backend ......... Enable WMF support [no] (Windows only) diff --git a/configure.json b/configure.json index e266fa918c..5d5af7d035 100644 --- a/configure.json +++ b/configure.json @@ -56,8 +56,6 @@ "android-toolchain-version": "string", "accessibility": "boolean", - "alsa": "boolean", - "audio-backend": "boolean", "avx": "boolean", "avx2": "boolean", "avx512": { "type": "boolean", "name": "avx512f" }, @@ -81,7 +79,6 @@ "gcc-sysroot": "boolean", "gcov": "boolean", "gnumake": { "type": "boolean", "name": "GNUmake" }, - "gstreamer": { "type": "optionalString", "values": [ "no", "yes", "0.10", "1.0" ] }, "gui": "boolean", "headersclean": "boolean", "host-option": "string", @@ -102,7 +99,6 @@ "platform": "string", "plugin-manifests": "boolean", "profile": "boolean", - "pulseaudio": "boolean", "qml-debug": "boolean", "qreal": "string", "qtlibinfix": { "type": "string", "name": "qt_libinfix" }, @@ -133,7 +129,6 @@ "warnings-are-errors": { "type": "boolean", "name": "warnings_are_errors" }, "Werror": { "type": "boolean", "name": "warnings_are_errors" }, "widgets": "boolean", - "wmf-backend": "boolean", "xplatform": "string", "zlib": { "type": "enum", "name": "system-zlib", "values": { "system": "yes", "qt": "no" } } }, @@ -157,39 +152,6 @@ { "libs": "-lz", "condition": "!config.msvc" } ] }, - "alsa": { - "label": "ALSA", - "export": "", - "test": "unix/alsa", - "sources": [ - "-lasound" - ] - }, - "pulseaudio": { - "label": "PulseAudio >= 0.9.10", - "test": "unix/pulseaudio", - "sources": [ - { "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" } - ] - }, - "gstreamer_1_0": { - "label": "GStreamer 1.0", - "export": "", - "test": "unix/gstreamer", - "sources": [ - { "type": "pkgConfig", - "args": "gstreamer-1.0 gstreamer-base-1.0 gstreamer-audio-1.0 gstreamer-video-1.0 gstreamer-pbutils-1.0" } - ] - }, - "gstreamer_0_10": { - "label": "GStreamer 0.10", - "export": "", - "test": "unix/gstreamer", - "sources": [ - { "type": "pkgConfig", - "args": "gstreamer-0.10 gstreamer-base-0.10 gstreamer-audio-0.10 gstreamer-video-0.10 gstreamer-pbutils-0.10" } - ] - }, "dbus": { "label": "D-Bus >= 1.2", "test": "unix/dbus", @@ -451,11 +413,6 @@ "label": "IncrediBuild", "type": "files", "files": [ "BuildConsole.exe", "xgConsole.exe" ] - }, - "wmf": { - "label": "WMF", - "type": "files", - "files": [ "mfapi.h", "mf.lib" ] } }, @@ -899,11 +856,6 @@ { "type": "define", "name": "QT_COMPILER_SUPPORTS_NEON", "value": 1 } ] }, - "alsa": { - "label": "ALSA", - "condition": "libs.alsa", - "output": [ "feature" ] - }, "mremap": { "label": "mremap()", "condition": "tests.mremap", @@ -923,11 +875,6 @@ "label": "Accessibility", "output": [ "publicFeature", "feature" ] }, - "pulseaudio": { - "label": "PulseAudio", - "condition": "libs.pulseaudio", - "output": [ "feature" ] - }, "system-zlib": { "label": "Using system zlib", "condition": "libs.zlib", @@ -985,24 +932,6 @@ "condition": "libs.libudev", "output": [ "privateFeature" ] }, - "gstreamer-1_0": { - "label": "GStreamer 1.0", - "disable": "input.gstreamer == '0.10' || input.gstreamer == 'no'", - "enable": "input.gstreamer == '1.0'", - "condition": "libs.gstreamer_1_0", - "output": [ { "type": "publicQtConfig", "name": "gstreamer-1.0" } ] - }, - "gstreamer-0_10": { - "label": "GStreamer 0.10", - "disable": "input.gstreamer == 'no'", - "enable": "input.gstreamer == '0.10'", - "condition": "!features.gstreamer-1_0 && libs.gstreamer_0_10", - "output": [ { "type": "publicQtConfig", "name": "gstreamer-0.10" } ] - }, - "audio-backend": { - "label": "Audio backend", - "output": [ "publicQtConfig" ] - }, "qml-debug": { "label": "QML debugging", "output": [ { "type": "publicQtConfig", "negative": true } ] @@ -1029,13 +958,6 @@ "autoDetect": false, "condition": "!features.shared", "output": [ "publicConfig", "publicQtConfig" ] - }, - "wmf-backend": { - "label": "Windows Media Foundation backend for Qt Multimedia", - "emitIf": "config.win32", - "autoDetect": false, - "condition": "tests.wmf", - "output": [ "publicQtConfig" ] } }, @@ -1181,11 +1103,7 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5 "section": "Support enabled for", "entries": [ "accessibility", - "alsa", - "gstreamer-0_10", - "gstreamer-1_0", "pkg-config", - "pulseaudio", "qml-debug", "libudev", "system-zlib" -- cgit v1.2.1 From 71d21ed500a20f3fbabb000243cef1168893c9d5 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 4 Nov 2016 09:55:04 +0100 Subject: Fix image format conversion QImage::convertToFormat() returns the converted image. Change-Id: Icfd3ff43e04939e6b92c7fa94e5e0af60f633385 Reviewed-by: Andy Nichols --- src/plugins/platforms/mirclient/qmirclientcursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.cpp b/src/plugins/platforms/mirclient/qmirclientcursor.cpp index 83ea116c11..a0da3fdd77 100644 --- a/src/plugins/platforms/mirclient/qmirclientcursor.cpp +++ b/src/plugins/platforms/mirclient/qmirclientcursor.cpp @@ -167,7 +167,7 @@ void QMirClientCursor::configureMirCursorWithPixmapQCursor(MirSurface *surface, QImage image = cursor.pixmap().toImage(); if (image.format() != QImage::Format_ARGB32) { - image.convertToFormat(QImage::Format_ARGB32); + image = image.convertToFormat(QImage::Format_ARGB32); } MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection, -- cgit v1.2.1 From e133f0cca44181005f19d006d6c896abe59c1b33 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 11 Nov 2016 17:06:19 +0100 Subject: Improve error offset in JSON parsing Do not consume white-space after a token before the token has been parsed, otherwise we end up with misleading offsets. This also fixes a wrong error of illegal number in several cases. Change-Id: I492ca4de0346a1d0ab73b1c23d7a72dba812664c Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- src/corelib/json/qjsonparser.cpp | 15 ++++++++++++++- tests/auto/corelib/json/tst_qtjson.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 094cb7a76b..0eb0d21ecf 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -283,7 +283,6 @@ char Parser::nextToken() case ValueSeparator: case EndArray: case EndObject: - eatSpace(); case Quote: break; default: @@ -469,6 +468,10 @@ bool Parser::parseMember(int baseOffset) lastError = QJsonParseError::MissingNameSeparator; return false; } + if (!eatSpace()) { + lastError = QJsonParseError::UnterminatedObject; + return false; + } QJsonPrivate::Value val; if (!parseValue(&val, baseOffset)) return false; @@ -544,6 +547,10 @@ bool Parser::parseArray() nextToken(); } else { while (1) { + if (!eatSpace()) { + lastError = QJsonParseError::UnterminatedArray; + return false; + } QJsonPrivate::Value val; if (!parseValue(&val, arrayOffset)) return false; @@ -686,6 +693,12 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) DEBUG << "value: object"; END; return true; + case ValueSeparator: + // Essentially missing value, but after a colon, not after a comma + // like the other MissingObject errors. + lastError = QJsonParseError::IllegalValue; + return false; + case EndObject: case EndArray: lastError = QJsonParseError::MissingObject; return false; diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 17892b44a2..4a6584a0f6 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -139,6 +139,9 @@ private Q_SLOTS: void removeNonLatinKey(); void documentFromVariant(); + void parseErrorOffset_data(); + void parseErrorOffset(); + private: QString testDataDir; }; @@ -2830,5 +2833,35 @@ void tst_QtJson::documentFromVariant() QCOMPARE(do1.object(), do2.object()); } +void tst_QtJson::parseErrorOffset_data() +{ + QTest::addColumn("json"); + QTest::addColumn("errorOffset"); + + QTest::newRow("Trailing comma in object") << QByteArray("{ \"value\": false, }") << 19; + QTest::newRow("Trailing comma in object plus whitespace") << QByteArray("{ \"value\": false, } ") << 19; + QTest::newRow("Trailing comma in array") << QByteArray("[ false, ]") << 10; + QTest::newRow("Trailing comma in array plus whitespace") << QByteArray("[ false, ] ") << 10; + QTest::newRow("Missing value in object") << QByteArray("{ \"value\": , } ") << 12; + QTest::newRow("Missing value in array") << QByteArray("[ \"value\" , , ] ") << 13; + QTest::newRow("Leading comma in object") << QByteArray("{ , \"value\": false}") << 3; + QTest::newRow("Leading comma in array") << QByteArray("[ , false]") << 3; + QTest::newRow("Stray ,") << QByteArray(" , ") << 3; + QTest::newRow("Stray [") << QByteArray(" [ ") << 5; + QTest::newRow("Stray }") << QByteArray(" } ") << 3; +} + +void tst_QtJson::parseErrorOffset() +{ + QFETCH(QByteArray, json); + QFETCH(int, errorOffset); + + QJsonParseError error; + QJsonDocument::fromJson(json, &error); + + QVERIFY(error.error != QJsonParseError::NoError); + QCOMPARE(error.offset, errorOffset); +} + QTEST_MAIN(tst_QtJson) #include "tst_qtjson.moc" -- cgit v1.2.1 From 887e260a9370dfd8061754ed47cda7d9e4621711 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 11 Nov 2016 15:22:45 +0100 Subject: Improve QMake JSON error We can not improve the result from JSON parsing without changing API, so instead recalculate the line and column based on input and offset. Change-Id: I54149233f71023aa5d30deff854d6f3406c5c48c Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakebuiltins.cpp | 39 +++++++++++++++++++++++++++++++--- tests/auto/tools/qmakelib/evaltest.cpp | 2 +- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 544ccac6d2..6fe3ba1605 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -396,14 +396,47 @@ static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProV } } +struct ErrorPosition { + int line; + int column; +}; + +static ErrorPosition calculateErrorPosition(const QByteArray &json, int offset) +{ + ErrorPosition pos = { 0, 0 }; + offset--; // offset is 1-based, switching to 0-based + for (int i = 0; i < offset; ++i) { + switch (json.at(i)) { + case '\n': + pos.line++; + pos.column = 0; + break; + case '\r': + break; + case '\t': + pos.column = (pos.column + 8) & ~7; + break; + default: + pos.column++; + break; + } + } + // Lines and columns in text editors are 1-based: + pos.line++; + pos.column++; + return pos; +} + QMakeEvaluator::VisitReturn QMakeEvaluator::parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value) { QJsonParseError error; QJsonDocument document = QJsonDocument::fromJson(json, &error); if (document.isNull()) { - if (error.error != QJsonParseError::NoError) - evalError(fL1S("Error parsing json at offset %1: %2") - .arg(error.offset).arg(error.errorString())); + if (error.error != QJsonParseError::NoError) { + ErrorPosition errorPos = calculateErrorPosition(json, error.offset); + evalError(fL1S("Error parsing JSON at %1:%2: %3") + .arg(errorPos.line).arg(errorPos.column).arg(error.errorString())); + } return QMakeEvaluator::ReturnFalse; } diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index 62fcedddb9..01214b3d38 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2259,7 +2259,7 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << "jsontext = not good\n" "parseJson(jsontext, json): OK = 1" << "OK = UNDEF" - << "##:2: Error parsing json at offset 1: illegal value" + << "##:2: Error parsing JSON at 1:1: illegal value" << true; QTest::newRow("parseJson(): bad number of arguments") -- cgit v1.2.1 From e71cf692179732080a7bf75dc1bcbcefd4f94f0b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 14 Nov 2016 20:57:16 +0100 Subject: fix directfb build 60985aa42 converted the QT_CONFIG use, not taking into account that the feature isn't actually known to the configure system - it's coming directly from the makespec. so revert that hunk (until we have a better integration between makespecs and configure). Task-number: QTBUG-57039 Change-Id: Iaf57b5f5339250055f1c378e091da3ab3fcd4292 Reviewed-by: Jake Petroules --- src/plugins/platforms/directfb/directfb.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 406b89e3b2..4e95aebe35 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -27,7 +27,7 @@ HEADERS = qdirectfbintegration.h \ qdirectfbeglhooks.h # ### port the GL context -qtConfig(directfb_egl) { +contains(QT_CONFIG, directfb_egl) { HEADERS += qdirectfb_egl.h SOURCES += qdirectfb_egl.cpp DEFINES += DIRECTFB_GL_EGL -- cgit v1.2.1 From fa8e467804428127429ca91aaa1538bae70b1871 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Nov 2016 18:01:41 +0100 Subject: fix configure logging when no cache is present yet this got broken in 2ad4d75754. however, the new configure system operates from the top-level build dir anyway, so there is no point in messing with the cache as a reference point to start with - just use OUT_PWD. Task-number: QTBUG-57120 Change-Id: I69629bf497931574bff8452939170abb1776ab60 Reviewed-by: Lars Knoll --- mkspecs/features/configure.prf | 1 + mkspecs/features/configure_base.prf | 2 -- mkspecs/features/qt_configure.prf | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 62eae6d813..4ca7c6ba07 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -4,6 +4,7 @@ cache() load(configure_base) +QMAKE_CONFIG_LOG = $$dirname(_QMAKE_CACHE_)/config.log recheck: write_file($$QMAKE_CONFIG_LOG, "") isEmpty(QMAKE_CONFIG_TESTS_DIR): QMAKE_CONFIG_TESTS_DIR = $$_PRO_FILE_PWD_/config.tests diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf index 4d68affabf..4e7292451e 100644 --- a/mkspecs/features/configure_base.prf +++ b/mkspecs/features/configure_base.prf @@ -42,5 +42,3 @@ defineTest(qtRunLoggedCommand) { !equals(result, 0): return(false) return(true) } - -QMAKE_CONFIG_LOG = $$dirname(_QMAKE_CACHE_)/config.log diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 38305890b5..2810faad1a 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1768,6 +1768,8 @@ equals(QMAKE_CONFIG_CACHE_USE, none) { "cache.xplatform = $$[QMAKE_XSPEC]" write_file($$QMAKE_CONFIG_CACHE, cont) } + +QMAKE_CONFIG_LOG = $$OUT_PWD/config.log !equals(QMAKE_CONFIG_CACHE_USE, all): \ write_file($$QMAKE_CONFIG_LOG, "") -- cgit v1.2.1 From d01c774f4508b1606dfac0905a66ac5748af6b90 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Nov 2016 18:59:16 +0100 Subject: configure: fix caching of includedir results amends ce7df6ac7. Change-Id: Id56ee59b5955addb58cc4d0879dc097bdd7841d8 Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 2810faad1a..c984206f0d 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -647,7 +647,7 @@ defineTest(qtConfHandleLibrary) { qtLog(" => source accepted.") $${lpfx}.cache += source - for (v, $$list(libs includes cflags version export)): \ + for (v, $$list(libs includedir cflags version export)): \ $${lpfx}.cache += sources.$${s}.$${v} for (b, $${spfx}.builds._KEYS_): \ $${lpfx}.cache += sources.$${s}.builds.$${b} -- cgit v1.2.1 From 5c263bf984ac830b7733c2ac6597bf84d0c0b1ba Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Nov 2016 18:02:52 +0100 Subject: configure: fix parsing of -hostprefix without argument Change-Id: I94c0bc40e4f995d2c50bea828adcf8ed8bb96a90 Reviewed-by: Lars Knoll --- configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.json b/configure.json index 5d5af7d035..3480aed20f 100644 --- a/configure.json +++ b/configure.json @@ -25,7 +25,7 @@ "custom": "qmakeArgs", "options": { "prefix": "string", - "hostprefix": "string", + "hostprefix": "optionalString", "extprefix": "string", "archdatadir": "string", -- cgit v1.2.1 From 6cd358db7e648265ab15b796815eea9609228d69 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Nov 2016 18:02:56 +0100 Subject: mark up output of called commands in configure log otherwise it's sometimes quite hard to tell it apart from configure's own messages. Change-Id: I2f4908344367a9a3ce38e032bf76486fc4552ffd Reviewed-by: Lars Knoll --- mkspecs/features/configure_base.prf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/configure_base.prf b/mkspecs/features/configure_base.prf index 4e7292451e..dd1f4e5bfc 100644 --- a/mkspecs/features/configure_base.prf +++ b/mkspecs/features/configure_base.prf @@ -33,7 +33,10 @@ defineTest(qtRunLoggedCommand) { qtLog("+ $$1") output = $$system("( $$1 ) 2>&1", lines, result) - qtLog($$output) + lg = + for (l, output): \ + lg += "> $$l" + qtLog($$lg) !isEmpty(2) { $$2 = $$output export($$2) -- cgit v1.2.1 From b5464f42373918518420939226982438b15b3af9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Nov 2016 13:21:13 +0100 Subject: bump qmake version there are plenty new functions, let's do this symbolic act. Change-Id: Iaeb88afa5e33cacd81dc0ea26e380a16af06a739 Reviewed-by: Lars Knoll Reviewed-by: Jake Petroules --- qmake/option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/option.h b/qmake/option.h index 8b9e2f1027..eaa3706b24 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE -#define QMAKE_VERSION_STR "3.0" +#define QMAKE_VERSION_STR "3.1" QString qmake_getpwd(); bool qmake_setpwd(const QString &p); -- cgit v1.2.1 From d442a9a4e672863abd1c1069482f8d8f0bdc7a07 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Nov 2016 17:23:30 +0100 Subject: ensure that QMAKE_QMAKE always ends in .exe on windows Change-Id: I72d5eda83250a0c33af505005732c3f370a04c57 Reviewed-by: Lars Knoll --- qmake/option.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qmake/option.cpp b/qmake/option.cpp index 52bd10bfee..fb49f5a100 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -313,6 +313,10 @@ Option::init(int argc, char **argv) if(argc && argv) { QString argv0 = argv[0]; +#ifdef Q_OS_WIN + if (!argv0.endsWith(QLatin1String(".exe"), Qt::CaseInsensitive)) + argv0 += QLatin1String(".exe"); +#endif if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING) Option::qmake_mode = default_mode(argv0); if(!argv0.isEmpty() && !QFileInfo(argv0).isRelative()) { @@ -336,10 +340,6 @@ Option::init(int argc, char **argv) if ((*p).isEmpty()) continue; QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0); -#ifdef Q_OS_WIN - if (!candidate.endsWith(QLatin1String(".exe"))) - candidate += QLatin1String(".exe"); -#endif if (QFile::exists(candidate)) { globals->qmake_abslocation = candidate; break; -- cgit v1.2.1 From 2b6bcd5ff31a51611f4701995a9c42a774eb4b8c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 9 Nov 2016 13:12:23 +0100 Subject: make use of $$QMAKE_QMAKE there is no need to reconstruct it from scratch. Change-Id: Ied6f88634f1875b4aa47a39af0d0d89a7ad4a654 Reviewed-by: Lars Knoll --- mkspecs/features/moc.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 1756ca35bf..59ed81b49e 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -32,7 +32,7 @@ if(gcc|intel_icl|msvc):!rim_qcc:!uikit { gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} else:msvc { - moc_predefs.commands += $$QMAKE_CXX -Bx$$shell_quote($$shell_path($$[QT_INSTALL_BINS/get]/qmake)) $$QMAKE_CXXFLAGS -E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT} + moc_predefs.commands += $$QMAKE_CXX -Bx$$QMAKE_QMAKE $$QMAKE_CXXFLAGS -E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT} } else: error("Oops, I messed up") moc_predefs.output = $$MOC_DIR/moc_predefs.h moc_predefs.input = MOC_PREDEF_FILE -- cgit v1.2.1 From 71fd04031860517c72de5487b6aa46793aad7d44 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Nov 2016 17:38:13 +0100 Subject: qmake: fix /dev properties with -external-hostbindir if the externally provided qmake had a different on-device install tree layout, things would go wrong. of course, that's a rather unlikely case, so nobody noticed ... Change-Id: I59f9976a769ccb6099b7237ef42555f0549615aa Reviewed-by: Lars Knoll --- configure | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 789ba4cc74..3b0240f341 100755 --- a/configure +++ b/configure @@ -1803,15 +1803,9 @@ fi # Build qmake # create a qt.conf for the Qt build tree itself #------------------------------------------------------------------------------- -QTCONFFILE="$outpath/bin/qt.conf" -cat > "$QTCONFFILE" <> "$QTCONFFILE" < "$QTCONFFILE" <> "$QTCONFFILE" < Date: Tue, 8 Nov 2016 17:01:01 +0100 Subject: qmake: fix file name treatment in emission of extra targets that is, adjust path separators and don't quote them. we already did that to some degree, but totally inconsistently, so it just didn't work for any targets with "fancy" file names. note that we don't bother doing that for recursive targets, as these are assumed to be identifiers. Change-Id: Ic75f003b71abc6fed03a4121b903ad5ee8253ed2 Reviewed-by: Lars Knoll --- qmake/generators/makefile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 5d7700ec82..4450e619b9 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2623,8 +2623,8 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList recurse; @@ -2690,7 +2690,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList Date: Mon, 7 Nov 2016 18:55:08 +0100 Subject: qmake: don't look for qrc-based qt.conf we know there is none. Change-Id: I75bc39f8b900525e7db29664f7dd2117d2bd33d2 Reviewed-by: Lars Knoll --- src/corelib/global/qlibraryinfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 1a7d64780f..061137427d 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -163,14 +163,14 @@ void QLibrarySettings::load() QSettings *QLibraryInfoPrivate::findConfiguration() { - QString qtconfig = QStringLiteral(":/qt/etc/qt.conf"); - if (QFile::exists(qtconfig)) - return new QSettings(qtconfig, QSettings::IniFormat); #ifdef QT_BUILD_QMAKE - qtconfig = qmake_libraryInfoFile(); + QString qtconfig = qmake_libraryInfoFile(); if (QFile::exists(qtconfig)) return new QSettings(qtconfig, QSettings::IniFormat); #else + QString qtconfig = QStringLiteral(":/qt/etc/qt.conf"); + if (QFile::exists(qtconfig)) + return new QSettings(qtconfig, QSettings::IniFormat); #ifdef Q_OS_DARWIN CFBundleRef bundleRef = CFBundleGetMainBundle(); if (bundleRef) { -- cgit v1.2.1 From cff05b398cb767af7fddae6a617f26f998c7a781 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 10 Nov 2016 20:04:20 +0100 Subject: qmake: add "undecorated" mode to $$prompt() the normal mode forces the prompt into a pattern which may be undesirable. Change-Id: I01689c7a6573415801862348b32bafc6a609ed4a Reviewed-by: Lars Knoll --- qmake/doc/src/qmake-manual.qdoc | 5 ++++- qmake/library/qmakebuiltins.cpp | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index b6c950cab6..aa6c8b35cc 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -3018,10 +3018,13 @@ sum = $$num_add($$first, $$second_neg) \endcode - \section2 prompt(question) + \section2 prompt(question [, decorate]) Displays the specified \c question, and returns a value read from stdin. + If \c decorate is \e true (the default), the question gets a generic + prefix and suffix identifying it as a prompt. + \section2 quote(string) Converts a whole \c string into a single entity and returns the result. diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 6fe3ba1605..b8df43c5fb 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1091,16 +1091,22 @@ ProStringList QMakeEvaluator::evaluateBuiltinExpand( break; #ifdef PROEVALUATOR_FULL case E_PROMPT: { - if (args.count() != 1) { - evalError(fL1S("prompt(question) requires one argument.")); + if (args.count() != 1 && args.count() != 2) { + evalError(fL1S("prompt(question, [decorate=true]) requires one or two arguments.")); // } else if (currentFileName() == QLatin1String("-")) { // evalError(fL1S("prompt(question) cannot be used when '-o -' is used")); } else { QString msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp1)); - if (!msg.endsWith(QLatin1Char('?'))) - msg += QLatin1Char('?'); - fprintf(stderr, "Project PROMPT: %s ", qPrintable(msg)); - + bool decorate = true; + if (args.count() == 2) + decorate = isTrue(args.at(1)); + if (decorate) { + if (!msg.endsWith(QLatin1Char('?'))) + msg += QLatin1Char('?'); + fprintf(stderr, "Project PROMPT: %s ", qPrintable(msg)); + } else { + fputs(qPrintable(msg), stderr); + } QFile qfile; if (qfile.open(stdin, QIODevice::ReadOnly)) { QTextStream t(&qfile); -- cgit v1.2.1 From 965e861e61ec56c91216d483987d33fb5a508b85 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Nov 2016 20:01:53 +0100 Subject: qmake: let discard_from() discard function definitions as well for completeness. Change-Id: I3ffc14e041408c773e277442828170e3df04ec8d Reviewed-by: Lars Knoll --- qmake/library/qmakebuiltins.cpp | 12 ++++++++++++ tests/auto/tools/qmakelib/evaltest.cpp | 10 ++++++++-- tests/auto/tools/qmakelib/testdata/include/inc.pri | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index b8df43c5fb..47c60271c8 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1365,6 +1365,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } ++vit; } + for (auto fit = m_functionDefs.testFunctions.begin(); fit != m_functionDefs.testFunctions.end(); ) { + if (fit->pro() == pro) + fit = m_functionDefs.testFunctions.erase(fit); + else + ++fit; + } + for (auto fit = m_functionDefs.replaceFunctions.begin(); fit != m_functionDefs.replaceFunctions.end(); ) { + if (fit->pro() == pro) + fit = m_functionDefs.replaceFunctions.erase(fit); + else + ++fit; + } pro->deref(); return ReturnTrue; } diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index 01214b3d38..614568ee53 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2326,8 +2326,14 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << true; QTest::newRow("discard_from()") - << "HERE = 1\nPLUS = one\ninclude(include/inc.pri)\ndiscard_from(include/inc.pri): OK = 1" - << "OK = 1\nHERE = 1\nPLUS = one\nVAR = UNDEF" + << "HERE = 1\nPLUS = one\n" + "defineTest(tfunc) {}\ndefineReplace(rfunc) {}\n" + "include(include/inc.pri)\n" + "discard_from(include/inc.pri): OK = 1\n" + "defined(tfunc, test): TDEF = 1\ndefined(rfunc, replace): RDEF = 1\n" + "defined(func, test): DTDEF = 1\ndefined(func, replace): DRDEF = 1\n" + << "OK = 1\nHERE = 1\nPLUS = one\nVAR = UNDEF\n" + "TDEF = 1\nRDEF = 1\nDTDEF = UNDEF\nDRDEF = UNDEF" << "" << true; diff --git a/tests/auto/tools/qmakelib/testdata/include/inc.pri b/tests/auto/tools/qmakelib/testdata/include/inc.pri index f9a4ec1bfa..5c570f49e5 100644 --- a/tests/auto/tools/qmakelib/testdata/include/inc.pri +++ b/tests/auto/tools/qmakelib/testdata/include/inc.pri @@ -8,3 +8,7 @@ fake-*: MATCH = 1 defineTest(func) { message("say hi!") } + +defineReplace(func) { + return("say hi!") +} -- cgit v1.2.1 From c05f0a83fdb4823604d76f61bb884e206887e704 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Nov 2016 14:45:48 +0100 Subject: qmake: make discard_from() patch up QMAKE_INTERNAL_INCLUDED_FILES as well when the file's effects are discarded, the mention of the file should be as well. Change-Id: I894b7e2b887dd34d18533b197bfa9d0d84d647e7 Reviewed-by: Lars Knoll --- qmake/library/qmakebuiltins.cpp | 4 ++++ tests/auto/tools/qmakelib/evaltest.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 47c60271c8..9daa7ada10 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1378,6 +1378,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( ++fit; } pro->deref(); + ProStringList &iif = m_valuemapStack.first()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")]; + int idx = iif.indexOf(ProString(fn)); + if (idx >= 0) + iif.removeAt(idx); return ReturnTrue; } case T_INFILE: diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index 614568ee53..44c82fb376 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2329,10 +2329,12 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << "HERE = 1\nPLUS = one\n" "defineTest(tfunc) {}\ndefineReplace(rfunc) {}\n" "include(include/inc.pri)\n" + "contains(QMAKE_INTERNAL_INCLUDED_FILES, .*/include/inc\\\\.pri): PRE = 1\n" "discard_from(include/inc.pri): OK = 1\n" + "!contains(QMAKE_INTERNAL_INCLUDED_FILES, .*/include/inc\\\\.pri): POST = 1\n" "defined(tfunc, test): TDEF = 1\ndefined(rfunc, replace): RDEF = 1\n" "defined(func, test): DTDEF = 1\ndefined(func, replace): DRDEF = 1\n" - << "OK = 1\nHERE = 1\nPLUS = one\nVAR = UNDEF\n" + << "PRE = 1\nPOST = 1\nOK = 1\nHERE = 1\nPLUS = one\nVAR = UNDEF\n" "TDEF = 1\nRDEF = 1\nDTDEF = UNDEF\nDRDEF = UNDEF" << "" << true; -- cgit v1.2.1 From c16593fd0b719afc7b88ae02cc40614db8045719 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Nov 2016 15:59:22 +0100 Subject: build qmake.exe directly in bin/ so far, qmake.exe was built in qmake/ and then copied to bin/, with possible errors in the second step ignored. this made no sense. this unifies the nmake makefile with the unix one; compare 46e51ce1d. Change-Id: Ieb9c7cd46f0be0501d17e297808ac1cdad1b3c4a Reviewed-by: Lars Knoll --- qmake/Makefile.win32 | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 5db8b04aa0..3e67632939 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -53,7 +53,6 @@ CXXFLAGS = $(CFLAGS) LFLAGS = LIBS = ole32.lib advapi32.lib shell32.lib -LINKQMAKE = $(LINKER) $(LFLAGS) -OUT:qmake.exe $(OBJS) $(QTOBJS) $(LIBS) ADDCLEAN = qmake.pdb qmake.ilk #qmake code @@ -130,11 +129,10 @@ QTOBJS= \ qjsonobject.obj \ qjsonvalue.obj -first all: qmake.exe +first all: $(BUILD_PATH)\bin\qmake.exe -qmake.exe: $(OBJS) $(QTOBJS) - $(LINKQMAKE) $(PCH_OBJECT) - -copy qmake.exe $(BUILD_PATH)\bin\qmake.exe +$(BUILD_PATH)\bin\qmake.exe: $(OBJS) $(QTOBJS) + $(LINKER) $(LFLAGS) /OUT:$(BUILD_PATH)\bin\qmake.exe $(OBJS) $(QTOBJS) $(PCH_OBJECT) $(LIBS) clean:: -del $(QTOBJS) @@ -146,7 +144,6 @@ clean:: -del qmake.tds distclean:: clean - -del qmake.exe -del $(BUILD_PATH)\bin\qmake.exe -del Makefile -- cgit v1.2.1 From 4d90bd55a5f330b56ebcd92f56a138dd79cfcef9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Nov 2016 19:02:43 +0100 Subject: re-arrange QLibraryInfo::rawLocation() for comprehensibility swap the branches for (not) reading from qt.conf, and use a state variable instead of an 'else' for mutual exclusion. this is somewhat more self-documenting, and allows for a saner handling of the mkspec fallbacks (which really should have been in a separate [QMake] section along with Host* and Sysroot, but changing that now is way too much hassle downstream). Change-Id: I80a73294022fd1e8d84fe501b737c4fc7758662f Reviewed-by: Lars Knoll --- src/corelib/global/qlibraryinfo.cpp | 71 ++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 061137427d..1469f5776b 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -449,6 +449,8 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) { #endif // QT_BUILD_QMAKE, started inside location ! QString ret; + bool fromConf = false; +#ifndef QT_NO_SETTINGS #ifdef QT_BUILD_QMAKE // Logic for choosing the right data source: if EffectivePaths are requested // and qt.conf with that section is present, use it, otherwise fall back to @@ -457,40 +459,18 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) // EffectiveSourcePaths falls back to EffectivePaths. // DevicePaths falls back to FinalPaths. PathGroup orig_group = group; - if (!QLibraryInfoPrivate::haveGroup(group) - && !(group == EffectiveSourcePaths - && (group = EffectivePaths, QLibraryInfoPrivate::haveGroup(group))) - && !((group == EffectivePaths || group == DevicePaths) - && (group = FinalPaths, QLibraryInfoPrivate::haveGroup(group))) - && (group = orig_group, true)) -#elif !defined(QT_NO_SETTINGS) - if (!QLibraryInfoPrivate::configuration()) + if (QLibraryInfoPrivate::haveGroup(group) + || (group == EffectiveSourcePaths + && (group = EffectivePaths, QLibraryInfoPrivate::haveGroup(group))) + || ((group == EffectivePaths || group == DevicePaths) + && (group = FinalPaths, QLibraryInfoPrivate::haveGroup(group))) + || (group = orig_group, false)) +#else + if (QLibraryInfoPrivate::configuration()) #endif { - const char * volatile path = 0; - if (loc == PrefixPath) { - path = -#ifdef QT_BUILD_QMAKE - (group != DevicePaths) ? - QT_CONFIGURE_EXT_PREFIX_PATH : -#endif - QT_CONFIGURE_PREFIX_PATH; - } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) { - path = qt_configure_strs + qt_configure_str_offsets[loc - 1]; -#ifndef Q_OS_WIN // On Windows we use the registry - } else if (loc == SettingsPath) { - path = QT_CONFIGURE_SETTINGS_PATH; -#endif -#ifdef QT_BUILD_QMAKE - } else if (loc == HostPrefixPath) { - path = QT_CONFIGURE_HOST_PREFIX_PATH; -#endif - } + fromConf = true; - if (path) - ret = QString::fromLocal8Bit(path); -#ifndef QT_NO_SETTINGS - } else { QString key; QString defaultValue; if (unsigned(loc) < sizeof(qtConfEntries)/sizeof(qtConfEntries[0])) { @@ -522,7 +502,9 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) ret = config->value(QLatin1String(qtConfEntries[PrefixPath].key), QLatin1String(qtConfEntries[PrefixPath].value)).toString(); else if (loc == TargetSpecPath || loc == HostSpecPath) - ret = QString::fromLocal8Bit(qt_configure_strs + qt_configure_str_offsets[loc - 1]); + fromConf = false; + // The last case here is SysrootPath, which can be legitimately empty. + // All other keys have non-empty fallbacks to start with. } #endif @@ -540,7 +522,32 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) ret = QDir::fromNativeSeparators(ret); } + } #endif // QT_NO_SETTINGS + + if (!fromConf) { + const char * volatile path = 0; + if (loc == PrefixPath) { + path = +#ifdef QT_BUILD_QMAKE + (group != DevicePaths) ? + QT_CONFIGURE_EXT_PREFIX_PATH : +#endif + QT_CONFIGURE_PREFIX_PATH; + } else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) { + path = qt_configure_strs + qt_configure_str_offsets[loc - 1]; +#ifndef Q_OS_WIN // On Windows we use the registry + } else if (loc == SettingsPath) { + path = QT_CONFIGURE_SETTINGS_PATH; +#endif +#ifdef QT_BUILD_QMAKE + } else if (loc == HostPrefixPath) { + path = QT_CONFIGURE_HOST_PREFIX_PATH; +#endif + } + + if (path) + ret = QString::fromLocal8Bit(path); } #ifdef QT_BUILD_QMAKE -- cgit v1.2.1 From 1a43199fcea1bcec1ebf1a1a12cd3dcb942d67b4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Nov 2016 18:50:54 +0100 Subject: configure: turn qtConfOutputPostProcess_*() callbacks into replace functions now the callbacks don't need to re-export the designated file contents, which improves the abstraction and removes some boilerplate. Change-Id: Ifa50313155fc96762025e2610b810ebb71daa373 Reviewed-by: Lars Knoll --- configure.pri | 12 ++++++------ mkspecs/features/qt_configure.prf | 14 +++++++++----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/configure.pri b/configure.pri index 0e6bb6a6f5..19719736a9 100644 --- a/configure.pri +++ b/configure.pri @@ -457,9 +457,10 @@ defineTest(qtConfOutput_qmakeArgs) { export($${currentConfig}.output.privatePro) } -defineTest(qtConfOutputPostProcess_publicPro) { +defineReplace(qtConfOutputPostProcess_publicPro) { qt_version = $$[QT_VERSION] output = \ + $$1 \ "QT_VERSION = $$qt_version" \ "QT_MAJOR_VERSION = $$section(qt_version, '.', 0, 0)" \ "QT_MINOR_VERSION = $$section(qt_version, '.', 1, 1)" \ @@ -476,13 +477,13 @@ defineTest(qtConfOutputPostProcess_publicPro) { "QT_RELEASE_DATE = $$config.input.qt_release_date" } - $${currentConfig}.output.publicPro += $$output - export($${currentConfig}.output.publicPro) + return($$output) } -defineTest(qtConfOutputPostProcess_publicHeader) { +defineReplace(qtConfOutputPostProcess_publicHeader) { qt_version = $$[QT_VERSION] output = \ + $$1 \ "$${LITERAL_HASH}define QT_VERSION_STR \"$$qt_version\"" \ "$${LITERAL_HASH}define QT_VERSION_MAJOR $$section(qt_version, '.', 0, 0)" \ "$${LITERAL_HASH}define QT_VERSION_MINOR $$section(qt_version, '.', 1, 1)" \ @@ -499,8 +500,7 @@ defineTest(qtConfOutputPostProcess_publicHeader) { !isEmpty(config.input.qt_libinfix): \ output += "$${LITERAL_HASH}define QT_LIBINFIX \"$$eval(config.input.qt_libinfix)\"" - $${currentConfig}.output.publicHeader += $$output - export($${currentConfig}.output.publicHeader) + return($$output) } diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index c984206f0d..289e2250bd 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1672,13 +1672,17 @@ defineTest(qtConfProcessOutput) { } } - ppScope = - !isEmpty(module): ppScope = $${module}_ - defined(qtConfOutputPostProcess_$${ppScope}$${type}, test): \ - qtConfOutputPostProcess_$${ppScope}$${type}() + content = $$eval($${currentConfig}.output.$${type}) + + !isEmpty(module): \ + call = qtConfOutputPostProcess_$${module}_$${type} + else: \ + call = qtConfOutputPostProcess_$${type} + defined($$call, replace): \ + eval(content = \$\$"$$call"(\$\$content)) file = $$eval($${currentConfig}.files.$${type}) - fileCont.$$file += $$eval($${currentConfig}.output.$${type}) + fileCont.$$file += $$content fileCont._KEYS_ *= $$file } -- cgit v1.2.1 From 27aeeac6eeb11150b505f8ffde6e87e157c22c90 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 24 Oct 2016 14:07:33 -0700 Subject: Cocoa Dialog Helpers: Refactor OK-Cancel buttons view Since virtually all the logic is shared between QNSColorPanelDelegate and QNSFontPanelDelegate, we extract the added buttons and layouting logic and move it into its own class. This requires the two afore mentioned Objective C classes to satisfy the QNSPanelDelegate protocol. Change-Id: Ie26e758f5db71920896d930a4f3644b51a1ce3fa Reviewed-by: Timur Pocheptsov --- .../platforms/cocoa/qcocoacolordialoghelper.mm | 119 +++---------------- .../platforms/cocoa/qcocoafontdialoghelper.mm | 126 ++------------------- src/plugins/platforms/cocoa/qcocoahelpers.h | 23 ++++ src/plugins/platforms/cocoa/qcocoahelpers.mm | 114 +++++++++++++++++++ 4 files changed, 163 insertions(+), 219 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index 3a5a0c8e78..60c4c1a8ca 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -50,31 +50,13 @@ QT_USE_NAMESPACE -static NSButton *macCreateButton(const char *text, NSView *superview) -{ - static const NSRect buttonFrameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; - - NSButton *button = [[NSButton alloc] initWithFrame:buttonFrameRect]; - [button setButtonType:NSMomentaryLightButton]; - [button setBezelStyle:NSRoundedBezelStyle]; - [button setTitle:(NSString*)(CFStringRef)QCFString( - QPlatformTheme::removeMnemonics(QCoreApplication::translate("QPlatformTheme", text)))]; - [[button cell] setFont:[NSFont systemFontOfSize: - [NSFont systemFontSizeForControlSize:NSRegularControlSize]]]; - [superview addSubview:button]; - return button; -} - -@class QT_MANGLE_NAMESPACE(QNSColorPanelDelegate); - -@interface QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) : NSObject +@interface QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) : NSObject { @public NSColorPanel *mColorPanel; QCocoaColorDialogHelper *mHelper; NSView *mStolenContentView; - NSButton *mOkButton; - NSButton *mCancelButton; + QNSPanelContentsWrapper *mPanelButtons; QColor mQtColor; NSInteger mResultCode; BOOL mDialogIsExecuting; @@ -82,7 +64,6 @@ static NSButton *macCreateButton(const char *text, NSView *superview) BOOL mClosingDueToKnownButton; }; - (void)restoreOriginalContentView; -- (void)relayout; - (void)updateQtColor; - (void)finishOffWithCode:(NSInteger)code; @end @@ -97,8 +78,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); mColorPanel = [NSColorPanel sharedColorPanel]; mHelper = 0; mStolenContentView = 0; - mOkButton = 0; - mCancelButton = 0; + mPanelButtons = nil; mResultCode = NSCancelButton; mDialogIsExecuting = false; mResultSet = false; @@ -142,23 +122,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); [mColorPanel setContentView:0]; // create a new content view and add the stolen one as a subview - NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; - NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; - [ourContentView addSubview:mStolenContentView]; - - // create OK and Cancel buttons and add these as subviews - mOkButton = macCreateButton("&OK", ourContentView); - mCancelButton = macCreateButton("Cancel", ourContentView); - - [mColorPanel setContentView:ourContentView]; - [mColorPanel setDefaultButtonCell:[mOkButton cell]]; - [self relayout]; - - [mOkButton setAction:@selector(onOkClicked)]; - [mOkButton setTarget:self]; - - [mCancelButton setAction:@selector(onCancelClicked)]; - [mCancelButton setTarget:self]; + mPanelButtons = [[QNSPanelContentsWrapper alloc] initWithPanelDelegate:self]; + [mPanelButtons addSubview:mStolenContentView]; + mColorPanel.contentView = mPanelButtons; + mColorPanel.defaultButtonCell = mPanelButtons.okButton.cell; } } @@ -167,12 +134,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); [mColorPanel close]; } -- (void)windowDidResize:(NSNotification *)notification -{ - Q_UNUSED(notification); - [self relayout]; -} - - (void)colorChanged:(NSNotification *)notification { Q_UNUSED(notification); @@ -182,7 +143,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); - (void)windowWillClose:(NSNotification *)notification { Q_UNUSED(notification); - if (mCancelButton && mHelper && !mClosingDueToKnownButton) { + if (mPanelButtons && mHelper && !mClosingDueToKnownButton) { mClosingDueToKnownButton = true; // prevent repeating emit emit mHelper->reject(); } @@ -191,68 +152,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); - (void)restoreOriginalContentView { if (mStolenContentView) { - NSView *ourContentView = [mColorPanel contentView]; - // return stolen stuff to its rightful owner [mStolenContentView removeFromSuperview]; [mColorPanel setContentView:mStolenContentView]; - [mOkButton release]; - [mCancelButton release]; - [ourContentView release]; - mOkButton = 0; - mCancelButton = 0; - mStolenContentView = 0; + [mStolenContentView release]; + mStolenContentView = nil; + [mPanelButtons release]; + mPanelButtons = nil; } } -- (void)relayout -{ - if (!mOkButton) - return; - - NSRect rect = [[mStolenContentView superview] frame]; - - // should a priori be kept in sync with qfontdialog_mac.mm - const CGFloat ButtonMinWidth = 78.0; // 84.0 for Carbon - const CGFloat ButtonMinHeight = 32.0; - const CGFloat ButtonSpacing = 0.0; - const CGFloat ButtonTopMargin = 0.0; - const CGFloat ButtonBottomMargin = 7.0; - const CGFloat ButtonSideMargin = 9.0; - - [mOkButton sizeToFit]; - NSSize okSizeHint = [mOkButton frame].size; - - [mCancelButton sizeToFit]; - NSSize cancelSizeHint = [mCancelButton frame].size; - - const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth, - qMax(okSizeHint.width, cancelSizeHint.width)), - CGFloat((rect.size.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5)); - const CGFloat ButtonHeight = qMax(ButtonMinHeight, - qMax(okSizeHint.height, cancelSizeHint.height)); - - NSRect okRect = { { rect.size.width - ButtonSideMargin - ButtonWidth, - ButtonBottomMargin }, - { ButtonWidth, ButtonHeight } }; - [mOkButton setFrame:okRect]; - [mOkButton setNeedsDisplay:YES]; - - NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth, - ButtonBottomMargin }, - { ButtonWidth, ButtonHeight } }; - [mCancelButton setFrame:cancelRect]; - [mCancelButton setNeedsDisplay:YES]; - - const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin; - NSRect stolenCVRect = { { 0.0, Y }, - { rect.size.width, rect.size.height - Y } }; - [mStolenContentView setFrame:stolenCVRect]; - [mStolenContentView setNeedsDisplay:YES]; - - [[mStolenContentView superview] setNeedsDisplay:YES]; -} - - (void)onOkClicked { mClosingDueToKnownButton = true; @@ -263,7 +172,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); - (void)onCancelClicked { - if (mOkButton) { + if (mPanelButtons) { mClosingDueToKnownButton = true; [mColorPanel close]; mQtColor = QColor(); @@ -335,7 +244,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate); - (BOOL)windowShouldClose:(id)window { Q_UNUSED(window); - if (!mOkButton) + if (!mPanelButtons) [self updateQtColor]; if (mDialogIsExecuting) { [self finishOffWithCode:NSCancelButton]; diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 0be931b54f..e565f3b5b1 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -58,33 +58,6 @@ typedef float CGFloat; // Should only not be defined on 32-bit platforms QT_USE_NAMESPACE -// should a priori be kept in sync with qcolordialog_mac.mm -const CGFloat ButtonMinWidth = 78.0; -const CGFloat ButtonMinHeight = 32.0; -const CGFloat ButtonSpacing = 0.0; -const CGFloat ButtonTopMargin = 0.0; -const CGFloat ButtonBottomMargin = 7.0; -const CGFloat ButtonSideMargin = 9.0; - -// looks better with some margins -const CGFloat DialogTopMargin = 7.0; -const CGFloat DialogSideMargin = 9.0; - -static NSButton *macCreateButton(const char *text, NSView *superview) -{ - static const NSRect buttonFrameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; - - NSButton *button = [[NSButton alloc] initWithFrame:buttonFrameRect]; - [button setButtonType:NSMomentaryLightButton]; - [button setBezelStyle:NSRoundedBezelStyle]; - [button setTitle:(NSString*)(CFStringRef)QCFString( - QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", text)))]; - [[button cell] setFont:[NSFont systemFontOfSize: - [NSFont systemFontSizeForControlSize:NSRegularControlSize]]]; - [superview addSubview:button]; - return button; -} - static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) { QFont newFont; @@ -103,22 +76,19 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) @class QT_MANGLE_NAMESPACE(QNSFontPanelDelegate); -@interface QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) : NSObject +@interface QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) : NSObject { @public NSFontPanel *mFontPanel; QCocoaFontDialogHelper *mHelper; NSView *mStolenContentView; - NSButton *mOkButton; - NSButton *mCancelButton; + QNSPanelContentsWrapper *mPanelButtons; QFont mQtFont; NSInteger mResultCode; BOOL mDialogIsExecuting; BOOL mResultSet; }; - (void)restoreOriginalContentView; -- (void)relayout; -- (void)relayoutToContentSize:(NSSize)frameSize; - (void)updateQtFont; - (void)changeFont:(id)sender; - (void)finishOffWithCode:(NSInteger)code; @@ -134,8 +104,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); mFontPanel = [NSFontPanel sharedFontPanel]; mHelper = 0; mStolenContentView = 0; - mOkButton = 0; - mCancelButton = 0; + mPanelButtons = 0; mResultCode = NSCancelButton; mDialogIsExecuting = false; mResultSet = false; @@ -173,23 +142,11 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); [mFontPanel setContentView:0]; // create a new content view and add the stolen one as a subview - NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; - NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; - [ourContentView addSubview:mStolenContentView]; - - // create OK and Cancel buttons and add these as subviews - mOkButton = macCreateButton("&OK", ourContentView); - mCancelButton = macCreateButton("Cancel", ourContentView); - - [mFontPanel setContentView:ourContentView]; - [mFontPanel setDefaultButtonCell:[mOkButton cell]]; - [self relayoutToContentSize:[[mStolenContentView superview] frame].size]; - - [mOkButton setAction:@selector(onOkClicked)]; - [mOkButton setTarget:self]; - - [mCancelButton setAction:@selector(onCancelClicked)]; - [mCancelButton setTarget:self]; + mPanelButtons = [[QNSPanelContentsWrapper alloc] initWithPanelDelegate:self]; + [mPanelButtons addSubview:mStolenContentView]; + mPanelButtons.panelContentsMargins = NSEdgeInsetsMake(0, 0, 7, 0); + mFontPanel.contentView = mPanelButtons; + mFontPanel.defaultButtonCell = mPanelButtons.okButton.cell; } } @@ -198,77 +155,18 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); [mFontPanel close]; } -- (void)windowDidResize:(NSNotification *)notification -{ - Q_UNUSED(notification); - [self relayout]; -} - - (void)restoreOriginalContentView { if (mStolenContentView) { - NSView *ourContentView = [mFontPanel contentView]; - // return stolen stuff to its rightful owner [mStolenContentView removeFromSuperview]; [mFontPanel setContentView:mStolenContentView]; - [mOkButton release]; - [mCancelButton release]; - [ourContentView release]; - mOkButton = 0; - mCancelButton = 0; mStolenContentView = 0; + [mPanelButtons release]; + mPanelButtons = nil; } } -- (void)relayout -{ - if (!mOkButton) - return; - - [self relayoutToContentSize:[[mStolenContentView superview] frame].size]; -} - -- (void)relayoutToContentSize:(NSSize)frameSize -{ - Q_ASSERT(mOkButton); - - [mOkButton sizeToFit]; - NSSize okSizeHint = [mOkButton frame].size; - - [mCancelButton sizeToFit]; - NSSize cancelSizeHint = [mCancelButton frame].size; - - const CGFloat ButtonWidth = qMin(qMax(ButtonMinWidth, - qMax(okSizeHint.width, cancelSizeHint.width)), - CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5)); - const CGFloat ButtonHeight = qMax(ButtonMinHeight, - qMax(okSizeHint.height, cancelSizeHint.height)); - - const CGFloat X = DialogSideMargin; - const CGFloat Y = ButtonBottomMargin + ButtonHeight + ButtonTopMargin; - - NSRect okRect = { { frameSize.width - ButtonSideMargin - ButtonWidth, - ButtonBottomMargin }, - { ButtonWidth, ButtonHeight } }; - [mOkButton setFrame:okRect]; - [mOkButton setNeedsDisplay:YES]; - - NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - ButtonWidth, - ButtonBottomMargin }, - { ButtonWidth, ButtonHeight } }; - [mCancelButton setFrame:cancelRect]; - [mCancelButton setNeedsDisplay:YES]; - - NSRect stolenCVRect = { { X, Y }, - { frameSize.width - X - X, frameSize.height - Y - DialogTopMargin } }; - [mStolenContentView setFrame:stolenCVRect]; - [mStolenContentView setNeedsDisplay:YES]; - - [[mStolenContentView superview] setNeedsDisplay:YES]; -} - - - (void)onOkClicked { [mFontPanel close]; @@ -277,7 +175,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); - (void)onCancelClicked { - if (mOkButton) { + if (mPanelButtons) { [mFontPanel close]; mQtFont = QFont(); [self finishOffWithCode:NSCancelButton]; @@ -332,7 +230,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); - (BOOL)windowShouldClose:(id)window { Q_UNUSED(window); - if (!mOkButton) + if (!mPanelButtons) [self updateQtFont]; if (mDialogIsExecuting) { [self finishOffWithCode:NSCancelButton]; diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 1b038a6b5e..a2e0876073 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -158,7 +158,30 @@ T qt_mac_resolveOption(const T &fallback, QWindow *window, const QByteArray &pro // return default value. return fallback; } + QT_END_NAMESPACE +@protocol QT_MANGLE_NAMESPACE(QNSPanelDelegate) +@required +- (void)onOkClicked; +- (void)onCancelClicked; +@end + +@interface QT_MANGLE_NAMESPACE(QNSPanelContentsWrapper) : NSView + +@property (nonatomic, readonly) NSButton *okButton; +@property (nonatomic, readonly) NSButton *cancelButton; +@property (nonatomic, readonly) NSView *panelContents; // ARC: unretained, make it weak +@property (nonatomic, assign) NSEdgeInsets panelContentsMargins; + +- (instancetype)initWithPanelDelegate:(id)panelDelegate; +- (void)dealloc; + +- (NSButton *)createButtonWithTitle:(const char *)title; +- (void)layout; +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper); + #endif //QCOCOAHELPERS_H diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index c57567bdd6..01fbb7bad2 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -300,3 +300,117 @@ QString qt_mac_removeAmpersandEscapes(QString s) } QT_END_NAMESPACE + +/*! \internal + + This NSView derived class is used to add OK/Cancel + buttons to NSColorPanel and NSFontPanel. It replaces + the panel's content view, while reparenting the former + content view into itself. It also takes care of setting + the target-action for the OK/Cancel buttons and making + sure the layout is consistent. + */ +@implementation QNSPanelContentsWrapper + +- (instancetype)initWithPanelDelegate:(id)panelDelegate +{ + if ((self = [super initWithFrame:NSZeroRect])) { + // create OK and Cancel buttons and add these as subviews + _okButton = [self createButtonWithTitle:"&OK"]; + _okButton.action = @selector(onOkClicked); + _okButton.target = panelDelegate; + + _cancelButton = [self createButtonWithTitle:"Cancel"]; + _cancelButton.action = @selector(onCancelClicked); + _cancelButton.target = panelDelegate; + + _panelContents = nil; + + _panelContentsMargins = NSEdgeInsetsMake(0, 0, 0, 0); + } + + return self; +} + +- (void)dealloc +{ + [_okButton release]; + _okButton = nil; + [_cancelButton release]; + _cancelButton = nil; + + _panelContents = nil; + + [super dealloc]; +} + +- (NSButton *)createButtonWithTitle:(const char *)title +{ + NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect]; + button.buttonType = NSMomentaryLightButton; + button.bezelStyle = NSRoundedBezelStyle; + const QString &cleanTitle = QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", title)); + // FIXME: Not obvious, from Cocoa's documentation, that QString::toNSString() makes a deep copy + button.title = (NSString *)cleanTitle.toCFString(); + ((NSButtonCell *)button.cell).font = + [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; + [self addSubview:button]; + return button; +} + +- (void)layout +{ + static const CGFloat ButtonMinWidth = 78.0; // 84.0 for Carbon + static const CGFloat ButtonMinHeight = 32.0; + static const CGFloat ButtonSpacing = 0.0; + static const CGFloat ButtonTopMargin = 0.0; + static const CGFloat ButtonBottomMargin = 7.0; + static const CGFloat ButtonSideMargin = 9.0; + + NSSize frameSize = self.frame.size; + + [self.okButton sizeToFit]; + NSSize okSizeHint = self.okButton.frame.size; + + [self.cancelButton sizeToFit]; + NSSize cancelSizeHint = self.cancelButton.frame.size; + + const CGFloat buttonWidth = qMin(qMax(ButtonMinWidth, + qMax(okSizeHint.width, cancelSizeHint.width)), + CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5)); + const CGFloat buttonHeight = qMax(ButtonMinHeight, + qMax(okSizeHint.height, cancelSizeHint.height)); + + NSRect okRect = { { frameSize.width - ButtonSideMargin - buttonWidth, + ButtonBottomMargin }, + { buttonWidth, buttonHeight } }; + self.okButton.frame = okRect; + self.okButton.needsDisplay = YES; + + NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - buttonWidth, + ButtonBottomMargin }, + { buttonWidth, buttonHeight } }; + self.cancelButton.frame = cancelRect; + self.cancelButton.needsDisplay = YES; + + // The third view should be the original panel contents. Cache it. + if (!self.panelContents) + for (NSView *view in self.subviews) + if (view != self.okButton && view != self.cancelButton) { + _panelContents = view; + break; + } + + const CGFloat buttonBoxHeight = ButtonBottomMargin + buttonHeight + ButtonTopMargin; + const NSRect panelContentsFrame = NSMakeRect( + self.panelContentsMargins.left, + buttonBoxHeight + self.panelContentsMargins.bottom, + frameSize.width - (self.panelContentsMargins.left + self.panelContentsMargins.right), + frameSize.height - buttonBoxHeight - (self.panelContentsMargins.top + self.panelContentsMargins.bottom)); + self.panelContents.frame = panelContentsFrame; + self.panelContents.needsDisplay = YES; + + self.needsDisplay = YES; +} + +@end -- cgit v1.2.1 From 78e33de8e5538235b06623bbeef0019d4fb320c8 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 16 Nov 2016 08:35:36 +0100 Subject: winrt: Check for sanity of variables in debug build Identified as potential issues by analyze mode. Change-Id: I3f7c63a2349f29cc3de7baa78157fec157b9e561 Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index e49817ada4..b0e70608f9 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -110,7 +110,12 @@ static void devMessageHandler(QtMsgType type, const QMessageLogContext &context, if (!event) event = CreateEventEx(NULL, L"qdebug-event", 0, EVENT_ALL_ACCESS); + Q_ASSERT_X(shmem, Q_FUNC_INFO, "Could not create file mapping"); + Q_ASSERT_X(event, Q_FUNC_INFO, "Could not create debug event"); + void *data = MapViewOfFileFromApp(shmem, FILE_MAP_WRITE, 0, 4096); + Q_ASSERT_X(data, Q_FUNC_INFO, "Could not map file"); + memset(data, quint32(type), sizeof(quint32)); memcpy_s(static_cast(data) + 1, 4096 - sizeof(quint32), message.data(), (message.length() + 1) * sizeof(wchar_t)); @@ -179,6 +184,7 @@ public: app->core->Exit(); return res; }, this, CREATE_SUSPENDED, nullptr); + Q_ASSERT_X(mainThread, Q_FUNC_INFO, "Could not create Qt main thread"); HRESULT hr; ComPtr appStatics; -- cgit v1.2.1 From a6fbfea24a26d6dc4237eb5fcb9ab4298a612732 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 15 Nov 2016 15:58:54 +0100 Subject: Doc: Mention qtmain library in Qt Core overview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The documentation for the qtmain license is right now pretty hidden. The library is added by qmake independent of the Qt module that are linked to, but it seems safe to assume people at least link against Qt Core. Change-Id: Id474990edde45feab6727bada2bc6a28946216cd Reviewed-by: Friedemann Kleint Reviewed-by: Topi Reiniö --- src/corelib/doc/src/qtcore-index.qdoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/doc/src/qtcore-index.qdoc b/src/corelib/doc/src/qtcore-index.qdoc index fe9b43507c..9004c018ed 100644 --- a/src/corelib/doc/src/qtcore-index.qdoc +++ b/src/corelib/doc/src/qtcore-index.qdoc @@ -109,6 +109,11 @@ the \l{GNU General Public License, version 2}. See \l{Qt Licensing} for further details. + Executables on Windows potentially link + against \l{The qtmain Library}. This library is available + under commercial licenses, and in addition under the + \l{BSD 3-clause "New" or "Revised" License}. + Furthermore Qt Core potentially contains third party modules under following permissive licenses: -- cgit v1.2.1 From 38e935701c0faeb19b9b1493dc2d6d60c6bc3ca3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 15 Nov 2016 14:01:15 +0100 Subject: make QMAKE_USE obey QMAKE_LIBDIR_* this is complementary to configure's makeSpec library source type. this should be sufficient to make QMAKE_USE += {egl,opengl,opengl_es2} actually work, obsoleting the need for opengl.prf and egl.prf (and the currently dysfunct openvg.prf). Change-Id: I2f7595ac89afa087ea7f0f25060e8e47e6148be9 Reviewed-by: Andy Nichols Reviewed-by: Lars Knoll --- mkspecs/features/qmake_use.prf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf index 81b841d457..9b6c67ccc2 100644 --- a/mkspecs/features/qmake_use.prf +++ b/mkspecs/features/qmake_use.prf @@ -10,14 +10,17 @@ for(ever) { else: \ libs = $$eval(QMAKE_LIBS_$${nu}_RELEASE) libs += $$eval(QMAKE_LIBS_$$nu) + libdir = $$eval(QMAKE_LIBDIR_$$nu) defines = $$eval(QMAKE_DEFINES_$${nu}) includes = $$eval(QMAKE_INCDIR_$${nu}) isEmpty(libs):isEmpty(defines):isEmpty(includes): \ error("Library '$$name' is not defined.") - !contains(use, nolink): \ + !contains(use, nolink) { + QMAKE_LIBDIR += $$libdir LIBS$${suffix} += $$libs + } !contains(use, linkonly) { DEFINES += $$defines INCLUDEPATH += $$includes -- cgit v1.2.1 From 3e3b22adeb5267d47ad9aedce9fef816e91197e9 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 15 Nov 2016 13:09:01 +0100 Subject: winrt: Fix ill-constructed loop That loop could never have worked properly. Identified by analyze compile switch. Change-Id: I5e987dc9f5c57d3ffbcf054b7b417b506c02e7e1 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtfileengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index 53e7ebd30d..557c13cf63 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -92,7 +92,7 @@ public: } firstDot = fileName.size(); - for (int i = lastSeparator; i > fileName.size(); ++i) { + for (int i = lastSeparator; i < fileName.size(); ++i) { if (fileName.at(i).unicode() == '.') { firstDot = i; break; -- cgit v1.2.1 From 7912ac5d672bef9ab46d05a11fc71cb6ed68acf7 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 15 Nov 2016 13:10:10 +0100 Subject: winrt: move to range based loop Change-Id: I0694adcff9b591eecf1025074e8b1c478484bd74 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp index 038a6d32e8..417dbdc1db 100644 --- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp +++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp @@ -195,8 +195,8 @@ static bool initializeOpenPickerOptions(T *picker, const QSharedPointer> filters; hr = picker->get_FileTypeFilter(&filters); RETURN_FALSE_IF_FAILED("Failed to get file type filters list"); - foreach (const QString &namedFilter, options->nameFilters()) { - foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(namedFilter)) { + for (const QString &namedFilter : options->nameFilters()) { + for (const QString &filter : QPlatformFileDialogHelper::cleanFilterList(namedFilter)) { // Remove leading star const int offset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0; HStringReference filterRef(reinterpret_cast(filter.utf16() + offset), @@ -419,13 +419,15 @@ bool QWinRTFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit ComPtr *>> choices; hr = picker->get_FileTypeChoices(&choices); RETURN_FALSE_IF_FAILED("Failed to get file extension choices"); - foreach (const QString &namedFilter, dialogOptions->nameFilters()) { + const QStringList nameFilters = dialogOptions->nameFilters(); + for (const QString &namedFilter : nameFilters) { ComPtr> entry = Make(); - foreach (const QString &filter, QPlatformFileDialogHelper::cleanFilterList(namedFilter)) { + const QStringList cleanFilter = QPlatformFileDialogHelper::cleanFilterList(namedFilter); + for (const QString &filter : cleanFilter) { // Remove leading star - const int offset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0; - HStringReference filterRef(reinterpret_cast(filter.utf16() + offset), - filter.length() - offset); + const int starOffset = (filter.length() > 1 && filter.startsWith(QLatin1Char('*'))) ? 1 : 0; + HStringReference filterRef(reinterpret_cast(filter.utf16() + starOffset), + filter.length() - starOffset); hr = entry->Append(filterRef.Get()); if (FAILED(hr)) { qWarning("Failed to add named file filter \"%s\": %s", -- cgit v1.2.1 From 3e5e2cd3bd1271ce886fe5b97fe07dffb2631cc6 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 15 Nov 2016 13:48:39 +0100 Subject: winrt: Do not shadow variable Change-Id: I70fc9254bfdfe42bf0e8d379537eb60b21be8275 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtdrag.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp index 055aacbf56..89ebf7d26f 100644 --- a/src/plugins/platforms/winrt/qwinrtdrag.cpp +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -322,9 +322,9 @@ QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVari hr = res.As(&propertyValue); if (SUCCEEDED(hr)) { // We need to check which type of custom data we are receiving - PropertyType type; - propertyValue->get_Type(&type); - switch (type) { + PropertyType propertyType; + propertyValue->get_Type(&propertyType); + switch (propertyType) { case PropertyType_UInt8: { quint8 v; hr = propertyValue->GetUInt8(&v); @@ -410,7 +410,7 @@ QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVari return S_OK; } default: - qCDebug(lcQpaMime) << "Unknown property type dropped:" << type; + qCDebug(lcQpaMime) << "Unknown property type dropped:" << propertyType; } return S_OK; } -- cgit v1.2.1 From e8a41ed8668437eb6ad406ddabf4141fd66a85d2 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 2 Nov 2016 17:37:43 -0700 Subject: QCocoaMenu: Force NSMenuValidation when syncing items When a menu item's enabled state changes after -[QCocoaMenuDelegate menuWillOpen:] is invoked, i.e., during or after QMenu::aboutToShow() is emitted, that state change may not be taken into account. This is because the automatic menu validation, upon which Qt relies, is not made aware of any such change. By calling -[NSMenu update] when syncing the QPA menu item, we induce Cocoa to invoke -[QCocoaMenuDelegate validateMenuItem:] and ensure that previously synced items, whose state may have changed, will be properly updated. This, however, has a small side effect, namely that menu-holding items will also go through the automatic menu enabling path and may appear disabled since, until now, they were not properly configured. In order to solve this, we set the action on those items as well, and make sure that both of QCocoaMenuDelegate's relevant methods, validateMenuItem: and itemFired:, properly process menu-holding items. Menurama manual test updated accordingly. Change-Id: I62f955538b8be09b8494ea0ce87fca7910148d38 Task-number: QTBUG-56850 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoamenu.mm | 17 +++- tests/manual/cocoa/menurama/mainwindow.cpp | 8 +- tests/manual/cocoa/menurama/mainwindow.ui | 98 ++++++++++++---------- .../manual/cocoa/menurama/menuramaapplication.cpp | 16 ++-- tests/manual/cocoa/menurama/menuramaapplication.h | 1 + 5 files changed, 85 insertions(+), 55 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 566363e01f..88ffd48538 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -147,6 +147,10 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (void) itemFired:(NSMenuItem*) item { QCocoaMenuItem *cocoaItem = reinterpret_cast([item tag]); + // Menu-holding items also get a target to play nicely + // with NSMenuValidation but should not trigger. + if (cocoaItem->menu()) + return; QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData); QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers:[NSEvent modifierFlags]]; static QMetaMethod activatedSignal = QMetaMethod::fromSignal(&QCocoaMenuItem::activated); @@ -156,7 +160,8 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { QCocoaMenuItem *cocoaItem = reinterpret_cast(menuItem.tag); - if (!cocoaItem) + // Menu-holding items are always enabled, as it's conventional in Cocoa + if (!cocoaItem || cocoaItem->menu()) return YES; return cocoaItem->isEnabled(); @@ -327,9 +332,9 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem * void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) { item->nsItem().target = m_nativeMenu.delegate; - if (!item->menu()) - [item->nsItem() setAction:@selector(itemFired:)]; - else if (isOpen() && item->nsItem()) // Someone's adding new items after aboutToShow() was emitted + item->nsItem().action = @selector(itemFired:); + // Someone's adding new items after aboutToShow() was emitted + if (isOpen() && item->menu() && item->nsItem()) item->menu()->setAttachedItem(item->nsItem()); item->setParentEnabled(isEnabled()); @@ -425,6 +430,10 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) QCocoaMenuItem* beforeItem = itemOrNull(m_menuItems.indexOf(cocoaItem) + 1); insertNative(cocoaItem, beforeItem); + } else { + // Force NSMenuValidation to kick in. This is needed e.g. + // when an item's enabled state changes after menuWillOpen: + [m_nativeMenu update]; } } diff --git a/tests/manual/cocoa/menurama/mainwindow.cpp b/tests/manual/cocoa/menurama/mainwindow.cpp index db8fdafc21..f7762f57f5 100644 --- a/tests/manual/cocoa/menurama/mainwindow.cpp +++ b/tests/manual/cocoa/menurama/mainwindow.cpp @@ -56,7 +56,13 @@ MainWindow::MainWindow(QWidget *parent) : }); connect(ui->menuDynamic_Stuff, &QMenu::aboutToShow, [=] { - menuApp->addDynMenu(QLatin1String("Added After aboutToShow()"), ui->menuDynamic_Stuff); + menuApp->addDynMenu(QLatin1String("Menu Added After aboutToShow()"), ui->menuDynamic_Stuff); + + const QLatin1String itemTitle = QLatin1String("Disabled Item Added After aboutToShow()"); + if (QAction *a = menuApp->findAction(itemTitle, ui->menuDynamic_Stuff)) + ui->menuDynamic_Stuff->removeAction(a); + QAction *a = ui->menuDynamic_Stuff->addAction(itemTitle); + a->setEnabled(false); }); connect(ui->pushButton, &QPushButton::clicked, [=] { diff --git a/tests/manual/cocoa/menurama/mainwindow.ui b/tests/manual/cocoa/menurama/mainwindow.ui index f73b41b861..d3caa6c608 100644 --- a/tests/manual/cocoa/menurama/mainwindow.ui +++ b/tests/manual/cocoa/menurama/mainwindow.ui @@ -6,63 +6,71 @@ 0 0 - 566 - 300 + 429 + 251 MainWindow - - - - 10 - 40 - 151 - 20 - - - - Enable "Stuff" Menu - - - true - - - - - - 10 - 10 - 321 - 16 - - - - The "Help" menu should NOT be visible. - - - - - - 10 - 80 - 211 - 32 - - - - Populate Dynamic Submenu - - + + + + + 24 + + + + + The "Help" menu should NOT be visible. + +Click on "Dynamic Stuff" then move left and right to other menus. Disabled items should remain that way. + + + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + Enable "Stuff" Menu + + + true + + + + + + + + 0 + 0 + + + + Populate Dynamic Submenu + + + + + + 0 0 - 566 + 429 22 diff --git a/tests/manual/cocoa/menurama/menuramaapplication.cpp b/tests/manual/cocoa/menurama/menuramaapplication.cpp index 534d5fa371..13e457d7dd 100644 --- a/tests/manual/cocoa/menurama/menuramaapplication.cpp +++ b/tests/manual/cocoa/menurama/menuramaapplication.cpp @@ -69,13 +69,19 @@ void MenuramaApplication::populateMenu(QMenu *menu, bool clear) void MenuramaApplication::addDynMenu(QLatin1String title, QMenu *parentMenu) { - foreach (QAction *a, parentMenu->actions()) - if (a->text() == title) { - parentMenu->removeAction(a); - break; - } + if (QAction *a = findAction(title, parentMenu)) + parentMenu->removeAction(a); QMenu *subMenu = new QMenu(title, parentMenu); populateMenu(subMenu, false /*clear*/); parentMenu->addMenu(subMenu); } + +QAction *MenuramaApplication::findAction(QLatin1String title, QMenu *parentMenu) +{ + foreach (QAction *a, parentMenu->actions()) + if (a->text() == title) + return a; + + return Q_NULLPTR; +} diff --git a/tests/manual/cocoa/menurama/menuramaapplication.h b/tests/manual/cocoa/menurama/menuramaapplication.h index 07c8da27a1..b0670cc53b 100644 --- a/tests/manual/cocoa/menurama/menuramaapplication.h +++ b/tests/manual/cocoa/menurama/menuramaapplication.h @@ -50,6 +50,7 @@ class MenuramaApplication : public QApplication public: MenuramaApplication(int argc, char **argv); void addDynMenu(QLatin1String title, QMenu *parentMenu); + QAction *findAction(QLatin1String title, QMenu *parentMenu); public slots: void populateMenu(QMenu *menu, bool clear); -- cgit v1.2.1 From 094b64fb605b39d1ae88d91d2b9a0672b9ff4780 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Tue, 15 Nov 2016 18:16:50 +0100 Subject: QRawFont: Add a qHash overload This will be used in QtQuick to avoid costly string manipulation (which in turn involves memory allocations). Change-Id: I51a67a4cd97cc576f399483c9c0c13da1e1c6e72 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qrawfont.cpp | 13 +++++++++++++ src/gui/text/qrawfont.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 886cf5ef39..b2d8bf01af 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -315,6 +315,19 @@ bool QRawFont::operator==(const QRawFont &other) const return d->fontEngine == other.d->fontEngine; } +/*! + Returns the hash value for \a font. If specified, \a seed is used + to initialize the hash. + + \relates QRawFont + \since 5.8 +*/ +uint qHash(const QRawFont &font, uint seed) Q_DECL_NOTHROW +{ + return qHash(QRawFontPrivate::get(font)->fontEngine, seed); +} + + /*! \fn bool QRawFont::operator!=(const QRawFont &other) const diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 0252e62370..470f2694e4 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -158,6 +158,8 @@ Q_DECLARE_SHARED(QRawFont) Q_DECLARE_OPERATORS_FOR_FLAGS(QRawFont::LayoutFlags) +Q_GUI_EXPORT uint qHash(const QRawFont &font, uint seed = 0) Q_DECL_NOTHROW; + inline QVector QRawFont::advancesForGlyphIndexes(const QVector &glyphIndexes, QRawFont::LayoutFlags layoutFlags) const { QVector advances(glyphIndexes.size()); -- cgit v1.2.1 From 33573bf7eac70e27fa839b890bed2cb6e7fc0793 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 15 Nov 2016 17:26:53 +0100 Subject: Manual Dialog test: Fix compilation against Qt 4 Change-Id: I79a90cd252e99fb94c0429a3f03eb1ddacab1786 Reviewed-by: Oliver Wolff --- tests/manual/dialogs/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/manual/dialogs/main.cpp b/tests/manual/dialogs/main.cpp index f0f4e437e9..3f7b33ee7a 100644 --- a/tests/manual/dialogs/main.cpp +++ b/tests/manual/dialogs/main.cpp @@ -80,12 +80,15 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) int main(int argc, char *argv[]) { +#if QT_VERSION >= 0x050700 for (int a = 1; a < argc; ++a) { if (!qstrcmp(argv[a], "-n")) { qDebug("AA_DontUseNativeDialogs"); QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs); } } +#endif // Qt 5 + QApplication a(argc, argv); MainWindow w; w.move(500, 200); -- cgit v1.2.1 From 03c1a6ac717e3c5693653a5e294214056bda970e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 16 Nov 2016 16:57:24 +0100 Subject: Remove last traces of opengl es 1 support Change-Id: I3f86d4892ec3235003d34fdcf3f093f1513c821f Reviewed-by: Laszlo Agocs --- examples/opengl/legacy/hellogl/glwidget.cpp | 4 ---- tests/auto/opengl/qgl/tst_qgl.cpp | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/opengl/legacy/hellogl/glwidget.cpp b/examples/opengl/legacy/hellogl/glwidget.cpp index 84daf074e2..22934136e5 100644 --- a/examples/opengl/legacy/hellogl/glwidget.cpp +++ b/examples/opengl/legacy/hellogl/glwidget.cpp @@ -177,11 +177,7 @@ void GLWidget::resizeGL(int width, int height) glMatrixMode(GL_PROJECTION); glLoadIdentity(); -#ifdef QT_OPENGL_ES_1 - glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); -#else glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); -#endif glMatrixMode(GL_MODELVIEW); } //! [8] diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 4dec107f1e..af0248b432 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -739,16 +739,14 @@ void tst_QGL::openGLVersionCheck() // However, the complicated parts are in openGLVersionFlags(const QString &versionString) // tested above -#if defined(QT_OPENGL_ES_1) - QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Common_Version_1_0); -#elif defined(QT_OPENGL_ES_2) +#if defined(QT_OPENGL_ES_2) QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); #else if (QOpenGLContext::currentContext()->isOpenGLES()) QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); else QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1); -#endif //defined(QT_OPENGL_ES_1) +#endif //defined(QT_OPENGL_ES_2) } #endif //QT_BUILD_INTERNAL -- cgit v1.2.1