Merge remote-tracking branch 'origin/5.9' into dev

Change-Id: I7d84cfed0b2a122d334b8a920e6e4f18472d2f11
This commit is contained in:
Liang Qi 2017-02-28 13:03:36 +01:00
commit 1a4f0deeb4
67 changed files with 678 additions and 238 deletions

View File

@ -56,7 +56,6 @@
"android-sdk": "string",
"android-toolchain-version": "string",
"accessibility": "boolean",
"android-style-assets": "boolean",
"appstore-compliant": "boolean",
"avx": "boolean",
@ -941,10 +940,6 @@
"condition": "config.qnx && tests.stack_protector",
"output": [ "publicQtConfig" ]
},
"accessibility": {
"label": "Accessibility",
"output": [ "publicFeature", "feature" ]
},
"system-zlib": {
"label": "Using system zlib",
"condition": "libs.zlib",
@ -1106,11 +1101,6 @@ or compile needed modules into the library."
"message": "Qt is using double for qreal on this system. This is binary-incompatible against Qt 5.1.
Configure with '-qreal float' to create a build that is binary-compatible with 5.1."
},
{
"type": "warning",
"condition": "!features.accessibility",
"message": "Accessibility disabled. This configuration of Qt is unsupported."
},
{
"type": "error",
"condition": "!features.stl",
@ -1217,7 +1207,6 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
}, {
"section": "Support enabled for",
"entries": [
"accessibility",
"pkg-config",
"qml-debug",
"libudev",

View File

@ -1,5 +1,5 @@
CONFIG(release, debug|release):DEFINES *= NDEBUG
DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_RTREE
DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
qtConfig(posix_fallocate): DEFINES += HAVE_POSIX_FALLOCATE=1
winrt: DEFINES += SQLITE_OS_WINRT

View File

@ -58,9 +58,10 @@ class QTypeInfo
{
public:
enum {
isSpecialized = std::is_enum<T>::value, // don't require every enum to be marked manually
isPointer = false,
isIntegral = std::is_integral<T>::value,
isComplex = true,
isComplex = !isIntegral && !std::is_enum<T>::value,
isStatic = true,
isRelocatable = std::is_enum<T>::value,
isLarge = (sizeof(T)>sizeof(void*)),
@ -74,6 +75,7 @@ class QTypeInfo<void>
{
public:
enum {
isSpecialized = true,
isPointer = false,
isIntegral = false,
isComplex = false,
@ -90,6 +92,7 @@ class QTypeInfo<T*>
{
public:
enum {
isSpecialized = true,
isPointer = true,
isIntegral = false,
isComplex = false,
@ -152,6 +155,7 @@ class QTypeInfoMerger
{
public:
enum {
isSpecialized = true,
isComplex = QTypeInfoQuery<T1>::isComplex || QTypeInfoQuery<T2>::isComplex
|| QTypeInfoQuery<T3>::isComplex || QTypeInfoQuery<T4>::isComplex,
isStatic = QTypeInfoQuery<T1>::isStatic || QTypeInfoQuery<T2>::isStatic
@ -173,6 +177,7 @@ class QTypeInfo< CONTAINER<T> > \
{ \
public: \
enum { \
isSpecialized = true, \
isPointer = false, \
isIntegral = false, \
isComplex = true, \
@ -201,6 +206,7 @@ class QTypeInfo< CONTAINER<K, V> > \
{ \
public: \
enum { \
isSpecialized = true, \
isPointer = false, \
isIntegral = false, \
isComplex = true, \
@ -241,6 +247,7 @@ class QTypeInfo<TYPE > \
{ \
public: \
enum { \
isSpecialized = true, \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \
isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \

View File

@ -143,21 +143,17 @@ public:
}
bool operator==(const QArgumentType &other) const
{
if (_type)
if (_type && other._type)
return _type == other._type;
else if (other._type)
return false;
else
return _name == other._name;
return name() == other.name();
}
bool operator!=(const QArgumentType &other) const
{
if (_type)
if (_type && other._type)
return _type != other._type;
else if (other._type)
return true;
else
return _name != other._name;
return name() != other.name();
}
private:

View File

@ -316,22 +316,39 @@ void QThreadPoolPrivate::clear()
}
/*!
\internal
Searches for \a runnable in the queue, removes it from the queue and
returns \c true if it was found in the queue
\since 5.9
Attempts to remove the specified \a runnable from the queue if it is not yet started.
If the runnable had not been started, returns \c true, and ownership of \a runnable
is transferred to the caller (even when \c{runnable->autoDelete() == true}).
Otherwise returns \c false.
\note If \c{runnable->autoDelete() == true}, this function may remove the wrong
runnable. This is known as the \l{https://en.wikipedia.org/wiki/ABA_problem}{ABA problem}:
the original \a runnable may already have executed and has since been deleted.
The memory is re-used for another runnable, which then gets removed instead of
the intended one. For this reason, we recommend calling this function only for
runnables that are not auto-deleting.
\sa start(), QRunnable::autoDelete()
*/
bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable)
bool QThreadPool::tryTake(QRunnable *runnable)
{
Q_D(QThreadPool);
if (runnable == 0)
return false;
{
QMutexLocker locker(&mutex);
QVector<QPair<QRunnable *, int> >::iterator it = queue.begin();
QVector<QPair<QRunnable *, int> >::iterator end = queue.end();
QMutexLocker locker(&d->mutex);
auto it = d->queue.begin();
auto end = d->queue.end();
while (it != end) {
if (it->first == runnable) {
queue.erase(it);
d->queue.erase(it);
if (runnable->autoDelete())
--runnable->ref; // undo ++ref in start()
return true;
}
++it;
@ -349,10 +366,10 @@ bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable)
*/
void QThreadPoolPrivate::stealAndRunRunnable(QRunnable *runnable)
{
if (!stealRunnable(runnable))
Q_Q(QThreadPool);
if (!q->tryTake(runnable))
return;
const bool autoDelete = runnable->autoDelete();
bool del = autoDelete && !--runnable->ref;
const bool del = runnable->autoDelete() && !runnable->ref; // tryTake already deref'ed
runnable->run();
@ -642,24 +659,23 @@ void QThreadPool::clear()
d->clear();
}
#if QT_DEPRECATED_SINCE(5, 9)
/*!
\since 5.5
\obsolete use tryTake() instead, but note the different deletion rules.
Removes the specified \a runnable from the queue if it is not yet started.
The runnables for which \l{QRunnable::autoDelete()}{runnable->autoDelete()}
returns \c true are deleted.
\sa start()
\sa start(), tryTake()
*/
void QThreadPool::cancel(QRunnable *runnable)
{
Q_D(QThreadPool);
if (!d->stealRunnable(runnable))
return;
if (runnable->autoDelete() && !--runnable->ref) {
if (tryTake(runnable) && runnable->autoDelete() && !runnable->ref) // tryTake already deref'ed
delete runnable;
}
}
#endif
QT_END_NAMESPACE

View File

@ -83,7 +83,12 @@ public:
bool waitForDone(int msecs = -1);
void clear();
#if QT_DEPRECATED_SINCE(5, 9)
QT_DEPRECATED_X("use tryTake(), but note the different deletion rules")
void cancel(QRunnable *runnable);
#endif
bool tryTake(QRunnable *runnable) Q_REQUIRED_RESULT;
};
QT_END_NAMESPACE

View File

@ -82,7 +82,6 @@ public:
void reset();
bool waitForDone(int msecs);
void clear();
bool stealRunnable(QRunnable *runnable);
void stealAndRunRunnable(QRunnable *runnable);
mutable QMutex mutex;

View File

@ -145,7 +145,7 @@ struct QGenericArrayOps
T *const begin = this->begin();
do {
new (begin + this->size) T();
new (begin + this->size) T;
} while (uint(++this->size) != newSize);
}
@ -412,7 +412,7 @@ struct QArrayOpsSelector
template <class T>
struct QArrayOpsSelector<T,
typename std::enable_if<
!QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic
!QTypeInfoQuery<T>::isComplex && QTypeInfoQuery<T>::isRelocatable
>::type>
{
typedef QPodArrayOps<T> Type;
@ -421,7 +421,7 @@ struct QArrayOpsSelector<T,
template <class T>
struct QArrayOpsSelector<T,
typename std::enable_if<
QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic
QTypeInfoQuery<T>::isComplex && QTypeInfoQuery<T>::isRelocatable
>::type>
{
typedef QMovableArrayOps<T> Type;

View File

@ -132,6 +132,9 @@ private:
}
};
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4351) // MSVC 2013: "new behavior: elements of array ... will be default initialized"
// remove once we drop MSVC 2013 support
template <uint N>
class QStaticByteArrayMatcher : QStaticByteArrayMatcherBase
{
@ -153,6 +156,8 @@ public:
QByteArray pattern() const { return QByteArray(m_pattern, int(N - 1)); }
};
QT_WARNING_POP
template <uint N>
Q_DECL_RELAXED_CONSTEXPR QStaticByteArrayMatcher<N> qMakeStaticByteArrayMatcher(const char (&pattern)[N]) Q_DECL_NOTHROW
{ return QStaticByteArrayMatcher<N>(pattern); }

View File

@ -126,6 +126,7 @@ class QList
public:
struct MemoryLayout
: std::conditional<
// must stay isStatic until ### Qt 6 for BC reasons (don't use !isRelocatable)!
QTypeInfo<T>::isStatic || QTypeInfo<T>::isLarge,
QListData::IndirectLayout,
typename std::conditional<

View File

@ -136,7 +136,7 @@ QTimeZonePrivate::~QTimeZonePrivate()
{
}
QTimeZonePrivate *QTimeZonePrivate::clone()
QTimeZonePrivate *QTimeZonePrivate::clone() const
{
return new QTimeZonePrivate(*this);
}
@ -784,7 +784,7 @@ QUtcTimeZonePrivate::~QUtcTimeZonePrivate()
{
}
QTimeZonePrivate *QUtcTimeZonePrivate::clone()
QUtcTimeZonePrivate *QUtcTimeZonePrivate::clone() const
{
return new QUtcTimeZonePrivate(*this);
}

View File

@ -88,7 +88,7 @@ void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
m_id = ianaId;
}
QTimeZonePrivate *QAndroidTimeZonePrivate::clone()
QAndroidTimeZonePrivate *QAndroidTimeZonePrivate::clone() const
{
return new QAndroidTimeZonePrivate(*this);
}

View File

@ -305,7 +305,7 @@ QIcuTimeZonePrivate::~QIcuTimeZonePrivate()
ucal_close(m_ucal);
}
QTimeZonePrivate *QIcuTimeZonePrivate::clone()
QIcuTimeZonePrivate *QIcuTimeZonePrivate::clone() const
{
return new QIcuTimeZonePrivate(*this);
}

View File

@ -82,7 +82,7 @@ QMacTimeZonePrivate::~QMacTimeZonePrivate()
[m_nstz release];
}
QTimeZonePrivate *QMacTimeZonePrivate::clone()
QMacTimeZonePrivate *QMacTimeZonePrivate::clone() const
{
return new QMacTimeZonePrivate(*this);
}

View File

@ -92,7 +92,7 @@ public:
QTimeZonePrivate(const QTimeZonePrivate &other);
virtual ~QTimeZonePrivate();
virtual QTimeZonePrivate *clone();
virtual QTimeZonePrivate *clone() const;
bool operator==(const QTimeZonePrivate &other) const;
bool operator!=(const QTimeZonePrivate &other) const;
@ -187,7 +187,7 @@ public:
QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other);
virtual ~QUtcTimeZonePrivate();
QTimeZonePrivate *clone() Q_DECL_OVERRIDE;
QUtcTimeZonePrivate *clone() const override;
Data data(qint64 forMSecsSinceEpoch) const Q_DECL_OVERRIDE;
@ -234,7 +234,7 @@ public:
QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other);
~QIcuTimeZonePrivate();
QTimeZonePrivate *clone() Q_DECL_OVERRIDE;
QIcuTimeZonePrivate *clone() const override;
QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
const QLocale &locale) const Q_DECL_OVERRIDE;
@ -287,15 +287,15 @@ Q_DECL_CONSTEXPR inline bool operator!=(const QTzTransitionRule &lhs, const QTzT
class Q_AUTOTEST_EXPORT QTzTimeZonePrivate Q_DECL_FINAL : public QTimeZonePrivate
{
QTzTimeZonePrivate(const QTzTimeZonePrivate &) = default;
public:
// Create default time zone
QTzTimeZonePrivate();
// Create named time zone
QTzTimeZonePrivate(const QByteArray &ianaId);
QTzTimeZonePrivate(const QTzTimeZonePrivate &other);
~QTzTimeZonePrivate();
QTimeZonePrivate *clone() Q_DECL_OVERRIDE;
QTzTimeZonePrivate *clone() const override;
QLocale::Country country() const Q_DECL_OVERRIDE;
QString comment() const Q_DECL_OVERRIDE;
@ -351,7 +351,7 @@ public:
QMacTimeZonePrivate(const QMacTimeZonePrivate &other);
~QMacTimeZonePrivate();
QTimeZonePrivate *clone() Q_DECL_OVERRIDE;
QMacTimeZonePrivate *clone() const override;
QString comment() const Q_DECL_OVERRIDE;
@ -404,7 +404,7 @@ public:
QWinTimeZonePrivate(const QWinTimeZonePrivate &other);
~QWinTimeZonePrivate();
QTimeZonePrivate *clone() Q_DECL_OVERRIDE;
QWinTimeZonePrivate *clone() const override;
QString comment() const Q_DECL_OVERRIDE;
@ -454,7 +454,7 @@ public:
QAndroidTimeZonePrivate(const QAndroidTimeZonePrivate &other);
~QAndroidTimeZonePrivate();
QTimeZonePrivate *clone() Q_DECL_OVERRIDE;
QAndroidTimeZonePrivate *clone() const override;
QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
const QLocale &locale) const Q_DECL_OVERRIDE;

View File

@ -452,13 +452,31 @@ static inline bool asciiIsLetter(char ch)
return ch >= 'a' && ch <= 'z';
}
namespace {
struct PosixZone
{
enum {
InvalidOffset = INT_MIN,
};
QString name;
int offset;
static PosixZone invalid() { return {QString(), InvalidOffset}; }
static PosixZone parse(const char *&pos, const char *end);
bool hasValidOffset() const Q_DECL_NOTHROW { return offset != InvalidOffset; }
};
} // unnamed namespace
// Returns the zone name, the offset (in seconds) and advances \a begin to
// where the parsing ended. Returns a zone of INT_MIN in case an offset
// couldn't be read.
static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const char *end)
PosixZone PosixZone::parse(const char *&pos, const char *end)
{
static const char offsetChars[] = "0123456789:";
QPair<QString, int> result = qMakePair(QString(), INT_MIN);
const char *nameBegin = pos;
const char *nameEnd;
@ -480,7 +498,7 @@ static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const c
pos = nameEnd;
}
if (nameEnd - nameBegin < 3)
return result; // name must be at least 3 characters long
return invalid(); // name must be at least 3 characters long
// zone offset, form [+-]hh:mm:ss
const char *zoneBegin = pos;
@ -493,11 +511,10 @@ static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const c
++zoneEnd;
}
result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
if (zoneEnd > zoneBegin)
result.second = parsePosixOffset(zoneBegin, zoneEnd);
QString name = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
const int offset = zoneEnd > zoneBegin ? parsePosixOffset(zoneBegin, zoneEnd) : InvalidOffset;
pos = zoneEnd;
return result;
return {std::move(name), offset};
}
static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
@ -517,19 +534,19 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
QList<QByteArray> parts = posixRule.split(',');
QPair<QString, int> stdZone, dstZone;
PosixZone stdZone, dstZone;
{
const QByteArray &zoneinfo = parts.at(0);
const char *begin = zoneinfo.constBegin();
stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
if (stdZone.second == INT_MIN) {
stdZone.second = 0; // reset to UTC if we failed to parse
stdZone = PosixZone::parse(begin, zoneinfo.constEnd());
if (!stdZone.hasValidOffset()) {
stdZone.offset = 0; // reset to UTC if we failed to parse
} else if (begin < zoneinfo.constEnd()) {
dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
if (dstZone.second == INT_MIN) {
dstZone = PosixZone::parse(begin, zoneinfo.constEnd());
if (!dstZone.hasValidOffset()) {
// if the dst offset isn't provided, it is 1 hour ahead of the standard offset
dstZone.second = stdZone.second + (60 * 60);
dstZone.offset = stdZone.offset + (60 * 60);
}
}
}
@ -538,10 +555,10 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
if (parts.count() == 1) {
QTimeZonePrivate::Data data;
data.atMSecsSinceEpoch = lastTranMSecs;
data.offsetFromUtc = stdZone.second;
data.standardTimeOffset = stdZone.second;
data.offsetFromUtc = stdZone.offset;
data.standardTimeOffset = stdZone.offset;
data.daylightTimeOffset = 0;
data.abbreviation = stdZone.first;
data.abbreviation = stdZone.name;
result << data;
return result;
}
@ -568,18 +585,18 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
for (int year = startYear; year <= endYear; ++year) {
QTimeZonePrivate::Data dstData;
QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC);
dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000);
dstData.offsetFromUtc = dstZone.second;
dstData.standardTimeOffset = stdZone.second;
dstData.daylightTimeOffset = dstZone.second - stdZone.second;
dstData.abbreviation = dstZone.first;
dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.offset * 1000);
dstData.offsetFromUtc = dstZone.offset;
dstData.standardTimeOffset = stdZone.offset;
dstData.daylightTimeOffset = dstZone.offset - stdZone.offset;
dstData.abbreviation = dstZone.name;
QTimeZonePrivate::Data stdData;
QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC);
stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000);
stdData.offsetFromUtc = stdZone.second;
stdData.standardTimeOffset = stdZone.second;
stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.offset * 1000);
stdData.offsetFromUtc = stdZone.offset;
stdData.standardTimeOffset = stdZone.offset;
stdData.daylightTimeOffset = 0;
stdData.abbreviation = stdZone.first;
stdData.abbreviation = stdZone.name;
// Part of the high year will overflow
if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) {
if (dstData.atMSecsSinceEpoch > 0) {
@ -598,37 +615,21 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// Create the system default time zone
QTzTimeZonePrivate::QTzTimeZonePrivate()
#if QT_CONFIG(icu)
: m_icu(0)
#endif
{
init(systemTimeZoneId());
}
// Create a named time zone
QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
#if QT_CONFIG(icu)
: m_icu(0)
#endif
{
init(ianaId);
}
QTzTimeZonePrivate::QTzTimeZonePrivate(const QTzTimeZonePrivate &other)
: QTimeZonePrivate(other), m_tranTimes(other.m_tranTimes),
m_tranRules(other.m_tranRules), m_abbreviations(other.m_abbreviations),
#if QT_CONFIG(icu)
m_icu(other.m_icu),
#endif
m_posixRule(other.m_posixRule)
{
}
QTzTimeZonePrivate::~QTzTimeZonePrivate()
{
}
QTimeZonePrivate *QTzTimeZonePrivate::clone()
QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
{
return new QTzTimeZonePrivate(*this);
}

View File

@ -415,7 +415,7 @@ QWinTimeZonePrivate::~QWinTimeZonePrivate()
{
}
QTimeZonePrivate *QWinTimeZonePrivate::clone()
QWinTimeZonePrivate *QWinTimeZonePrivate::clone() const
{
return new QWinTimeZonePrivate(*this);
}

View File

@ -352,7 +352,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a
a = Prealloc;
}
s = 0;
if (QTypeInfo<T>::isStatic) {
if (!QTypeInfoQuery<T>::isRelocatable) {
QT_TRY {
// copy all the old elements
while (s < copySize) {
@ -445,7 +445,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
if (n != 0) {
resize(s + n);
const T copy(t);
if (QTypeInfo<T>::isStatic) {
if (!QTypeInfoQuery<T>::isRelocatable) {
T *b = ptr + offset;
T *j = ptr + s;
T *i = j - n;

View File

@ -553,7 +553,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
T *srcEnd = asize > d->size ? d->end() : d->begin() + asize;
T *dst = x->begin();
if (QTypeInfo<T>::isStatic || (isShared && QTypeInfo<T>::isComplex)) {
if (!QTypeInfoQuery<T>::isRelocatable || (isShared && QTypeInfo<T>::isComplex)) {
// we can not move the data, we need to copy construct it
while (srcBegin != srcEnd) {
new (dst++) T(*srcBegin++);
@ -598,7 +598,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo
}
if (d != x) {
if (!d->ref.deref()) {
if (QTypeInfo<T>::isStatic || !aalloc || (isShared && QTypeInfo<T>::isComplex)) {
if (!QTypeInfoQuery<T>::isRelocatable || !aalloc || (isShared && QTypeInfo<T>::isComplex)) {
// data was copy constructed, we need to call destructors
// or if !alloc we did nothing to the old 'd'.
freeData(d);
@ -697,7 +697,7 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
const T copy(t);
if (!isDetached() || d->size + n > int(d->alloc))
reallocData(d->size, d->size + n, QArrayData::Grow);
if (QTypeInfo<T>::isStatic) {
if (!QTypeInfoQuery<T>::isRelocatable) {
T *b = d->end();
T *i = d->end() + n;
while (i != b)
@ -746,7 +746,7 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
detach();
abegin = d->begin() + itemsUntouched;
aend = abegin + itemsToErase;
if (QTypeInfo<T>::isStatic) {
if (!QTypeInfoQuery<T>::isRelocatable) {
iterator moveBegin = abegin + itemsToErase;
iterator moveEnd = d->end();
while (moveBegin != moveEnd) {

View File

@ -7,6 +7,7 @@
"commandline": {
"options": {
"accessibility": "boolean",
"angle": "boolean",
"direct2d": "boolean",
"directfb": "boolean",
@ -1042,6 +1043,11 @@ Specify -opengl desktop to use regular OpenGL."
"message": "The OpenGL functionality tests failed!
You might need to modify the include and library search paths by editing QMAKE_INCDIR_OPENGL[_ES2],
QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your platform."
},
{
"type": "warning",
"condition": "!features.accessibility",
"message": "Accessibility disabled. This configuration of Qt is unsupported."
}
],
@ -1049,6 +1055,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
{
"section": "Qt Gui",
"entries": [
"accessibility",
"freetype",
"system-freetype",
"harfbuzz",

View File

@ -3,7 +3,7 @@ QT = core-private
qtConfig(opengl.*): MODULE_CONFIG = opengl
DEFINES += QT_NO_USING_NAMESPACE
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
QMAKE_DOCS = $$PWD/doc/qtgui.qdocconf

View File

@ -745,7 +745,7 @@ static void set_text(const QImage &image, png_structp png_ptr, png_infop info_pt
#ifdef PNG_iTXt_SUPPORTED
bool needsItxt = false;
foreach(const QChar c, it.value()) {
for (const QChar c : it.value()) {
uchar ch = c.cell();
if (c.row() || (ch < 0x20 && ch != '\n') || (ch > 0x7e && ch < 0xa0)) {
needsItxt = true;

View File

@ -1124,7 +1124,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
= QStringLiteral("This application failed to start because it could not find or load the Qt platform plugin \"%1\"\nin \"%2\".\n\n").arg(name, QDir::toNativeSeparators(platformPluginPath));
if (!keys.isEmpty()) {
fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg(
keys.join(QStringLiteral(", ")));
keys.join(QLatin1String(", ")));
}
fatalMessage += QStringLiteral("Reinstalling the application may fix this problem.");
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)

View File

@ -109,6 +109,7 @@ public:
virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0;
virtual QPlatformWindow *createForeignWindow(QWindow *, WId) const { return 0; }
virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0;
#ifndef QT_NO_OPENGL
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;

View File

@ -424,7 +424,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate)
}
}
void QWindowPrivate::create(bool recursive)
void QWindowPrivate::create(bool recursive, WId nativeHandle)
{
Q_Q(QWindow);
if (platformWindow)
@ -433,8 +433,10 @@ void QWindowPrivate::create(bool recursive)
if (q->parent())
q->parent()->create();
platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow);
QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
platformWindow = nativeHandle ? platformIntegration->createForeignWindow(q, nativeHandle)
: platformIntegration->createPlatformWindow(q);
Q_ASSERT(platformWindow);
if (!platformWindow) {
qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags();
@ -629,9 +631,6 @@ WId QWindow::winId() const
{
Q_D(const QWindow);
if (type() == Qt::ForeignWindow)
return WId(property("_q_foreignWinId").value<WId>());
if(!d->platformWindow)
const_cast<QWindow *>(this)->create();
@ -865,7 +864,12 @@ void QWindow::setFlags(Qt::WindowFlags flags)
Qt::WindowFlags QWindow::flags() const
{
Q_D(const QWindow);
return d->windowFlags;
Qt::WindowFlags flags = d->windowFlags;
if (d->platformWindow && d->platformWindow->isForeignWindow())
flags |= Qt::ForeignWindow;
return flags;
}
/*!
@ -2584,13 +2588,13 @@ QWindow *QWindow::fromWinId(WId id)
}
QWindow *window = new QWindow;
window->setFlags(Qt::ForeignWindow);
window->setProperty("_q_foreignWinId", QVariant::fromValue(id));
window->create();
qt_window_private(window)->create(false, id);
if (!window->handle()) {
delete window;
return nullptr;
}
return window;
}

View File

@ -136,7 +136,7 @@ public:
void updateSiblingPosition(SiblingPosition);
bool windowRecreationRequired(QScreen *newScreen) const;
void create(bool recursive);
void create(bool recursive, WId nativeHandle = 0);
void destroy();
void setTopLevelScreen(QScreen *newScreen, bool recreate);
void connectToScreen(QScreen *topLevelScreen);

View File

@ -133,7 +133,7 @@ NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize)
QList<QSize> availableSizes = icon.availableSizes();
if (availableSizes.isEmpty() && defaultSize > 0)
availableSizes << QSize(defaultSize, defaultSize);
foreach (QSize size, availableSizes) {
for (QSize size : qAsConst(availableSizes)) {
QPixmap pm = icon.pixmap(size);
if (pm.isNull())
continue;

View File

@ -6549,8 +6549,8 @@ static void qInitDrawhelperFunctions()
destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
qMemRotateFunctions[QPixelLayout::BPP16][0] = qt_memrotate90_16_neon;
qMemRotateFunctions[QPixelLayout::BPP16][2] = qt_memrotate270_16_neon;
#endif
#endif // defined(__ARM_NEON__)

View File

@ -45,12 +45,11 @@
QT_BEGIN_NAMESPACE
QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window)
QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window, WId nativeHandle)
: QAndroidPlatformWindow(window),
m_surfaceId(-1)
{
const WId wId = window->property("_q_foreignWinId").value<WId>();
m_view = reinterpret_cast<jobject>(wId);
m_view = reinterpret_cast<jobject>(nativeHandle);
if (m_view.isValid())
QtAndroid::setViewVisibility(m_view.object(), false);
}

View File

@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
class QAndroidPlatformForeignWindow : public QAndroidPlatformWindow
{
public:
explicit QAndroidPlatformForeignWindow(QWindow *window);
explicit QAndroidPlatformForeignWindow(QWindow *window, WId nativeHandle);
~QAndroidPlatformForeignWindow();
void lower() override;
void raise() override;
@ -57,6 +57,7 @@ public:
void setVisible(bool visible) override;
void applicationStateChanged(Qt::ApplicationState state) override;
void setParent(const QPlatformWindow *window) override;
bool isForeignWindow() const override { return true; }
private:
int m_surfaceId;

View File

@ -285,10 +285,13 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind
{
if (!QtAndroid::activity())
return nullptr;
if (window->type() == Qt::ForeignWindow)
return new QAndroidPlatformForeignWindow(window);
else
return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
}
QPlatformWindow *QAndroidPlatformIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
{
return new QAndroidPlatformForeignWindow(window, nativeHandle);
}
QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const

View File

@ -78,6 +78,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QAbstractEventDispatcher *createEventDispatcher() const override;

View File

@ -126,6 +126,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const Q_DECL_OVERRIDE;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
#endif

View File

@ -524,6 +524,11 @@ QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const
return new QCocoaWindow(window);
}
QPlatformWindow *QCocoaIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
{
return new QCocoaWindow(window, nativeHandle);
}
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{

View File

@ -156,7 +156,7 @@ class QCocoaWindow : public QObject, public QPlatformWindow
{
Q_OBJECT
public:
QCocoaWindow(QWindow *tlw);
QCocoaWindow(QWindow *tlw, WId nativeHandle = 0);
~QCocoaWindow();
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
@ -186,6 +186,8 @@ public:
QMargins frameMargins() const Q_DECL_OVERRIDE;
QSurfaceFormat format() const Q_DECL_OVERRIDE;
bool isForeignWindow() const Q_DECL_OVERRIDE;
void requestActivateWindow() Q_DECL_OVERRIDE;
WId winId() const Q_DECL_OVERRIDE;
@ -206,7 +208,9 @@ public:
Q_NOTIFICATION_HANDLER(NSWindowDidResignKeyNotification) void windowDidResignKey();
Q_NOTIFICATION_HANDLER(NSWindowDidMiniaturizeNotification) void windowDidMiniaturize();
Q_NOTIFICATION_HANDLER(NSWindowDidDeminiaturizeNotification) void windowDidDeminiaturize();
Q_NOTIFICATION_HANDLER(NSWindowWillEnterFullScreenNotification) void windowWillEnterFullScreen();
Q_NOTIFICATION_HANDLER(NSWindowDidEnterFullScreenNotification) void windowDidEnterFullScreen();
Q_NOTIFICATION_HANDLER(NSWindowWillExitFullScreenNotification) void windowWillExitFullScreen();
Q_NOTIFICATION_HANDLER(NSWindowDidExitFullScreenNotification) void windowDidExitFullScreen();
Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen();
Q_NOTIFICATION_HANDLER(NSWindowDidOrderOnScreenAndFinishAnimatingNotification) void windowDidOrderOnScreen();

View File

@ -433,7 +433,7 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterNotificationCallbacks)
const int QCocoaWindow::NoAlertRequest = -1;
QCocoaWindow::QCocoaWindow(QWindow *tlw)
QCocoaWindow::QCocoaWindow(QWindow *tlw, WId nativeHandle)
: QPlatformWindow(tlw)
, m_view(nil)
, m_nsWindow(0)
@ -470,8 +470,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
QMacAutoReleasePool pool;
if (tlw->type() == Qt::ForeignWindow) {
m_view = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>());
if (nativeHandle) {
m_view = reinterpret_cast<NSView *>(nativeHandle);
[m_view retain];
} else {
m_view = [[QNSView alloc] initWithCocoaWindow:this];
// Enable high-dpi OpenGL for retina displays. Enabling has the side
@ -562,6 +563,11 @@ void QCocoaWindow::setGeometry(const QRect &rectIn)
setCocoaGeometry(rect);
}
bool QCocoaWindow::isForeignWindow() const
{
return ![m_view isKindOfClass:[QNSView class]];
}
QRect QCocoaWindow::geometry() const
{
// QWindows that are embedded in a NSView hiearchy may be considered
@ -941,6 +947,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
if (m_drawContentBorderGradient)
styleMask |= NSTexturedBackgroundWindowMask;
// Don't wipe fullscreen state
if (m_nsWindow.styleMask & NSFullScreenWindowMask)
styleMask |= NSFullScreenWindowMask;
return styleMask;
}
@ -1363,19 +1373,40 @@ void QCocoaWindow::windowDidDeminiaturize()
reportCurrentWindowState();
}
void QCocoaWindow::windowWillEnterFullScreen()
{
// The NSWindow needs to be resizable, otherwise we'll end up with
// the normal window geometry, centered in the middle of the screen
// on a black background. The styleMask will be reset below.
m_nsWindow.styleMask |= NSResizableWindowMask;
}
void QCocoaWindow::windowDidEnterFullScreen()
{
Q_ASSERT_X(m_nsWindow.qt_fullScreen, "QCocoaWindow",
"FullScreen category processes window notifications first");
// Reset to original styleMask
setWindowFlags(m_windowFlags);
reportCurrentWindowState();
}
void QCocoaWindow::windowWillExitFullScreen()
{
// The NSWindow needs to be resizable, otherwise we'll end up with
// a weird zoom animation. The styleMask will be reset below.
m_nsWindow.styleMask |= NSResizableWindowMask;
}
void QCocoaWindow::windowDidExitFullScreen()
{
Q_ASSERT_X(!m_nsWindow.qt_fullScreen, "QCocoaWindow",
"FullScreen category processes window notifications first");
// Reset to original styleMask
setWindowFlags(m_windowFlags);
Qt::WindowState requestedState = window()->windowState();
// Deliver update of QWindow state
@ -1869,24 +1900,13 @@ void QCocoaWindow::toggleMaximized()
void QCocoaWindow::toggleFullScreen()
{
// The NSWindow needs to be resizable, otherwise we'll end up with
// the normal window geometry, centered in the middle of the screen
// on a black background.
const bool wasResizable = m_nsWindow.styleMask & NSResizableWindowMask;
m_nsWindow.styleMask |= NSResizableWindowMask;
// It also needs to have the correct collection behavior for the
// toggleFullScreen call to have an effect.
const bool wasFullScreenEnabled = m_nsWindow.collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary;
// The window needs to have the correct collection behavior for the
// toggleFullScreen call to have an effect. The collection behavior
// will be reset in windowDidEnterFullScreen/windowDidLeaveFullScreen.
m_nsWindow.collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
const id sender = m_nsWindow;
[m_nsWindow toggleFullScreen:sender];
if (!wasResizable)
m_nsWindow.styleMask &= ~NSResizableWindowMask;
if (!wasFullScreenEnabled)
m_nsWindow.collectionBehavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
}
bool QCocoaWindow::isTransitioningToFullScreen() const

View File

@ -41,6 +41,7 @@
#include "qeglfskmsegldevice.h"
#include <QGuiApplication>
#include <QLoggingCategory>
#include <errno.h>
QT_BEGIN_NAMESPACE

View File

@ -81,7 +81,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
d << "QMimeData(";
if (mimeData) {
const QStringList formats = mimeData->formats();
d << "formats=" << formats.join(QStringLiteral(", "));
d << "formats=" << formats.join(QLatin1String(", "));
if (mimeData->hasText())
d << ", text=" << mimeData->text();
if (mimeData->hasHtml())
@ -321,7 +321,7 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
const HRESULT src = OleSetClipboard(m_data);
if (src != S_OK) {
QString mimeDataFormats = mimeData ?
mimeData->formats().join(QStringLiteral(", ")) : QString(QStringLiteral("NULL"));
mimeData->formats().join(QLatin1String(", ")) : QString(QStringLiteral("NULL"));
qErrnoWarning("OleSetClipboard: Failed to set mime data (%s) on clipboard: %s",
qPrintable(mimeDataFormats),
QWindowsContext::comErrorString(src).constData());

View File

@ -1167,7 +1167,7 @@ void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter)
if (index < 0) {
qWarning("%s: Invalid parameter '%s' not found in '%s'.",
__FUNCTION__, qPrintable(filter),
qPrintable(m_nameFilters.join(QStringLiteral(", "))));
qPrintable(m_nameFilters.join(QLatin1String(", "))));
return;
}
m_fileDialog->SetFileTypeIndex(index + 1); // one-based.

View File

@ -304,24 +304,6 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
return result;
}
if (window->type() == Qt::ForeignWindow) {
const HWND hwnd = reinterpret_cast<HWND>(window->winId());
if (!IsWindow(hwnd)) {
qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd);
return nullptr;
}
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);
const QRect obtainedGeometry = result->geometry();
QScreen *screen = Q_NULLPTR;
if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry))
screen = pScreen->screen();
if (screen && screen != window->screen())
window->setScreen(screen);
qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex
<< result->winId() << noshowbase << dec << obtainedGeometry << screen;
return result;
}
QWindowsWindowData requested;
requested.flags = window->flags();
requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
@ -365,6 +347,25 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
return result;
}
QPlatformWindow *QWindowsIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
{
const HWND hwnd = reinterpret_cast<HWND>(nativeHandle);
if (!IsWindow(hwnd)) {
qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd);
return nullptr;
}
QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);
const QRect obtainedGeometry = result->geometry();
QScreen *screen = Q_NULLPTR;
if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry))
screen = pScreen->screen();
if (screen && screen != window->screen())
window->setScreen(screen);
qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex
<< result->winId() << noshowbase << dec << obtainedGeometry << screen;
return result;
}
// Overridden to return a QWindowsDirect2DWindow in Direct2D plugin.
QWindowsWindow *QWindowsIntegration::createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &data) const
{

View File

@ -73,6 +73,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext::OpenGLModuleType openGLModuleType() override;

View File

@ -171,6 +171,7 @@ public:
void raise() override { raise_sys(); }
void lower() override { lower_sys(); }
void setWindowTitle(const QString &title) override { setWindowTitle_sys(title); }
bool isForeignWindow() const override { return true; }
protected:
HWND handle() const override { return m_hwnd; }

View File

@ -214,6 +214,27 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
return xcbWindow;
}
class QXcbForeignWindow : public QXcbWindow
{
public:
QXcbForeignWindow(QWindow *window, WId nativeHandle)
: QXcbWindow(window) { m_window = nativeHandle; }
~QXcbForeignWindow() {}
bool isForeignWindow() const override { return true; }
protected:
// No-ops
void create() override {}
void destroy() override {}
};
QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
{
QXcbWindow *xcbWindow = new QXcbForeignWindow(window, nativeHandle);
xcbWindow->create();
return xcbWindow;
}
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{

View File

@ -61,6 +61,7 @@ public:
~QXcbIntegration();
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
#endif

View File

@ -341,11 +341,6 @@ enum {
void QXcbWindow::create()
{
if (window()->type() == Qt::ForeignWindow) {
m_window = window()->winId();
return;
}
destroy();
m_windowState = Qt::WindowNoState;
@ -590,9 +585,10 @@ QXcbWindow::~QXcbWindow()
if (m_currentBitmapCursor != XCB_CURSOR_NONE) {
xcb_free_cursor(xcb_connection(), m_currentBitmapCursor);
}
if (window()->type() != Qt::ForeignWindow)
destroy();
else {
destroy();
if (isForeignWindow()) {
if (connection()->mouseGrabber() == this)
connection()->setMouseGrabber(Q_NULLPTR);
if (connection()->mousePressWindow() == this)

View File

@ -47,8 +47,6 @@
#include <QtCore/qglobal.h>
#ifndef QT_NO_ACCESSIBILITY
#define QVERIFY_EVENT(event) \
QVERIFY(QTestAccessibility::verifyEvent(event))
@ -59,6 +57,8 @@
#include <QtTest/qtest_global.h>
#include <QtTest/qtestsystem.h>
#if QT_CONFIG(accessibility)
QT_BEGIN_NAMESPACE
@ -294,5 +294,5 @@ private:
QT_END_NAMESPACE
#endif // QT_NO_ACCESSIBILITY
#endif // QT_CONFIG(accessibility)
#endif // QTESTACCESSIBLE_H

View File

@ -305,7 +305,7 @@ int runMoc(int argc, char **argv)
const QStringList files = parser.positionalArguments();
if (files.count() > 1) {
error(qPrintable(QStringLiteral("Too many input files specified: '") + files.join(QStringLiteral("' '")) + QLatin1Char('\'')));
error(qPrintable(QLatin1String("Too many input files specified: '") + files.join(QLatin1String("' '")) + QLatin1Char('\'')));
parser.showHelp(1);
} else if (!files.isEmpty()) {
filename = files.first();

View File

@ -62,6 +62,13 @@
QT_BEGIN_NAMESPACE
namespace {
struct Message {
QString content;
QString type;
};
}
class QErrorMessagePrivate : public QDialogPrivate
{
Q_DECLARE_PUBLIC(QErrorMessage)
@ -70,7 +77,7 @@ public:
QCheckBox * again;
QTextEdit * errors;
QLabel * icon;
std::queue<QPair<QString, QString> > pending;
std::queue<Message> pending;
QSet<QString> doNotShow;
QSet<QString> doNotShowType;
QString currentMessage;
@ -163,14 +170,20 @@ static void jump(QtMsgType t, const QMessageLogContext & /*context*/, const QStr
switch (t) {
case QtDebugMsg:
default:
rich = QErrorMessage::tr("Debug Message:");
break;
case QtWarningMsg:
rich = QErrorMessage::tr("Warning:");
break;
case QtCriticalMsg:
rich = QErrorMessage::tr("Critical Error:");
break;
case QtFatalMsg:
rich = QErrorMessage::tr("Fatal Error:");
break;
case QtInfoMsg:
rich = QErrorMessage::tr("Information:");
break;
}
rich = QString::fromLatin1("<p><b>%1</b></p>").arg(rich);
rich += Qt::convertFromPlainText(m, Qt::WhiteSpaceNormal);
@ -297,9 +310,8 @@ bool QErrorMessagePrivate::isMessageToBeShown(const QString &message, const QStr
bool QErrorMessagePrivate::nextPending()
{
while (!pending.empty()) {
QPair<QString,QString> &pendingMessage = pending.front();
QString message = qMove(pendingMessage.first);
QString type = qMove(pendingMessage.second);
QString message = std::move(pending.front().content);
QString type = std::move(pending.front().type);
pending.pop();
if (isMessageToBeShown(message, type)) {
#ifndef QT_NO_TEXTHTMLPARSER
@ -349,7 +361,7 @@ void QErrorMessage::showMessage(const QString &message, const QString &type)
Q_D(QErrorMessage);
if (!d->isMessageToBeShown(message, type))
return;
d->pending.push(qMakePair(message, type));
d->pending.push({message, type});
if (!isVisible() && d->nextPending())
show();
}

View File

@ -254,6 +254,11 @@ QSizePolicy::ControlType QSizePolicy::controlType() const
\sa QStyle::layoutSpacing()
*/
void QSizePolicy::setControlType(ControlType type)
{
bits.ctype = toControlTypeFieldValue(type);
}
quint32 QSizePolicy::toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW
{
/*
The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
@ -271,10 +276,8 @@ void QSizePolicy::setControlType(ControlType type)
int i = 0;
while (true) {
if (type & (0x1 << i)) {
bits.ctype = i;
return;
}
if (type & (0x1 << i))
return i;
++i;
}
}

View File

@ -119,18 +119,25 @@ public:
QT_SIZEPOLICY_CONSTEXPR QSizePolicy() : data(0) { }
#ifdef Q_COMPILER_UNIFORM_INIT
QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType)
: bits{0, 0, quint32(horizontal), quint32(vertical),
type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0}
{}
#else
QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType)
: data(0) {
bits.horPolicy = horizontal;
bits.verPolicy = vertical;
setControlType(type);
}
#endif // uniform-init
QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); }
QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); }
ControlType controlType() const;
void setHorizontalPolicy(Policy d) { bits.horPolicy = d; }
void setVerticalPolicy(Policy d) { bits.verPolicy = d; }
Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) { bits.horPolicy = d; }
Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) { bits.verPolicy = d; }
void setControlType(ControlType type);
QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const {
@ -138,9 +145,9 @@ public:
| ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ;
}
void setHeightForWidth(bool b) { bits.hfw = b; }
Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) { bits.hfw = b; }
QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const { return bits.hfw; }
void setWidthForHeight(bool b) { bits.wfh = b; }
Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) { bits.wfh = b; }
QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const { return bits.wfh; }
QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const { return data == s.data; }
@ -152,13 +159,13 @@ public:
QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const { return static_cast<int>(bits.horStretch); }
QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const { return static_cast<int>(bits.verStretch); }
void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; }
void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; }
Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; }
void transpose() { *this = transposed(); }
Q_DECL_RELAXED_CONSTEXPR void transpose() { *this = transposed(); }
#ifndef Q_QDOC
QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT
#endif
@ -176,6 +183,8 @@ private:
struct Bits;
QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { }
static quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW;
struct Bits {
quint32 horStretch : 8;
quint32 verStretch : 8;

View File

@ -9190,6 +9190,7 @@ bool QWidget::event(QEvent *event)
const QWindow *win = te->window;
d->setWinId((win && win->handle()) ? win->handle()->winId() : 0);
}
d->updateFont(d->data.fnt);
#ifndef QT_NO_OPENGL
d->renderToTextureReallyDirty = 1;
#endif

View File

@ -694,6 +694,10 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
this, SLOT(_q_editorTextChanged(QString)));
connect(d->edit, SIGNAL(cursorPositionChanged(int,int)),
this, SLOT(_q_editorCursorPositionChanged(int,int)));
connect(d->edit, SIGNAL(cursorPositionChanged(int,int)),
this, SLOT(updateMicroFocus()));
connect(d->edit->d_func()->control, SIGNAL(updateMicroFocus()),
this, SLOT(updateMicroFocus()));
}
d->updateEditFieldGeometry();
d->edit->setContextMenuPolicy(Qt::NoContextMenu);

View File

@ -65,6 +65,7 @@
#include <private/qcombobox_p.h>
#include <private/qabstractitemmodel_p.h>
#include <private/qabstractscrollarea_p.h>
#include <private/qlineedit_p.h>
#include <qdebug.h>
#if 0 /* Used to be included in Qt4 for Q_WS_MAC */ && !defined(QT_NO_EFFECTS) && QT_CONFIG(style_mac)
#include <private/qcore_mac_p.h>
@ -1790,6 +1791,7 @@ void QComboBox::setLineEdit(QLineEdit *edit)
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(currentTextChanged(QString)));
connect(d->lineEdit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateMicroFocus()));
connect(d->lineEdit, SIGNAL(selectionChanged()), this, SLOT(updateMicroFocus()));
connect(d->lineEdit->d_func()->control, SIGNAL(updateMicroFocus()), this, SLOT(updateMicroFocus()));
d->lineEdit->setFrame(false);
d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
d->updateFocusPolicy();

View File

@ -239,6 +239,7 @@ public:
private:
friend class QAbstractSpinBox;
friend class QAccessibleLineEdit;
friend class QComboBox;
#ifdef QT_KEYPAD_NAVIGATION
friend class QDateTimeEdit;
#endif

View File

@ -196,6 +196,9 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(textChanged(QString)),
q, SLOT(updateMicroFocus()));
QObject::connect(control, SIGNAL(updateMicroFocus()),
q, SLOT(updateMicroFocus()));
// for now, going completely overboard with updates.
QObject::connect(control, SIGNAL(selectionChanged()),
q, SLOT(update()));

View File

@ -44,6 +44,7 @@
#include <QtGui/QWindow>
#include <qpa/qplatformnativeinterface.h>
#include <private/qwidget_p.h>
#include <private/qwindow_p.h>
/*!
\class QMacCocoaViewContainer
@ -117,7 +118,9 @@ QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate()
QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent)
: QWidget(*new QMacCocoaViewContainerPrivate, parent, 0)
{
// Ensures that we have a QWindow, even if we're not a top level widget
setAttribute(Qt::WA_NativeWindow);
setCocoaView(view);
}
@ -149,23 +152,19 @@ void QMacCocoaViewContainer::setCocoaView(NSView *view)
[view retain];
d->nsview = view;
// Get rid of QWindow completely, and re-create a new vanilla one, which
// we will then re-configure to be a foreign window.
destroy();
create();
// Can't use QWindow::fromWinId() here due to QWidget controlling its
// QWindow, and can't use QWidget::createWindowContainer() due to the
// QMacCocoaViewContainer class being public API instead of a factory
// function.
QWindow *window = windowHandle();
// Note that we only set the flag on the QWindow, and not the QWidget.
// These two are not in sync, so from a QWidget standpoint the widget
// is not a Window, and hence will be shown when the parent widget is
// shown, like all QWidget children.
window->setFlags(Qt::ForeignWindow);
window->setProperty("_q_foreignWinId", view ? WId(view) : QVariant());
// Destroying the platform window implies hiding the window, and we
// also lose the geometry information that the platform window kept,
// and fall back to the stale QWindow geometry, so we update the two
// based on the widget visibility and geometry, which is up to date.
window->destroy();
window->setVisible(isVisible());
window->setGeometry(geometry());
window->create();
qt_window_private(window)->create(false, WId(view));
Q_ASSERT(window->handle());
[oldView release];
}

View File

@ -734,7 +734,7 @@ QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW)
QTest::newRow("QPair<P,C>") << ::qMetaTypeId<QPair<P,C> >() << false << true << false << false;
QTest::newRow("QPair<P,M>") << ::qMetaTypeId<QPair<P,M> >() << true << true << false << false;
QTest::newRow("QPair<P,P>") << ::qMetaTypeId<QPair<P,P> >() << true << false << false << false;
QTest::newRow("FlagsDataEnum") << ::qMetaTypeId<FlagsDataEnum>() << true << true << false << true;
QTest::newRow("FlagsDataEnum") << ::qMetaTypeId<FlagsDataEnum>() << true << false << false << true;
// invalid ids.
QTest::newRow("-1") << -1 << false << false << false << false;

View File

@ -89,6 +89,7 @@ private slots:
void waitForDone();
void clear();
void cancel();
void tryTake();
void waitForDoneTimeout();
void destroyingWaitsForTasksToFinish();
void stressTest();
@ -1042,6 +1043,97 @@ void tst_QThreadPool::cancel()
delete runnables[runs-1];
}
void tst_QThreadPool::tryTake()
{
QSemaphore sem(0);
QSemaphore startedThreads(0);
class SemaphoreReleaser
{
QSemaphore &sem;
int n;
Q_DISABLE_COPY(SemaphoreReleaser)
public:
explicit SemaphoreReleaser(QSemaphore &sem, int n)
: sem(sem), n(n) {}
~SemaphoreReleaser()
{
sem.release(n);
}
};
class BlockingRunnable : public QRunnable
{
public:
QSemaphore &sem;
QSemaphore &startedThreads;
QAtomicInt &dtorCounter;
QAtomicInt &runCounter;
int dummy;
explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r)
: sem(s), startedThreads(started), dtorCounter(c), runCounter(r) {}
~BlockingRunnable()
{
dtorCounter.fetchAndAddRelaxed(1);
}
void run() override
{
startedThreads.release();
runCounter.fetchAndAddRelaxed(1);
sem.acquire();
count.ref();
}
};
enum {
MaxThreadCount = 3,
OverProvisioning = 2,
Runs = MaxThreadCount * OverProvisioning
};
QThreadPool threadPool;
threadPool.setMaxThreadCount(MaxThreadCount);
BlockingRunnable *runnables[Runs];
// ensure that the QThreadPool doesn't deadlock if any of the checks fail
// and cause an early return:
const SemaphoreReleaser semReleaser(sem, Runs);
count.store(0);
QAtomicInt dtorCounter = 0;
QAtomicInt runCounter = 0;
for (int i = 0; i < Runs; i++) {
runnables[i] = new BlockingRunnable(sem, startedThreads, dtorCounter, runCounter);
runnables[i]->setAutoDelete(i != 0 && i != Runs - 1); // one which will run and one which will not
QVERIFY(!threadPool.tryTake(runnables[i])); // verify NOOP for jobs not in the queue
threadPool.start(runnables[i]);
}
// wait for all worker threads to have started up:
QVERIFY(startedThreads.tryAcquire(MaxThreadCount, 60*1000 /* 1min */));
for (int i = 0; i < MaxThreadCount; ++i) {
// check taking runnables doesn't work once they were started:
QVERIFY(!threadPool.tryTake(runnables[i]));
}
for (int i = MaxThreadCount; i < Runs ; ++i) {
QVERIFY(threadPool.tryTake(runnables[i]));
delete runnables[i];
}
runnables[0]->dummy = 0; // valgrind will catch this if tryTake() is crazy enough to delete currently running jobs
QCOMPARE(dtorCounter.load(), int(Runs - MaxThreadCount));
sem.release(MaxThreadCount);
threadPool.waitForDone();
QCOMPARE(runCounter.load(), int(MaxThreadCount));
QCOMPARE(count.load(), int(MaxThreadCount));
QCOMPARE(dtorCounter.load(), int(Runs - 1));
delete runnables[0]; // if the pool deletes them then we'll get double-free crash
}
void tst_QThreadPool::destroyingWaitsForTasksToFinish()
{
QTime total, pass;

View File

@ -113,6 +113,8 @@ void tst_QSizePolicy::constExpr()
// check that certain ctors are constexpr (compile-only):
{ Q_CONSTEXPR QSizePolicy sp; Q_UNUSED(sp); }
{ Q_CONSTEXPR QSizePolicy sp = QSizePolicy(); Q_UNUSED(sp); }
{ Q_CONSTEXPR QSizePolicy sp = QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); Q_UNUSED(sp); }
{ Q_CONSTEXPR QSizePolicy sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding, QSizePolicy::DefaultType); Q_UNUSED(sp); }
#else
QSKIP("QSizePolicy cannot be constexpr with this version of the compiler.");
#endif

View File

@ -4,7 +4,7 @@
CONFIG += testcase
TARGET = tst_qabstractspinbox
QT += widgets testlib
QT += widgets gui-private core-private testlib
SOURCES += tst_qabstractspinbox.cpp

View File

@ -35,6 +35,20 @@
#include <qlineedit.h>
#include <qspinbox.h>
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
static inline void centerOnScreen(QWidget *w, const QSize &size)
{
const QPoint offset = QPoint(size.width() / 2, size.height() / 2);
w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
}
static inline void centerOnScreen(QWidget *w)
{
centerOnScreen(w, w->geometry().size());
}
class tst_QAbstractSpinBox : public QObject
{
Q_OBJECT
@ -44,11 +58,19 @@ public:
virtual ~tst_QAbstractSpinBox();
private slots:
void initTestCase();
void cleanupTestCase();
void getSetCheck();
// task-specific tests below me:
void task183108_clear();
void task228728_cssselector();
void inputMethodUpdate();
private:
PlatformInputContext m_platformInputContext;
};
tst_QAbstractSpinBox::tst_QAbstractSpinBox()
@ -67,6 +89,18 @@ public:
void setLineEdit(QLineEdit *le) { QAbstractSpinBox::setLineEdit(le); }
};
void tst_QAbstractSpinBox::initTestCase()
{
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
inputMethodPrivate->testContext = &m_platformInputContext;
}
void tst_QAbstractSpinBox::cleanupTestCase()
{
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
inputMethodPrivate->testContext = 0;
}
// Testing get/set functions
void tst_QAbstractSpinBox::getSetCheck()
{
@ -141,6 +175,60 @@ void tst_QAbstractSpinBox::task228728_cssselector()
QSpinBox box;
}
void tst_QAbstractSpinBox::inputMethodUpdate()
{
QSpinBox box;
QSpinBox *testWidget = &box;
testWidget->setRange(0, 1);
centerOnScreen(testWidget);
testWidget->clear();
testWidget->show();
QVERIFY(QTest::qWaitForWindowExposed(testWidget));
testWidget->activateWindow();
testWidget->setFocus();
QTRY_VERIFY(testWidget->hasFocus());
QTRY_COMPARE(qApp->focusObject(), testWidget);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("1", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
QInputMethodEvent event("1", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("", attributes);
event.setCommitString("1");
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
QCOMPARE(testWidget->value(), 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
QInputMethodEvent event("", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
}
QTEST_MAIN(tst_QAbstractSpinBox)
#include "tst_qabstractspinbox.moc"

View File

@ -64,6 +64,9 @@
#include <qproxystyle.h>
#include <qfont.h>
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
static inline void setFrameless(QWidget *w)
{
Qt::WindowFlags flags = w->windowFlags();
@ -80,6 +83,8 @@ public:
tst_QComboBox() {}
private slots:
void initTestCase();
void cleanupTestCase();
void getSetCheck();
void ensureReturnIsIgnored();
void setEditable();
@ -162,6 +167,10 @@ private slots:
void task_QTBUG_39088_inputMethodHints();
void task_QTBUG_49831_scrollerNotActivated();
void task_QTBUG_56693_itemFontFromModel();
void inputMethodUpdate();
private:
PlatformInputContext m_platformInputContext;
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@ -207,6 +216,18 @@ protected:
QRegion visualRegionForSelection(const QItemSelection &) const { return QRegion(); }
};
void tst_QComboBox::initTestCase()
{
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
inputMethodPrivate->testContext = &m_platformInputContext;
}
void tst_QComboBox::cleanupTestCase()
{
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
inputMethodPrivate->testContext = 0;
}
// Testing get/set functions
void tst_QComboBox::getSetCheck()
{
@ -3324,5 +3345,59 @@ void tst_QComboBox::task_QTBUG_56693_itemFontFromModel()
box.hidePopup();
}
void tst_QComboBox::inputMethodUpdate()
{
TestWidget topLevel;
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
QComboBox *testWidget = topLevel.comboBox();
// make sure we have no lineedit
QVERIFY(!testWidget->lineEdit());
// test setEditable(true)
testWidget->setEditable(true);
QVERIFY(testWidget->lineEdit());
testWidget->activateWindow();
testWidget->setFocus();
QTRY_VERIFY(testWidget->hasFocus());
QTRY_COMPARE(qApp->focusObject(), testWidget);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("preedit text", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
QInputMethodEvent event("preedit text", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("", attributes);
event.setCommitString("preedit text");
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
QCOMPARE(testWidget->lineEdit()->text(), QString("preedit text"));
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
QInputMethodEvent event("", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
}
QTEST_MAIN(tst_QComboBox)
#include "tst_qcombobox.moc"

View File

@ -294,6 +294,8 @@ private slots:
void inputMethodQueryImHints_data();
void inputMethodQueryImHints();
void inputMethodUpdate();
void undoRedoAndEchoModes_data();
void undoRedoAndEchoModes();
@ -4184,6 +4186,57 @@ void tst_QLineEdit::inputMethodQueryImHints()
QCOMPARE(static_cast<Qt::InputMethodHints>(value.toInt()), hints);
}
void tst_QLineEdit::inputMethodUpdate()
{
QLineEdit *testWidget = ensureTestWidget();
centerOnScreen(testWidget);
testWidget->show();
QVERIFY(QTest::qWaitForWindowExposed(testWidget));
testWidget->setText("");
testWidget->activateWindow();
testWidget->setFocus();
QTRY_VERIFY(testWidget->hasFocus());
QTRY_COMPARE(qApp->focusObject(), testWidget);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("preedit text", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant());
QInputMethodEvent event("preedit text", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event("", attributes);
event.setCommitString("preedit text");
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
QCOMPARE(testWidget->text(), QString("preedit text"));
m_platformInputContext.m_updateCallCount = 0;
{
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
QInputMethodEvent event("", attributes);
QApplication::sendEvent(testWidget, &event);
}
QVERIFY(m_platformInputContext.m_updateCallCount >= 1);
}
void tst_QLineEdit::undoRedoAndEchoModes_data()
{
QTest::addColumn<int>("echoMode");

View File

@ -49,6 +49,7 @@ SUBDIRS=\
# The following tests depend on private API:
!qtConfig(private_tests): SUBDIRS -= \
qabstractspinbox \
qcombobox \
qmainwindow \
qtextedit \

View File

@ -191,12 +191,12 @@ static bool isTopLevel(const QObject *o)
return false;
}
static Qt::WindowState windowState(const QObject *o)
static Qt::WindowStates windowState(const QObject *o)
{
if (o->isWidgetType()) {
Qt::WindowStates states = static_cast<const QWidget *>(o)->windowState();
states &= ~Qt::WindowActive;
return static_cast<Qt::WindowState>(int(states));
return states;
}
#if QT_VERSION >= 0x050000
if (o->isWindowType())

View File

@ -202,16 +202,21 @@ PreviewWindow::PreviewWindow(QWidget *parent)
setWindowTitle(tr("Preview <QWidget> Qt %1").arg(QLatin1String(QT_VERSION_STR)));
}
void PreviewWindow::resizeEvent(QResizeEvent *e)
bool PreviewWindow::event(QEvent *event)
{
QWidget::resizeEvent(e);
updateInfo();
}
const bool ret = QWidget::event(event);
void PreviewWindow::moveEvent(QMoveEvent *e)
{
QWidget::moveEvent(e);
updateInfo();
switch (event->type()) {
case QEvent::Move:
case QEvent::Resize:
case QEvent::WindowStateChange:
updateInfo();
break;
default:
break;
}
return ret;
}
void PreviewWindow::setWindowFlags(Qt::WindowFlags flags)
@ -234,16 +239,21 @@ PreviewDialog::PreviewDialog(QWidget *parent)
setWindowTitle(tr("Preview <QDialog> Qt %1").arg(QLatin1String(QT_VERSION_STR)));
}
void PreviewDialog::resizeEvent(QResizeEvent *e)
bool PreviewDialog::event(QEvent *event)
{
QDialog::resizeEvent(e);
updateInfo();
}
const bool ret = QDialog::event(event);
void PreviewDialog::moveEvent(QMoveEvent *e)
{
QDialog::moveEvent(e);
updateInfo();
switch (event->type()) {
case QEvent::Move:
case QEvent::Resize:
case QEvent::WindowStateChange:
updateInfo();
break;
default:
break;
}
return ret;
}
void PreviewDialog::setWindowFlags(Qt::WindowFlags flags)

View File

@ -48,8 +48,7 @@ public slots:
void updateInfo();
protected:
void resizeEvent(QResizeEvent *);
void moveEvent(QMoveEvent *);
bool event(QEvent *) override;
private:
QPlainTextEdit *textEdit;
@ -68,8 +67,7 @@ public slots:
void updateInfo();
protected:
void resizeEvent(QResizeEvent *);
void moveEvent(QMoveEvent *);
bool event(QEvent *) override;
private:
QPlainTextEdit *textEdit;