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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 --- src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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) -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 --- src/gui/configure.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 + 2 files changed, 9 insertions(+) (limited to 'src') 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: -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 ++------- 6 files changed, 56 insertions(+), 38 deletions(-) (limited to 'src') 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 -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 +- 23 files changed, 55 insertions(+), 503 deletions(-) (limited to 'src') 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) { -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 + 1 file changed, 1 insertion(+) (limited to 'src') 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)); -- cgit v1.2.3 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 +- 4 files changed, 6 insertions(+), 22 deletions(-) (limited to 'src') 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); -- cgit v1.2.3 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 ++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 21 deletions(-) (limited to 'src') 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 -- cgit v1.2.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') 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. -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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 (limited to 'src') 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.3 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 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') 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); -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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 --- src/gui/opengl/qopengl.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 ++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 19 deletions(-) (limited to 'src') 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; -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 --- src/gui/kernel/kernel.pri | 2 +- src/gui/opengl/opengl.pri | 2 +- src/src.pro | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') 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 } -- cgit v1.2.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') 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; -- cgit v1.2.3 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(-) (limited to 'src') 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.3 From 712a041eb84f3b0377679f84e78173387480159d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(+) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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(-) (limited to 'src') 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.3 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 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src') 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]; } } -- cgit v1.2.3 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(+) (limited to 'src') 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.3