summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-09-21 10:23:29 +0200
committerLiang Qi <liang.qi@qt.io>2016-09-21 11:57:52 +0200
commit7555a925816e3244073803f0adc4d44640f5ac1d (patch)
treef6f11015ae7387b50eaa76aa2c80ff273093b188 /src
parent31c251765db45a068f1268027e5dd600151af1e5 (diff)
parent8d64d1e0c3f7ebcee859e8b5f40aa27a8df86351 (diff)
Merge remote-tracking branch 'origin/5.7' into 5.8
5971b88e is not needed in new configure. This merge also reverts "fix QMAKE_DEFAULT_*DIRS resolution with apple SDK", 2c9d15d7, because it breaks iOS build with new configure system. Conflicts: mkspecs/features/default_pre.prf mkspecs/features/mac/toolchain.prf mkspecs/features/toolchain.prf src/dbus/qdbusconnection.cpp src/plugins/sqldrivers/mysql/qsql_mysql.cpp src/sql/drivers/mysql/qsql_mysql.cpp src/widgets/widgets/qmenubar.cpp src/widgets/widgets/qmenubar_p.h tools/configure/configureapp.cpp tools/configure/environment.cpp tools/configure/environment.h Change-Id: I995533dd334211ebd25912db05b639d6f908aaec
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qlogging.cpp3
-rw-r--r--src/corelib/kernel/qobjectdefs.h2
-rw-r--r--src/corelib/tools/qdatetime.cpp31
-rw-r--r--src/corelib/tools/qstring.h23
-rw-r--r--src/dbus/qdbusconnection.cpp20
-rw-r--r--src/dbus/qdbusconnection_p.h19
-rw-r--r--src/dbus/qdbuserror.h7
-rw-r--r--src/dbus/qdbusintegrator.cpp18
-rw-r--r--src/dbus/qdbusserver.cpp2
-rw-r--r--src/dbus/qdbusutil_p.h3
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp8
-rw-r--r--src/gui/text/qtextengine.cpp2
-rw-r--r--src/platformsupport/dbusmenu/qdbusplatformmenu.cpp4
-rw-r--r--src/platformsupport/dbustray/qdbustrayicon.cpp5
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp14
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp14
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp2
-rw-r--r--src/plugins/platforms/ios/qiosmessagedialog.mm2
-rw-r--r--src/plugins/platforms/ios/qiostextinputoverlay.mm4
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h11
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp9
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp15
-rw-r--r--src/widgets/kernel/qwidget.cpp18
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp68
-rw-r--r--src/widgets/styles/qstyleoption.h8
-rw-r--r--src/widgets/widgets/qmenu.cpp86
-rw-r--r--src/widgets/widgets/qmenu_p.h23
-rw-r--r--src/widgets/widgets/qmenubar.cpp52
-rw-r--r--src/widgets/widgets/qmenubar_p.h4
-rw-r--r--src/widgets/widgets/qtabbar.cpp3
-rw-r--r--src/widgets/widgets/qtoolbutton.cpp3
-rw-r--r--src/winmain/qtmain_winrt.cpp8
40 files changed, 319 insertions, 216 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index a6da9567c6..6c7cd9c5c6 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1199,7 +1199,8 @@ void QMessagePattern::setPattern(const QString &pattern)
#if defined(QLOGGING_HAVE_BACKTRACE) && !defined(QT_BOOTSTRAPPED)
// make sure the function has "Message" in the name so the function is removed
-#if (defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize)
+#if ((defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize)) \
+ && !defined(Q_CC_INTEL)
// force skipping the frame pointer, to save the backtrace() function some work
__attribute__((optimize("omit-frame-pointer")))
#endif
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 7ed6088d3b..5cdbef443b 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -185,7 +185,7 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {}
#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306
# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override")
-#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 510
+#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501
# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override")
#else
# define Q_OBJECT_NO_OVERRIDE_WARNING
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index e4b28178e8..f8611b3e68 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -845,7 +845,7 @@ static QString toStringIsoDate(qint64 jd)
range 0 to 9999. This restriction may apply to locale-aware
formats as well, depending on the locale settings.
- \sa shortDayName(), shortMonthName()
+ \sa fromString(), shortDayName(), shortMonthName(), QLocale::toString()
*/
QString QDate::toString(Qt::DateFormat format) const
{
@@ -921,7 +921,7 @@ QString QDate::toString(Qt::DateFormat format) const
If the datetime is invalid, an empty string will be returned.
- \sa QDateTime::toString(), QTime::toString(), QLocale::toString()
+ \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString()
*/
QString QDate::toString(const QString& format) const
@@ -1201,6 +1201,8 @@ qint64 QDate::daysTo(const QDate &d) const
Note for Qt::TextDate: It is recommended that you use the
English short month names (e.g. "Jan"). Although localized month
names can also be used, they depend on the user's locale settings.
+
+ \sa toString(), QLocale::toDate()
*/
QDate QDate::fromString(const QString& string, Qt::DateFormat format)
{
@@ -1319,8 +1321,8 @@ QDate QDate::fromString(const QString& string, Qt::DateFormat format)
\snippet code/src_corelib_tools_qdatetime.cpp 3
- \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(),
- QDateTime::toString(), QTime::toString()
+ \sa toString(), QDateTime::fromString(), QTime::fromString(),
+ QLocale::toDate()
*/
QDate QDate::fromString(const QString &string, const QString &format)
@@ -1587,7 +1589,7 @@ int QTime::msec() const
If the time is invalid, an empty string will be returned.
- \sa QDate::toString(), QDateTime::toString()
+ \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
*/
QString QTime::toString(Qt::DateFormat format) const
@@ -1660,7 +1662,7 @@ QString QTime::toString(Qt::DateFormat format) const
If the time is invalid, an empty string will be returned.
If \a format is empty, the default format "hh:mm:ss" is used.
- \sa QDate::toString(), QDateTime::toString(), QLocale::toString()
+ \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
*/
QString QTime::toString(const QString& format) const
{
@@ -1932,6 +1934,8 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format,
this may result in two conversion attempts (if the conversion
fails for the default locale). This should be considered an
implementation detail.
+
+ \sa toString(), QLocale::toTime()
*/
QTime QTime::fromString(const QString& string, Qt::DateFormat format)
{
@@ -2005,8 +2009,8 @@ QTime QTime::fromString(const QString& string, Qt::DateFormat format)
\snippet code/src_corelib_tools_qdatetime.cpp 8
- \sa QDateTime::fromString(), QDate::fromString(), QDate::toString(),
- QDateTime::toString(), QTime::toString()
+ \sa toString(), QDateTime::fromString(), QDate::fromString(),
+ QLocale::toTime()
*/
QTime QTime::fromString(const QString &string, const QString &format)
@@ -3732,7 +3736,8 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
range 0 to 9999. This restriction may apply to locale-aware
formats as well, depending on the locale settings.
- \sa QDate::toString(), QTime::toString(), Qt::DateFormat
+ \sa fromString(), QDate::toString(), QTime::toString(),
+ QLocale::toString()
*/
QString QDateTime::toString(Qt::DateFormat format) const
@@ -3872,7 +3877,7 @@ QString QDateTime::toString(Qt::DateFormat format) const
If the datetime is invalid, an empty string will be returned.
- \sa QDate::toString(), QTime::toString(), QLocale::toString()
+ \sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString()
*/
QString QDateTime::toString(const QString& format) const
{
@@ -4615,6 +4620,8 @@ int QDateTime::utcOffset() const
Note for Qt::TextDate: It is recommended that you use the
English short month names (e.g. "Jan"). Although localized month
names can also be used, they depend on the user's locale settings.
+
+ \sa toString(), QLocale::toDateTime()
*/
QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format)
{
@@ -4916,8 +4923,8 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format)
\snippet code/src_corelib_tools_qdatetime.cpp 14
- \sa QDate::fromString(), QTime::fromString(), QDate::toString(),
- QDateTime::toString(), QTime::toString()
+ \sa toString(), QDate::fromString(), QTime::fromString(),
+ QLocale::toDateTime()
*/
QDateTime QDateTime::fromString(const QString &string, const QString &format)
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 53a28d9278..b50b2ee4e5 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -976,6 +976,7 @@ inline QString QString::section(QChar asep, int astart, int aend, SectionFlags a
QT_WARNING_PUSH
QT_WARNING_DISABLE_MSVC(4127) // "conditional expression is constant"
+QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable"
inline int QString::toWCharArray(wchar_t *array) const
{
@@ -1157,21 +1158,21 @@ inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); }
inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); }
inline bool operator==(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
-{ return (s1.size() == s2.size() && !memcmp(s1.latin1(), s2.latin1(), s1.size())); }
+{ return s1.size() == s2.size() && (!s1.size() || !memcmp(s1.latin1(), s2.latin1(), s1.size())); }
inline bool operator!=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
-{ return (s1.size() != s2.size() || memcmp(s1.latin1(), s2.latin1(), s1.size())); }
+{ return !operator==(s1, s2); }
inline bool operator<(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
-{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
- return (r < 0) || (r == 0 && s1.size() < s2.size()); }
-inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
-{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
- return (r < 0) || (r == 0 && s1.size() <= s2.size()); }
+{
+ const int len = qMin(s1.size(), s2.size());
+ const int r = len ? memcmp(s1.latin1(), s2.latin1(), len) : 0;
+ return r < 0 || (r == 0 && s1.size() < s2.size());
+}
inline bool operator>(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
-{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
- return (r > 0) || (r == 0 && s1.size() > s2.size()); }
+{ return operator<(s2, s1); }
+inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
+{ return !operator>(s1, s2); }
inline bool operator>=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW
-{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size()));
- return (r > 0) || (r == 0 && s1.size() >= s2.size()); }
+{ return !operator<(s1, s2); }
inline bool QLatin1String::operator==(const QString &s) const Q_DECL_NOTHROW
{ return s == *this; }
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index cddb7dfb95..f95cc3a15d 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -71,24 +71,6 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
-// can be replaced with a lambda in Qt 5.7
-class QDBusConnectionDispatchEnabler : public QObject
-{
- Q_OBJECT
- QDBusConnectionPrivate *con;
-public:
- QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {}
-
-public slots:
- void execute()
- {
- con->setDispatchEnabled(true);
- if (!con->ref.deref())
- con->deleteLater();
- deleteLater();
- }
-};
-
struct QDBusConnectionManager::ConnectionRequestData
{
enum RequestType {
@@ -1280,6 +1262,4 @@ QByteArray QDBusConnection::localMachineId()
QT_END_NAMESPACE
-#include "qdbusconnection.moc"
-
#endif // QT_NO_DBUS
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 0b7c731810..a63e976f99 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -381,6 +381,25 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod
const QDBusMessage &msg);
extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
const QDBusMessage &msg);
+
+// can be replaced with a lambda in Qt 5.7
+class QDBusConnectionDispatchEnabler : public QObject
+{
+ Q_OBJECT
+ QDBusConnectionPrivate *con;
+public:
+ QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {}
+
+public slots:
+ void execute()
+ {
+ con->setDispatchEnabled(true);
+ if (!con->ref.deref())
+ con->deleteLater();
+ deleteLater();
+ }
+};
+
#endif // QT_BOOTSTRAPPED
QT_END_NAMESPACE
diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h
index 7c3abc9cc7..c264f62b7d 100644
--- a/src/dbus/qdbuserror.h
+++ b/src/dbus/qdbuserror.h
@@ -100,8 +100,8 @@ public:
QDBusError(const QDBusError &other);
#ifdef Q_COMPILER_RVALUE_REFS
QDBusError(QDBusError &&other) Q_DECL_NOTHROW
- : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm)), unused(other.unused)
- { other.unused = Q_NULLPTR; }
+ : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm))
+ {}
QDBusError &operator=(QDBusError &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
QDBusError &operator=(const QDBusError &other);
@@ -114,7 +114,6 @@ public:
qSwap(code, other.code);
qSwap(msg, other.msg);
qSwap(nm, other.nm);
- qSwap(unused, other.unused);
}
ErrorType type() const;
@@ -128,6 +127,8 @@ private:
ErrorType code;
QString msg;
QString nm;
+ // ### This class has an implicit (therefore inline) destructor
+ // so the following field cannot be used:
void *unused;
};
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusError)
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 21bc3c8ac2..c63fb05e74 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -315,9 +315,21 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v
// setPeer does the error handling for us
QDBusErrorInternal error;
newConnection->setPeer(connection, error);
+ newConnection->setDispatchEnabled(false);
// this is a queued connection and will resume in the QDBusServer's thread
emit serverConnection->newServerConnection(newConnection);
+
+ // we've disabled dispatching of events, so now we post an event to the
+ // QDBusServer's thread in order to enable it after the
+ // QDBusServer::newConnection() signal has been received by the
+ // application's code
+ newConnection->ref.ref();
+ QReadLocker serverLock(&serverConnection->lock);
+ QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(newConnection);
+ QTimer::singleShot(0, o, SLOT(execute()));
+ if (serverConnection->serverObject)
+ o->moveToThread(serverConnection->serverObject->thread());
}
void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnection)
@@ -1250,6 +1262,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in
break;
}
+ checkThread();
QDBusReadLocker locker(RelaySignalAction, this);
QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface,
QLatin1String(memberName));
@@ -2358,12 +2371,9 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node)
connector->connectAllSignals(node->obj);
}
- // disconnect and reconnect to avoid duplicates
- connector->disconnect(SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)),
- this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)));
connect(connector, SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)),
this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)),
- Qt::DirectConnection);
+ Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection));
}
}
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index a242ad984c..a59496bce8 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -103,12 +103,14 @@ QDBusServer::QDBusServer(QObject *parent)
*/
QDBusServer::~QDBusServer()
{
+ QWriteLocker locker(&d->lock);
if (QDBusConnectionManager::instance()) {
QMutexLocker locker(&QDBusConnectionManager::instance()->mutex);
for (const QString &name : qAsConst(d->serverConnectionNames))
QDBusConnectionManager::instance()->removeConnection(name);
d->serverConnectionNames.clear();
}
+ d->serverObject = nullptr;
d->ref.store(0);
d->deleteLater();
}
diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h
index 9a95ab7ba3..931a374ad9 100644
--- a/src/dbus/qdbusutil_p.h
+++ b/src/dbus/qdbusutil_p.h
@@ -63,7 +63,8 @@
QT_BEGIN_NAMESPACE
-namespace QDBusUtil
+#define Q_DBUS_NO_EXPORT // force findclasslist.pl looking into this namespace
+namespace Q_DBUS_NO_EXPORT QDBusUtil
{
Q_DBUS_EXPORT bool isValidInterfaceName(const QString &ifaceName);
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 76663cdc01..1085b546a7 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -170,11 +170,11 @@ static inline qreal initialGlobalScaleFactor()
The QT_SCALE_FACTOR environment variable can be used to set
a global scale factor for all windows in the processs. This
is useful for testing and debugging (you can simulate any
- devicePixelRatio without needing access to sepcial hardware),
+ devicePixelRatio without needing access to special hardware),
and perhaps also for targeting a specific application to
a specific display type (embedded use cases).
- 2) A per-screen scale factors
+ 2) Per-screen scale factors
Some platform plugins support providing a per-screen scale
factor based on display density information. These platforms
include X11, Windows, and Android.
@@ -187,13 +187,13 @@ static inline qreal initialGlobalScaleFactor()
Enabling either will make QHighDpiScaling call QPlatformScreen::pixelDensity()
and use the value provided as the scale factor for the screen in
question. Disabling is done on a 'veto' basis where either the
- environment or the application source can disable. The intended use
+ environment or the application can disable the scaling. The intended use
cases are 'My system is not providing correct display density
information' and 'My application needs to work in display pixels',
respectively.
The QT_SCREEN_SCALE_FACTORS environment variable can be used to set the screen
- scale factors manually.Set this to a semicolon-separated
+ scale factors manually. Set this to a semicolon-separated
list of scale factors (matching the order of QGuiApplications::screens()),
or to a list of name=value pairs (where name matches QScreen::name()).
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 8a13455ee0..5dbeccff7f 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -928,7 +928,7 @@ void QTextEngine::shapeLine(const QScriptLine &line)
if (item == -1)
return;
- const int end = findItem(line.from + line.length - 1, item);
+ const int end = findItem(line.from + line.length + line.trailingSpaces - 1, item);
for ( ; item <= end; ++item) {
QScriptItem &si = layoutData->items[item];
if (si.analysis.flags == QScriptAnalysis::Tab) {
diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp
index 993571eb13..15440a03cd 100644
--- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp
+++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp
@@ -67,6 +67,8 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag)
QDBusPlatformMenuItem::~QDBusPlatformMenuItem()
{
menuItemsByID.remove(m_dbusID);
+ if (m_subMenu)
+ static_cast<QDBusPlatformMenu *>(m_subMenu)->setContainingMenuItem(Q_NULLPTR);
}
void QDBusPlatformMenuItem::setTag(quintptr tag)
@@ -176,6 +178,8 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag)
QDBusPlatformMenu::~QDBusPlatformMenu()
{
+ if (m_containingMenuItem)
+ m_containingMenuItem->setMenu(Q_NULLPTR);
}
void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp
index 883d0e345c..0369eaf144 100644
--- a/src/platformsupport/dbustray/qdbustrayicon.cpp
+++ b/src/platformsupport/dbustray/qdbustrayicon.cpp
@@ -125,6 +125,8 @@ void QDBusTrayIcon::cleanup()
dBusConnection()->unregisterTrayIcon(this);
delete m_dbusConnection;
m_dbusConnection = Q_NULLPTR;
+ delete m_notifier;
+ m_notifier = Q_NULLPTR;
m_registered = false;
}
@@ -162,9 +164,10 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon)
}
if (!necessary)
return Q_NULLPTR;
+ qreal dpr = qGuiApp->devicePixelRatio();
QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this);
ret->open();
- icon.pixmap(QSize(22, 22)).save(ret);
+ icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret);
ret->close();
return ret;
}
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index d507751d5e..f8fe671a2b 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -112,15 +112,15 @@ static QByteArray localHostName()
*/
static QComposeCacheFileHeader readFileMetadata(const QString &path)
{
- QComposeCacheFileHeader info;
- info.reserved = 0;
- info.fileSize = 0;
+ quint64 fileSize = 0;
+ qint64 lastModified = 0;
const QByteArray pathBytes = QFile::encodeName(path);
QT_STATBUF st;
- if (QT_STAT(pathBytes.data(), &st) != 0)
- return info;
- info.lastModified = st.st_mtime;
- info.fileSize = st.st_size;
+ if (QT_STAT(pathBytes.data(), &st) == 0) {
+ lastModified = st.st_mtime;
+ fileSize = st.st_size;
+ }
+ QComposeCacheFileHeader info = { 0, 0, fileSize, lastModified };
return info;
}
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
index d17abbb65a..857f437661 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
@@ -168,11 +168,19 @@ bool QComposeInputContext::checkComposeTable()
TableGenerator reader;
m_tableState = reader.tableState();
- if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors)
- m_composeTable = reader.composeTable();
-
m_compositionTableInitialized = true;
+ if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) {
+ m_composeTable = reader.composeTable();
+ } else {
+#ifdef DEBUG_COMPOSING
+ qDebug( "### FAILED_PARSING ###" );
+#endif
+ // if we have errors, don' try to look things up anyways.
+ reset();
+ return false;
+ }
}
+ Q_ASSERT(!m_composeTable.isEmpty());
QVector<QComposeTableElement>::const_iterator it =
std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare());
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 677a2e2626..c79198d7fe 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -672,11 +672,6 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state
QAndroidEventDispatcherStopper::instance()->goingToStop(true);
QCoreApplication::processEvents();
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state));
- {
- AndroidDeadlockProtector protector;
- if (protector.acquire())
- QWindowSystemInterface::flushWindowSystemEvents();
- }
if (state == Qt::ApplicationSuspended)
QAndroidEventDispatcherStopper::instance()->stopAll();
} else {
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index fa768e64d3..97a1f30a35 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -155,7 +155,7 @@ void QAndroidPlatformWindow::updateStatusBarVisibility()
if (!isNonRegularWindow) {
if (m_windowState & Qt::WindowFullScreen)
QtAndroid::hideStatusBar();
- else if (m_windowState & Qt::WindowMaximized)
+ else
QtAndroid::showStatusBar();
}
}
diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm
index ac04bf88e1..50d5442f17 100644
--- a/src/plugins/platforms/ios/qiosmessagedialog.mm
+++ b/src/plugins/platforms/ios/qiosmessagedialog.mm
@@ -108,7 +108,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win
Q_UNUSED(windowFlags);
if (m_alertController // Ensure that the dialog is not showing already
|| !options() // Some message dialogs don't have options (QErrorMessage)
- || windowModality != Qt::ApplicationModal // We can only do app modal dialogs
+ || windowModality == Qt::NonModal // We can only do modal dialogs
|| QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) // API limitation
return false;
diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm
index ff260d02dc..9d73a296fa 100644
--- a/src/plugins/platforms/ios/qiostextinputoverlay.mm
+++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm
@@ -299,7 +299,11 @@ static void executeBlockWithoutAnimation(Block block)
// -------------------------------------------------------------------------
+#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_10_0)
+@interface QIOSHandleLayer : CALayer <CAAnimationDelegate> {
+#else
@interface QIOSHandleLayer : CALayer {
+#endif
CALayer *_handleCursorLayer;
CALayer *_handleKnobLayer;
Qt::Edge _selectionEdge;
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 9d38742d6f..7229d7d2a8 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -112,7 +112,7 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
options |= QQnxIntegration::FullScreenApplication;
}
- if (!paramList.contains(QLatin1String("flush-screen-context"))) {
+ if (paramList.contains(QLatin1String("flush-screen-context"))) {
options |= QQnxIntegration::AlwaysFlushScreenContext;
}
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index 3fa511e6df..b7264d0973 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -49,6 +49,17 @@
#include <screen/screen.h>
+// For pre-7.0 SDPs, map some screen property names to the old
+// names.
+#include <sys/neutrino.h>
+#if _NTO_VERSION < 700
+const int SCREEN_PROPERTY_FLAGS = SCREEN_PROPERTY_KEY_FLAGS;
+const int SCREEN_PROPERTY_FOCUS = SCREEN_PROPERTY_KEYBOARD_FOCUS;
+const int SCREEN_PROPERTY_MODIFIERS = SCREEN_PROPERTY_KEY_MODIFIERS;
+const int SCREEN_PROPERTY_SCAN = SCREEN_PROPERTY_KEY_SCAN;
+const int SCREEN_PROPERTY_SYM = SCREEN_PROPERTY_KEY_SYM;
+#endif
+
QT_BEGIN_NAMESPACE
class QQnxWindow;
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 42651732c2..beda6e1a49 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -239,20 +239,20 @@ void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
{
// get flags of key event
int flags;
- Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags),
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, &flags),
"Failed to query event flags");
// get key code
int sym;
- Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym),
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, &sym),
"Failed to query event sym");
int modifiers;
- Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers),
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_MODIFIERS, &modifiers),
"Failed to query event modifieres");
int scan;
- Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan),
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SCAN, &scan),
"Failed to query event scan");
int cap;
@@ -594,7 +594,7 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
qFatal("QQnx: failed to query window property, errno=%d", errno);
switch (property) {
- case SCREEN_PROPERTY_KEYBOARD_FOCUS:
+ case SCREEN_PROPERTY_FOCUS:
handleKeyboardFocusPropertyEvent(window);
break;
default:
@@ -607,7 +607,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
{
errno = 0;
int focus = 0;
- if (Q_UNLIKELY(window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0))
+ if (Q_UNLIKELY(window && screen_get_window_property_iv(window, SCREEN_PROPERTY_FOCUS, &focus) != 0))
qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno);
QWindow *focusWindow = QQnxIntegration::window(window);
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index f4e6ca9804..7b3a5ec70c 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -581,7 +581,7 @@ void QQnxWindow::setFocus(screen_window_t newFocusWindow)
screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP,
reinterpret_cast<void**>(&screenGroup));
if (screenGroup) {
- screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_KEYBOARD_FOCUS,
+ screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS,
reinterpret_cast<void**>(&newFocusWindow));
}
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 9236de58a1..e8e869c04f 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -828,7 +828,7 @@ void QWinRTScreen::addWindow(QWindow *window)
}
handleExpose();
- QWindowSystemInterface::flushWindowSystemEvents();
+ QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP)
QWinRTDrag::instance()->setDropTarget(window);
@@ -848,7 +848,7 @@ void QWinRTScreen::removeWindow(QWindow *window)
if (wasTopWindow && type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool)
QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason);
handleExpose();
- QWindowSystemInterface::flushWindowSystemEvents();
+ QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP)
if (wasTopWindow)
QWinRTDrag::instance()->setDropTarget(topWindow());
@@ -1157,6 +1157,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
#endif
+ // Devices like the Hololens set a static pressure of 0.5 independent
+ // of the pressed state. In those cases we need to synthesize the
+ // pressure value. To our knowledge this does not apply to pens
+ if (pointerDeviceType == PointerDeviceType_Touch && pressure == 0.5f)
+ pressure = isPressed ? 1. : 0.;
+
const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor,
area.Width * d->scaleFactor, area.Height * d->scaleFactor);
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index fbf3acc54b..4915bb1b11 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -992,6 +992,9 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
} else {
dropData = platformDropData();
supported_drop_actions = accepted_drop_action;
+
+ // Drop coming from another app? Update keyboard modifiers.
+ QGuiApplicationPrivate::modifier_buttons = QGuiApplication::queryKeyboardModifiers();
}
if (!dropData)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 07932ceeb8..4c908359f3 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -1393,10 +1393,11 @@ void QXcbKeyboard::resolveMaskConflicts()
class KeyChecker
{
public:
- KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time)
+ KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time, quint16 state)
: m_window(window)
, m_code(code)
, m_time(time)
+ , m_state(state)
, m_error(false)
, m_release(true)
{
@@ -1413,7 +1414,7 @@ public:
xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev;
- if (event->event != m_window || event->detail != m_code) {
+ if (event->event != m_window || event->detail != m_code || event->state != m_state) {
m_error = true;
return false;
}
@@ -1441,6 +1442,7 @@ private:
xcb_window_t m_window;
xcb_keycode_t m_code;
xcb_timestamp_t m_time;
+ quint16 m_state;
bool m_error;
bool m_release;
@@ -1505,7 +1507,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
}
} else {
// look ahead for auto-repeat
- KeyChecker checker(source->xcb_window(), code, time);
+ KeyChecker checker(source->xcb_window(), code, time, state);
xcb_generic_event_t *event = connection()->checkEvent(checker);
if (event) {
isAutoRepeat = true;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 51390bfdae..c81858c408 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2541,8 +2541,13 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
const quint32 *data = (const quint32 *)xcb_get_property_value(reply);
- if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0])
- newState = Qt::WindowMinimized;
+ if (reply->length != 0) {
+ if (data[0] == XCB_WM_STATE_ICONIC
+ || (data[0] == XCB_WM_STATE_WITHDRAWN
+ && m_lastWindowStateEvent == Qt::WindowMinimized)) {
+ newState = Qt::WindowMinimized;
+ }
+ }
}
free(reply);
} else { // _NET_WM_STATE can't change minimized state
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index 30a0a04f44..eb2bddd0bd 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -640,8 +640,15 @@ QVariant QMYSQLResult::data(int field)
if (f.nullIndicator)
return QVariant(f.type);
- if (qIsInteger(f.type))
- return QVariant(f.type, f.outField);
+ if (qIsInteger(f.type)) {
+ QVariant variant(f.type, f.outField);
+ // we never want to return char variants here, see QTBUG-53397
+ if (static_cast<int>(f.type) == QMetaType::UChar)
+ return variant.toUInt();
+ else if (static_cast<int>(f.type) == QMetaType::Char)
+ return variant.toInt();
+ return variant;
+ }
if (f.type != QVariant::ByteArray)
val = toUnicode(d->drv_d_func()->tc, f.outField, f.bufLength);
@@ -1371,7 +1378,7 @@ bool QMYSQLDriver::open(const QString& db,
: sslCipher.toLocal8Bit().constData());
}
-#if MYSQL_VERSION_ID >= 50000
+#if MYSQL_VERSION_ID >= 50100
if (connectTimeout != 0)
mysql_options(d->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connectTimeout);
if (readTimeout != 0)
@@ -1400,7 +1407,7 @@ bool QMYSQLDriver::open(const QString& db,
setOpenError(true);
return false;
}
-#if MYSQL_VERSION_ID >= 50000
+#if MYSQL_VERSION_ID >= 50100
if (reconnect)
mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect);
#endif
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index bfadd69db5..28f4cd34ce 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -283,6 +283,8 @@ QWidgetPrivate::QWidgetPrivate(int version)
, renderToTextureReallyDirty(1)
, renderToTextureComposeActive(0)
#endif
+ , childrenHiddenByWState(0)
+ , childrenShownByExpose(0)
#if defined(Q_OS_WIN)
, noPaintOnScreen(0)
#endif
@@ -9026,13 +9028,23 @@ bool QWidget::event(QEvent *event)
case QEvent::WindowStateChange: {
const bool wasMinimized = static_cast<const QWindowStateChangeEvent *>(event)->oldState() & Qt::WindowMinimized;
if (wasMinimized != isMinimized()) {
+ QWidget *widget = const_cast<QWidget *>(this);
if (wasMinimized) {
- QShowEvent showEvent;
- QCoreApplication::sendEvent(const_cast<QWidget *>(this), &showEvent);
+ // Always send the spontaneous events here, otherwise it can break the application!
+ if (!d->childrenShownByExpose) {
+ // Show widgets only when they are not yet shown by the expose event
+ d->showChildren(true);
+ QShowEvent showEvent;
+ QCoreApplication::sendSpontaneousEvent(widget, &showEvent);
+ }
+ d->childrenHiddenByWState = false; // Set it always to "false" when window is restored
} else {
QHideEvent hideEvent;
- QCoreApplication::sendEvent(const_cast<QWidget *>(this), &hideEvent);
+ QCoreApplication::sendSpontaneousEvent(widget, &hideEvent);
+ d->hideChildren(true);
+ d->childrenHiddenByWState = true;
}
+ d->childrenShownByExpose = false; // Set it always to "false" when window state changes
}
changeEvent(event);
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 0a810df102..a2579df48f 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -753,6 +753,8 @@ public:
uint renderToTextureReallyDirty : 1;
uint renderToTextureComposeActive : 1;
#endif
+ uint childrenHiddenByWState : 1;
+ uint childrenShownByExpose : 1;
// *************************** Platform specific ************************************
#if defined(Q_OS_WIN)
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 2a4f31babf..f3fbe13763 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -387,7 +387,14 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event)
const QEnterEvent *ee = static_cast<QEnterEvent *>(event);
QWidget *child = m_widget->childAt(ee->pos());
QWidget *receiver = child ? child : m_widget.data();
- QApplicationPrivate::dispatchEnterLeave(receiver, 0, ee->screenPos());
+ QWidget *leave = Q_NULLPTR;
+ if (QApplicationPrivate::inPopupMode() && receiver == m_widget
+ && qt_last_mouse_receiver != m_widget) {
+ // This allows to deliver the leave event to the native widget
+ // action on first-level menu.
+ leave = qt_last_mouse_receiver;
+ }
+ QApplicationPrivate::dispatchEnterLeave(receiver, leave, ee->screenPos());
qt_last_mouse_receiver = receiver;
}
}
@@ -477,34 +484,31 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
receiver = popupChild;
if (receiver != activePopupWidget)
widgetPos = receiver->mapFromGlobal(event->globalPos());
- QWidget *alien = receiver;
#if !defined(Q_OS_OSX) && !defined(Q_OS_IOS) // Cocoa tracks popups
const bool reallyUnderMouse = activePopupWidget->rect().contains(mapped);
const bool underMouse = activePopupWidget->underMouse();
- if (activePopupWidget != m_widget || (!underMouse && qt_button_down)) {
- // If active popup menu is not the first-level popup menu then we must emulate enter/leave events,
- // because first-level popup menu grabs the mouse and enter/leave events are delivered only to it
- // by QPA. Make an exception for first-level popup menu when the mouse button is pressed on widget.
- if (underMouse != reallyUnderMouse) {
- if (reallyUnderMouse) {
+ if (underMouse != reallyUnderMouse) {
+ if (reallyUnderMouse) {
+ const QPoint receiverMapped = receiver->mapFromGlobal(event->screenPos().toPoint());
+ // Prevent negative mouse position on enter event - this event
+ // should be properly handled in "handleEnterLeaveEvent()".
+ if (receiverMapped.x() >= 0 && receiverMapped.y() >= 0) {
QApplicationPrivate::dispatchEnterLeave(receiver, Q_NULLPTR, event->screenPos());
qt_last_mouse_receiver = receiver;
- } else {
- QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos());
- qt_last_mouse_receiver = receiver;
- receiver = activePopupWidget;
}
+ } else {
+ QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos());
+ qt_last_mouse_receiver = receiver;
+ receiver = activePopupWidget;
}
- } else if (!reallyUnderMouse) {
- alien = Q_NULLPTR;
}
#endif
QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers(), event->source());
e.setTimestamp(event->timestamp());
- QApplicationPrivate::sendMouseEvent(receiver, &e, alien, receiver->window(), &qt_button_down, qt_last_mouse_receiver);
+ QApplicationPrivate::sendMouseEvent(receiver, &e, receiver, receiver->window(), &qt_button_down, qt_last_mouse_receiver);
qt_last_mouse_receiver = receiver;
} else {
// close disabled popups when a mouse button is pressed or released
@@ -881,10 +885,40 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event)
void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
{
- if (isExposed()) {
+ QWidgetPrivate *wPriv = m_widget->d_func();
+ const bool exposed = isExposed();
+
+ if (wPriv->childrenHiddenByWState) {
+ // If widgets has been previously hidden by window state change event
+ // and they aren't yet shown...
+ if (exposed) {
+ // If the window becomes exposed...
+ if (!wPriv->childrenShownByExpose) {
+ // ... and they haven't been shown by this function yet - show it.
+ wPriv->showChildren(true);
+ QShowEvent showEvent;
+ QCoreApplication::sendSpontaneousEvent(m_widget, &showEvent);
+ wPriv->childrenShownByExpose = true;
+ }
+ } else {
+ // If the window becomes not exposed...
+ if (wPriv->childrenShownByExpose) {
+ // ... and child widgets was previously shown by the expose event - hide widgets again.
+ // This is a workaround, because sometimes when window is minimized programatically,
+ // the QPA can notify that the window is exposed after changing window state to minimized
+ // and then, the QPA can send next expose event with null exposed region (not exposed).
+ wPriv->hideChildren(true);
+ QHideEvent hideEvent;
+ QCoreApplication::sendSpontaneousEvent(m_widget, &hideEvent);
+ wPriv->childrenShownByExpose = false;
+ }
+ }
+ }
+
+ if (exposed) {
m_widget->setAttribute(Qt::WA_Mapped);
if (!event->region().isNull())
- m_widget->d_func()->syncBackingStore(event->region());
+ wPriv->syncBackingStore(event->region());
} else {
m_widget->setAttribute(Qt::WA_Mapped, false);
}
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
index 896024f73a..9679411402 100644
--- a/src/widgets/styles/qstyleoption.h
+++ b/src/widgets/styles/qstyleoption.h
@@ -671,7 +671,7 @@ T qstyleoption_cast(const QStyleOption *opt)
|| (int(Opt::Type) == QStyleOption::SO_Complex
&& opt->type > QStyleOption::SO_Complex)))
return static_cast<T>(opt);
- return 0;
+ return Q_NULLPTR;
}
template <typename T>
@@ -683,7 +683,7 @@ T qstyleoption_cast(QStyleOption *opt)
|| (int(Opt::Type) == QStyleOption::SO_Complex
&& opt->type > QStyleOption::SO_Complex)))
return static_cast<T>(opt);
- return 0;
+ return Q_NULLPTR;
}
// -------------------------- QStyleHintReturn -------------------------------
@@ -732,7 +732,7 @@ T qstyleoption_cast(const QStyleHintReturn *hint)
if (hint && hint->version <= Opt::Version &&
(hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default))
return static_cast<T>(hint);
- return 0;
+ return Q_NULLPTR;
}
template <typename T>
@@ -742,7 +742,7 @@ T qstyleoption_cast(QStyleHintReturn *hint)
if (hint && hint->version <= Opt::Version &&
(hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default))
return static_cast<T>(hint);
- return 0;
+ return Q_NULLPTR;
}
#if !defined(QT_NO_DEBUG_STREAM)
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index ed67446261..d957dda162 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -76,22 +76,6 @@
QT_BEGIN_NAMESPACE
QMenu *QMenuPrivate::mouseDown = 0;
-QPointer<QMenu> QMenuPrivate::previousMouseMenu(Q_NULLPTR);
-static void handleEnterLeaveEvents(QPointer<QMenu> *previous_ptr, QMenu *next)
-{
- QWidget *previous = previous_ptr->data();
- if (previous != next) {
- if (previous) {
- QEvent leaveEvent(QEvent::Leave);
- QApplication::sendEvent(previous, &leaveEvent);
- }
- if (next) {
- QEvent enterEvent(QEvent::Enter);
- QApplication::sendEvent(next, &enterEvent);
- }
- }
- *previous_ptr = next;
-}
/* QMenu code */
// internal class used for the torn off popup
@@ -510,8 +494,6 @@ void QMenuPrivate::hideMenu(QMenu *menu)
menu->d_func()->causedPopup.action = 0;
menu->close();
menu->d_func()->causedPopup.widget = 0;
- if (previousMouseMenu.data() == menu)
- handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR);
}
void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst)
@@ -677,10 +659,26 @@ void QMenuSloppyState::enter()
m_parent->childEnter();
}
+void QMenuSloppyState::childEnter()
+{
+ stopTimer();
+ if (m_parent)
+ m_parent->childEnter();
+}
+
+void QMenuSloppyState::leave()
+{
+ if (!m_dont_start_time_on_leave) {
+ if (m_parent)
+ m_parent->childLeave();
+ startTimerIfNotRunning();
+ }
+}
+
void QMenuSloppyState::childLeave()
{
if (m_enabled && !QMenuPrivate::get(m_menu)->hasReceievedEnter) {
- startTimer();
+ startTimerIfNotRunning();
if (m_parent)
m_parent->childLeave();
}
@@ -726,8 +724,17 @@ public:
void QMenuSloppyState::timeout()
{
QMenuPrivate *menu_priv = QMenuPrivate::get(m_menu);
+
+ bool reallyHasMouse = menu_priv->hasReceievedEnter;
+ if (!reallyHasMouse) {
+ // Check whether the menu really has a mouse, because only active popup
+ // menu gets the enter/leave events. Currently Cocoa is an exception.
+ const QPoint lastCursorPos = QGuiApplicationPrivate::lastCursorPosition.toPoint();
+ reallyHasMouse = m_menu->frameGeometry().contains(lastCursorPos);
+ }
+
if (menu_priv->currentAction == m_reset_action
- && menu_priv->hasReceievedEnter
+ && reallyHasMouse
&& (menu_priv->currentAction
&& menu_priv->currentAction->menu() == menu_priv->activeMenu)) {
return;
@@ -735,13 +742,13 @@ void QMenuSloppyState::timeout()
ResetOnDestroy resetState(this, &m_init_guard);
- if (hasParentActiveDelayTimer() || !m_menu || !m_menu->isVisible())
+ if (hasParentActiveDelayTimer() || !m_menu->isVisible())
return;
if (m_sub_menu)
menu_priv->hideMenu(m_sub_menu);
- if (menu_priv->hasReceievedEnter)
+ if (reallyHasMouse)
menu_priv->setCurrentAction(m_reset_action,0);
else
menu_priv->setCurrentAction(Q_NULLPTR, 0);
@@ -1095,10 +1102,8 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
tearoffHighlighted = 0;
}
- if (q->frameGeometry().contains(e->globalPos())) { //otherwise if the event is in our rect we want it..
- handleEnterLeaveEvents(&previousMouseMenu, q);
- return false;
- }
+ if (q->frameGeometry().contains(e->globalPos()))
+ return false; //otherwise if the event is in our rect we want it..
for(QWidget *caused = causedPopup.widget; caused;) {
bool passOnEvent = false;
@@ -1114,17 +1119,16 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e)
next_widget = m->d_func()->causedPopup.widget;
}
if (passOnEvent) {
- handleEnterLeaveEvents(&previousMouseMenu,qobject_cast<QMenu *>(caused));
- if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) {
- QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(),
- e->button(), e->buttons(), e->modifiers(), e->source());
- QApplication::sendEvent(caused, &new_e);
- return true;
+ if (e->type() != QEvent::MouseButtonRelease || mouseDown == caused) {
+ QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(),
+ e->button(), e->buttons(), e->modifiers(), e->source());
+ QApplication::sendEvent(caused, &new_e);
+ return true;
}
}
caused = next_widget;
if (!caused)
- handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR);
+ sloppyState.leave(); // Start timers
}
return false;
}
@@ -3218,7 +3222,6 @@ void QMenu::enterEvent(QEvent *)
Q_D(QMenu);
d->hasReceievedEnter = true;
d->sloppyState.enter();
- d->sloppyState.startTimer();
d->motions = -1; // force us to ignore the generate mouse move in mouseMoveEvent()
}
@@ -3229,7 +3232,6 @@ void QMenu::leaveEvent(QEvent *)
{
Q_D(QMenu);
d->hasReceievedEnter = false;
- d->sloppyState.leave();
if (!d->activeMenu && d->currentAction)
setActiveAction(0);
}
@@ -3393,10 +3395,18 @@ void QMenu::internalDelayedPopup()
const QRect actionRect(d->actionRect(d->currentAction));
const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top())));
- QPoint pos(rightPos);
-
- d->activeMenu->popup(pos);
+ d->activeMenu->popup(rightPos);
d->sloppyState.setSubMenuPopup(actionRect, d->currentAction, d->activeMenu);
+
+#if !defined(Q_OS_DARWIN)
+ // Send the leave event to the current menu - only active popup menu gets
+ // mouse enter/leave events. Currently Cocoa is an exception, so disable
+ // it there to avoid event duplication.
+ if (underMouse()) {
+ QEvent leaveEvent(QEvent::Leave);
+ QCoreApplication::sendEvent(this, &leaveEvent);
+ }
+#endif
}
/*!
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index dbc0958f03..2b0dc482da 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -120,8 +120,6 @@ public:
void reset();
bool enabled() const { return m_enabled; }
- void setResetAction(QAction *action) { m_reset_action = action; }
-
enum MouseEventResult {
EventIsProcessed,
EventShouldBePropagated,
@@ -146,22 +144,9 @@ public:
}
void enter();
+ void childEnter();
- void childEnter()
- {
- stopTimer();
- if (m_parent)
- m_parent->childEnter();
- }
-
- void leave()
- {
- if (m_dont_start_time_on_leave)
- return;
- if (m_parent)
- m_parent->childLeave();
- startTimer();
- }
+ void leave();
void childLeave();
static float slope(const QPointF &p1, const QPointF &p2)
@@ -187,8 +172,7 @@ public:
if (!m_enabled)
return EventShouldBePropagated;
- if (!m_time.isActive())
- startTimer();
+ startTimerIfNotRunning();
if (!m_sub_menu) {
reset();
@@ -460,7 +444,6 @@ public:
QPointer<QAction> actionAboutToTrigger;
QPointer<QWidget> noReplayFor;
- static QPointer<QMenu> previousMouseMenu;
};
#endif // QT_NO_MENU
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 99fddee53d..a77c0f9753 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -612,9 +612,10 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
for items in the menu bar are only shown when the \uicontrol{Alt} key is
pressed.
- \section1 QMenuBar on \macos
+ \section1 QMenuBar as a Global Menu Bar
- QMenuBar on \macos is a wrapper for using the system-wide menu bar.
+ On \macos and on certain Linux desktop environments such as
+ Ubuntu Unity, QMenuBar is a wrapper for using the system-wide menu bar.
If you have multiple menu bars in one dialog the outermost menu bar
(normally inside a widget with widget flag Qt::Window) will
be used for the system-wide menu bar.
@@ -657,11 +658,16 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti
as its parent. That menu bar would only be displayed for the
parent QMainWindow.
- \b{Note:} The text used for the application name in the menu
+ \b{Note:} The text used for the application name in the \macos menu
bar is obtained from the value set in the \c{Info.plist} file in
the application's bundle. See \l{Qt for macOS - Deployment}
for more information.
+ \b{Note:} On Linux, if the com.canonical.AppMenu.Registrar
+ service is available on the D-Bus session bus, then Qt will
+ communicate with it to install the application's menus into the
+ global menu bar, as described.
+
\section1 Examples
The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar
@@ -985,13 +991,11 @@ void QMenuBar::paintEvent(QPaintEvent *e)
*/
void QMenuBar::setVisible(bool visible)
{
-#if defined(Q_OS_DARWIN)
if (isNativeMenuBar()) {
if (!visible)
QWidget::setVisible(false);
return;
}
-#endif
QWidget::setVisible(visible);
}
@@ -1534,11 +1538,7 @@ QRect QMenuBar::actionGeometry(QAction *act) const
QSize QMenuBar::minimumSizeHint() const
{
Q_D(const QMenuBar);
-#if defined(Q_OS_DARWIN)
const bool as_gui_menubar = !isNativeMenuBar();
-#else
- const bool as_gui_menubar = true;
-#endif
ensurePolished();
QSize ret(0, 0);
@@ -1590,12 +1590,7 @@ QSize QMenuBar::minimumSizeHint() const
QSize QMenuBar::sizeHint() const
{
Q_D(const QMenuBar);
-#if defined(Q_OS_DARWIN)
const bool as_gui_menubar = !isNativeMenuBar();
-#else
- const bool as_gui_menubar = true;
-#endif
-
ensurePolished();
QSize ret(0, 0);
@@ -1648,11 +1643,7 @@ QSize QMenuBar::sizeHint() const
int QMenuBar::heightForWidth(int) const
{
Q_D(const QMenuBar);
-#if defined(Q_OS_DARWIN)
const bool as_gui_menubar = !isNativeMenuBar();
-#else
- const bool as_gui_menubar = true;
-#endif
const_cast<QMenuBarPrivate*>(d)->updateGeometries();
int height = 0;
@@ -1783,23 +1774,23 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const
\brief Whether or not a menubar will be used as a native menubar on platforms that support it
\since 4.6
- This property specifies whether or not the menubar should be used as a native menubar on \macos.
+ This property specifies whether or not the menubar should be used as a native menubar on
+ platforms that support it. The currently supported platforms are \macos, and
+ Linux desktops which use the com.canonical.dbusmenu D-Bus interface (such as Ubuntu Unity).
If this property is \c true, the menubar is used in the native menubar and is not in the window of
- its parent, if \c false the menubar remains in the window. On other platforms the value of this
- attribute has no effect.
+ its parent; if \c false the menubar remains in the window. On other platforms,
+ setting this attribute has no effect, and reading this attribute will always return \c false.
The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
- is set for the application. Explicitly settings this property overrides
- the presence (or abscence) of the attribute.
+ is set for the application. Explicitly setting this property overrides
+ the presence (or absence) of the attribute.
*/
void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
{
Q_D(QMenuBar);
- if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
- d->nativeMenuBar = nativeMenuBar;
-
- if (!d->nativeMenuBar) {
+ if (nativeMenuBar != bool(d->platformMenuBar)) {
+ if (!nativeMenuBar) {
delete d->platformMenuBar;
d->platformMenuBar = 0;
} else {
@@ -1808,7 +1799,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
}
updateGeometry();
- if (!d->nativeMenuBar && parentWidget())
+ if (!nativeMenuBar && parentWidget())
setVisible(true);
}
}
@@ -1816,10 +1807,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
bool QMenuBar::isNativeMenuBar() const
{
Q_D(const QMenuBar);
- if (d->nativeMenuBar == -1) {
- return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
- }
- return d->nativeMenuBar;
+ return bool(d->platformMenuBar);
}
/*!
diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h
index 153df35297..f5409b9762 100644
--- a/src/widgets/widgets/qmenubar_p.h
+++ b/src/widgets/widgets/qmenubar_p.h
@@ -66,7 +66,7 @@ class QMenuBarPrivate : public QWidgetPrivate
public:
QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0),
closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0),
- nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0)
+ doChildEffects(false), platformMenuBar(0)
{ }
~QMenuBarPrivate()
@@ -103,8 +103,6 @@ public:
uint keyboardState : 1, altPressed : 1;
QPointer<QWidget> keyboardFocusWidget;
-
- int nativeMenuBar : 3; // Only has values -1, 0, and 1
//firing of events
void activateAction(QAction *, QAction::ActionEvent);
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index d56c6b39d1..b6a3ef7eb8 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -1958,9 +1958,8 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
}
}
- int offset = (event->pos() - d->dragStartPosition).manhattanLength();
if (event->buttons() == Qt::LeftButton
- && offset > QApplication::startDragDistance()
+ && d->dragInProgress
&& d->validIndex(d->pressedIndex)) {
bool vertical = verticalTabs(d->shape);
int dragDistance;
diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp
index 8b40325a24..80a061e6d5 100644
--- a/src/widgets/widgets/qtoolbutton.cpp
+++ b/src/widgets/widgets/qtoolbutton.cpp
@@ -196,7 +196,6 @@ QToolButton::QToolButton(QWidget * parent)
void QToolButtonPrivate::init()
{
Q_Q(QToolButton);
- delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q);
defaultAction = 0;
#ifndef QT_NO_TOOLBAR
if (qobject_cast<QToolBar*>(parent))
@@ -222,7 +221,7 @@ void QToolButtonPrivate::init()
#endif
setLayoutItemMargins(QStyle::SE_ToolButtonLayoutItem);
-
+ delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q);
}
/*!
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 83a7dc800c..e49817ada4 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -198,6 +198,14 @@ public:
private:
HRESULT activatedLaunch(IInspectable *activateArgs) {
+ // Check if an application instance is already running
+ // This is mostly needed for Windows Phone and file pickers
+ QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
+ if (dispatcher) {
+ QCoreApplication::postEvent(dispatcher, new QActivationEvent(activateArgs));
+ return S_OK;
+ }
+
QCoreApplication *app = QCoreApplication::instance();
// Check whether the app already runs