summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-04-29 16:09:54 +0200
committerLiang Qi <liang.qi@qt.io>2016-04-29 17:55:20 +0200
commitb894a8def5d9107663e4968d2d395f5ef3059125 (patch)
treef894c50c9e5cbdd7ec102291eb94979977ce5b37 /src
parentd2304a28ca657634253af26ad803c7f292e6f4cc (diff)
parent002112e80516a29efbb6cef721d74c5fc39fc19d (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: mkspecs/features/qml_module.prf mkspecs/features/qt_common.prf src/gui/text/qzip.cpp src/plugins/platforms/cocoa/qnsview.mm src/plugins/platforms/windows/array.h src/testlib/qtestcase.cpp src/widgets/dialogs/qfilesystemmodel.h Change-Id: Ie41c5868415b81f7693c80e045497035504bb210
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qcompilerdetection.h17
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.h1
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qmetatype.h2
-rw-r--r--src/corelib/kernel/qobject.cpp6
-rw-r--r--src/corelib/tools/qarraydata.cpp13
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qstring.cpp14
-rw-r--r--src/corelib/tools/qvarlengtharray.h7
-rw-r--r--src/corelib/tools/qvector.h2
-rw-r--r--src/dbus/dbus_minimal_p.h2
-rw-r--r--src/dbus/qdbusconnection_p.h3
-rw-r--r--src/dbus/qdbusintegrator.cpp41
-rw-r--r--src/dbus/qdbusutil_p.h2
-rw-r--r--src/gui/kernel/qkeysequence.cpp2
-rw-r--r--src/gui/kernel/qkeysequence_p.h3
-rw-r--r--src/gui/painting/qpainter.cpp12
-rw-r--r--src/gui/painting/qpdf.cpp2
-rw-r--r--src/gui/text/qzip.cpp9
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp1
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp40
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm6
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp19
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp12
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp67
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp55
-rw-r--r--src/testlib/qtestcase.cpp15
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.h1
-rw-r--r--src/widgets/styles/qstyle.cpp4
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp2
-rw-r--r--src/widgets/widgets/qabstractslider.cpp5
-rw-r--r--src/widgets/widgets/qdatetimeedit_p.h15
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp2
-rw-r--r--src/widgets/widgets/qtextedit.cpp2
38 files changed, 265 insertions, 135 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 86d027eb35..a08fde8bb0 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -105,6 +105,12 @@
# endif
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
+# if _MSC_VER >= 1800
+# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x)
+# endif
+# if _MSC_VER >= 1500
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N))
+# endif
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
# if defined(__INTEL_COMPILER)
# define Q_DECL_VARIABLE_DEPRECATED
@@ -1106,6 +1112,11 @@
# define Q_ALIGNOF(x) alignof(x)
#endif
+#if defined(Q_COMPILER_ALIGNAS)
+# undef Q_DECL_ALIGN
+# define Q_DECL_ALIGN(n) alignas(n)
+#endif
+
/*
* Fallback macros to certain compiler features
*/
@@ -1174,6 +1185,12 @@
#ifndef Q_DECL_CONST_FUNCTION
# define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION
#endif
+#ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR
+# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x)
+#endif
+#ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR
+# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x)
+#endif
/*
* SG10's SD-6 feature detection and some useful extensions from Clang and GCC
diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h
index 7a75f42d81..e93740c1a2 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.h
+++ b/src/corelib/itemmodels/qidentityproxymodel.h
@@ -62,6 +62,7 @@ public:
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const Q_DECL_OVERRIDE;
QModelIndex mapToSource(const QModelIndex& proxyIndex) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE;
+ using QObject::parent;
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) Q_DECL_OVERRIDE;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 0c1c37c89d..7bb2e7a78c 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -419,7 +419,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
if (!isArgvModified(argc, argv)) {
origArgc = argc;
origArgv = new char *[argc];
- std::copy(argv, argv + argc, origArgv);
+ std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
}
#endif // Q_OS_WIN && !Q_OS_WINRT
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index ebe118dce4..b68dbacbd3 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1189,6 +1189,7 @@ public:
public:
template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p)
+ , _iterator(Q_NULLPTR)
, _metaType_id_key(qMetaTypeId<typename T::key_type>())
, _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
, _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
@@ -1208,6 +1209,7 @@ public:
QAssociativeIterableImpl()
: _iterable(Q_NULLPTR)
+ , _iterator(Q_NULLPTR)
, _metaType_id_key(QMetaType::UnknownType)
, _metaType_flags_key(0)
, _metaType_id_value(QMetaType::UnknownType)
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index fc5e6abf00..2b0eff3708 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2151,8 +2151,8 @@ void QObject::deleteLater()
Returns a translated version of \a sourceText, optionally based on a
\a disambiguation string and value of \a n for strings containing plurals;
- otherwise returns \a sourceText itself if no appropriate translated string
- is available.
+ otherwise returns QString::fromUtf8(\a sourceText) if no appropriate
+ translated string is available.
Example:
\snippet ../widgets/mainwindows/sdi/mainwindow.cpp implicit tr context
@@ -2178,7 +2178,7 @@ void QObject::deleteLater()
translators while performing translations is not supported. Doing
so will probably result in crashes or other undesirable behavior.
- \sa trUtf8(), QCoreApplication::translate(), {Internationalization with Qt}
+ \sa QCoreApplication::translate(), {Internationalization with Qt}
*/
/*!
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp
index 21ad799e25..bf336a8f31 100644
--- a/src/corelib/tools/qarraydata.cpp
+++ b/src/corelib/tools/qarraydata.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <QtCore/qarraydata.h>
+#include <QtCore/private/qnumeric_p.h>
#include <QtCore/private/qtools_p.h>
#include <stdlib.h>
@@ -93,16 +94,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
if (capacity > std::numeric_limits<size_t>::max() / objectSize)
return 0;
- size_t alloc = objectSize * capacity;
+ size_t alloc;
+ if (mul_overflow(objectSize, capacity, &alloc))
+ return 0;
- // Make sure qAllocMore won't overflow.
+ // Make sure qAllocMore won't overflow qAllocMore.
if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize)
return 0;
capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize);
}
- size_t allocSize = headerSize + objectSize * capacity;
+ size_t allocSize;
+ if (mul_overflow(objectSize, capacity, &allocSize))
+ return 0;
+ if (add_overflow(allocSize, headerSize, &allocSize))
+ return 0;
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
if (header) {
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 5509c3adce..ec279769eb 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -852,7 +852,7 @@ inline bool QList<T>::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou
const T *lb = reinterpret_cast<const T*>(l.p.begin());
const T *b = reinterpret_cast<const T*>(p.begin());
const T *e = reinterpret_cast<const T*>(p.end());
- return std::equal(b, e, lb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size()));
}
template <typename T>
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index c3aae2fd22..9f968978dc 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -712,8 +712,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
}
#define REHASH(a) \
- if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \
- hashHaystack -= (a) << sl_minus_1; \
+ if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \
+ hashHaystack -= uint(a) << sl_minus_1; \
hashHaystack <<= 1
inline bool qIsUpper(char ch)
@@ -3096,8 +3096,9 @@ int qFindString(
const ushort *needle = (const ushort *)needle0;
const ushort *haystack = (const ushort *)haystack0 + from;
const ushort *end = (const ushort *)haystack0 + (l-sl);
- const int sl_minus_1 = sl-1;
- int hashNeedle = 0, hashHaystack = 0, idx;
+ const uint sl_minus_1 = sl - 1;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
if (cs == Qt::CaseSensitive) {
for (idx = 0; idx < sl; ++idx) {
@@ -3172,10 +3173,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee
const ushort *end = haystack;
haystack += from;
- const int sl_minus_1 = sl-1;
+ const uint sl_minus_1 = sl - 1;
const ushort *n = needle+sl_minus_1;
const ushort *h = haystack+sl_minus_1;
- int hashNeedle = 0, hashHaystack = 0, idx;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
if (cs == Qt::CaseSensitive) {
for (idx = 0; idx < sl; ++idx) {
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 24574dc90b..c3ac104399 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -102,7 +102,8 @@ public:
QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list)
{
resize(list.size());
- std::copy(list.begin(), list.end(), this->begin());
+ std::copy(list.begin(), list.end(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size()));
return *this;
}
#endif
@@ -473,7 +474,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
int l = int(aend - ptr);
int n = l - f;
if (QTypeInfo<T>::isComplex) {
- std::copy(ptr + l, ptr + s, ptr + f);
+ std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f));
T *i = ptr + s;
T *b = ptr + s - n;
while (i != b) {
@@ -495,7 +496,7 @@ bool operator==(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T,
const T *rb = r.begin();
const T *b = l.begin();
const T *e = l.end();
- return std::equal(b, e, rb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(rb, r.size()));
}
template <typename T, int Prealloc1, int Prealloc2>
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 806a127cc2..557bec9676 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -773,7 +773,7 @@ bool QVector<T>::operator==(const QVector<T> &v) const
const T *vb = v.d->begin();
const T *b = d->begin();
const T *e = d->end();
- return std::equal(b, e, vb);
+ return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(vb, v.d->size));
}
template <typename T>
diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h
index 8b40742e0c..b52b0153e4 100644
--- a/src/dbus/dbus_minimal_p.h
+++ b/src/dbus/dbus_minimal_p.h
@@ -105,9 +105,11 @@ typedef dbus_uint32_t dbus_bool_t;
/* dbus-shared.h */
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
+#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index b2fa8faae8..f00988c05f 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -265,6 +265,8 @@ private:
QString getNameOwnerNoCache(const QString &service);
+ void watchForDBusDisconnection();
+
void _q_newConnection(QDBusConnectionPrivate *newConnection);
protected:
@@ -284,6 +286,7 @@ private slots:
void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner);
void registerServiceNoLock(const QString &serviceName);
void unregisterServiceNoLock(const QString &serviceName);
+ void handleDBusDisconnection();
signals:
void dispatchStatusChanged();
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index cc3080e6db..c73f808485 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1126,6 +1126,12 @@ void QDBusConnectionPrivate::closeConnection()
rootNode.children.clear(); // free resources
}
+void QDBusConnectionPrivate::handleDBusDisconnection()
+{
+ while (!pendingCalls.isEmpty())
+ processFinishedCall(pendingCalls.first());
+}
+
void QDBusConnectionPrivate::checkThread()
{
Q_ASSERT(thread() == QDBusConnectionManager::instance());
@@ -1651,6 +1657,19 @@ void QDBusConnectionPrivate::handleSignal(const QDBusMessage& msg)
handleSignal(key, msg); // third try
}
+void QDBusConnectionPrivate::watchForDBusDisconnection()
+{
+ SignalHook hook;
+ // Initialize the hook for Disconnected signal
+ hook.service.clear(); // org.freedesktop.DBus.Local.Disconnected uses empty service name
+ hook.path = QDBusUtil::dbusPathLocal();
+ hook.obj = this;
+ hook.params << QMetaType::Void;
+ hook.midx = staticMetaObject.indexOfSlot("handleDBusDisconnection()");
+ Q_ASSERT(hook.midx != -1);
+ signalHooks.insert(QLatin1String("Disconnected:" DBUS_INTERFACE_LOCAL), hook);
+}
+
void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const QDBusErrorInternal &error)
{
mode = ServerMode;
@@ -1716,6 +1735,8 @@ void QDBusConnectionPrivate::setPeer(DBusConnection *c, const QDBusErrorInternal
qDBusSignalFilter,
this, 0);
+ watchForDBusDisconnection();
+
QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection);
}
@@ -1792,6 +1813,8 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError
Q_ASSERT(hook.midx != -1);
signalHooks.insert(QLatin1String("NameOwnerChanged:" DBUS_INTERFACE_DBUS), hook);
+ watchForDBusDisconnection();
+
qDBusDebug() << this << ": connected successfully";
// schedule a dispatch:
@@ -1818,10 +1841,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
QDBusMessage &msg = call->replyMessage;
if (call->pending) {
- // decode the message
- DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
- msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
- q_dbus_message_unref(reply);
+ // when processFinishedCall is called and pending call is not completed,
+ // it means we received disconnected signal from libdbus
+ if (q_dbus_pending_call_get_completed(call->pending)) {
+ // decode the message
+ DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
+ msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
+ q_dbus_message_unref(reply);
+ } else {
+ msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
+ }
}
qDBusDebug() << connection << "got message reply:" << msg;
@@ -2121,8 +2150,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void *
pcall->pending = pending;
q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
- // DBus won't notify us when a peer disconnects so we need to track these ourselves
- if (mode == QDBusConnectionPrivate::PeerMode)
+ // DBus won't notify us when a peer disconnects or server terminates so we need to track these ourselves
+ if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode)
pendingCalls.append(pcall);
return;
diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h
index e0ba92be2e..e11fe573b5 100644
--- a/src/dbus/qdbusutil_p.h
+++ b/src/dbus/qdbusutil_p.h
@@ -164,6 +164,8 @@ namespace QDBusUtil
{ return QStringLiteral(DBUS_SERVICE_DBUS); }
inline QString dbusPath()
{ return QStringLiteral(DBUS_PATH_DBUS); }
+ inline QString dbusPathLocal()
+ { return QStringLiteral(DBUS_PATH_LOCAL); }
inline QString dbusInterface()
{
// it's the same string, but just be sure
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 8a6eeb4cc9..8ccd85795b 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1643,7 +1643,7 @@ QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
s >> keys[i];
}
qAtomicDetach(keysequence.d);
- std::copy(keys, keys + MaxKeys, keysequence.d->key);
+ std::copy(keys, keys + MaxKeys, QT_MAKE_CHECKED_ARRAY_ITERATOR(keysequence.d->key, MaxKeys));
return s;
}
diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h
index eeea0f5772..116e91c0cd 100644
--- a/src/gui/kernel/qkeysequence_p.h
+++ b/src/gui/kernel/qkeysequence_p.h
@@ -76,7 +76,8 @@ public:
}
inline QKeySequencePrivate(const QKeySequencePrivate &copy) : ref(1)
{
- std::copy(copy.key, copy.key + MaxKeyCount, key);
+ std::copy(copy.key, copy.key + MaxKeyCount,
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(key, MaxKeyCount));
}
QAtomicInt ref;
int key[MaxKeyCount];
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index bcef14ca61..0b205b8b0e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6183,7 +6183,8 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
QString key = QLatin1String("WaveUnderline-")
% pen.color().name()
- % HexString<qreal>(radiusBase);
+ % HexString<qreal>(radiusBase)
+ % HexString<qreal>(pen.widthF());
QPixmap pixmap;
if (QPixmapCache::find(key, pixmap))
@@ -6191,7 +6192,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
- const int radius = qFloor(radiusBase);
+ const qreal radius = qFloor(radiusBase * 2) / 2.;
QPainterPath path;
@@ -6214,7 +6215,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
// due to it having a rather thick width for the regular underline.
const qreal maxPenWidth = .8 * radius;
if (wavePen.widthF() > maxPenWidth)
- wavePen.setWidth(maxPenWidth);
+ wavePen.setWidthF(maxPenWidth);
QPainter imgPainter(&pixmap);
imgPainter.setPen(wavePen);
@@ -6267,14 +6268,15 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
if (underlineStyle == QTextCharFormat::WaveUnderline) {
painter->save();
painter->translate(0, pos.y() + 1);
+ qreal maxHeight = fe->descent().toReal() - qreal(1);
QColor uc = charFormat.underlineColor();
if (uc.isValid())
pen.setColor(uc);
// Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
- const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
- const int descent = (int) fe->descent().toReal();
+ const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()), maxHeight / 2.), pen);
+ const int descent = qFloor(maxHeight);
painter->setBrushOrigin(painter->brushOrigin().x(), 0);
painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 8189351bd8..9e38c5272f 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1202,7 +1202,7 @@ void QPdfEngine::setPen()
switch(d->pen.joinStyle()) {
case Qt::MiterJoin:
case Qt::SvgMiterJoin:
- *d->currentPage << d->pen.miterLimit() << "M ";
+ *d->currentPage << qMax(qreal(1.0), d->pen.miterLimit()) << "M ";
pdfJoinStyle = 0;
break;
case Qt::BevelJoin:
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index 5178f5a9a8..7cb89543ba 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -822,12 +822,12 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode)
{
QScopedPointer<QFile> f(new QFile(archive));
- f->open(mode);
+ const bool result = f->open(mode);
QZipReader::Status status;
const QFileDevice::FileError error = f->error();
- if (error == QFile::NoError)
+ if (result && error == QFile::NoError) {
status = NoError;
- else {
+ } else {
if (error == QFile::ReadError)
status = FileReadError;
else if (error == QFile::OpenError)
@@ -1119,9 +1119,8 @@ void QZipReader::close()
QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode)
{
QScopedPointer<QFile> f(new QFile(fileName));
- f->open(mode);
QZipWriter::Status status;
- if (f->error() == QFile::NoError)
+ if (f->open(mode) && f->error() == QFile::NoError)
status = QZipWriter::NoError;
else {
if (f->error() == QFile::WriteError)
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 67b4550607..45caaffe75 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -287,7 +287,6 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx)
qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem();
qCDebug(lcSsl) << "dumping chain";
foreach (QSslCertificate cert, QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx))) {
- QString certFormat(QStringLiteral("O=%1 CN=%2 L=%3 OU=%4 C=%5 ST=%6"));
qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
<< "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
<< "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index b288a05e32..652a9f4add 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -69,12 +69,6 @@ static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper,
return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
}
-static inline bool requiresOpenType(int writingSystem)
-{
- return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
-}
-
static inline int weightFromFcWeight(int fcweight)
{
// Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
@@ -300,10 +294,10 @@ static const char *languageForWritingSystem[] = {
Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
#if FC_VERSION >= 20297
-// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
-// open type tables for is directly. Do this so we don't pick some strange
-// pseudo unicode font
-static const char *openType[] = {
+// Newer FontConfig let's us sort out fonts that report certain scripts support,
+// but no open type tables for handling them correctly.
+// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
+static const char *capabilityForWritingSystem[] = {
0, // Any
0, // Latin
0, // Greek
@@ -339,7 +333,7 @@ static const char *openType[] = {
0, // Runic
"nko " // N'Ko
};
-Q_STATIC_ASSERT(sizeof(openType) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
+Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
#endif
static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
@@ -422,11 +416,23 @@ static void populateFromPattern(FcPattern *pattern)
FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
if (res == FcResultMatch) {
bool hasLang = false;
+#if FC_VERSION >= 20297
+ FcChar8 *cap = Q_NULLPTR;
+ FcResult capRes = FcResultNoMatch;
+#endif
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
if (lang) {
FcLangResult langRes = FcLangSetHasLang(langset, lang);
if (langRes != FcLangDifferentLang) {
+#if FC_VERSION >= 20297
+ if (capabilityForWritingSystem[j] != Q_NULLPTR) {
+ if (cap == Q_NULLPTR)
+ capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
+ if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0)
+ continue;
+ }
+#endif
writingSystems.setSupported(QFontDatabase::WritingSystem(j));
hasLang = true;
}
@@ -442,18 +448,6 @@ static void populateFromPattern(FcPattern *pattern)
writingSystems.setSupported(QFontDatabase::Other);
}
-#if FC_VERSION >= 20297
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
FontFile *fontFile = new FontFile;
fontFile->fileName = QString::fromLocal8Bit((const char *)file_value);
fontFile->indexValue = indexValue;
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 0690a8e0fa..a388155c03 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -105,7 +105,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
{
Q_ASSERT(m_menu->nsMenu() == menu);
- return m_menu->items().count();
+ return menu.numberOfItems;
}
- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 908277a1e3..697cece77f 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -747,8 +747,7 @@ QT_WARNING_POP
- (void)handleMouseEvent:(NSEvent *)theEvent
{
- if ([self handleTabletEvent: theEvent])
- return;
+ bool isTabletEvent = [self handleTabletEvent: theEvent];
QPointF qtWindowPoint;
QPointF qtScreenPoint;
@@ -777,7 +776,8 @@ QT_WARNING_POP
nativeDrag->setLastMouseEvent(theEvent, self);
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
+ QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers,
+ isTabletEvent ? Qt::MouseEventSynthesizedByQt : Qt::MouseEventNotSynthesized);
}
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index f34649e327..5ba49a8a98 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -45,6 +45,7 @@
#include <QtGui/qaccessible.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/qdebug.h>
#include <algorithm>
@@ -607,7 +608,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex
// The IDL documents that the client must free with CoTaskMemFree
arrayOfBindingsToReturn = coTaskMemAllocArray<BSTR>(numBindings);
std::transform(keyBindings.constBegin(), keyBindings.constEnd(),
- arrayOfBindingsToReturn, QStringToBSTR);
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(arrayOfBindingsToReturn, numBindings),
+ QStringToBSTR);
}
}
*keyBindings = arrayOfBindingsToReturn;
@@ -666,9 +668,11 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, l
QAccessibleInterface *parentIface = accessible->parent();
if (parentIface && parentIface->isValid())
topLeft -= parentIface->rect().topLeft();
+ const QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, accessible->window());
- *x = topLeft.x();
- *y = topLeft.y();
+
+ *x = nativeTopLeft.x();
+ *y = nativeTopLeft.y();
return S_OK;
}
@@ -989,7 +993,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele
*selectedColumns = Q_NULLPTR;
if (count) {
*selectedColumns = coTaskMemAllocArray<long>(count);
- std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns);
+ std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedColumns, count));
}
return count ? S_OK : S_FALSE;
}
@@ -1011,7 +1016,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte
*selectedRows = Q_NULLPTR;
if (count) {
*selectedRows = coTaskMemAllocArray<long>(count);
- std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows);
+ std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(),
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedRows, count));
}
return count ? S_OK : S_FALSE;
}
@@ -1680,7 +1686,8 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface*
if (count) {
*outputAccessibles = coTaskMemAllocArray<IUnknown *>(count);
std::transform(inputCells.constBegin(), inputCells.constEnd(),
- *outputAccessibles, QWindowsAccessibility::wrap);
+ QT_MAKE_CHECKED_ARRAY_ITERATOR(*outputAccessibles, count),
+ QWindowsAccessibility::wrap);
}
return count > 0 ? S_OK : S_FALSE;
}
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 0fff804e29..5fb06a6ed1 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -55,6 +55,7 @@
#include <QtGui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/qwindow.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
//#include <uiautomationcoreapi.h>
#ifndef UiaRootObjectId
@@ -503,7 +504,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT
if (!accessible)
return E_FAIL;
- QAccessibleInterface *child = accessible->childAt(xLeft, yTop);
+ const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window());
+ QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y());
if (child == 0) {
// no child found, return this item if it contains the coordinates
if (accessible->rect().contains(xLeft, yTop)) {
@@ -545,7 +547,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long
QAccessibleInterface *acc = childPointer(accessible, varID);
if (!acc || !acc->isValid())
return E_FAIL;
- const QRect rect = acc->rect();
+ const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window());
*pxLeft = rect.x();
*pyTop = rect.y();
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index ea68ba8cab..501b956a68 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -654,7 +654,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1);
std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(),
- pastReconv);
+ QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv));
return memSize;
}
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
index ad81ef4f5f..53e7ebd30d 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -466,14 +466,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
- hr = QWinRTFunctions::await(op, buffer.GetAddressOf());
+ // Quoting MSDN IInputStream::ReadAsync() documentation:
+ // "Depending on the implementation, the data that's read might be placed
+ // into the input buffer, or it might be returned in a different buffer."
+ // Using GetAddressOf can cause ref counting errors leaking the original
+ // buffer.
+ ComPtr<IBuffer> effectiveBuffer;
+ hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf());
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
- hr = buffer->get_Length(&length);
+ hr = effectiveBuffer->get_Length(&length);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
- hr = buffer.As(&byteArrayAccess);
+ hr = effectiveBuffer.As(&byteArrayAccess);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
byte *bytes;
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index f3667aaa0d..aed33f6b48 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -955,8 +955,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
return S_OK;
}
-HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *)
+HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
{
+ Q_D(QWinRTScreen);
+
+ ComPtr<IPointerPoint> pointerPoint;
+ if (FAILED(args->get_CurrentPoint(&pointerPoint)))
+ return E_INVALIDARG;
+
+ quint32 id;
+ if (FAILED(pointerPoint->get_PointerId(&id)))
+ return E_INVALIDARG;
+
+ d->touchPoints.remove(id);
+
QWindowSystemInterface::handleLeaveEvent(0);
return S_OK;
}
@@ -1040,6 +1052,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
break;
}
+ case PointerDeviceType_Pen:
case PointerDeviceType_Touch: {
if (!d->touchDevice) {
d->touchDevice = new QTouchDevice;
@@ -1058,51 +1071,45 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
float pressure;
properties->get_Pressure(&pressure);
- QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
- if (it != d->touchPoints.end()) {
- boolean isPressed;
+ boolean isPressed;
#ifndef Q_OS_WINPHONE
- pointerPoint->get_IsInContact(&isPressed);
+ pointerPoint->get_IsInContact(&isPressed);
#else
- properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
+ properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
#endif
- it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
- } else {
+
+ const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor,
+ area.Width * d->scaleFactor, area.Height * d->scaleFactor);
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
+ if (it == d->touchPoints.end()) {
it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
- it.value().state = Qt::TouchPointPressed;
it.value().id = id;
}
- it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor,
- area.Width * d->scaleFactor, area.Height * d->scaleFactor);
+
+ if (isPressed && it.value().pressure == 0.)
+ it.value().state = Qt::TouchPointPressed;
+ else if (!isPressed && it.value().pressure > 0.)
+ it.value().state = Qt::TouchPointReleased;
+ else if (it.value().area == areaRect)
+ it.value().state = Qt::TouchPointStationary;
+ else
+ it.value().state = Qt::TouchPointMoved;
+
+ it.value().area = areaRect;
it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height());
it.value().pressure = pressure;
QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods);
- // Remove released points, station others
- for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) {
- if (i.value().state == Qt::TouchPointReleased)
- i = d->touchPoints.erase(i);
- else
- (i++).value().state = Qt::TouchPointStationary;
- }
-
- break;
- }
- case PointerDeviceType_Pen: {
- quint32 id;
- pointerPoint->get_PointerId(&id);
-
- boolean isPressed;
- pointerPoint->get_IsInContact(&isPressed);
+ // Fall-through for pen to generate tablet event
+ if (pointerDeviceType != PointerDeviceType_Pen)
+ break;
boolean isEraser;
properties->get_IsEraser(&isEraser);
int pointerType = isEraser ? 3 : 1;
- float pressure;
- properties->get_Pressure(&pressure);
-
float xTilt;
properties->get_XTilt(&xTilt);
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index ea20ef7a04..1c9faa17ea 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -1078,6 +1078,40 @@ void QXcbDrag::cancel()
send_leave();
}
+// find an ancestor with XdndAware on it
+static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
+{
+ xcb_window_t target = 0;
+ forever {
+ // check if window has XdndAware
+ xcb_get_property_cookie_t gpCookie = Q_XCB_CALL(
+ xcb_get_property(c->xcb_connection(), false, window,
+ c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
+ xcb_get_property_reply_t *gpReply = xcb_get_property_reply(
+ c->xcb_connection(), gpCookie, 0);
+ bool aware = gpReply && gpReply->type != XCB_NONE;
+ free(gpReply);
+ if (aware) {
+ target = window;
+ break;
+ }
+
+ // try window's parent
+ xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL(
+ xcb_query_tree_unchecked(c->xcb_connection(), window));
+ xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply(
+ c->xcb_connection(), qtCookie, NULL);
+ if (!qtReply)
+ break;
+ xcb_window_t root = qtReply->root;
+ xcb_window_t parent = qtReply->parent;
+ free(qtReply);
+ if (window == root)
+ break;
+ window = parent;
+ }
+ return target;
+}
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
{
@@ -1105,17 +1139,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
// xcb_convert_selection() that we sent the XdndDrop event to.
at = findTransactionByWindow(event->requestor);
}
-// if (at == -1 && event->time == XCB_CURRENT_TIME) {
-// // previous Qt versions always requested the data on a child of the target window
-// // using CurrentTime... but it could be asking for either drop data or the current drag's data
-// Window target = findXdndAwareParent(event->requestor);
-// if (target) {
-// if (current_target && current_target == target)
-// at = -2;
-// else
-// at = findXdndDropTransactionByWindow(target);
-// }
-// }
+
+ if (at == -1 && event->time == XCB_CURRENT_TIME) {
+ xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
+ if (target) {
+ if (current_target == target)
+ at = -2;
+ else
+ at = findTransactionByWindow(target);
+ }
+ }
}
QDrag *transactionDrag = 0;
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index f4f758df6c..dcd1268f6f 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -239,6 +239,7 @@ namespace QTest
static int keyDelay = -1;
static int mouseDelay = -1;
static int eventDelay = -1;
+ static int timeout = -1;
static bool noCrashHandler = false;
/*! \internal
@@ -290,6 +291,18 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
+static int defaultTimeout()
+{
+ if (timeout == -1) {
+ bool ok = false;
+ timeout = qEnvironmentVariableIntValue("QTEST_FUNCTION_TIMEOUT", &ok);
+
+ if (!ok || timeout <= 0)
+ timeout = 5*60*1000;
+ }
+ return timeout;
+}
+
Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
Q_TESTLIB_EXPORT QStringList testFunctions;
Q_TESTLIB_EXPORT QStringList testTags;
@@ -867,7 +880,7 @@ public:
void beginTest() {
QMutexLocker locker(&mutex);
- timeout.store(5*60*1000);
+ timeout.store(defaultTimeout());
waitCondition.wakeAll();
}
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index d9b6dc05bf..1cf2d2b05e 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -3596,7 +3596,7 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
}
} else {
// Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE)
- if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)
+ if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, Q_NULLPTR, qFileDialogUi->treeView)
|| q->fileMode() != QFileDialog::ExistingFiles || !(QGuiApplication::keyboardModifiers() & Qt::CTRL)) {
q->accept();
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h
index b7e77f31db..6d50d0b606 100644
--- a/src/widgets/dialogs/qfilesystemmodel.h
+++ b/src/widgets/dialogs/qfilesystemmodel.h
@@ -81,6 +81,7 @@ public:
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex index(const QString &path, int column = 0) const;
QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE;
+ using QObject::parent;
QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 103c49496e..3e17b22102 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -157,10 +157,10 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
Qt's built-in widgets use QStyle to perform nearly all of their
drawing, ensuring that they look exactly like the equivalent
- native widgets. The diagram below shows a QComboBox in eight
+ native widgets. The diagram below shows a QComboBox in nine
different styles.
- \image qstyle-comboboxes.png Eight combo boxes
+ \image qstyle-comboboxes.png Nine combo boxes
Topics:
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 2ad9f88e6b..1482b990a6 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -310,7 +310,7 @@ void QAbstractScrollAreaPrivate::init()
viewportFilter.reset(new QAbstractScrollAreaFilter(this));
viewport->installEventFilter(viewportFilter.data());
viewport->setFocusProxy(q);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index 3f6185b4e7..4221ff40ef 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -734,9 +734,10 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb
if (stepsToScroll == 0) {
// We moved less than a line, but might still have accumulated partial scroll,
// unless we already are at one of the ends.
- if (offset_accumulated > 0.f && value < maximum)
+ const float effective_offset = invertedControls ? -offset_accumulated : offset_accumulated;
+ if (effective_offset > 0.f && value < maximum)
return true;
- if (offset_accumulated < 0.f && value > minimum)
+ if (effective_offset < 0.f && value > minimum)
return true;
offset_accumulated = 0;
return false;
diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h
index 6abb3cd9a3..be7bc213a2 100644
--- a/src/widgets/widgets/qdatetimeedit_p.h
+++ b/src/widgets/widgets/qdatetimeedit_p.h
@@ -78,15 +78,14 @@ public:
void init(const QVariant &var);
void readLocaleSettings();
- void emitSignals(EmitPolicy ep, const QVariant &old);
- QString textFromValue(const QVariant &f) const;
- QVariant valueFromText(const QString &f) const;
-
QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state,
bool fixup = false) const;
void clearSection(int index);
// Override QAbstractSpinBoxPrivate:
+ void emitSignals(EmitPolicy ep, const QVariant &old) Q_DECL_OVERRIDE;
+ QString textFromValue(const QVariant &f) const Q_DECL_OVERRIDE;
+ QVariant valueFromText(const QString &f) const Q_DECL_OVERRIDE;
void _q_editorCursorPositionChanged(int oldpos, int newpos) Q_DECL_OVERRIDE;
void interpret(EmitPolicy ep) Q_DECL_OVERRIDE;
void clearCache() const Q_DECL_OVERRIDE;
@@ -94,16 +93,18 @@ public:
void updateEditFieldGeometry() Q_DECL_OVERRIDE;
QVariant getZeroVariant() const Q_DECL_OVERRIDE;
void setRange(const QVariant &min, const QVariant &max) Q_DECL_OVERRIDE;
+ void updateEdit() Q_DECL_OVERRIDE;
- // Override QDateTimePraser:
+ // Override QDateTimeParser:
QString displayText() const Q_DECL_OVERRIDE { return edit->text(); }
QDateTime getMinimum() const Q_DECL_OVERRIDE { return minimum.toDateTime(); }
QDateTime getMaximum() const Q_DECL_OVERRIDE { return maximum.toDateTime(); }
QLocale locale() const Q_DECL_OVERRIDE { return q_func()->locale(); }
+ QString getAmPmText(AmPm ap, Case cs) const Q_DECL_OVERRIDE;
+ int cursorPosition() const Q_DECL_OVERRIDE { return edit ? edit->cursorPosition() : -1; }
int absoluteIndex(QDateTimeEdit::Section s, int index) const;
int absoluteIndex(const SectionNode &s) const;
- void updateEdit();
QDateTime stepBy(int index, int steps, bool test = false) const;
int sectionAt(int pos) const;
int closestSection(int index, bool forward) const;
@@ -114,8 +115,6 @@ public:
void updateTimeSpec();
QString valueToText(const QVariant &var) const { return textFromValue(var); }
- QString getAmPmText(AmPm ap, Case cs) const;
- int cursorPosition() const { return edit ? edit->cursorPosition() : -1; }
void _q_resetButton();
void updateArrow(QStyle::StateFlag state);
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 1da8028efb..9675e5e9f2 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -802,7 +802,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_KeyCompression);
q->setAttribute(Qt::WA_InputMethodEnabled);
q->setInputMethodHints(Qt::ImhMultiLine);
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index a81781bd4d..df69b49687 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -177,7 +177,7 @@ void QTextEditPrivate::init(const QString &html)
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_KeyCompression);
q->setAttribute(Qt::WA_InputMethodEnabled);
q->setInputMethodHints(Qt::ImhMultiLine);