diff options
Diffstat (limited to 'src')
90 files changed, 607 insertions, 426 deletions
diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index c142c5a9736..fb6771759b8 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -7,15 +7,15 @@ CONFIG += \ load(qt_helper_lib) -DEFINES += HAVE_OT HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED +DEFINES += HAVE_OT HAVE_QT5_ATOMICS HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED # platform/compiler specific definitions DEFINES += HAVE_ATEXIT -gcc: DEFINES += HAVE_INTEL_ATOMIC_PRIMITIVES unix: DEFINES += HAVE_PTHREAD HAVE_SCHED_H HAVE_SCHED_YIELD win32: DEFINES += HB_NO_WIN1256 INCLUDEPATH += $$PWD/include +INCLUDEPATH += $$QT.core.includes SOURCES += \ $$PWD/src/hb-blob.cc \ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh index e6738b7d9f6..48eb56141ff 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh @@ -41,6 +41,25 @@ #if 0 +#elif !defined(HB_NO_MT) && defined(HAVE_QT5_ATOMICS) +#include <QtCore/qatomic.h> + +QT_USE_NAMESPACE + +namespace { +// We need to cast hb_atomic_int_t to QAtomicInt and pointers to +// QAtomicPointer instead of using QAtomicOps, otherwise we get a failed +// overload resolution of the template arguments for testAndSetOrdered. +template <typename T> QAtomicPointer<T> *makeAtomicPointer(T * const &ptr) +{ + return reinterpret_cast<QAtomicPointer<T> *>(const_cast<T **>(&ptr)); +} +} + +typedef int hb_atomic_int_t; +#define hb_atomic_int_add(AI, V) reinterpret_cast<QAtomicInt &>(AI).fetchAndAddOrdered(V) +#define hb_atomic_ptr_get(P) makeAtomicPointer(*P)->loadAcquire() +#define hb_atomic_ptr_cmpexch(P,O,N) makeAtomicPointer(*P)->testAndSetOrdered((O), (N)) #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh index 45b7712ce8f..cfe77f1606d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh @@ -94,16 +94,6 @@ # endif #endif -#ifdef _MSC_VER -#undef inline -#define inline __inline -#endif - -#ifdef __STRICT_ANSI__ -#undef inline -#define inline __inline__ -#endif - #if __GNUC__ >= 3 #define HB_FUNC __PRETTY_FUNCTION__ #elif defined(_MSC_VER) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 4387bedc447..7213a844f5a 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -134,13 +134,13 @@ if (NOT TARGET Qt5::WinMain) set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:Qt5_NO_LINK_QTMAIN>>>) set(_isPolicyNEW $<TARGET_POLICY:CMP0020>) get_target_property(_configs Qt5::Core IMPORTED_CONFIGURATIONS) + set_property(TARGET Qt5::Core APPEND PROPERTY + INTERFACE_LINK_LIBRARIES + $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt5::WinMain> + ) + # For backward compatibility with CMake < 2.8.12 foreach(_config ${_configs}) set_property(TARGET Qt5::Core APPEND PROPERTY - INTERFACE_LINK_LIBRARIES - $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt5::WinMain> - ) - # For backward compatibility with CMake < 2.8.12 - set_property(TARGET Qt5::Core APPEND PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES_${_config} $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt5::WinMain> ) diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index d5a3ee751b6..fc87cd4cc8b 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -44,7 +44,7 @@ animations in parallel. The animation group finishes when the longest lasting animation has finished. - You can treat QParallelAnimation as any other QAbstractAnimation, + You can treat QParallelAnimationGroup as any other QAbstractAnimation, e.g., pause, resume, or add it to other animation groups. \code diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 5a14ba9088f..f3aff83a8ba 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -25,7 +25,7 @@ qhp.QtCore.subprojects.classes.sortPages = true tagfile = ../../../doc/qtcore/qtcore.tags -depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake +depends += activeqt qtdbus qtgui qtwidgets qtnetwork qtdoc qtmacextras qtquick qtlinguist qtdesigner qtconcurrent qtxml qmake qtwinextras # depends += qtqml # Qt namespace collides with QtQml::Qt, see QTBUG-38630 headerdirs += .. diff --git a/src/corelib/doc/src/animation.qdoc b/src/corelib/doc/src/animation.qdoc index e70553090ab..e5e67cf5038 100644 --- a/src/corelib/doc/src/animation.qdoc +++ b/src/corelib/doc/src/animation.qdoc @@ -48,7 +48,7 @@ The animation framework aims to provide an easy way for creating animated and smooth GUIs. By animating Qt properties, the framework provides great - freedom for animating widgets and other {QObject}s. The framework can + freedom for animating widgets and other \l{QObject}s. The framework can also be used with the Graphics View framework. Many of the concepts available in the animation framework are also available in \l{Qt Quick}, where it offers a declarative way of defining animations. Much of the @@ -57,7 +57,7 @@ In this overview, we explain the basics of its architecture. We also show examples of the most common techniques that the - framework allows for animating {QObject}s and graphics items. + framework allows for animating \l{QObject}s and graphics items. \tableofcontents @@ -85,7 +85,7 @@ over the property using an easing curve. So when you want to animate a value, you can declare it as a property and make your class a QObject. Note that this gives us great freedom in - animating already existing widgets and other {QObject}s. + animating already existing widgets and other \l{QObject}s. Complex animations can be constructed by building a tree structure of \l{QAbstractAnimation}s. The tree is built by using diff --git a/src/corelib/doc/src/filestorage.qdoc b/src/corelib/doc/src/filestorage.qdoc index 62fb68ccdc3..0cdb6b56ae5 100644 --- a/src/corelib/doc/src/filestorage.qdoc +++ b/src/corelib/doc/src/filestorage.qdoc @@ -87,7 +87,7 @@ There are three general ways to use QTextStream when reading text files: \list \li Chunk by chunk, by calling \l{QBuffer::readLine()}{readLine()} or \l{QBuffer::readAll()}{readAll()}. - \li Word by word. QTextStream supports streaming into {QString}s, {QByteArray}s + \li Word by word. QTextStream supports streaming into \l{QString}s, \l{QByteArray}s and char* buffers. Words are delimited by space, and leading white space is automatically skipped. \li Character by character, by streaming into QChar or char types. This diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 6958912e671..0ca67df1e28 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -549,7 +549,10 @@ # define Q_COMPILER_UNRESTRICTED_UNIONS # endif # if __INTEL_COMPILER >= 1500 -# define Q_COMPILER_CONSTEXPR +# if __INTEL_COMPILER * 100 + __INTEL_COMPILER_UPDATE >= 150001 +// the bug mentioned above is fixed in 15.0.1 +# define Q_COMPILER_CONSTEXPR +# endif # define Q_COMPILER_ALIGNAS # define Q_COMPILER_ALIGNOF # define Q_COMPILER_INHERITING_CONSTRUCTORS diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 554c5b658a5..a171f0894b3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -882,6 +882,7 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic /* make use of decltype or GCC's __typeof__ extension */ template <typename T> class QForeachContainer { + QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE; public: inline QForeachContainer(const T& t) : c(t), i(c.begin()), e(c.end()), control(1) { } const T c; diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index d8f5b59c63a..d9d21c535c5 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -78,11 +78,12 @@ #ifndef QT_BOOTSTRAPPED #if !defined QT_NO_REGULAREXPRESSION -# if (defined(__GLIBC__) && defined(__GLIBCXX__)) || (__has_include(<cxxabi.h>) && __has_include(<execinfo.h>)) +# ifdef __UCLIBC__ +# if __UCLIBC_HAS_BACKTRACE__ +# define QLOGGING_HAVE_BACKTRACE +# endif +# elif (defined(__GLIBC__) && defined(__GLIBCXX__)) || (__has_include(<cxxabi.h>) && __has_include(<execinfo.h>)) # define QLOGGING_HAVE_BACKTRACE -# include <qregularexpression.h> -# include <cxxabi.h> -# include <execinfo.h> # endif #endif @@ -116,6 +117,12 @@ static QT_PREPEND_NAMESPACE(qint64) qt_gettid() return qintptr(QThread::currentThreadId()); } #endif + +#ifdef QLOGGING_HAVE_BACKTRACE +# include <qregularexpression.h> +# include <cxxabi.h> +# include <execinfo.h> +#endif #endif // !QT_BOOTSTRAPPED #include <stdio.h> @@ -998,7 +1005,7 @@ QMessagePattern::QMessagePattern() QMessagePattern::~QMessagePattern() { - for (int i = 0; literals[i] != 0; ++i) + for (int i = 0; literals[i]; ++i) delete [] literals[i]; delete [] literals; literals = 0; @@ -1008,8 +1015,12 @@ QMessagePattern::~QMessagePattern() void QMessagePattern::setPattern(const QString &pattern) { + if (literals) { + for (int i = 0; literals[i]; ++i) + delete [] literals[i]; + delete [] literals; + } delete [] tokens; - delete [] literals; // scanner QList<QString> lexemes; @@ -1285,13 +1296,13 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16)); #ifdef QLOGGING_HAVE_BACKTRACE } else if (token == backtraceTokenC) { - QVarLengthArray<void*, 32> buffer(15 + pattern->backtraceDepth); + QVarLengthArray<void*, 32> buffer(7 + pattern->backtraceDepth); int n = backtrace(buffer.data(), buffer.size()); if (n > 0) { - QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(buffer.data(), n)); int numberPrinted = 0; for (int i = 0; i < n && numberPrinted < pattern->backtraceDepth; ++i) { - QString trace = QString::fromLatin1(strings.data()[i]); + QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(buffer.data() + i, 1)); + QString trace = QString::fromLatin1(strings.data()[0]); // The results of backtrace_symbols looks like this: // /lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413] // The offset and function name are optional. diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 1be83caa06d..ba3a621751c 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -498,7 +498,7 @@ \value TextExpandTabs Makes the U+0009 (ASCII tab) character move to the next tab stop. \value TextShowMnemonic Displays the string "\&P" as \underline{P} - (see QButton for an example). For an ampersand, use "\&\&". + For an ampersand, use "\&\&". \value TextWordWrap Breaks lines at appropriate points, e.g. at word boundaries. \value TextWrapAnywhere Breaks lines anywhere, even within words. @@ -902,8 +902,7 @@ on QWidget::contentsRect(). This is set by the widget's author. \value WA_LayoutUsesWidgetRect Ignore the layout item rect from the style - when laying out this widget with QLayout. This makes a difference in - QMacStyle and QPlastiqueStyle for some widgets. + when laying out this widget with QLayout. \value WA_MacNoClickThrough When a widget that has this attribute set is clicked, and its window is inactive, the click will make the window @@ -1162,7 +1161,7 @@ _NET_WM_WINDOW_TYPE X11 window property. See http://standards.freedesktop.org/wm-spec/ for more details. This attribute has no effect on non-X11 platforms. \b Note: Qt - automatically sets this attribute for QMenus added to a QMenuBar. + automatically sets this attribute for QMenu objects added to a QMenuBar. \value WA_X11NetWmWindowTypePopupMenu Adds _NET_WM_WINDOW_TYPE_POPUP_MENU to the window's _NET_WM_WINDOW_TYPE X11 window property. See diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp index 32f55f3e2c9..4ca07ba41db 100644 --- a/src/corelib/io/qfileselector.cpp +++ b/src/corelib/io/qfileselector.cpp @@ -231,7 +231,7 @@ static QString qrcScheme() } /*! - This is a convenience version of select operating on QUrls. If the scheme is not file or qrc, + This is a convenience version of select operating on QUrl objects. If the scheme is not file or qrc, \a filePath is returned immediately. Otherwise selection is applied to the path of \a filePath and a QUrl is returned with the selected path and other QUrl parts the same as \a filePath. diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 0aa4db34e5c..ea7e7b2731e 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -706,7 +706,7 @@ bool QIODevice::reset() number of bytes to allocate in a buffer before reading. Subclasses that reimplement this function must call the base - implementation in order to include the size of QIODevices' buffer. Example: + implementation in order to include the size of the buffer of QIODevice. Example: \snippet code/src_corelib_io_qiodevice.cpp 1 diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index e7439e6f25a..6451bae0baa 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1456,7 +1456,7 @@ void QProcess::setStandardErrorFile(const QString &fileName, OpenMode mode) The following shell command: \snippet code/src_corelib_io_qprocess.cpp 2 - Can be accomplished with QProcesses with the following code: + Can be accomplished with QProcess with the following code: \snippet code/src_corelib_io_qprocess.cpp 3 */ void QProcess::setStandardOutputProcess(QProcess *destination) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 606859032e2..4b85645a90d 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -197,7 +197,7 @@ Q_GLOBAL_STATIC(QStringList, resourceSearchPaths) path requested in setFileName(). The unregisterResource() function removes a reference to a particular - file. If there are QResources that currently reference resources related + file. If there are QResource objects that currently reference resources related to the unregistered file, they will continue to be valid but the resource file itself will be removed from the resource roots, and thus no further QResource can be created pointing into this resource data. The resource diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index 31939830e0e..4fd429cad49 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -77,15 +77,10 @@ QT_BEGIN_NAMESPACE this user, but should still be assumed to be unreachable by applications by other users. - The only exception is QStandardPaths::TempLocation (which is the same as - QDir::tempPath()): the path returned may be application-specific, but files - stored there may be accessed by other applications run by the same user. - Data interchange with other users is out of the scope of QStandardPaths. \value DesktopLocation Returns the user's desktop directory. This is a generic value. - On systems with no concept of a desktop, this is the same as - QStandardPaths::HomeLocation. + On systems with no concept of a desktop. \value DocumentsLocation Returns the directory containing user document files. This is a generic value. The returned path is never empty. \value FontsLocation Returns the directory containing user's fonts. This is a generic value. @@ -118,9 +113,6 @@ QT_BEGIN_NAMESPACE \value GenericCacheLocation Returns a directory location where user-specific non-essential (cached) data, shared across applications, should be written. This is a generic value. Note that the returned path may be empty if the system has no concept of shared cache. - \value GenericDataLocation Returns a directory location where persistent - data shared across applications can be stored. This is a generic value. The returned - path is never empty. \value RuntimeLocation Returns a directory location where runtime communication files should be written, like Unix local sockets. This is a generic value. The returned path may be empty on some systems. diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp index 8c8e871a4b7..350e5cdbeaa 100644 --- a/src/corelib/io/qstandardpaths_android.cpp +++ b/src/corelib/io/qstandardpaths_android.cpp @@ -57,7 +57,7 @@ static QJNIObjectPrivate applicationContext() if (appCtx.isValid()) return appCtx; - QJNIObjectPrivate activity = QtAndroidPrivate::activity(); + QJNIObjectPrivate activity(QtAndroidPrivate::activity()); if (!activity.isValid()) return appCtx; @@ -131,7 +131,7 @@ static QString getExternalFilesDir(const char *directoryField = 0) if (!path.isEmpty()) return path; - QJNIObjectPrivate activity = QtAndroidPrivate::activity(); + QJNIObjectPrivate activity(QtAndroidPrivate::activity()); if (!activity.isValid()) return QString(); diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 7e23ac897d2..45b32830cd7 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -54,6 +54,7 @@ # include <sys/statvfs.h> #elif defined(Q_OS_SOLARIS) # include <sys/mnttab.h> +# include <sys/statvfs.h> #elif defined(Q_OS_HAIKU) # include <Directory.h> # include <Path.h> @@ -210,17 +211,17 @@ inline bool QStorageIterator::next() inline QString QStorageIterator::rootPath() const { - return QFile::decodeName(mnt->mnt_mountp); + return QFile::decodeName(mnt.mnt_mountp); } inline QByteArray QStorageIterator::fileSystemType() const { - return QByteArray(mnt->mnt_fstype); + return QByteArray(mnt.mnt_fstype); } inline QByteArray QStorageIterator::device() const { - return QByteArray(mnt->mnt_mntopts); + return QByteArray(mnt.mnt_mntopts); } #elif defined(Q_OS_ANDROID) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index ad0a6b8d537..89f5aad97f5 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -82,7 +82,7 @@ For the convenience of generating encoded URL strings or query strings, there are two static functions called fromPercentEncoding() and toPercentEncoding() which deal with - percent encoding and decoding of QStrings. + percent encoding and decoding of QString objects. Calling isRelative() will tell whether or not the URL is relative. A relative URL can be resolved by passing it as argument @@ -172,7 +172,7 @@ setters setting components of a URL; it is not permitted in the QUrl constructor, in fromEncoded() or in setUrl(). For more information on this mode, see the documentation for - QUrl::FullyDecoded. + \l {QUrl::ComponentFormattingOption}{QUrl::FullyDecoded}. In TolerantMode, the parser has the following behaviour: @@ -3083,6 +3083,21 @@ bool QUrl::hasFragment() const URL does not contain a valid TLD, in which case the function returns an empty string. + Note that this function considers a TLD to be any domain that allows users + to register subdomains under, including many home, dynamic DNS websites and + blogging providers. This is useful for determining whether two websites + belong to the same infrastructure and communication should be allowed, such + as browser cookies: two domains should be considered part of the same + website if they share at least one label in addition to the value + returned by this function. + + \list + \li \c{foo.co.uk} and \c{foo.com} do not share a top-level domain + \li \c{foo.co.uk} and \c{bar.co.uk} share the \c{.co.uk} domain, but the next label is different + \li \c{www.foo.co.uk} and \c{ftp.foo.co.uk} share the same top-level domain and one more label, + so they are considered part of the same site + \endlist + If \a options includes EncodeUnicode, the returned string will be in ASCII Compatible Encoding. */ @@ -4041,7 +4056,7 @@ QString QUrl::errorString() const /*! \since 5.1 - Converts a list of \a urls into a list of QStrings, using toString(\a options). + Converts a list of \a urls into a list of QString objects, using toString(\a options). */ QStringList QUrl::toStringList(const QList<QUrl> &urls, FormattingOptions options) { diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 6be7d3531ff..77d1ab3e24a 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -414,7 +414,7 @@ bool QUrlQuery::operator ==(const QUrlQuery &other) const } /*! - Returns \c true if this QUrlQUery object contains no key-value pairs, such as + Returns \c true if this QUrlQuery object contains no key-value pairs, such as after being default-constructed or after parsing an empty query string. \sa setQuery(), clear() diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp index 66078f3cc8a..c3b58e59a50 100644 --- a/src/corelib/json/qjson.cpp +++ b/src/corelib/json/qjson.cpp @@ -200,6 +200,7 @@ bool Object::isValid() const if (tableOffset + length*sizeof(offset) > size) return false; + QString lastKey; for (uint i = 0; i < length; ++i) { offset entryOffset = table()[i]; if (entryOffset + sizeof(Entry) >= tableOffset) @@ -208,8 +209,12 @@ bool Object::isValid() const int s = e->size(); if (table()[i] + s > tableOffset) return false; + QString key = e->key(); + if (key < lastKey) + return false; if (!e->value.isValid(this)) return false; + lastKey = key; } return true; } diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index 1e4c668a4c5..a993fd6ea4b 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -531,8 +531,8 @@ bool QJsonArray::contains(const QJsonValue &value) const \a i must be a valid index position in the array (i.e., \c{0 <= i < size()}). - The return value is of type QJsonValueRef, a helper class for QJsonArray - and QJsonObject. When you get an object of type QJsonValueRef, you can + The return value is of type \keyword QJsonValueRef, a helper class for QJsonArray + and QJsonObject. When you get an object of type \keyword QJsonValueRef, you can use it as if it were a reference to a QJsonValue. If you assign to it, the assignment will apply to the character in the QJsonArray of QJsonObject from which you got the reference. @@ -731,13 +731,14 @@ bool QJsonArray::operator!=(const QJsonArray &other) const /*! \fn QJsonValueRef QJsonArray::iterator::operator*() const + Returns a modifiable reference to the current item. You can change the value of an item by using operator*() on the left side of an assignment. - The return value is of type QJsonValueRef, a helper class for QJsonArray - and QJsonObject. When you get an object of type QJsonValueRef, you can + The return value is of type \keyword QJsonValueRef, a helper class for QJsonArray + and QJsonObject. When you get an object of type \keyword QJsonValueRef, you can use it as if it were a reference to a QJsonValue. If you assign to it, the assignment will apply to the character in the QJsonArray of QJsonObject from which you got the reference. @@ -756,8 +757,8 @@ bool QJsonArray::operator!=(const QJsonArray &other) const This function is provided to make QJsonArray iterators behave like C++ pointers. - The return value is of type QJsonValueRef, a helper class for QJsonArray - and QJsonObject. When you get an object of type QJsonValueRef, you can + The return value is of type \keyword QJsonValueRef, a helper class for QJsonArray + and QJsonObject. When you get an object of type \keyword QJsonValueRef, you can use it as if it were a reference to a QJsonValue. If you assign to it, the assignment will apply to the character in the QJsonArray of QJsonObject from which you got the reference. diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index bdedc3f17bb..22bad6f8a27 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -264,6 +264,8 @@ QVariantHash QJsonObject::toVariantHash() const /*! Returns a list of all keys in this object. + + The list is sorted lexographically. */ QStringList QJsonObject::keys() const { diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp index 306cc1d15b7..4845d8c8769 100644 --- a/src/corelib/json/qjsonvalue.cpp +++ b/src/corelib/json/qjsonvalue.cpp @@ -74,6 +74,20 @@ QT_BEGIN_NAMESPACE conversions. This implies that converting to a type that is not stored in the value will return a default constructed return value. + \section1 QJsonValueRef + + QJsonValueRef is a helper class for QJsonArray and QJsonObject. + When you get an object of type QJsonValueRef, you can + use it as if it were a reference to a QJsonValue. If you assign to it, + the assignment will apply to the element in the QJsonArray or QJsonObject + from which you got the reference. + + The following methods return QJsonValueRef: + \list + \li \l {QJsonArray}::operator[](int i) + \li \l {QJsonObject}::operator[](const QString & key) const + \endlist + \sa {JSON Support in Qt}, {JSON Save Game Example} */ @@ -419,13 +433,13 @@ QJsonValue QJsonValue::fromVariant(const QVariant &variant) The QJsonValue types will be converted as follows: - \value Null {QVariant::}{QVariant()} + \value Null \l {QVariant::}{QVariant()} \value Bool QMetaType::Bool \value Double QMetaType::Double \value String QString \value Array QVariantList \value Object QVariantMap - \value Undefined {QVariant::}{QVariant()} + \value Undefined \l {QVariant::}{QVariant()} \sa fromVariant() */ diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 67ce7d45fc8..0b5898a6b90 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -386,7 +386,7 @@ void QAbstractEventDispatcher::closingDown() \note The filter function set here receives native messages, that is, MSG or XEvent structs. - For maximum portability, you should always try to use QEvents + For maximum portability, you should always try to use QEvent objects and QObject::installEventFilter() whenever possible. \sa QObject::installEventFilter() diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 194c3f1cba1..18a379f8b91 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -80,6 +80,11 @@ #ifdef Q_OS_WIN # ifdef Q_OS_WINRT # include "qeventdispatcher_winrt_p.h" +# include "qfunctions_winrt.h" +# include <wrl.h> +# include <Windows.ApplicationModel.core.h> + using namespace ABI::Windows::ApplicationModel::Core; + using namespace Microsoft::WRL; # else # include "qeventdispatcher_win_p.h" # endif @@ -1244,6 +1249,19 @@ void QCoreApplication::exit(int returnCode) QEventLoop *eventLoop = data->eventLoops.at(i); eventLoop->exit(returnCode); } +#ifdef Q_OS_WINRT + qWarning("QCoreApplication::exit: It is not recommended to explicitly exit an application on Windows Store Apps"); + ComPtr<ICoreApplication> app; + HRESULT hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), + IID_PPV_ARGS(&app)); + RETURN_VOID_IF_FAILED("Could not acquire ICoreApplication object"); + ComPtr<ICoreApplicationExit> appExit; + + hr = app.As(&appExit); + RETURN_VOID_IF_FAILED("Could not acquire ICoreApplicationExit object"); + hr = appExit->Exit(); + RETURN_VOID_IF_FAILED("Could not exit application"); +#endif // Q_OS_WINRT } /***************************************************************************** @@ -2405,7 +2423,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) INSTALL/plugins, where \c INSTALL is the directory where Qt was installed). The directory of the application executable (NOT the working directory) is always added, as well as the colon separated - entries of the QT_PLUGIN_PATH environment variable. + entries of the \c QT_PLUGIN_PATH environment variable. If you want to iterate over the list, you can use the \l foreach pseudo-keyword: @@ -2550,7 +2568,7 @@ void QCoreApplication::removeLibraryPath(const QString &path) \note Native event filters will be disabled when the application the Qt::AA_MacPluginApplication attribute is set. - For maximum portability, you should always try to use QEvents + For maximum portability, you should always try to use QEvent and QObject::installEventFilter() whenever possible. \sa QObject::installEventFilter() diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 301f1230326..b2b22ad99cd 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE send events using QCoreApplication::sendEvent() and QCoreApplication::postEvent() (spontaneous() returns \c false). - QObjects receive events by having their QObject::event() function + \l {QObject}{QObjects} receive events by having their QObject::event() function called. The function can be reimplemented in subclasses to customize event handling and add additional event types; QWidget::event() is a notable example. By default, events are @@ -102,13 +102,13 @@ QT_BEGIN_NAMESPACE \value ChildAdded An object gets a child (QChildEvent). \value ChildPolished A widget child gets polished (QChildEvent). \value ChildRemoved An object loses a child (QChildEvent). - \value Clipboard The clipboard contents have changed (QClipboardEvent). + \value Clipboard The clipboard contents have changed. \value Close Widget was closed (QCloseEvent). \value CloseSoftwareInputPanel A widget wants to close the software input panel (SIP). \value ContentsRectChange The margins of the widget's content rect changed. \value ContextMenu Context popup menu (QContextMenuEvent). \value CursorChange The widget's cursor has changed. - \value DeferredDelete The object will be deleted after it has cleaned up (QDeferredDeleteEvent). + \value DeferredDelete The object will be deleted after it has cleaned up (QDeferredDeleteEvent) \value DragEnter The cursor enters a widget during a drag and drop operation (QDragEnterEvent). \value DragLeave The cursor leaves a widget during a drag and drop operation (QDragLeaveEvent). \value DragMove A drag and drop operation is in progress (QDragMoveEvent). @@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE \value DynamicPropertyChange A dynamic property was added, changed, or removed from the object. \value EnabledChange Widget's enabled state has changed. \value Enter Mouse enters widget's boundaries (QEnterEvent). - \value EnterEditFocus An editor widget gains focus for editing. QT_KEYPAD_NAVIGATION must be defined. + \value EnterEditFocus An editor widget gains focus for editing. \c QT_KEYPAD_NAVIGATION must be defined. \value EnterWhatsThisMode Send to toplevel widgets when the application enters "What's This?" mode. \value Expose Sent to a window when its on-screen contents are invalidated and need to be flushed from the backing store. \value FileOpen File open request (QFileOpenEvent). @@ -177,7 +177,7 @@ QT_BEGIN_NAMESPACE \value MouseTrackingChange The mouse tracking state has changed. \value Move Widget's position changed (QMoveEvent). \value NativeGesture The system has detected a gesture (QNativeGestureEvent). - \value OrientationChange The screens orientation has changes (QScreenOrientationChangeEvent) + \value OrientationChange The screens orientation has changes (QScreenOrientationChangeEvent). \value Paint Screen update necessary (QPaintEvent). \value PaletteChange Palette of the widget changed. \value ParentAboutToChange The widget parent is about to change. diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index a7f98bc5322..694463b9d8d 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -96,7 +96,7 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) if (clazz != 0 || isCached) return clazz; - QJNIObjectPrivate classLoader = QtAndroidPrivate::classLoader(); + QJNIObjectPrivate classLoader(QtAndroidPrivate::classLoader()); if (!classLoader.isValid()) return 0; @@ -2239,6 +2239,13 @@ bool QJNIObjectPrivate::isValid() const return d->m_jobject; } +QJNIObjectPrivate QJNIObjectPrivate::fromLocalRef(jobject lref) +{ + QJNIObjectPrivate o(lref); + QJNIEnvironmentPrivate()->DeleteLocalRef(lref); + return o; +} + bool QJNIObjectPrivate::isSameObject(jobject obj) const { QJNIEnvironmentPrivate env; diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index a7859a800f5..e79caed5b80 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -84,7 +84,10 @@ public: QJNIObjectPrivate(const char *className, const char *sig, ...); explicit QJNIObjectPrivate(jclass clazz); QJNIObjectPrivate(jclass clazz, const char *sig, ...); - QJNIObjectPrivate(jobject obj); + // In most cases you should never call this function with a local ref. unless you intend + // to manage the local ref. yourself. + // NOTE: see fromLocalRef() for converting a local ref. to QJNIObjectPrivate. + explicit QJNIObjectPrivate(jobject globalRef); template <typename T> T callMethod(const char *methodName, @@ -183,6 +186,9 @@ public: return *this; } + // This function takes ownership of the jobject and releases the local ref. before returning. + static QJNIObjectPrivate fromLocalRef(jobject lref); + private: friend class QAndroidJniObject; diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 8f79bf56456..8adb4a49039 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -201,6 +201,8 @@ struct DefinedTypesFilter { \enum QMetaType::Type These are the built-in types supported by QMetaType: + Read doc on QChar + Read doc on \l QChar \value Void \c void \value Bool \c bool diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index 2abed68826b..2c872716d19 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -55,7 +55,7 @@ \li When using QPointer on a QWidget (or a subclass of QWidget), previously the QPointer would be cleared by the QWidget destructor. Now, the QPointer - is cleared by the QObject destructor (since this is when QWeakPointers are + is cleared by the QObject destructor (since this is when QWeakPointer objects are cleared). Any QPointers tracking a widget will \b NOT be cleared before the QWidget destructor destroys the children for the widget being tracked. diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 3f986559880..b9109a96aa5 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -91,7 +91,7 @@ QT_BEGIN_NAMESPACE its work. This is the traditional way of implementing heavy work in GUI applications, but as multithreading is nowadays becoming available on more and more platforms, we expect that zero-millisecond - QTimers will gradually be replaced by \l{QThread}s. + QTimer objects will gradually be replaced by \l{QThread}s. \section1 Accuracy and Timer Resolution diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 34f4c6884fd..3dc0805dd19 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1410,13 +1410,13 @@ QVariant::QVariant(const char *val) /*! \fn QVariant::QVariant(const QMap<QString, QVariant> &val) - Constructs a new variant with a map of QVariants, \a val. + Constructs a new variant with a map of \l {QVariant}s, \a val. */ /*! \fn QVariant::QVariant(const QHash<QString, QVariant> &val) - Constructs a new variant with a hash of QVariants, \a val. + Constructs a new variant with a hash of \l {QVariant}s, \a val. */ /*! @@ -3610,7 +3610,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) Q_OBJECT macro. If the QVariant contains a sequential container and \c{T} is QVariantList, the - elements of the container will be converted into QVariants and returned as a QVariantList. + elements of the container will be converted into \l {QVariant}s and returned as a QVariantList. \snippet code/src_corelib_kernel_qvariant.cpp 9 diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 8ed9199c602..0bdf9034ee5 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -420,7 +420,7 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin plugin) /*! Returns a list of static plugin instances (root components) held by the plugin loader. - \sa staticPlugins() + \sa staticPlugin() */ QObjectList QPluginLoader::staticInstances() { diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index f0ba7a7f070..996ed1779df 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -389,14 +389,13 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW int QThread::idealThreadCount() Q_DECL_NOTHROW { - int cores = -1; + int cores = 1; #if defined(Q_OS_HPUX) // HP-UX struct pst_dynamic psd; if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) == -1) { perror("pstat_getdynamic"); - cores = -1; } else { cores = (int)psd.psd_proc_cnt; } @@ -408,7 +407,6 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW mib[1] = HW_NCPU; if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) { perror("sysctl"); - cores = -1; } #elif defined(Q_OS_IRIX) // IRIX @@ -443,9 +441,9 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW #else // the rest: Linux, Solaris, AIX, Tru64 cores = (int)sysconf(_SC_NPROCESSORS_ONLN); -#endif if (cores == -1) return 1; +#endif return cores; } diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp index 90dfcb7ba1d..fd6af7db39b 100644 --- a/src/corelib/thread/qwaitcondition_unix.cpp +++ b/src/corelib/thread/qwaitcondition_unix.cpp @@ -52,9 +52,12 @@ QT_BEGIN_NAMESPACE #ifdef Q_OS_ANDROID -// Android lacks pthread_condattr_setclock, but it does have a nice function -// for relative waits. Use weakref so we can determine at runtime whether it is -// present. +// pthread_condattr_setclock is available only since Android 5.0. On older versions, there's +// a private function for relative waits (hidden in 5.0). +// Use weakref so we can determine at runtime whether each of them is present. +static int local_condattr_setclock(pthread_condattr_t*, clockid_t) +__attribute__((weakref("pthread_condattr_setclock"))); + static int local_cond_timedwait_relative(pthread_cond_t*, pthread_mutex_t *, const timespec *) __attribute__((weakref("__pthread_cond_timedwait_relative"))); #endif @@ -70,10 +73,15 @@ void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where) pthread_condattr_t condattr; pthread_condattr_init(&condattr); -#if !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID) && !defined(Q_OS_HAIKU) && (_POSIX_MONOTONIC_CLOCK-0 >= 0) +#if (_POSIX_MONOTONIC_CLOCK-0 >= 0) +#if defined(Q_OS_ANDROID) + if (local_condattr_setclock && QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock) + local_condattr_setclock(&condattr, CLOCK_MONOTONIC); +#elif !defined(Q_OS_MAC) && !defined(Q_OS_HAIKU) if (QElapsedTimer::clockType() == QElapsedTimer::MonotonicClock) pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); #endif +#endif report_error(pthread_cond_init(cond, &condattr), where, "cv init"); pthread_condattr_destroy(&condattr); } @@ -108,7 +116,7 @@ public: { timespec ti; #ifdef Q_OS_ANDROID - if (Q_LIKELY(local_cond_timedwait_relative)) { + if (local_cond_timedwait_relative) { ti.tv_sec = time / 1000; ti.tv_nsec = time % 1000 * Q_UINT64_C(1000) * 1000; return local_cond_timedwait_relative(&cond, &mutex, &ti); diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index d94167466db..eb967574573 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -786,7 +786,7 @@ static inline char qToLower(char c) occurrences of a particular value with another, use one of the two-parameter replace() overloads. - {QByteArray}s can be compared using overloaded operators such as + \l{QByteArray}s can be compared using overloaded operators such as operator<(), operator<=(), operator==(), operator>=(), and so on. The comparison is based exclusively on the numeric values of the characters and is very fast, but is not what a human would @@ -831,7 +831,7 @@ static inline char qToLower(char c) lastIndexOf(), operator<(), operator<=(), operator>(), operator>=(), toLower() and toUpper(). - This issue does not apply to {QString}s since they represent + This issue does not apply to \l{QString}s since they represent characters using Unicode. \sa QString, QBitArray diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp index 164db5ed0cc..8e6a0a05785 100644 --- a/src/corelib/tools/qtimezoneprivate.cpp +++ b/src/corelib/tools/qtimezoneprivate.cpp @@ -625,6 +625,15 @@ QTimeZonePrivate *QUtcTimeZonePrivate::clone() return new QUtcTimeZonePrivate(*this); } +QTimeZonePrivate::Data QUtcTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const +{ + Data d = invalidData(); + d.abbreviation = m_abbreviation; + d.atMSecsSinceEpoch = forMSecsSinceEpoch; + d.offsetFromUtc = m_offsetFromUtc; + return d; +} + void QUtcTimeZonePrivate::init(const QByteArray &zoneId) { m_id = zoneId; diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h index 803ba1f57a5..e15ac801bc9 100644 --- a/src/corelib/tools/qtimezoneprivate_p.h +++ b/src/corelib/tools/qtimezoneprivate_p.h @@ -186,6 +186,8 @@ public: QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + Data data(qint64 forMSecsSinceEpoch) const Q_DECL_OVERRIDE; + QLocale::Country country() const Q_DECL_OVERRIDE; QString comment() const Q_DECL_OVERRIDE; diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 5245c4ed10d..9d5b749e79f 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -154,7 +154,9 @@ public: const const_iterator ce = this->cend(), cit = std::find(this->cbegin(), ce, t); if (cit == ce) return 0; - const iterator e = end(), it = std::remove(c2m(cit), e, t); + // next operation detaches, so ce, cit may become invalidated: + const int firstFoundIdx = std::distance(this->cbegin(), cit); + const iterator e = end(), it = std::remove(begin() + firstFoundIdx, e, t); const int result = std::distance(it, e); erase(it, e); return result; diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 390d3a666fc..61353ebe6df 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -314,12 +314,20 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int } } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) { red_shift = calc_shift(red_mask); + if (((red_mask >> red_shift) + 1) == 0) + return false; red_scale = 256 / ((red_mask >> red_shift) + 1); green_shift = calc_shift(green_mask); + if (((green_mask >> green_shift) + 1) == 0) + return false; green_scale = 256 / ((green_mask >> green_shift) + 1); blue_shift = calc_shift(blue_mask); + if (((blue_mask >> blue_shift) + 1) == 0) + return false; blue_scale = 256 / ((blue_mask >> blue_shift) + 1); alpha_shift = calc_shift(alpha_mask); + if (((alpha_mask >> alpha_shift) + 1) == 0) + return false; alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1); } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) { blue_mask = 0x000000ff; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 1467c96adb3..0d5a130dfd7 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1675,15 +1675,13 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) { // A mouse event should not change both position and buttons at the same time. Instead we // should first send a move event followed by a button changed event. Since this is not the case - // with the current event, we fake a move-only event that we recurse and process first. This - // will update the global mouse position and cause the second event to be a button only event. - QWindowSystemInterfacePrivate::MouseEvent moveEvent(e->window.data(), - e->timestamp, e->type, e->localPos, e->globalPos, buttons, e->modifiers, e->source); + // with the current event, we split it in two. + QWindowSystemInterfacePrivate::MouseEvent *mouseButtonEvent = new QWindowSystemInterfacePrivate::MouseEvent( + e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers); if (e->flags & QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic) - moveEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; - processMouseEvent(&moveEvent); - Q_ASSERT(e->globalPos == QGuiApplicationPrivate::lastCursorPosition); - // continue with processing mouse button change event + mouseButtonEvent->flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; + QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(mouseButtonEvent); + stateChange = Qt::NoButton; } QWindow *window = e->window.data(); diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index b0245dd5c7c..f480a2a109b 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -840,6 +840,8 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe return QOpenGLTexture::UInt8; case QOpenGLTexture::DepthFormat: + return QOpenGLTexture::UInt32; + case QOpenGLTexture::AlphaFormat: case QOpenGLTexture::RGBFormat: case QOpenGLTexture::RGBAFormat: @@ -1859,7 +1861,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target \value SRGB_Alpha_DXT5 Equivalent to GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT \value SRGB_BP_UNorm Equivalent to GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB - \value DepthFormat Equivalent to GL_DEPTH_COMPONENT (OpenGL ES 2 only and when OES_depth_texture is present) + \value DepthFormat Equivalent to GL_DEPTH_COMPONENT (only OpenGL ES 3 or ES 2 with OES_depth_texture) \value AlphaFormat Equivalent to GL_ALPHA (OpenGL ES 2 only) \value RGBFormat Equivalent to GL_RGB (OpenGL ES 2 only) \value RGBAFormat Equivalent to GL_RGBA (OpenGL ES 2 only) diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 9f3e577c34a..29eea6032e4 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -65,8 +65,6 @@ struct StrokeHandler; QDebug Q_GUI_EXPORT &operator<<(QDebug &, const QVectorPath &path); #endif -class QPixmapFilter; - class Q_GUI_EXPORT QPaintEngineEx : public QPaintEngine { Q_DECLARE_PRIVATE(QPaintEngineEx) @@ -140,13 +138,6 @@ public: virtual void beginNativePainting() {} virtual void endNativePainting() {} - // Return a pixmap filter of "type" that can render the parameters - // in "prototype". The returned filter is owned by the engine and - // will be destroyed when the engine is destroyed. The "prototype" - // allows the engine to pick different filters based on the parameters - // that will be requested, and not just the "type". - virtual QPixmapFilter *pixmapFilter(int /*type*/, const QPixmapFilter * /*prototype*/) { return 0; } - // These flags are needed in the implementation of paint buffers. enum Flags { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 47af6a883a5..01f99047989 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5536,6 +5536,11 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun) { Q_D(QPainter); + if (!d->engine) { + qWarning("QPainter::drawGlyphRun: Painter not active"); + return; + } + QRawFont font = glyphRun.rawFont(); if (!font.isValid()) return; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 8fe57d3d23d..cc1ad02eee6 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1051,7 +1051,7 @@ void QPdfEngine::drawPath (const QPainterPath &p) if (!d->hasPen && !d->hasBrush) return; - if (d->simplePen && d->opacity == 1.0) { + if (d->simplePen) { // draw strokes natively in this case for better output *d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath); } else { @@ -1198,7 +1198,7 @@ void QPdfEngine::updateState(const QPaintEngineState &state) d->stroker.setPen(d->pen, state.renderHints()); QBrush penBrush = d->pen.brush(); bool oldSimple = d->simplePen; - d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque()); + d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0); if (oldSimple != d->simplePen) flags |= DirtyTransform; } else if (flags & DirtyHints) { @@ -1214,8 +1214,13 @@ void QPdfEngine::updateState(const QPaintEngineState &state) d->brushOrigin = state.brushOrigin(); flags |= DirtyBrush; } - if (flags & DirtyOpacity) + if (flags & DirtyOpacity) { d->opacity = state.opacity(); + if (d->simplePen && d->opacity != 1.0) { + d->simplePen = false; + flags |= DirtyTransform; + } + } bool ce = d->clipEnabled; if (flags & DirtyClipPath) { diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index e22fae058f3..b79f971156d 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1696,7 +1696,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matr glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format) { - Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix); + Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true); glyph_metrics_t overall; if (g) { @@ -1839,7 +1839,8 @@ void QFontEngineFT::unlockAlphaMapForGlyph() QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, - const QTransform &t) + const QTransform &t, + bool fetchBoundingBox) { FT_Face face = 0; QGlyphSet *glyphSet = 0; @@ -1852,7 +1853,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, Q_ASSERT(glyphSet != 0); } - if (glyphSet != 0 && glyphSet->outline_drawing) + if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox) return 0; Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 96d0329ae6a..1218893e19c 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -266,7 +266,7 @@ private: 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); + Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false); QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix); diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index a4b51b16d24..77c5028fb34 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -235,19 +235,11 @@ void QLocalSocket::connectToServer(OpenMode openMode) } // create the socket - if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) { + if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0, O_NONBLOCK))) { d->errorOccurred(UnsupportedSocketOperationError, QLatin1String("QLocalSocket::connectToServer")); return; } - // set non blocking so we can try to connect and it won't wait - int flags = fcntl(d->connectingSocket, F_GETFL, 0); - if (-1 == flags - || -1 == (fcntl(d->connectingSocket, F_SETFL, flags | O_NONBLOCK))) { - d->errorOccurred(UnknownSocketError, - QLatin1String("QLocalSocket::connectToServer")); - return; - } // _q_connectToSocket does the actual connecting d->connectingName = d->serverName; diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index b78aaef8d01..db6c7c487a0 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -357,14 +357,6 @@ bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType socketType, QAb return false; } - // Make the socket nonblocking. - if (!setOption(NonBlockingSocketOption, 1)) { - d->setError(QAbstractSocket::UnsupportedSocketOperationError, - QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString); - close(); - return false; - } - // Set the broadcasting flag if it's a UDP socket. if (socketType == QAbstractSocket::UdpSocket && !setOption(BroadcastSocketOption, 1)) { diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 52a2944a36a..da36e4a6daa 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -138,10 +138,10 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET; int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; - int socket = qt_safe_socket(protocol, type, 0); + int socket = qt_safe_socket(protocol, type, 0, O_NONBLOCK); if (socket < 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) { protocol = AF_INET; - socket = qt_safe_socket(protocol, type, 0); + socket = qt_safe_socket(protocol, type, 0, O_NONBLOCK); socketProtocol = QAbstractSocket::IPv4Protocol; } diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index c9477288f21..3dff11ec323 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -383,8 +383,15 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc #endif socketDescriptor = socket; - return true; + // Make the socket nonblocking. + if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) { + setError(QAbstractSocket::UnsupportedSocketOperationError, NonBlockingInitFailedErrorString); + q_func()->close(); + return false; + } + + return true; } /*! \internal diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 946091b5616..d42a360dc8a 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -768,7 +768,7 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc return false; } socketDescriptor = qintptr(socket.Detach()); - return true; + break; } case QAbstractSocket::UdpSocket: { ComPtr<IDatagramSocket> socket; @@ -780,13 +780,21 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc EventRegistrationToken token; socketDescriptor = qintptr(socket.Detach()); udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &token); - return true; + break; } default: qWarning("Invalid socket type"); return false; } - return false; + + // Make the socket nonblocking. + if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) { + setError(QAbstractSocket::UnsupportedSocketOperationError, NonBlockingInitFailedErrorString); + q_func()->close(); + return false; + } + + return true; } QNativeSocketEnginePrivate::QNativeSocketEnginePrivate() diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 286deaf8687..490b79664f2 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -163,7 +163,7 @@ Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy) QGLSignalProxy *QGLSignalProxy::instance() { QGLSignalProxy *proxy = theSignalProxy(); - if (proxy && proxy->thread() != qApp->thread()) { + if (proxy && qApp && proxy->thread() != qApp->thread()) { if (proxy->thread() == QThread::currentThread()) proxy->moveToThread(qApp->thread()); } diff --git a/src/opengl/qglcolormap.cpp b/src/opengl/qglcolormap.cpp index 12ce19026fd..58a69c8d8e7 100644 --- a/src/opengl/qglcolormap.cpp +++ b/src/opengl/qglcolormap.cpp @@ -37,7 +37,7 @@ a QGLWidget. \obsolete - \inmodule OpenGL + \inmodule QtOpenGL \ingroup painting-3D \ingroup shared diff --git a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp index 8b10c17bb55..da5f042abd6 100644 --- a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp +++ b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp @@ -295,8 +295,7 @@ QList<AndroidNetworkInfo> AndroidConnectivityManager::getAllNetworkInfo() const if (exceptionCheckAndClear(env)) break; - list << AndroidNetworkInfo(lref); - env->DeleteLocalRef(lref); + list << AndroidNetworkInfo(QJNIObjectPrivate::fromLocalRef(lref)); } return list; diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index d35492564a5..843387e6791 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -80,10 +80,10 @@ QNetworkManagerEngine::QNetworkManagerEngine(QObject *parent) this, SLOT(ofonoUnRegistered(QString))); if (QDBusConnection::systemBus().interface()->isServiceRegistered("org.ofono")) - ofonoRegistered(); + QMetaObject::invokeMethod(this, "ofonoRegistered", Qt::QueuedConnection); if (QDBusConnection::systemBus().interface()->isServiceRegistered(NM_DBUS_SERVICE)) - nmRegistered(); + QMetaObject::invokeMethod(this, "nmRegistered", Qt::QueuedConnection); } QNetworkManagerEngine::~QNetworkManagerEngine() diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 903da2498c2..4ece1b5a22f 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -438,7 +438,7 @@ static QString strippedText(QString s) - (void)panelSelectionDidChange:(id)sender { Q_UNUSED(sender); - if (mHelper) { + if (mHelper && [mSavePanel isVisible]) { QString selection = QCFString::toQString([[mSavePanel URL] path]); if (selection != mCurrentSelection) { *mCurrentSelection = selection; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index aedb8f7b88a..36cfff43f58 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -68,8 +68,6 @@ enum { D2DDebugFillRectTag, D2DDebugDrawRectsTag, D2DDebugDrawRectFsTag, - D2DDebugDrawLinesTag, - D2DDebugDrawLineFsTag, D2DDebugDrawEllipseTag, D2DDebugDrawEllipseFTag, D2DDebugDrawImageTag, @@ -102,22 +100,28 @@ static inline ID2D1Factory1 *factory() return QWindowsDirect2DContext::instance()->d2dFactory(); } -static inline D2D1_MATRIX_3X2_F transformFromLine(const QLineF &line, qreal penWidth) +static inline D2D1_MATRIX_3X2_F transformFromLine(const QLineF &line, qreal penWidth, qreal dashOffset) { const qreal halfWidth = penWidth / 2; const qreal angle = -qDegreesToRadians(line.angle()); - QTransform transform = QTransform::fromTranslate(line.p1().x() + qSin(angle) * halfWidth, - line.p1().y() - qCos(angle) * halfWidth); + const qreal sinA = qSin(angle); + const qreal cosA = qCos(angle); + QTransform transform = QTransform::fromTranslate(line.p1().x() + dashOffset * cosA + sinA * halfWidth, + line.p1().y() + dashOffset * sinA - cosA * halfWidth); transform.rotateRadians(angle); return to_d2d_matrix_3x2_f(transform); } +static void adjustLine(QPointF *p1, QPointF *p2); +static bool isLinePositivelySloped(const QPointF &p1, const QPointF &p2); + class Direct2DPathGeometryWriter { public: Direct2DPathGeometryWriter() : m_inFigure(false) , m_roundCoordinates(false) + , m_adjustPositivelySlopedLines(false) { } @@ -152,6 +156,11 @@ public: m_roundCoordinates = enable; } + void setPositiveSlopeAdjustmentEnabled(bool enable) + { + m_adjustPositivelySlopedLines = enable; + } + bool isInFigure() const { return m_inFigure; @@ -164,11 +173,20 @@ public: m_sink->BeginFigure(adjusted(point), D2D1_FIGURE_BEGIN_FILLED); m_inFigure = true; + m_previousPoint = point; } void lineTo(const QPointF &point) { - m_sink->AddLine(adjusted(point)); + QPointF pt = point; + if (m_adjustPositivelySlopedLines && isLinePositivelySloped(m_previousPoint, point)) { + moveTo(m_previousPoint - QPointF(0, 1)); + pt -= QPointF(0, 1); + } + m_sink->AddLine(adjusted(pt)); + if (pt != point) + moveTo(point); + m_previousPoint = point; } void curveTo(const QPointF &p1, const QPointF &p2, const QPointF &p3) @@ -180,6 +198,7 @@ public: }; m_sink->AddBezier(segment); + m_previousPoint = p3; } void close() @@ -212,6 +231,8 @@ private: bool m_inFigure; bool m_roundCoordinates; + bool m_adjustPositivelySlopedLines; + QPointF m_previousPoint; }; struct D2DVectorPathCache { @@ -257,6 +278,7 @@ public: ComPtr<ID2D1Brush> brush; ComPtr<ID2D1StrokeStyle1> strokeStyle; ComPtr<ID2D1BitmapBrush1> dashBrush; + int dashLength; inline void reset() { emulate = false; @@ -264,6 +286,7 @@ public: brush.Reset(); strokeStyle.Reset(); dashBrush.Reset(); + dashLength = 0; } } pen; @@ -566,6 +589,7 @@ public: D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = D2D1::BitmapBrushProperties1( D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, D2D1_INTERPOLATION_MODE_LINEAR); hr = dc()->CreateBitmapBrush(bitmap.bitmap(), bitmapBrushProperties, &pen.dashBrush); + pen.dashLength = bitmap.size().width(); } else { hr = factory()->CreateStrokeStyle(props, NULL, 0, &pen.strokeStyle); } @@ -795,6 +819,8 @@ public: writer.setWindingFillEnabled(path.hasWindingFill()); writer.setAliasingEnabled(alias); + writer.setPositiveSlopeAdjustmentEnabled(path.shape() == QVectorPath::LinesHint + || path.shape() == QVectorPath::PolygonHint); const QPainterPath::ElementType *types = path.elements(); const int count = path.elementCount(); @@ -910,6 +936,90 @@ public: DWRITE_MEASURING_MODE_GDI_CLASSIC); } + void stroke(const QVectorPath &path) + { + Q_Q(QWindowsDirect2DPaintEngine); + + // Default path (no optimization) + if (!(path.shape() == QVectorPath::LinesHint || path.shape() == QVectorPath::PolygonHint) + || !pen.dashBrush || q->state()->renderHints.testFlag(QPainter::HighQualityAntialiasing)) { + ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path); + if (!geometry) { + qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); + return; + } + dc()->DrawGeometry(geometry.Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get()); + return; + } + + // Optimized dash line drawing + const bool isPolygon = path.shape() == QVectorPath::PolygonHint && path.elementCount() >= 3; + const bool implicitClose = isPolygon && (path.hints() & QVectorPath::ImplicitClose); + const bool skipJoin = !isPolygon // Non-polygons don't require joins + || (pen.qpen.joinStyle() == Qt::MiterJoin && qFuzzyIsNull(pen.qpen.miterLimit())); + const qreal *points = path.points(); + const int lastElement = path.elementCount() - (implicitClose ? 1 : 2); + qreal dashOffset = 0; + QPointF jointStart; + ID2D1Brush *brush = pen.dashBrush ? pen.dashBrush.Get() : pen.brush.Get(); + for (int i = 0; i <= lastElement; ++i) { + QPointF p1(points[i * 2], points[i * 2 + 1]); + QPointF p2 = implicitClose && i == lastElement ? QPointF(points[0], points[1]) + : QPointF(points[i * 2 + 2], points[i * 2 + 3]); + if (!isPolygon) // Advance the count for lines + ++i; + + // Match raster engine output + if (p1 == p2 && pen.qpen.widthF() <= 1.0) { + q->fillRect(QRectF(p1, QSizeF(pen.qpen.widthF(), pen.qpen.widthF())), pen.qpen.brush()); + continue; + } + + if (!q->antiAliasingEnabled()) + adjustLine(&p1, &p2); + + q->adjustForAliasing(&p1); + q->adjustForAliasing(&p2); + + const QLineF line(p1, p2); + const qreal lineLength = line.length(); + if (pen.dashBrush) { + pen.dashBrush->SetTransform(transformFromLine(line, pen.qpen.widthF(), dashOffset)); + dashOffset = pen.dashLength - fmod(lineLength - dashOffset, pen.dashLength); + } + dc()->DrawLine(to_d2d_point_2f(p1), to_d2d_point_2f(p2), + brush, pen.qpen.widthF(), NULL); + + if (skipJoin) + continue; + + // Patch the join with the original brush + const qreal patchSegment = pen.dashBrush ? qBound(0.0, (pen.dashLength - dashOffset) / lineLength, 1.0) + : pen.qpen.widthF(); + if (i > 0) { + Direct2DPathGeometryWriter writer; + writer.begin(); + writer.moveTo(jointStart); + writer.lineTo(p1); + writer.lineTo(line.pointAt(patchSegment)); + writer.close(); + dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get()); + } + // Record the start position of the next joint + jointStart = line.pointAt(1 - patchSegment); + + if (implicitClose && i == lastElement) { // Close the polygon + Direct2DPathGeometryWriter writer; + writer.begin(); + writer.moveTo(jointStart); + writer.lineTo(p2); + writer.lineTo(QLineF(p2, QPointF(points[2], points[3])).pointAt(patchSegment)); + writer.close(); + dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get()); + } + } + } + ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe) { const QFontDef fontDef = fe->fontDef; @@ -1055,20 +1165,12 @@ void QWindowsDirect2DPaintEngine::setState(QPainterState *s) void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) { - Q_D(QWindowsDirect2DPaintEngine); - - ComPtr<ID2D1Geometry> geometry = d->vectorPathToID2D1PathGeometry(path); - if (!geometry) { - qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); - return; - } - const QBrush &brush = state()->brush; if (qbrush_style(brush) != Qt::NoBrush) { if (emulationRequired(BrushEmulation)) rasterFill(path, brush); else - fill(geometry.Get(), brush); + fill(path, brush); } const QPen &pen = state()->pen; @@ -1076,7 +1178,7 @@ void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path) if (emulationRequired(PenEmulation)) QPaintEngineEx::stroke(path, pen); else - stroke(geometry.Get(), pen); + stroke(path, pen); } } @@ -1106,18 +1208,6 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get()); } -void QWindowsDirect2DPaintEngine::fill(ID2D1Geometry *geometry, const QBrush &brush) -{ - Q_D(QWindowsDirect2DPaintEngine); - D2D_TAG(D2DDebugFillTag); - - ensureBrush(brush); - if (!d->brush.brush) - return; - - d->dc()->FillGeometry(geometry, d->brush.brush.Get()); -} - void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QWindowsDirect2DPaintEngine); @@ -1135,25 +1225,7 @@ void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pe if (!d->pen.brush) return; - ComPtr<ID2D1Geometry> geometry = d->vectorPathToID2D1PathGeometry(path); - if (!geometry) { - qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__); - return; - } - - d->dc()->DrawGeometry(geometry.Get(), d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); -} - -void QWindowsDirect2DPaintEngine::stroke(ID2D1Geometry *geometry, const QPen &pen) -{ - Q_D(QWindowsDirect2DPaintEngine); - D2D_TAG(D2DDebugFillTag); - - ensurePen(pen); - if (!d->pen.brush) - return; - - d->dc()->DrawGeometry(geometry, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); + d->stroke(path); } void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) @@ -1301,88 +1373,6 @@ static void adjustLine(QPointF *p1, QPointF *p2) } } -void QWindowsDirect2DPaintEngine::drawLines(const QLine *lines, int lineCount) -{ - Q_D(QWindowsDirect2DPaintEngine); - D2D_TAG(D2DDebugDrawLinesTag); - - ensurePen(); - - if (emulationRequired(PenEmulation)) { - QPaintEngineEx::drawLines(lines, lineCount); - } else if (d->pen.brush) { - for (int i = 0; i < lineCount; i++) { - QPointF p1 = lines[i].p1(); - QPointF p2 = lines[i].p2(); - - // Match raster engine output - if (p1 == p2 && d->pen.qpen.widthF() <= 1.0) { - fillRect(QRectF(p1, QSizeF(d->pen.qpen.widthF(), d->pen.qpen.widthF())), - d->pen.qpen.brush()); - continue; - } - - // Match raster engine output - if (!antiAliasingEnabled()) - adjustLine(&p1, &p2); - - adjustForAliasing(&p1); - adjustForAliasing(&p2); - - D2D1_POINT_2F d2d_p1 = to_d2d_point_2f(p1); - D2D1_POINT_2F d2d_p2 = to_d2d_point_2f(p2); - - if (!d->pen.dashBrush || state()->renderHints.testFlag(QPainter::HighQualityAntialiasing)) { - d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); - } else { - d->pen.dashBrush->SetTransform(transformFromLine(lines[i], d->pen.qpen.widthF())); - d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.dashBrush.Get(), d->pen.qpen.widthF(), NULL); - } - } - } -} - -void QWindowsDirect2DPaintEngine::drawLines(const QLineF *lines, int lineCount) -{ - Q_D(QWindowsDirect2DPaintEngine); - D2D_TAG(D2DDebugDrawLineFsTag); - - ensurePen(); - - if (emulationRequired(PenEmulation)) { - QPaintEngineEx::drawLines(lines, lineCount); - } else if (d->pen.brush) { - for (int i = 0; i < lineCount; i++) { - QPointF p1 = lines[i].p1(); - QPointF p2 = lines[i].p2(); - - // Match raster engine output - if (p1 == p2 && d->pen.qpen.widthF() <= 1.0) { - fillRect(QRectF(p1, QSizeF(d->pen.qpen.widthF(), d->pen.qpen.widthF())), - d->pen.qpen.brush()); - continue; - } - - // Match raster engine output - if (!antiAliasingEnabled()) - adjustLine(&p1, &p2); - - adjustForAliasing(&p1); - adjustForAliasing(&p2); - - D2D1_POINT_2F d2d_p1 = to_d2d_point_2f(p1); - D2D1_POINT_2F d2d_p2 = to_d2d_point_2f(p2); - - if (!d->pen.dashBrush || state()->renderHints.testFlag(QPainter::HighQualityAntialiasing)) { - d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get()); - } else { - d->pen.dashBrush->SetTransform(transformFromLine(lines[i], d->pen.qpen.widthF())); - d->dc()->DrawLine(d2d_p1, d2d_p2, d->pen.dashBrush.Get(), d->pen.qpen.widthF(), NULL); - } - } - } -} - void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r) { Q_D(QWindowsDirect2DPaintEngine); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index f9fd6eb591b..a75c0b6cc7c 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -92,9 +92,6 @@ public: void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE; void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE; - void drawLines(const QLine *lines, int lineCount) Q_DECL_OVERRIDE; - void drawLines(const QLineF *lines, int lineCount) Q_DECL_OVERRIDE; - void drawEllipse(const QRectF &r) Q_DECL_OVERRIDE; void drawEllipse(const QRect &r) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 9470d1844e3..f36cbaf6850 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -138,8 +138,9 @@ QRect previousGeometry = requestedGeometry != actualGeometry ? requestedGeometry : qt_window_private(m_qioswindow->window())->geometry; - QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), actualGeometry, previousGeometry); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindow *window = m_qioswindow->window(); + QWindowSystemInterface::handleGeometryChange(window, actualGeometry, previousGeometry); + QWindowSystemInterface::flushWindowSystemEvents(window->inherits("QWidgetWindow") ? QEventLoop::ExcludeUserInputEvents : QEventLoop::AllEvents); if (actualGeometry.size() != previousGeometry.size()) { // Trigger expose event on resize diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index 616e1af6b54..2c61f68e838 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -79,6 +79,8 @@ void QLinuxFbIntegration::initialize() m_inputContext = QPlatformInputContextFactory::create(); + m_nativeInterface.reset(new QPlatformNativeInterface); + m_vtHandler.reset(new QFbVtHandler); if (!qEnvironmentVariableIntValue("QT_QPA_FB_DISABLE_INPUT")) @@ -141,4 +143,9 @@ void QLinuxFbIntegration::createInputHandlers() #endif } +QPlatformNativeInterface *QLinuxFbIntegration::nativeInterface() const +{ + return m_nativeInterface.data(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h index f2fc95c4cea..0a3d5fd6ac0 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h @@ -61,6 +61,8 @@ public: QPlatformServices *services() const Q_DECL_OVERRIDE; QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + QList<QPlatformScreen *> screens() const; private: @@ -71,6 +73,7 @@ private: QScopedPointer<QPlatformFontDatabase> m_fontDb; QScopedPointer<QPlatformServices> m_services; QScopedPointer<QFbVtHandler> m_vtHandler; + QScopedPointer<QPlatformNativeInterface> m_nativeInterface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 8f48efc7f93..b397b123116 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -675,6 +675,8 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c #ifndef Q_OS_WINCE const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags); #else +// Under Windows CE we don't use ChildWindowFromPointEx as it's not available +// and ChildWindowFromPoint does not work properly. Q_UNUSED(cwexFlags) const HWND child = WindowFromPoint(point); #endif @@ -683,7 +685,13 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c if (QWindowsWindow *window = context->findPlatformWindow(child)) { *result = window; *hwnd = child; +#ifndef Q_OS_WINCE return true; +#else +// WindowFromPoint does not return same handle in two sequential calls, which leads +// to an endless loop, but calling WindowFromPoint once is good enough. + return false; +#endif } #ifndef Q_OS_WINCE // Does not have WS_EX_TRANSPARENT . // QTBUG-40555: despite CWP_SKIPINVISIBLE, it is possible to hit on invisible diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index db89402c055..0e26a172237 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -567,16 +567,15 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, Q_ASSERT(vk > 0 && vk < 256); int code = 0; QChar unicodeBuffer[5]; - // While key combinations containing alt and ctrl might trigger the third assignment of a key - // (for example "alt+ctrl+q" causes '@' on a German layout), ToUnicode often does not return the - // wanted character if only the ctrl modifier is used. Thus we unset this modifier temporarily - // if it is not used together with alt. - const unsigned char controlState = kbdBuffer[VK_MENU] ? 0 : kbdBuffer[VK_CONTROL]; - if (controlState) - kbdBuffer[VK_CONTROL] = 0; int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0); - if (controlState) + // When Ctrl modifier is used ToUnicode does not return correct values. In order to assign the + // right key the control modifier is removed for just that function if the previous call failed. + if (res == 0 && kbdBuffer[VK_CONTROL]) { + const unsigned char controlState = kbdBuffer[VK_CONTROL]; + kbdBuffer[VK_CONTROL] = 0; + res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0); kbdBuffer[VK_CONTROL] = controlState; + } if (res) code = unicodeBuffer[0].toUpper().unicode(); diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index ba8fcee829a..f33e07901a2 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -232,7 +232,7 @@ QVariant QWinRTTheme::styleHint(QPlatformIntegration::StyleHint hint) return false; case QPlatformIntegration::ShowIsMaximized: return false; - case MousePressAndHoldInterval: + case QPlatformIntegration::MousePressAndHoldInterval: return defaultThemeHint(MousePressAndHoldInterval); default: break; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 250527e3ae4..e1584999dbc 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -789,6 +789,15 @@ void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev) qCDebug(lcQpaXInput, "xcb: released mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons)); } +void QXcbConnection::handleMotionNotify(xcb_generic_event_t *ev) +{ + xcb_motion_notify_event_t *event = (xcb_motion_notify_event_t *)ev; + + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qDebug("xcb: moved mouse to %4d, %4d; button state %X", event->event_x, event->event_y, static_cast<unsigned int>(m_buttons)); +} + #ifndef QT_NO_XKB namespace { typedef union { @@ -839,11 +848,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) handleButtonRelease(event); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); case XCB_MOTION_NOTIFY: - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) { - xcb_motion_notify_event_t *mev = (xcb_motion_notify_event_t *)event; - qDebug("xcb: moved mouse to %4d, %4d; button state %X", mev->event_x, mev->event_y, static_cast<unsigned int>(m_buttons)); - } m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state); + handleMotionNotify(event); HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); case XCB_CONFIGURE_NOTIFY: HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index e3d9766a4b1..90b859e612c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -497,6 +497,7 @@ private: void updateScreens(); void handleButtonPress(xcb_generic_event_t *event); void handleButtonRelease(xcb_generic_event_t *event); + void handleMotionNotify(xcb_generic_event_t *event); bool m_xi2Enabled; int m_xi2Minor; @@ -507,6 +508,7 @@ private: XInput2TouchDeviceData *touchDeviceForId(int id); void xi2HandleEvent(xcb_ge_event_t *event); void xi2HandleHierachyEvent(void *event); + void xi2HandleDeviceChangedEvent(void *event); int m_xiOpCode, m_xiEventBase, m_xiErrorBase; #ifndef QT_NO_TABLETEVENT struct TabletData { @@ -540,6 +542,7 @@ private: Qt::Orientations legacyOrientations; QPointF lastScrollPosition; }; + void updateScrollingDevice(ScrollingDevice& scrollingDevice, int num_classes, void *classes); void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice); QHash<int, ScrollingDevice> m_scrollingDevices; #endif // XCB_USE_XINPUT2 diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index f225518cb90..e9fb47dabdf 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -348,6 +348,7 @@ void QXcbConnection::xi2Select(xcb_window_t window) // Listen for hotplug events XIEventMask xiEventMask; bitMask = XI_HierarchyChangedMask; + bitMask |= XI_DeviceChangedMask; xiEventMask.deviceid = XIAllDevices; xiEventMask.mask_len = sizeof(bitMask); xiEventMask.mask = xiBitMask; @@ -468,6 +469,11 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xi2HandleHierachyEvent(xiEvent); return; } + if (xiEvent->evtype == XI_DeviceChanged) { + xi2HandleDeviceChangedEvent(xiEvent); + return; + } + #ifndef QT_NO_TABLETEVENT for (int i = 0; i < m_tabletData.count(); ++i) { if (m_tabletData.at(i).deviceId == xiEvent->deviceid) { @@ -628,6 +634,64 @@ void QXcbConnection::xi2HandleHierachyEvent(void *event) } } +void QXcbConnection::xi2HandleDeviceChangedEvent(void *event) +{ + xXIDeviceChangedEvent *xiEvent = reinterpret_cast<xXIDeviceChangedEvent *>(event); + + // ### If a slave device changes (XIDeviceChange), we should probably run setup on it again. + if (xiEvent->reason != XISlaveSwitch) + return; + +#ifdef XCB_USE_XINPUT21 + // This code handles broken scrolling device drivers that reset absolute positions + // when they are made active. Whenever a new slave device is made active the + // primary pointer sends a DeviceChanged event with XISlaveSwitch, and the new + // active slave in sourceid. + + QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(xiEvent->sourceid); + if (device == m_scrollingDevices.end()) + return; + + int nrDevices = 0; + XIDeviceInfo* xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), xiEvent->sourceid, &nrDevices); + if (nrDevices <= 0) { + qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", xiEvent->sourceid); + return; + } + updateScrollingDevice(*device, xiDeviceInfo->num_classes, xiDeviceInfo->classes); + XIFreeDeviceInfo(xiDeviceInfo); +#endif +} + +void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int num_classes, void *classInfo) +{ +#ifdef XCB_USE_XINPUT21 + XIAnyClassInfo **classes = reinterpret_cast<XIAnyClassInfo**>(classInfo); + QPointF lastScrollPosition; + if (lcQpaXInput().isDebugEnabled()) + lastScrollPosition = scrollingDevice.lastScrollPosition; + for (int c = 0; c < num_classes; ++c) { + if (classes[c]->type == XIValuatorClass) { + XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classes[c]); + const int valuatorAtom = qatom(vci->label); + if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel) + scrollingDevice.lastScrollPosition.setX(vci->value); + else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel) + scrollingDevice.lastScrollPosition.setY(vci->value); + } + } + if (lcQpaXInput().isDebugEnabled() && lastScrollPosition != scrollingDevice.lastScrollPosition) + qCDebug(lcQpaXInput, "scrolling device %d moved from (%f, %f) to (%f, %f)", scrollingDevice.deviceId, + lastScrollPosition.x(), lastScrollPosition.y(), + scrollingDevice.lastScrollPosition.x(), + scrollingDevice.lastScrollPosition.y()); +#else + Q_UNUSED(scrollingDevice); + Q_UNUSED(num_classes); + Q_UNUSED(classInfo); +#endif +} + void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) { #ifdef XCB_USE_XINPUT21 @@ -638,19 +702,11 @@ void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) int nrDevices = 0; XIDeviceInfo* xiDeviceInfo = XIQueryDevice(static_cast<Display *>(m_xlib_display), scrollingDevice.deviceId, &nrDevices); if (nrDevices <= 0) { + qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", scrollingDevice.deviceId); it = m_scrollingDevices.erase(it); continue; } - for (int c = 0; c < xiDeviceInfo->num_classes; ++c) { - if (xiDeviceInfo->classes[c]->type == XIValuatorClass) { - XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(xiDeviceInfo->classes[c]); - const int valuatorAtom = qatom(vci->label); - if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel) - scrollingDevice.lastScrollPosition.setX(vci->value); - else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel) - scrollingDevice.lastScrollPosition.setY(vci->value); - } - } + updateScrollingDevice(scrollingDevice, xiDeviceInfo->num_classes, xiDeviceInfo->classes); XIFreeDeviceInfo(xiDeviceInfo); ++it; } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 34289fb90e1..54ebca05325 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -206,6 +206,18 @@ static inline QImage::Format imageFormatForVisual(int depth, quint32 red_mask, q break; } qWarning("Unsupported screen format: depth: %d, red_mask: %x, blue_mask: %x", depth, red_mask, blue_mask); + + switch (depth) { + case 24: + qWarning("Using RGB32 fallback, if this works your X11 server is reporting a bad screen format."); + return QImage::Format_RGB32; + case 16: + qWarning("Using RGB16 fallback, if this works your X11 server is reporting a bad screen format."); + return QImage::Format_RGB16; + default: + break; + } + return QImage::Format_Invalid; } diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm index 498394f1fc1..886cbc01524 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm +++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm @@ -76,8 +76,11 @@ QT_USE_NAMESPACE PMPageFormat format = static_cast<PMPageFormat>([printInfo PMPageFormat]); PMRect paperRect; PMGetUnadjustedPaperRect(format, &paperRect); + PMOrientation orientation; + PMGetOrientation(format, &orientation); QSizeF paperSize = QSizeF(paperRect.right - paperRect.left, paperRect.bottom - paperRect.top); printer->printEngine()->setProperty(QPrintEngine::PPK_CustomPaperSize, paperSize); + printer->printEngine()->setProperty(QPrintEngine::PPK_Orientation, orientation == kPMLandscape ? QPrinter::Landscape : QPrinter::Portrait); } dialog->done((returnCode == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); diff --git a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc index a3152cd2174..fee36e3537e 100644 --- a/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc +++ b/src/sql/doc/snippets/code/doc_src_sql-driver.qdoc @@ -60,34 +60,34 @@ END //! [3] -cd $QTDIR/src/plugins/sqldrivers/mysql +cd $QTDIR/qtbase/src/plugins/sqldrivers/mysql qmake "INCLUDEPATH+=/usr/local/include" "LIBS+=-L/usr/local/lib -lmysqlclient_r" mysql.pro make //! [3] //! [4] -cd $QTDIR/src/plugins/sqldrivers/mysql +cd $QTDIR/qtbase/src/plugins/sqldrivers/mysql make install //! [4] //! [5] -cd %QTDIR%\src\plugins\sqldrivers\mysql +cd %QTDIR%\qtbase\src\plugins\sqldrivers\mysql qmake "INCLUDEPATH+=C:/MySQL/include" "LIBS+=C:/MYSQL/MySQL Server <version>/lib/opt/libmysql.lib" mysql.pro nmake //! [5] //! [6] -cd $QTDIR/src/plugins/sqldrivers/oci +cd $QTDIR/qtbase/src/plugins/sqldrivers/oci qmake "INCLUDEPATH+=$ORACLE_HOME/rdbms/public $ORACLE_HOME/rdbms/demo" "LIBS+=-L$ORACLE_HOME/lib -lclntsh -lwtc9" oci.pro make //! [6] //! [7] -cd $QTDIR/src/plugins/sqldrivers/oci +cd $QTDIR/qtbase/src/plugins/sqldrivers/oci qmake "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client/" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib -lclntsh" oci.pro make //! [7] @@ -96,7 +96,7 @@ make //! [8] set INCLUDE=%INCLUDE%;c:\oracle\oci\include set LIB=%LIB%;c:\oracle\oci\lib\msvc -cd %QTDIR%\src\plugins\sqldrivers\oci +cd %QTDIR%\qtbase\src\plugins\sqldrivers\oci qmake oci.pro nmake //! [8] @@ -108,116 +108,116 @@ set PATH=%PATH%;c:\oracle\bin //! [11] -cd $QTDIR/src/plugins/sqldrivers/odbc +cd $QTDIR/qtbase/src/plugins/sqldrivers/odbc qmake "INCLUDEPATH+=/usr/local/unixODBC/include" "LIBS+=-L/usr/local/unixODBC/lib -lodbc" make //! [11] //! [12] -cd %QTDIR%\src\plugins\sqldrivers\odbc +cd %QTDIR%\qtbase\src\plugins\sqldrivers\odbc qmake odbc.pro nmake //! [12] //! [13] -cd $QTDIR/src/plugins/sqldrivers/psql +cd $QTDIR/qtbase/src/plugins/sqldrivers/psql qmake "INCLUDEPATH+=/usr/include/pgsql" "LIBS+=-L/usr/lib -lpq" psql.pro make //! [13] //! [14] -cd $QTDIR/src/plugins/sqldrivers/psql +cd $QTDIR/qtbase/src/plugins/sqldrivers/psql make install //! [14] //! [15] -cd %QTDIR%\src\plugins\sqldrivers\psql +cd %QTDIR%\qtbase\src\plugins\sqldrivers\psql qmake "INCLUDEPATH+=C:/psql/include" "LIBS+=C:/psql/lib/ms/libpq.lib" psql.pro nmake //! [15] //! [16] -cd $QTDIR/src/plugins/sqldrivers/tds +cd $QTDIR/qtbase/src/plugins/sqldrivers/tds qmake "INCLUDEPATH=$SYBASE/include" "LIBS=-L$SYBASE/lib -lsybdb" make //! [16] //! [17] -cd %QTDIR%\src\plugins\sqldrivers\tds +cd %QTDIR%\qtbase\src\plugins\sqldrivers\tds qmake "LIBS+=NTWDBLIB.LIB" tds.pro nmake //! [17] //! [18] -cd $QTDIR/src/plugins/sqldrivers/db2 +cd $QTDIR/qtbase/src/plugins/sqldrivers/db2 qmake "INCLUDEPATH+=$DB2DIR/include" "LIBS+=-L$DB2DIR/lib -ldb2" make //! [18] //! [19] -cd $QTDIR/src/plugins/sqldrivers/db2 +cd $QTDIR/qtbase/src/plugins/sqldrivers/db2 make install //! [19] //! [20] -cd %QTDIR%\src\plugins\sqldrivers\db2 +cd %QTDIR%\qtbase\src\plugins\sqldrivers\db2 qmake "INCLUDEPATH+=<DB2 home>/sqllib/include" "LIBS+=<DB2 home>/sqllib/lib/db2cli.lib" nmake //! [20] //! [21] -cd $QTDIR/src/plugins/sqldrivers/sqlite +cd $QTDIR/qtbase/src/plugins/sqldrivers/sqlite qmake "INCLUDEPATH+=$SQLITE/include" "LIBS+=-L$SQLITE/lib -lsqlite" make //! [21] //! [22] -cd $QTDIR/src/plugins/sqldrivers/sqlite +cd $QTDIR/qtbase/src/plugins/sqldrivers/sqlite make install //! [22] //! [23] -cd %QTDIR%\src\plugins\sqldrivers\sqlite +cd %QTDIR%\qtbase\src\plugins\sqldrivers\sqlite qmake "INCLUDEPATH+=C:/SQLITE/INCLUDE" "LIBS+=C:/SQLITE/LIB/SQLITE3.LIB" sqlite.pro nmake //! [23] //! [27] -cd $QTDIR/src/plugins/sqldrivers/ibase +cd $QTDIR/qtbase/src/plugins/sqldrivers/ibase qmake "INCLUDEPATH+=/opt/interbase/include" "LIBS+=-L/opt/interbase/lib" ibase.pro make //! [27] //! [28] -cd $QTDIR/src/plugins/sqldrivers/ibase +cd $QTDIR/qtbase/src/plugins/sqldrivers/ibase qmake "INCLUDEPATH+=/opt/interbase/include" "LIBS+=-L/opt/interbase/lib -lfbclient" ibase.pro make //! [28] //! [29] -cd %QTDIR%\src\plugins\sqldrivers\ibase +cd %QTDIR%\qtbase\src\plugins\sqldrivers\ibase qmake "INCLUDEPATH+=C:/interbase/include" ibase.pro nmake //! [29] //! [30] -cd %QTDIR%\src\plugins\sqldrivers\ibase +cd %QTDIR%\qtbase\src\plugins\sqldrivers\ibase qmake "INCLUDEPATH+=C:/interbase/include" "LIBS+=-lfbclient" ibase.pro nmake //! [30] @@ -229,7 +229,7 @@ make //! [32] //! [33] -cd $QTDIR/src/plugins/sqldrivers/oci +cd $QTDIR/qtbase/src/plugins/sqldrivers/oci qmake "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib -Wl,-rpath,/usr/lib/oracle/10.1.0.3/client/lib -lclntsh -lnnz10" oci.pro make //! [33] diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc index 369d193bb9b..43455b163ff 100644 --- a/src/sql/doc/src/sql-driver.qdoc +++ b/src/sql/doc/src/sql-driver.qdoc @@ -471,7 +471,7 @@ By default the Microsoft library is used on Windows, if you want to force the use of the Sybase Open Client, you must define \c - Q_USE_SYBASE in \c{%QTDIR%\src\sql\drivers\tds\qsql_tds.cpp}. If you + Q_USE_SYBASE in \c{%QTDIR%\qtbase\src\sql\drivers\tds\qsql_tds.cpp}. If you are not using a Microsoft compiler, replace \c nmake with \c make in the line above. @@ -751,7 +751,7 @@ must use the Q_PLUGIN_METADATA() macro. Read \l{How to Create Qt Plugins} for more information on this. You can also check out how this is done in the SQL plugins that are provided with Qt in - \c{QTDIR/src/plugins/sqldrivers} and \c{QTDIR/src/sql/drivers}. + \c{QTDIR/qtbase/src/plugins/sqldrivers} and \c{QTDIR/qtbase/src/sql/drivers}. The following code can be used as a skeleton for a SQL driver: diff --git a/src/src.pro b/src/src.pro index 7ec27653368..cb388ae4fcf 100644 --- a/src/src.pro +++ b/src/src.pro @@ -83,6 +83,7 @@ src_testlib.depends = src_corelib # src_gui & src_widgets are not build-depend src_3rdparty_harfbuzzng.subdir = $$PWD/3rdparty/harfbuzz-ng src_3rdparty_harfbuzzng.target = sub-3rdparty-harfbuzzng +src_3rdparty_harfbuzzng.depends = src_corelib # for the Qt atomics src_angle.subdir = $$PWD/angle src_angle.target = sub-angle diff --git a/src/testlib/doc/src/qt-webpages.qdoc b/src/testlib/doc/src/qt-webpages.qdoc index 0b6344a22e6..a0a248684a7 100644 --- a/src/testlib/doc/src/qt-webpages.qdoc +++ b/src/testlib/doc/src/qt-webpages.qdoc @@ -25,7 +25,7 @@ ** ****************************************************************************/ /*! - \externalpage http://blog.qt.io/ + \externalpage http://blog.qt.io \title Qt Labs */ /*! diff --git a/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc index 12eef508a89..98321f9a391 100644 --- a/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc @@ -428,7 +428,7 @@ \quotation \raw HTML <h3> - <a href="http://qt-project.org/doc/qt-5.0/qtcore/qchar.html#Joining-enum">Joining</a> + <a href="http://doc.qt.io/qt-5/qchar.html#JoiningType-enum">Joining</a> QChar::joining () const</h3> \endraw @@ -787,7 +787,7 @@ \quotation \raw HTML - <h3><a href="http://qt-project.org/doc/qt-5.0/qtwidgets/qaction.html">QAction</a> + <h3><a href="http://doc.qt.io/qt-5/qaction.html">QAction</a> * QMenu::addAction ( const QIcon & <i>icon</i>, const QString & <i>text</i> ) </h3> diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc index b3f4f29f0b5..f341699ee8e 100644 --- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc @@ -1479,10 +1479,10 @@ \printuntil hello First we create a \l - {http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html} {QApplication} + {http://doc.qt.io/qt-5/qapplication.html} {QApplication} object using the \c argc and \c argv parameters, then we create a \l - {http://qt-project.org/doc/qt-5.0/qtwidgets/qpushbutton.html} {QPushButton}. + {http://doc.qt.io/qt-5/qpushbutton.html} {QPushButton}. \endquotation See also \l {printline-command} {\\printline} and \l @@ -1782,7 +1782,7 @@ \code / *! - Read the \l {http://qt-project.org/doc/qt-5.0/} + Read the \l {http://doc.qt.io/qt-5/} {Qt 5.0 Documentation} carefully. * / \endcode @@ -1790,7 +1790,7 @@ QDoc renders this as: \quotation - Read the \l {http://qt-project.org/doc/qt-5.0/} + Read the \l {http://doc.qt.io/qt-5/} {Qt 5.0 Documentation} carefully. \endquotation @@ -2419,7 +2419,7 @@ <tr valign="top" bgcolor="#d0d0d0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html"> + <a href="http://doc.qt.io/qt-5/signalsandslots.html"> Signals and Slots</a> </td> <td>Signals and slots are used for communication @@ -2428,7 +2428,7 @@ <tr valign="top" bgcolor="#c0c0c0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtwidgets/layout.html"> + <a href="http://doc.qt.io/qt-5/layout.html"> Layout Management</a></td> <td>The Qt layout system provides a simple and powerful way of specifying the layout @@ -2437,7 +2437,7 @@ <tr valign="top" bgcolor="#d0d0d0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtgui/dnd.html"> + <a href="http://doc.qt.io/qt-5/dnd.html"> Drag and Drop</a></td> <td>Drag and drop provides a simple visual mechanism which users can use to transfer @@ -2538,7 +2538,7 @@ <tr valign="top" bgcolor="#d0d0d0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html"> + <a href="http://doc.qt.io/qt-5/signalsandslots.html"> Signals and Slots</a> </td> <td>Signals and slots are used for communication @@ -2600,7 +2600,7 @@ <tr valign="top" bgcolor="#d0d0d0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtcore/signalsandslots.html"> + <a href="http://doc.qt.io/qt-5/signalsandslots.html"> Signals and Slots</a> </td> <td>Signals and slots are used for communication @@ -2609,7 +2609,7 @@ <tr valign="top" bgcolor="#c0c0c0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtwidgets/layout.html"> + <a href="http://doc.qt.io/qt-5/layout.html"> Layout Management</a></td> <td>The Qt layout system provides a simple and powerful way of specifying the layout @@ -2618,7 +2618,7 @@ <tr valign="top" bgcolor="#d0d0d0"> <td> - <a href="http://qt-project.org/doc/qt-5.0/qtgui/dnd.html"> + <a href="http://doc.qt.io/qt-5/dnd.html"> Drag and Drop</a></td> <td>Drag and drop provides a simple visual mechanism which users can use to transfer @@ -3036,7 +3036,7 @@ \quotation \raw HTML <h3>geometry : - <a href="http://qt-project.org/doc/qt-5.0/qtcore/qrect.html">QRect</a> + <a href="http://doc.qt.io/qt-5/qrect.html">QRect</a> </h3> \endraw diff --git a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc index 987962fa383..226c107e3a0 100644 --- a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc @@ -1409,7 +1409,7 @@ \code project = Qt description = Qt Reference Documentation - url = http://qt-project.org/doc/qt-4.8/ + url = http://doc.qt.io/qt-4.8/ ... \endcode @@ -1432,7 +1432,7 @@ \code project = Qt description = Qt Reference Documentation - url = http://qt-project.org/doc/qt-4.8/ + url = http://doc.qt.io/qt-4.8/ ... \endcode diff --git a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc index be31e0e5df8..93cd25610d9 100644 --- a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc @@ -393,11 +393,11 @@ Files: \list - \li \l{http://qt-project.org/doc/qt-5.0/qtwidgets/widgets-imageviewer-imageviewer-cpp.html} + \li \l{http://doc.qt.io/qt-5/qtwidgets-widgets-imageviewer-imageviewer-cpp.html} {widgets/imageviewer/imageviewer.cpp} - \li \l{http://qt-project.org/doc/qt-5.0/qtwidgets/widgets-imageviewer-imageviewer-h.html} + \li \l{http://doc.qt.io/qt-5/qtwidgets-widgets-imageviewer-imageviewer-h.html} {widgets/imageviewer/imageviewer.h} - \li \l{http://qt-project.org/doc/qt-5.0/qtwidgets/widgets-imageviewer-main-cpp.html} + \li \l{http://doc.qt.io/qt-5/qtwidgets-widgets-imageviewer-main-cpp.html} {widgets/imageviewer/main.cpp} \endlist @@ -414,7 +414,7 @@ \code / *! - \externalpage http://qt-project.org/doc/ + \externalpage http://doc.qt.io/ \title Qt Documentation Site * / \endcode @@ -432,7 +432,7 @@ QDoc renders this as: \quotation - At the \l {http://qt-project.org/doc/}{Qt Documentation Site} + At the \l {http://doc.qt.io/}{Qt Documentation Site} you can find the latest documentation for Qt, Qt Creator, the Qt SDK and much more. \endquotation @@ -443,7 +443,7 @@ \code / *! - At the \l {http://qt-project.org/doc/}{Qt Documentation Site} + At the \l {http://doc.qt.io/}{Qt Documentation Site} you can find the latest documentation for Qt, Qt Creator, the Qt SDK and much more. * / @@ -543,7 +543,7 @@ <table width="100%"> <tr valign="top" bgcolor="#e0e0e0"> <td><b> - <a href="http://qt-project.org/doc/qt-5.0/qtnetwork/qabstractsocket.html">QAbstractSocket</a> + <a href="http://doc.qt.io/qt-5/qabstractsocket.html">QAbstractSocket</a> </b></td> <td> The base functionality common to all socket types @@ -551,7 +551,7 @@ <tr valign="top" bgcolor="#e0e0e0"> <td><b> - <a href="http://qt-project.org/doc/qt-5.0/qtcore/qbuffer.html">QBuffer</a> + <a href="http://doc.qt.io/qt-5/qbuffer.html">QBuffer</a> </b></td> <td> QIODevice interface for a QByteArray @@ -559,7 +559,7 @@ <tr valign="top" bgcolor="#e0e0e0"> <td><b> - <a href="http://qt-project.org/doc/qt-5.0/qtgui/qclipboard.html">QClipboard</a> + <a href="http://doc.qt.io/qt-5/qclipboard.html">QClipboard</a> </b></td> <td> Access to the window system clipboard @@ -635,7 +635,7 @@ <h3>Functions</h3> <ul> <li>RandomAccessIterator - <a href="http://qt-project.org/doc/qt-5.0/qtcore/qtalgorithms.html#qBinaryFind">qBinaryFind</a></b> + <a href="http://doc.qt.io/qt-5/qtalgorithms-obsolete.html#qBinaryFind">qBinaryFind</a></b> (RandomAccessIterator begin, RandomAccessIterator end, const T & value)</li> <li>...</li></ul> @@ -804,7 +804,7 @@ <table width="100%"> <tr valign="top" bgcolor="#d0d0d0"> <td><b> - <a href="http://qt-project.org/doc/qt-5.0/qtnetwork/qabstractsocket.html">QAbstractSocket</a> + <a href="http://doc.qt.io/qt-5/qabstractsocket.html">QAbstractSocket</a> </b></td> <td> The base functionality common to all socket types @@ -1539,7 +1539,7 @@ \quotation \raw HTML <h3> - <a href="http://qt-project.org/doc/qt-5.0/qtgui/qpalette.html"> + <a href="http://doc.qt.io/qt-5/qpalette.html"> QPalette </a> QStyleOption::palette diff --git a/src/tools/qdoc/doc/qtgui-qdocconf.qdoc b/src/tools/qdoc/doc/qtgui-qdocconf.qdoc index 25856c91391..3dcd2482d6d 100644 --- a/src/tools/qdoc/doc/qtgui-qdocconf.qdoc +++ b/src/tools/qdoc/doc/qtgui-qdocconf.qdoc @@ -43,7 +43,7 @@ every statement in the qdocconf file. project = QtGui description = Qt GUI Reference Documentation - url = http://qt-project.org/doc/qt-$QT_VER/qtgui + url = http://doc.qt.io/qt-$QT_VER/qtgui-index.html version = $QT_VERSION examplesinstallpath = gui @@ -125,7 +125,7 @@ name of the index file doesn't adopt the uppercase letters of the project name. A short description of the project concerned. \code - url = http://qt-project.org/doc/qt-$QT_VER/qtgui + url = http://doc.qt.io/qt-$QT_VER/qtgui-index.html \endcode The \c url variable holds the base url of the project. diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp index 3f12ae6f0dd..7080dd6f8d8 100644 --- a/src/widgets/accessible/qaccessiblewidgets.cpp +++ b/src/widgets/accessible/qaccessiblewidgets.cpp @@ -727,19 +727,31 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end int blockEnd = blockStart + block.length(); QTextBlock::iterator iter = block.begin(); - while (!iter.fragment().contains(offset)) + int lastFragmentIndex = blockStart; + while (!iter.atEnd()) { + QTextFragment f = iter.fragment(); + if (f.contains(offset)) + break; + lastFragmentIndex = f.position() + f.length(); ++iter; + } - QTextFragment fragment = iter.fragment(); - int pos = fragment.position(); - - // text block and fragment may overlap, use the smallest common range - *startOffset = qMax(pos, blockStart); + QTextCharFormat charFormat; + if (!iter.atEnd()) { + QTextFragment fragment = iter.fragment(); + charFormat = fragment.charFormat(); + int pos = fragment.position(); + // text block and fragment may overlap, use the smallest common range + *startOffset = qMax(pos, blockStart); + *endOffset = qMin(pos + fragment.length(), blockEnd); + } else { + charFormat = block.charFormat(); + *startOffset = lastFragmentIndex; + *endOffset = blockEnd; + } Q_ASSERT(*startOffset <= offset); - *endOffset = qMin(pos + fragment.length(), blockEnd); Q_ASSERT(*endOffset >= offset); - QTextCharFormat charFormat = fragment.charFormat(); QTextBlockFormat blockFormat = cursor.blockFormat(); QMap<QByteArray, QString> attrs; diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 70da6ff99b9..455111225e8 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2711,7 +2711,7 @@ void QFileDialogPrivate::createWidgets() return; Q_Q(QFileDialog); model = new QFileSystemModel(q); - options->setFilter(model->filter()); + model->setFilter(options->filter()); model->setObjectName(QLatin1String("qt_filesystem_model")); if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) model->setNameFilterDisables(helper->defaultNameFilterDisables()); diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp index 580ba334218..8956794e06b 100644 --- a/src/widgets/effects/qpixmapfilter.cpp +++ b/src/widgets/effects/qpixmapfilter.cpp @@ -416,17 +416,7 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q if (src.isNull()) return; - QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter); - if (convolutionFilter) { - convolutionFilter->setConvolutionKernel(d->convolutionKernel, d->kernelWidth, d->kernelHeight); - convolutionFilter->d_func()->convoluteAlpha = d->convoluteAlpha; - convolutionFilter->draw(painter, p, src, srcRect); - return; - } - - // falling back to raster implementation + // raster implementation QImage *target = 0; if (painter->paintEngine()->paintDevice()->devType() == QInternal::Image) { @@ -925,16 +915,6 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap if (qt_scaleForTransform(painter->transform(), &scale)) scaledRadius /= scale; - QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter); - if (blurFilter) { - blurFilter->setRadius(scaledRadius); - blurFilter->setBlurHints(d->hints); - blurFilter->draw(painter, p, src, srcRect); - return; - } - QImage srcImage; QImage destImage; @@ -1095,17 +1075,7 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q if (src.isNull()) return; - QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter); - if (colorizeFilter) { - colorizeFilter->setColor(d->color); - colorizeFilter->setStrength(d->strength); - colorizeFilter->draw(painter, dest, src, srcRect); - return; - } - - // falling back to raster implementation + // raster implementation if (!d->opaque) { painter->drawPixmap(dest, src, srcRect); @@ -1329,17 +1299,6 @@ void QPixmapDropShadowFilter::draw(QPainter *p, if (px.isNull()) return; - QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ? - static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0; - QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter); - if (dropShadowFilter) { - dropShadowFilter->setColor(d->color); - dropShadowFilter->setBlurRadius(d->radius); - dropShadowFilter->setOffset(d->offset); - dropShadowFilter->draw(p, pos, px, src); - return; - } - QImage tmp(px.size(), QImage::Format_ARGB32_Premultiplied); tmp.fill(0); QPainter tmpPainter(&tmp); diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index 1beeb63a2cc..0e0c1588a11 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -565,7 +565,7 @@ void QGridLayoutPrivate::add(QGridBox *box, int row1, int row2, int col1, int co add(box, row1, col1); return; } - expand(row2 + 1, col2 + 1); + expand(qMax(row1, row2) + 1, qMax(col1, col2) + 1); box->row = row1; box->col = col1; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 73815113e49..6d896f5f507 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5229,6 +5229,9 @@ QGraphicsEffect *QWidget::graphicsEffect() const \note This function will apply the effect on itself and all its children. + \note Graphics effects are not supported for OpenGL-based widgets, such as QGLWidget, + QOpenGLWidget and QQuickWidget. + \since 4.6 \sa graphicsEffect() @@ -12271,7 +12274,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const { #ifndef QT_NO_GRAPHICSVIEW Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget) { + if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); if (!views.isEmpty()) { const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos); @@ -12306,7 +12309,7 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const { #ifndef QT_NO_GRAPHICSVIEW Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget) { + if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); if (!views.isEmpty()) { const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos); diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 6c7dc070d52..6b03ad0b6ca 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -651,7 +651,7 @@ void QWidgetWindow::handleScreenChange() void QWidgetWindow::repaintWindow() { - if (!m_widget->isVisible() || !m_widget->updatesEnabled()) + if (!m_widget->isVisible() || !m_widget->updatesEnabled() || !m_widget->rect().isValid()) return; QTLWExtra *tlwExtra = m_widget->window()->d_func()->maybeTopData(); diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 5a137dc41da..8589b6b5441 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -1737,8 +1737,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio state = QIcon::On; QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state); - int w = pixmap.width(); - int h = pixmap.height(); + int w = pixmap.width() / pixmap.devicePixelRatio(); + int h = pixmap.height() / pixmap.devicePixelRatio(); if (!button->text.isEmpty()) w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 2; @@ -1746,15 +1746,17 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio point = QPoint(ir.x() + ir.width() / 2 - w / 2, ir.y() + ir.height() / 2 - h / 2); + w = pixmap.width() / pixmap.devicePixelRatio(); + if (button->direction == Qt::RightToLeft) - point.rx() += pixmap.width(); + point.rx() += w; painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap); if (button->direction == Qt::RightToLeft) ir.translate(-point.x() - 2, 0); else - ir.translate(point.x() + pixmap.width(), 0); + ir.translate(point.x() + w, 0); // left-align text if there is if (!button->text.isEmpty()) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 3973534d832..394d06843b5 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1962,6 +1962,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD || bdi->kind == kThemeComboBoxSmall || bdi->kind == kThemeComboBoxMini; const bool button = opt->type == QStyleOption::SO_Button; + const bool viewItem = opt->type == QStyleOption::SO_ViewItem; const bool pressed = bdi->state == kThemeStatePressed; const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9; @@ -2002,6 +2003,8 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD HIRect newRect = CGRectMake(xoff, yoff, macRect.size.width, macRect.size.height); if (button && pressed) bdi->state = kThemeStateActive; + else if (usingYosemiteOrLater && viewItem) + bdi->state = kThemeStateInactive; HIThemeDrawButton(&newRect, bdi, cg, kHIThemeOrientationNormal, 0); } } @@ -2049,7 +2052,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD rect.adjust(0, 0, -5, 0); drawNSViewInRect(cw, bc, rect, p); return; - } else if (usingYosemiteOrLater && editableCombo) { + } else if (usingYosemiteOrLater && (editableCombo || viewItem)) { QImage image = activePixmap.toImage(); for (int y = 0; y < height; ++y) { diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index 448ede5ec3a..1ee69c76354 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -262,8 +262,11 @@ inline static bool waitForWindowExposed(QWindow *window, int timeout = 1000) void QSplashScreen::finish(QWidget *mainWin) { - if (mainWin && mainWin->windowHandle()) + if (mainWin) { + if (!mainWin->windowHandle()) + mainWin->createWinId(); waitForWindowExposed(mainWin->windowHandle()); + } close(); } |