summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-02-28 13:03:36 +0100
committerLiang Qi <liang.qi@qt.io>2017-02-28 13:03:36 +0100
commit1a4f0deeb44e2bfb107a22a714df3796ac1d0c20 (patch)
treeb1c8db2d1b742d25106225c80893e0b32f98fb15
parentdb0064b767474a89bc72ea4374f477682983c5f4 (diff)
parent35fa30e65d26b9e4840cfa793ed8369b3475c1fd (diff)
Merge remote-tracking branch 'origin/5.9' into dev
-rw-r--r--configure.json11
-rw-r--r--src/3rdparty/sqlite.pri2
-rw-r--r--src/corelib/global/qtypeinfo.h9
-rw-r--r--src/corelib/kernel/qmetaobject_p.h12
-rw-r--r--src/corelib/thread/qthreadpool.cpp50
-rw-r--r--src/corelib/thread/qthreadpool.h5
-rw-r--r--src/corelib/thread/qthreadpool_p.h1
-rw-r--r--src/corelib/tools/qarraydataops.h6
-rw-r--r--src/corelib/tools/qbytearraymatcher.h5
-rw-r--r--src/corelib/tools/qlist.h1
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp4
-rw-r--r--src/corelib/tools/qtimezoneprivate_android.cpp2
-rw-r--r--src/corelib/tools/qtimezoneprivate_icu.cpp2
-rw-r--r--src/corelib/tools/qtimezoneprivate_mac.mm2
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h16
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp87
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp2
-rw-r--r--src/corelib/tools/qvarlengtharray.h4
-rw-r--r--src/corelib/tools/qvector.h8
-rw-r--r--src/gui/configure.json7
-rw-r--r--src/gui/gui.pro2
-rw-r--r--src/gui/image/qpnghandler.cpp2
-rw-r--r--src/gui/kernel/qguiapplication.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.h1
-rw-r--r--src/gui/kernel/qwindow.cpp24
-rw-r--r--src/gui/kernel/qwindow_p.h2
-rw-r--r--src/gui/painting/qcoregraphics.mm2
-rw-r--r--src/gui/painting/qdrawhelper.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp11
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm54
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp21
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp12
-rw-r--r--src/testlib/qtestaccessible.h6
-rw-r--r--src/tools/moc/main.cpp2
-rw-r--r--src/widgets/dialogs/qerrormessage.cpp24
-rw-r--r--src/widgets/kernel/qsizepolicy.cpp11
-rw-r--r--src/widgets/kernel/qsizepolicy.h25
-rw-r--r--src/widgets/kernel/qwidget.cpp1
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp4
-rw-r--r--src/widgets/widgets/qcombobox.cpp2
-rw-r--r--src/widgets/widgets/qlineedit.h1
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp3
-rw-r--r--src/widgets/widgets/qmaccocoaviewcontainer_mac.mm29
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp2
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp92
-rw-r--r--tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp2
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro2
-rw-r--r--tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp88
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp75
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp53
-rw-r--r--tests/auto/widgets/widgets/widgets.pro1
-rw-r--r--tests/manual/windowflags/controllerwindow.cpp4
-rw-r--r--tests/manual/windowflags/previewwindow.cpp42
-rw-r--r--tests/manual/windowflags/previewwindow.h6
67 files changed, 678 insertions, 238 deletions
diff --git a/configure.json b/configure.json
index 6ccb1acdd9..ee931ced06 100644
--- a/configure.json
+++ b/configure.json
@@ -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",
@@ -1107,11 +1102,6 @@ or compile needed modules into the library."
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",
"message": "Qt requires a compliant STL library."
@@ -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",
diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri
index 8f50454064..79179daaf4 100644
--- a/src/3rdparty/sqlite.pri
+++ b/src/3rdparty/sqlite.pri
@@ -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
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index d197c8d384..4f79c48c51 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -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), \
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 1c540f64c7..e247c48703 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -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:
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index 2ecf8f729a..e45aaec103 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -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
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index 0ad63c5ac3..74a8c28fc8 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -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
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index ea8127efef..4a9f9e5cfa 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -82,7 +82,6 @@ public:
void reset();
bool waitForDone(int msecs);
void clear();
- bool stealRunnable(QRunnable *runnable);
void stealAndRunRunnable(QRunnable *runnable);
mutable QMutex mutex;
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index 47a19dd75d..ae83e6986e 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -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;
diff --git a/src/corelib/tools/qbytearraymatcher.h b/src/corelib/tools/qbytearraymatcher.h
index 51e08ba4bf..476bc3c049 100644
--- a/src/corelib/tools/qbytearraymatcher.h
+++ b/src/corelib/tools/qbytearraymatcher.h
@@ -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); }
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index c0a92aaa10..f861c1e71c 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -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<
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index ea8f6d1438..7b780ecf7d 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -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);
}
diff --git a/src/corelib/tools/qtimezoneprivate_android.cpp b/src/corelib/tools/qtimezoneprivate_android.cpp
index e079fa0d63..c3f8c3e0d9 100644
--- a/src/corelib/tools/qtimezoneprivate_android.cpp
+++ b/src/corelib/tools/qtimezoneprivate_android.cpp
@@ -88,7 +88,7 @@ void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
m_id = ianaId;
}
-QTimeZonePrivate *QAndroidTimeZonePrivate::clone()
+QAndroidTimeZonePrivate *QAndroidTimeZonePrivate::clone() const
{
return new QAndroidTimeZonePrivate(*this);
}
diff --git a/src/corelib/tools/qtimezoneprivate_icu.cpp b/src/corelib/tools/qtimezoneprivate_icu.cpp
index c088fe7694..887486f567 100644
--- a/src/corelib/tools/qtimezoneprivate_icu.cpp
+++ b/src/corelib/tools/qtimezoneprivate_icu.cpp
@@ -305,7 +305,7 @@ QIcuTimeZonePrivate::~QIcuTimeZonePrivate()
ucal_close(m_ucal);
}
-QTimeZonePrivate *QIcuTimeZonePrivate::clone()
+QIcuTimeZonePrivate *QIcuTimeZonePrivate::clone() const
{
return new QIcuTimeZonePrivate(*this);
}
diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm
index 0c2dbe6fef..4e9a432fbf 100644
--- a/src/corelib/tools/qtimezoneprivate_mac.mm
+++ b/src/corelib/tools/qtimezoneprivate_mac.mm
@@ -82,7 +82,7 @@ QMacTimeZonePrivate::~QMacTimeZonePrivate()
[m_nstz release];
}
-QTimeZonePrivate *QMacTimeZonePrivate::clone()
+QMacTimeZonePrivate *QMacTimeZonePrivate::clone() const
{
return new QMacTimeZonePrivate(*this);
}
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index 682edd3996..9985d0672c 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -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;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 38dff88919..1714c9802f 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -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);
}
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index 4febeda537..16dfaefb74 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -415,7 +415,7 @@ QWinTimeZonePrivate::~QWinTimeZonePrivate()
{
}
-QTimeZonePrivate *QWinTimeZonePrivate::clone()
+QWinTimeZonePrivate *QWinTimeZonePrivate::clone() const
{
return new QWinTimeZonePrivate(*this);
}
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index bb5ae78d2b..25f5176c22 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -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;
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 5225b68d40..c69d27bbf9 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -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) {
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 08e50db906..52ccb60024 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -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",
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 5f8cbe2cbe..511cfd1d22 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -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
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index d55a26b2a4..1d19c165fc 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -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;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 7c596d5ae5..c057fccade 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -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)
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 29f7b9b3a6..54904ef60d 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -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;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 9d41a72072..8e98958949 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -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;
}
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 272401453a..59016e4551 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -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);
diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm
index a64a184e25..768d3e7148 100644
--- a/src/gui/painting/qcoregraphics.mm
+++ b/src/gui/painting/qcoregraphics.mm
@@ -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;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 654be5690b..9233bff68c 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -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__)
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
index 8c1f0ea8d2..1c920c0af9 100644
--- a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
@@ -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);
}
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.h b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
index d42c36dcee..af1eee5499 100644
--- a/src/plugins/platforms/android/qandroidplatformforeignwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
@@ -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;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 184a836e13..13f9dc5a68 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -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
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 2337801250..be10c3d161 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -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;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index a3c375881d..ecdd20c4dc 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -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
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 291d39ea9d..91f408e5c2 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -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
{
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index f60597fe42..567eb7438b 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -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();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 918f376446..75c13d6bbc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -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
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 7e5477e4bf..a27c89faab 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -41,6 +41,7 @@
#include "qeglfskmsegldevice.h"
#include <QGuiApplication>
#include <QLoggingCategory>
+#include <errno.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 11cd1756e6..01191a7dc1 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -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());
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 896bdd3610..59e2aacee9 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -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.
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 5a3020387a..316f93e3ac 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -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
{
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 7647b0f4a6..607203829f 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -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;
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 227b79a207..5664539058 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -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; }
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 47c85fce18..40858b39e0 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -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
{
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index f8034f436f..baa5c9d835 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -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
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 46b3f2ab5a..abd41bb942 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -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)
diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h
index c4c79b7deb..464f87fb5c 100644
--- a/src/testlib/qtestaccessible.h
+++ b/src/testlib/qtestaccessible.h
@@ -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
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index 6128d5490b..b30de66258 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -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();
diff --git a/src/widgets/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp
index 5fcbe3fe9d..8200135abe 100644
--- a/src/widgets/dialogs/qerrormessage.cpp
+++ b/src/widgets/dialogs/qerrormessage.cpp
@@ -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();
}
diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp
index a03523d2af..b08a9abb1e 100644
--- a/src/widgets/kernel/qsizepolicy.cpp
+++ b/src/widgets/kernel/qsizepolicy.cpp
@@ -255,6 +255,11 @@ QSizePolicy::ControlType QSizePolicy::controlType() const
*/
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,
etc. In memory, we pack it onto the available bits (CTSize) in
@@ -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;
}
}
diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h
index 3ab672a8e8..83ce5853ab 100644
--- a/src/widgets/kernel/qsizepolicy.h
+++ b/src/widgets/kernel/qsizepolicy.h
@@ -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;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 2ced12fb7d..cf9fbe2572 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -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
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 6bcdc372ef..7ee53587e6 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -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);
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 4519265fb8..f4e08dc670 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -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();
diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h
index 1bdcfaf848..96dd64164f 100644
--- a/src/widgets/widgets/qlineedit.h
+++ b/src/widgets/widgets/qlineedit.h
@@ -239,6 +239,7 @@ public:
private:
friend class QAbstractSpinBox;
friend class QAccessibleLineEdit;
+ friend class QComboBox;
#ifdef QT_KEYPAD_NAVIGATION
friend class QDateTimeEdit;
#endif
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 9947d63279..13f18f66d2 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -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()));
diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
index 8e565ecfe0..610df2125b 100644
--- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
+++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
@@ -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;
- QWindow *window = windowHandle();
+ // 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();
- // 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.
+ // 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();
window->destroy();
- window->setVisible(isVisible());
- window->setGeometry(geometry());
- window->create();
+ qt_window_private(window)->create(false, WId(view));
+ Q_ASSERT(window->handle());
[oldView release];
}
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 450bd1cf3f..d57c4629cc 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -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;
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 5b7242fddb..fdc4ecb5c8 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -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;
diff --git a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp
index 98b765a6c6..4ae1f02ce2 100644
--- a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp
+++ b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp
@@ -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
diff --git a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro
index f9b601228e..be758a8bdd 100644
--- a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro
+++ b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro
@@ -4,7 +4,7 @@
CONFIG += testcase
TARGET = tst_qabstractspinbox
-QT += widgets testlib
+QT += widgets gui-private core-private testlib
SOURCES += tst_qabstractspinbox.cpp
diff --git a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp
index 36f5df4649..3fb4863b0e 100644
--- a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp
+++ b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp
@@ -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"
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 3afdc0a12a..b882055888 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -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"
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index a4614d0a9d..4c0ffdc77c 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -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");
diff --git a/tests/auto/widgets/widgets/widgets.pro b/tests/auto/widgets/widgets/widgets.pro
index a8e8f6d865..c098108edc 100644
--- a/tests/auto/widgets/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets/widgets.pro
@@ -49,6 +49,7 @@ SUBDIRS=\
# The following tests depend on private API:
!qtConfig(private_tests): SUBDIRS -= \
+ qabstractspinbox \
qcombobox \
qmainwindow \
qtextedit \
diff --git a/tests/manual/windowflags/controllerwindow.cpp b/tests/manual/windowflags/controllerwindow.cpp
index 3654bfbad0..9a12c8b2c9 100644
--- a/tests/manual/windowflags/controllerwindow.cpp
+++ b/tests/manual/windowflags/controllerwindow.cpp
@@ -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())
diff --git a/tests/manual/windowflags/previewwindow.cpp b/tests/manual/windowflags/previewwindow.cpp
index 54084fd1bc..65a287f788 100644
--- a/tests/manual/windowflags/previewwindow.cpp
+++ b/tests/manual/windowflags/previewwindow.cpp
@@ -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)
diff --git a/tests/manual/windowflags/previewwindow.h b/tests/manual/windowflags/previewwindow.h
index acd79735ad..9730e7a3f9 100644
--- a/tests/manual/windowflags/previewwindow.h
+++ b/tests/manual/windowflags/previewwindow.h
@@ -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;