summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-08-16 13:34:53 +0200
committerLiang Qi <liang.qi@qt.io>2018-08-16 18:48:59 +0200
commit8559bf934def636ccff487464adb600d219f8778 (patch)
tree3063152f487798c7103dbf61216e48c37586a4e1
parentf1a6b97fe2d3eda9455b13bb79828f250d46b92e (diff)
parenta0ebd98f58b2d92c34fafbc620f024caa36bf0ad (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: src/corelib/global/qconfig-bootstrapped.h src/plugins/platforms/xcb/qxcbbackingstore.cpp Done-with: Gatis Paeglis <gatis.paeglis@qt.io> Change-Id: I4af138ffb2f5306373244523768209e8873b2798
-rw-r--r--mkspecs/features/qt_configure.prf4
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp17
-rw-r--r--src/3rdparty/xkbcommon/qt_attribution.json1
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h12
-rw-r--r--src/corelib/global/qglobal.cpp17
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp1
-rw-r--r--src/corelib/serialization/qxmlstream_p.h2
-rw-r--r--src/corelib/tools/qtimezoneprivate_mac.mm2
-rw-r--r--src/gui/text/qtextengine.cpp2
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp2
-rw-r--r--src/plugins/platforminputcontexts/ibus/ibus.pro2
-rw-r--r--src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml10
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp111
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h2
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp26
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusproxyportal.h49
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm21
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp143
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp4
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp10
-rw-r--r--tests/auto/cmake/CMakeLists.txt1
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp18
-rw-r--r--tests/auto/other/qfocusevent/qfocusevent.pro2
-rw-r--r--tests/auto/other/qfocusevent/tst_qfocusevent.cpp8
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp6
26 files changed, 379 insertions, 96 deletions
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
index 36b016bc7e..81b820978a 100644
--- a/mkspecs/features/qt_configure.prf
+++ b/mkspecs/features/qt_configure.prf
@@ -996,9 +996,9 @@ defineTest(qtConfTest_compile) {
# add compiler flags, these are set for the target and should not be applied to host tests
!isEmpty(EXTRA_DEFINES): \
qmake_args += $$system_quote(DEFINES += $$val_escape(EXTRA_DEFINES))
- !isEmpty(EXTRA_LIBDIR) \
+ !isEmpty(EXTRA_LIBDIR): \
qmake_args += $$system_quote(QMAKE_LIBDIR += $$val_escape(EXTRA_LIBDIR))
- !isEmpty(EXTRA_FRAMEWORKPATH) \
+ !isEmpty(EXTRA_FRAMEWORKPATH): \
qmake_args += $$system_quote(QMAKE_FRAMEWORKPATH += $$val_escape(EXTRA_FRAMEWORKPATH))
!isEmpty(EXTRA_INCLUDEPATH): \
qmake_args += $$system_quote(INCLUDEPATH += $$val_escape(EXTRA_INCLUDEPATH))
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index 59e6127e46..ad2976aa01 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -557,6 +557,12 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool)
addFilters(tempProj, xmlFilter, "Deployment Files");
addFilters(tempProj, xmlFilter, "Distribution Files");
+ tempProj.ExtraCompilers.reserve(tool.ExtraCompilersFiles.size());
+ std::transform(tool.ExtraCompilersFiles.cbegin(), tool.ExtraCompilersFiles.cend(),
+ std::back_inserter(tempProj.ExtraCompilers),
+ [] (const VCFilter &filter) { return filter.Name; });
+ tempProj.ExtraCompilers.removeDuplicates();
+
for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x)
addFilters(tempProj, xmlFilter, tempProj.ExtraCompilers.at(x));
@@ -1977,6 +1983,15 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml
return fileAdded;
}
+static bool isFileClCompatible(const QString &filePath)
+{
+ auto filePathEndsWith = [&filePath] (const QString &ext) {
+ return filePath.endsWith(ext, Qt::CaseInsensitive);
+ };
+ return std::any_of(Option::cpp_ext.cbegin(), Option::cpp_ext.cend(), filePathEndsWith)
+ || std::any_of(Option::c_ext.cbegin(), Option::c_ext.cend(), filePathEndsWith);
+}
+
void VCXProjectWriter::outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter,
const QString &filePath, const QString &filterName)
{
@@ -2000,7 +2015,7 @@ void VCXProjectWriter::outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter,
<< attrTagS("Filter", filterName);
xml << tag("ClInclude")
<< attrTag("Include", nativeFilePath);
- } else if (filePath.endsWith(".cpp")) {
+ } else if (isFileClCompatible(filePath)) {
xmlFilter << tag("ClCompile")
<< attrTag("Include", nativeFilePath)
<< attrTagS("Filter", filterName);
diff --git a/src/3rdparty/xkbcommon/qt_attribution.json b/src/3rdparty/xkbcommon/qt_attribution.json
index 8ee0df1b22..4be9b42917 100644
--- a/src/3rdparty/xkbcommon/qt_attribution.json
+++ b/src/3rdparty/xkbcommon/qt_attribution.json
@@ -6,6 +6,7 @@
"Description": "xkbcommon is a keymap compiler and support library which processes a reduced subset of keymaps as defined by the XKB specification.",
"Homepage": "http://xkbcommon.org/",
+ "Version": "0.4.1",
"License": "MIT Licenses (with no-advertisement clause)",
"LicenseId": "MIT",
"LicenseFile": "COPYING",
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 0564683f48..b8b064d43b 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -98,11 +98,19 @@
#define QT_NO_QOBJECT
#define QT_FEATURE_process -1
#define QT_FEATURE_regularexpression -1
-#define QT_FEATURE_renameat2 -1
+#ifdef __GLIBC_PREREQ
+# define QT_FEATURE_renameat2 (__GLIBC_PREREQ(2, 28) ? 1 : -1)
+#else
+# define QT_FEATURE_renameat2 -1
+#endif
#define QT_FEATURE_settings -1
#define QT_FEATURE_sharedmemory -1
#define QT_FEATURE_slog2 -1
-#define QT_FEATURE_statx -1
+#ifdef __GLIBC_PREREQ
+# define QT_FEATURE_statx (__GLIBC_PREREQ(2, 28) ? 1 : -1)
+#else
+# define QT_FEATURE_statx -1
+#endif
#define QT_FEATURE_syslog -1
#define QT_NO_SYSTEMLOCALE
#define QT_FEATURE_systemsemaphore -1
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index d197688316..37cc40f577 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2212,10 +2212,19 @@ static bool readEtcFile(QUnixOSVersion &v, const char *filename,
return true;
}
-static bool readEtcOsRelease(QUnixOSVersion &v)
+static bool readOsRelease(QUnixOSVersion &v)
{
- return readEtcFile(v, "/etc/os-release", QByteArrayLiteral("ID="),
- QByteArrayLiteral("VERSION_ID="), QByteArrayLiteral("PRETTY_NAME="));
+ QByteArray id = QByteArrayLiteral("ID=");
+ QByteArray versionId = QByteArrayLiteral("VERSION_ID=");
+ QByteArray prettyName = QByteArrayLiteral("PRETTY_NAME=");
+
+ // man os-release(5) says:
+ // The file /etc/os-release takes precedence over /usr/lib/os-release.
+ // Applications should check for the former, and exclusively use its data
+ // if it exists, and only fall back to /usr/lib/os-release if it is
+ // missing.
+ return readEtcFile(v, "/etc/os-release", id, versionId, prettyName) ||
+ readEtcFile(v, "/usr/lib/os-release", id, versionId, prettyName);
}
static bool readEtcLsbRelease(QUnixOSVersion &v)
@@ -2297,7 +2306,7 @@ static bool readEtcDebianVersion(QUnixOSVersion &v)
static bool findUnixOsVersion(QUnixOSVersion &v)
{
- if (readEtcOsRelease(v))
+ if (readOsRelease(v))
return true;
if (readEtcLsbRelease(v))
return true;
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 9d20ef5088..d0cd5449f0 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -91,7 +91,6 @@ extern "C" NSString *NSTemporaryDirectory();
# include <sys/syscall.h>
# include <sys/sendfile.h>
# include <linux/fs.h>
-# include <linux/stat.h>
// in case linux/fs.h is too old and doesn't define it:
#ifndef FICLONE
@@ -112,6 +111,7 @@ static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newp
# endif
# if !QT_CONFIG(statx) && defined(SYS_statx)
+# include <linux/stat.h>
static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf)
{ return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); }
# elif !QT_CONFIG(statx) && !defined(SYS_statx)
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 8cefa7a118..4c780a9294 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -345,7 +345,6 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
sizeof(GIdleTimerSource)));
idleTimerSource->timerSource = timerSource;
g_source_set_can_recurse(&idleTimerSource->source, true);
- g_source_set_priority(&idleTimerSource->source, G_PRIORITY_DEFAULT_IDLE);
g_source_attach(&idleTimerSource->source, mainContext);
}
diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h
index 4157fbbd0e..f8b1ede943 100644
--- a/src/corelib/serialization/qxmlstream_p.h
+++ b/src/corelib/serialization/qxmlstream_p.h
@@ -1250,7 +1250,7 @@ bool QXmlStreamReaderPrivate::parse()
state_stack[tos] = 0;
return true;
} else if (act > 0) {
- if (++tos == stack_size-1)
+ if (++tos >= stack_size-1)
reallocateStack();
Value &val = sym_stack[tos];
diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm
index fa0dd87cfc..d3c4fbe5da 100644
--- a/src/corelib/tools/qtimezoneprivate_mac.mm
+++ b/src/corelib/tools/qtimezoneprivate_mac.mm
@@ -227,7 +227,7 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::nextTransition(qint64 afterMSecsSinc
QTimeZonePrivate::Data QMacTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
{
// The native API only lets us search forward, so we need to find an early-enough start:
- const NSTimeInterval lowerBound = std::numeric_limits<NSTimeInterval>::min();
+ const NSTimeInterval lowerBound = std::numeric_limits<NSTimeInterval>::lowest();
const qint64 endSecs = beforeMSecsSinceEpoch / 1000;
const int year = 366 * 24 * 3600; // a (long) year, in seconds
NSTimeInterval prevSecs = endSecs; // sentinel for later check
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 2d1f0fa823..5d582551a7 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -2053,7 +2053,7 @@ void QTextEngine::itemize() const
layoutData->string.detach();
string = reinterpret_cast<const ushort *>(layoutData->string.unicode());
uc = string + offset;
- e = uc + length;
+ e = string + length;
*const_cast<ushort*>(uc) = 0x21B5; // visual line separator
}
break;
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index cf4be3df95..8de9760710 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -133,6 +133,8 @@ QByteArray QHttpNetworkRequest::uri(bool throughProxy) const
QUrl copy = d->url;
if (copy.path().isEmpty())
copy.setPath(QStringLiteral("/"));
+ else
+ format |= QUrl::NormalizePathSegments;
QByteArray uri = copy.toEncoded(format);
return uri;
}
diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro
index 9f6c848e6a..52836bb8b6 100644
--- a/src/plugins/platforminputcontexts/ibus/ibus.pro
+++ b/src/plugins/platforminputcontexts/ibus/ibus.pro
@@ -3,12 +3,14 @@ TARGET = ibusplatforminputcontextplugin
QT += dbus gui-private
SOURCES += $$PWD/qibusplatforminputcontext.cpp \
$$PWD/qibusproxy.cpp \
+ $$PWD/qibusproxyportal.cpp \
$$PWD/qibusinputcontextproxy.cpp \
$$PWD/qibustypes.cpp \
$$PWD/main.cpp
HEADERS += $$PWD/qibusplatforminputcontext.h \
$$PWD/qibusproxy.h \
+ $$PWD/qibusproxyportal.h \
$$PWD/qibusinputcontextproxy.h \
$$PWD/qibustypes.h
diff --git a/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml
new file mode 100644
index 0000000000..1a5414d0ae
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml
@@ -0,0 +1,10 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.IBus.Portal">
+ <method name="CreateInputContext">
+ <arg name="name" direction="in" type="s"/>
+ <arg name="context" direction="out" type="o"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index f339938f86..0e587965ca 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -50,6 +50,7 @@
#include <qpa/qwindowsysteminterface.h>
#include "qibusproxy.h"
+#include "qibusproxyportal.h"
#include "qibusinputcontextproxy.h"
#include "qibustypes.h"
@@ -78,19 +79,23 @@ public:
{
delete context;
delete bus;
+ delete portalBus;
delete connection;
}
static QString getSocketPath();
- static QDBusConnection *createConnection();
+ QDBusConnection *createConnection();
void initBus();
void createBusProxy();
QDBusConnection *connection;
QIBusProxy *bus;
+ QIBusProxyPortal *portalBus; // bus and portalBus are alternative.
QIBusInputContextProxy *context;
+ QDBusServiceWatcher serviceWatcher;
+ bool usePortal; // return value of shouldConnectIbusPortal
bool valid;
bool busConnected;
QString predit;
@@ -103,20 +108,25 @@ public:
QIBusPlatformInputContext::QIBusPlatformInputContext ()
: d(new QIBusPlatformInputContextPrivate())
{
- QString socketPath = QIBusPlatformInputContextPrivate::getSocketPath();
- QFile file(socketPath);
- if (file.open(QFile::ReadOnly)) {
+ if (!d->usePortal) {
+ QString socketPath = QIBusPlatformInputContextPrivate::getSocketPath();
+ QFile file(socketPath);
+ if (file.open(QFile::ReadOnly)) {
#ifndef QT_NO_FILESYSTEMWATCHER
- // If KDE session save is used or restart ibus-daemon,
- // the applications could run before ibus-daemon runs.
- // We watch the getSocketPath() to get the launching ibus-daemon.
- m_socketWatcher.addPath(socketPath);
- connect(&m_socketWatcher, SIGNAL(fileChanged(QString)), this, SLOT(socketChanged(QString)));
+ qCDebug(qtQpaInputMethods) << "socketWatcher.addPath" << socketPath;
+ // If KDE session save is used or restart ibus-daemon,
+ // the applications could run before ibus-daemon runs.
+ // We watch the getSocketPath() to get the launching ibus-daemon.
+ m_socketWatcher.addPath(socketPath);
+ connect(&m_socketWatcher, SIGNAL(fileChanged(QString)), this, SLOT(socketChanged(QString)));
#endif
+ }
+ m_timer.setSingleShot(true);
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(connectToBus()));
}
- m_timer.setSingleShot(true);
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(connectToBus()));
+ QObject::connect(&d->serviceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(busRegistered(QString)));
+ QObject::connect(&d->serviceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(busUnregistered(QString)));
connectToContextSignals();
@@ -507,6 +517,9 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
QLocale QIBusPlatformInputContext::locale() const
{
+ // d->locale is not updated when IBus portal is used
+ if (d->usePortal)
+ return QPlatformInputContext::locale();
return d->locale;
}
@@ -527,6 +540,22 @@ void QIBusPlatformInputContext::socketChanged(const QString &str)
m_timer.start(100);
}
+void QIBusPlatformInputContext::busRegistered(const QString &str)
+{
+ qCDebug(qtQpaInputMethods) << "busRegistered";
+ Q_UNUSED (str);
+ if (d->usePortal) {
+ connectToBus();
+ }
+}
+
+void QIBusPlatformInputContext::busUnregistered(const QString &str)
+{
+ qCDebug(qtQpaInputMethods) << "busUnregistered";
+ Q_UNUSED (str);
+ d->busConnected = false;
+}
+
// When getSocketPath() is modified, the bus is not established yet
// so use m_timer.
void QIBusPlatformInputContext::connectToBus()
@@ -536,7 +565,7 @@ void QIBusPlatformInputContext::connectToBus()
connectToContextSignals();
#ifndef QT_NO_FILESYSTEMWATCHER
- if (m_socketWatcher.files().size() == 0)
+ if (!d->usePortal && m_socketWatcher.files().size() == 0)
m_socketWatcher.addPath(QIBusPlatformInputContextPrivate::getSocketPath());
#endif
}
@@ -572,15 +601,34 @@ void QIBusPlatformInputContext::connectToContextSignals()
}
}
+static inline bool checkRunningUnderFlatpak()
+{
+ return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty();
+}
+
+static bool shouldConnectIbusPortal()
+{
+ // honor the same env as ibus-gtk
+ return (checkRunningUnderFlatpak() || !qgetenv("IBUS_USE_PORTAL").isNull());
+}
+
QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
: connection(0),
bus(0),
+ portalBus(0),
context(0),
+ usePortal(shouldConnectIbusPortal()),
valid(false),
busConnected(false),
needsSurroundingText(false)
{
- valid = !QStandardPaths::findExecutable(QString::fromLocal8Bit("ibus-daemon"), QStringList()).isEmpty();
+ if (usePortal) {
+ valid = true;
+ if (debug)
+ qDebug() << "use IBus portal";
+ } else {
+ valid = !QStandardPaths::findExecutable(QString::fromLocal8Bit("ibus-daemon"), QStringList()).isEmpty();
+ }
if (!valid)
return;
initBus();
@@ -603,21 +651,40 @@ void QIBusPlatformInputContextPrivate::createBusProxy()
if (!connection || !connection->isConnected())
return;
- bus = new QIBusProxy(QLatin1String("org.freedesktop.IBus"),
- QLatin1String("/org/freedesktop/IBus"),
- *connection);
- if (!bus->isValid()) {
- qWarning("QIBusPlatformInputContext: invalid bus.");
- return;
+ const char* ibusService = usePortal ? "org.freedesktop.portal.IBus" : "org.freedesktop.IBus";
+ QDBusReply<QDBusObjectPath> ic;
+ if (usePortal) {
+ portalBus = new QIBusProxyPortal(QLatin1String(ibusService),
+ QLatin1String("/org/freedesktop/IBus"),
+ *connection);
+ if (!portalBus->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid portal bus.");
+ return;
+ }
+
+ ic = portalBus->CreateInputContext(QLatin1String("QIBusInputContext"));
+ } else {
+ bus = new QIBusProxy(QLatin1String(ibusService),
+ QLatin1String("/org/freedesktop/IBus"),
+ *connection);
+ if (!bus->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid bus.");
+ return;
+ }
+
+ ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
}
- QDBusReply<QDBusObjectPath> ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
+ serviceWatcher.removeWatchedService(ibusService);
+ serviceWatcher.setConnection(*connection);
+ serviceWatcher.addWatchedService(ibusService);
+
if (!ic.isValid()) {
qWarning("QIBusPlatformInputContext: CreateInputContext failed.");
return;
}
- context = new QIBusInputContextProxy(QLatin1String("org.freedesktop.IBus"), ic.value().path(), *connection);
+ context = new QIBusInputContextProxy(QLatin1String(ibusService), ic.value().path(), *connection);
if (!context->isValid()) {
qWarning("QIBusPlatformInputContext: invalid input context.");
@@ -665,6 +732,8 @@ QString QIBusPlatformInputContextPrivate::getSocketPath()
QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
{
+ if (usePortal)
+ return new QDBusConnection(QDBusConnection::connectToBus(QDBusConnection::SessionBus, QLatin1String("QIBusProxy")));
QFile file(getSocketPath());
if (!file.open(QFile::ReadOnly))
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
index 9b92b2e1f9..f37552b937 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
@@ -108,6 +108,8 @@ public Q_SLOTS:
void showPreeditText();
void filterEventFinished(QDBusPendingCallWatcher *call);
void socketChanged(const QString &str);
+ void busRegistered(const QString &str);
+ void busUnregistered(const QString &str);
void connectToBus();
void globalEngineChanged(const QString &engine_name);
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp
new file mode 100644
index 0000000000..50482e2d9a
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -N -p qibusproxyportal -c QIBusProxyPortal interfaces/org.freedesktop.IBus.Portal.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "qibusproxyportal.h"
+
+/*
+ * Implementation of interface class QIBusProxyPortal
+ */
+
+QIBusProxyPortal::QIBusProxyPortal(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QIBusProxyPortal::~QIBusProxyPortal()
+{
+}
+
diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxyportal.h b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.h
new file mode 100644
index 0000000000..bdd1d9c395
--- /dev/null
+++ b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.h
@@ -0,0 +1,49 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -N -p qibusproxyportal -c QIBusProxyPortal interfaces/org.freedesktop.IBus.Portal.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef QIBUSPROXYPORTAL_H
+#define QIBUSPROXYPORTAL_H
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+
+/*
+ * Proxy class for interface org.freedesktop.IBus.Portal
+ */
+class QIBusProxyPortal: public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ { return "org.freedesktop.IBus.Portal"; }
+
+public:
+ QIBusProxyPortal(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr);
+
+ ~QIBusProxyPortal();
+
+public Q_SLOTS: // METHODS
+ inline QDBusPendingReply<QDBusObjectPath> CreateInputContext(const QString &name)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(name);
+ return asyncCallWithArgumentList(QStringLiteral("CreateInputContext"), argumentList);
+ }
+
+Q_SIGNALS: // SIGNALS
+};
+
+#endif
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 612290c9bd..0f87109ada 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -72,6 +72,12 @@
#include <IOKit/graphics/IOGraphicsLib.h>
+#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
+@interface NSApplication (MojaveForwardDeclarations)
+@property (strong) NSAppearance *appearance NS_AVAILABLE_MAC(10_14);
+@end
+#endif
+
static void initResources()
{
Q_INIT_RESOURCE(qcocoaresources);
@@ -133,6 +139,21 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
NSApplication *cocoaApplication = [QNSApplication sharedApplication];
qt_redirectNSApplicationSendEvent();
+ if (__builtin_available(macOS 10.14, *)) {
+ // Disable dark appearance, unless the Info.plist or environment requests that it should be enabled
+ bool plistEnablesDarkAppearance = [[[NSBundle mainBundle] objectForInfoDictionaryKey:
+ @"NSRequiresAquaSystemAppearance"] boolValue];
+
+ bool hasEnvironmentRequiresAquaAppearance;
+ int environmentRequiresAquaAppearance = qEnvironmentVariableIntValue(
+ "QT_MAC_REQUIRES_AQUA_SYSTEM_APPEARANCE", &hasEnvironmentRequiresAquaAppearance);
+ bool environmentEnablesDarkAppearance = hasEnvironmentRequiresAquaAppearance
+ && environmentRequiresAquaAppearance == 0;
+
+ if (!(plistEnablesDarkAppearance || environmentEnablesDarkAppearance))
+ NSApp.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
+ }
+
if (qEnvironmentVariableIsEmpty("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM")) {
// Applications launched from plain executables (without an app
// bundle) are "background" applications that does not take keybaord
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index e73e6f3e61..c29eb29b7e 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -85,7 +85,8 @@ class QXcbBackingStore;
class QXcbBackingStoreImage : public QXcbObject
{
public:
- QXcbBackingStoreImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format);
+ QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size);
+ QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size, uint depth, QImage::Format format);
~QXcbBackingStoreImage() { destroy(true); }
void resize(const QSize &size);
@@ -109,10 +110,10 @@ public:
xcb_shm_segment_info_t *shm_info = nullptr);
private:
- void createShmSegment(size_t segmentSize);
- void destroyShmSegment(size_t segmentSize);
+ void init(const QSize &size, uint depth, QImage::Format format);
- void create(const QSize &size, const xcb_format_t *fmt, QImage::Format format);
+ void createShmSegment(size_t segmentSize);
+ void destroyShmSegment();
void destroy(bool destroyShm);
void ensureGC(xcb_drawable_t dst);
@@ -120,10 +121,9 @@ private:
void flushPixmap(const QRegion &region, bool fullRegion = false);
void setClip(const QRegion &region);
- xcb_window_t m_screen_root;
-
xcb_shm_segment_info_t m_shm_info;
size_t m_segmentSize = 0;
+ QXcbBackingStore *m_backingStore = nullptr;
xcb_image_t *m_xcb_image = nullptr;
@@ -153,6 +153,9 @@ private:
bool m_hasAlpha = false;
bool m_clientSideScroll = false;
+
+ const xcb_format_t *m_xcb_format = nullptr;
+ QImage::Format m_qimage_format = QImage::Format_Invalid;
};
class QXcbGraphicsBuffer : public QPlatformGraphicsBuffer
@@ -190,83 +193,108 @@ static inline size_t imageDataSize(const xcb_image_t *image)
return static_cast<size_t>(image->stride) * image->height;
}
-QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
- : QXcbObject(screen->connection())
- , m_screen_root(screen->screen()->root)
+QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size)
+ : QXcbObject(backingStore->connection())
+ , m_backingStore(backingStore)
{
- const xcb_format_t *fmt = connection()->formatForDepth(depth);
- Q_ASSERT(fmt);
+ auto window = static_cast<QXcbWindow *>(m_backingStore->window()->handle());
+ init(size, window->depth(), window->imageFormat());
+}
- memset(&m_shm_info, 0, sizeof m_shm_info);
+QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size,
+ uint depth, QImage::Format format)
+ : QXcbObject(backingStore->connection())
+ , m_backingStore(backingStore)
+{
+ init(size, depth, format);
+}
- m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha;
+void QXcbBackingStoreImage::init(const QSize &size, uint depth, QImage::Format format)
+{
+ m_xcb_format = connection()->formatForDepth(depth);
+ Q_ASSERT(m_xcb_format);
+
+ m_qimage_format = format;
+ m_hasAlpha = QImage::toPixelFormat(m_qimage_format).alphaUsage() == QPixelFormat::UsesAlpha;
if (!m_hasAlpha)
- create(size, fmt, qt_maybeAlphaVersionWithSameDepth(format));
- else
- create(size, fmt, format);
+ m_qimage_format = qt_maybeAlphaVersionWithSameDepth(m_qimage_format);
+
+ memset(&m_shm_info, 0, sizeof m_shm_info);
+
+ resize(size);
}
void QXcbBackingStoreImage::resize(const QSize &size)
{
- xcb_format_t fmt;
- fmt.depth = m_xcb_image->depth;
- fmt.bits_per_pixel = m_xcb_image->bpp;
- fmt.scanline_pad = m_xcb_image->scanline_pad;
- memset(fmt.pad0, 0, sizeof(fmt.pad0));
destroy(false);
- create(size, &fmt, m_qimage.format());
-}
-void QXcbBackingStoreImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format)
-{
+ auto byteOrder = QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST
+ : XCB_IMAGE_ORDER_LSB_FIRST;
m_xcb_image = xcb_image_create(size.width(), size.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
- fmt->scanline_pad,
- fmt->depth, fmt->bits_per_pixel, 0,
- QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
+ m_xcb_format->scanline_pad,
+ m_xcb_format->depth,
+ m_xcb_format->bits_per_pixel,
+ 0, byteOrder,
XCB_IMAGE_ORDER_MSB_FIRST,
0, ~0, 0);
const size_t segmentSize = imageDataSize(m_xcb_image);
- if (!segmentSize)
- return;
if (connection()->hasShm()) {
- if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize))
- destroyShmSegment(m_segmentSize);
- if (!m_shm_info.shmaddr) {
- qCDebug(lcQpaXcb) << "creating shared memory" << segmentSize << "for"
- << size << "depth" << fmt->depth << "bits" << fmt->bits_per_pixel;
- createShmSegment(segmentSize);
+ if (segmentSize == 0) {
+ if (m_segmentSize > 0) {
+ destroyShmSegment();
+ qCDebug(lcQpaXcb) << "[" << m_backingStore->window()
+ << "] destroyed SHM segment due to resize to" << size;
+ }
+ } else {
+ // Destroy shared memory segment if it is double (or more) of what we actually
+ // need with new window size. Or if the new size is bigger than what we currently
+ // have allocated.
+ if (m_shm_info.shmaddr && (m_segmentSize < segmentSize || m_segmentSize / 2 >= segmentSize))
+ destroyShmSegment();
+ if (!m_shm_info.shmaddr) {
+ qCDebug(lcQpaXcb) << "[" << m_backingStore->window()
+ << "] creating shared memory" << segmentSize << "bytes for"
+ << size << "depth" << m_xcb_format->depth << "bits"
+ << m_xcb_format->bits_per_pixel;
+ createShmSegment(segmentSize);
+ }
}
}
- m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize);
+ if (segmentSize == 0)
+ return;
- m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
+ m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize);
+ m_qimage = QImage(static_cast<uchar *>(m_xcb_image->data), m_xcb_image->width,
+ m_xcb_image->height, m_xcb_image->stride, m_qimage_format);
m_graphics_buffer = new QXcbGraphicsBuffer(&m_qimage);
m_xcb_pixmap = xcb_generate_id(xcb_connection());
+ auto xcbScreen = static_cast<QXcbScreen *>(m_backingStore->window()->screen()->handle());
xcb_create_pixmap(xcb_connection(),
m_xcb_image->depth,
m_xcb_pixmap,
- m_screen_root,
+ xcbScreen->root(),
m_xcb_image->width, m_xcb_image->height);
}
void QXcbBackingStoreImage::destroy(bool destroyShm)
{
- if (m_xcb_image->data) {
- if (m_shm_info.shmaddr) {
- if (destroyShm)
- destroyShmSegment(m_segmentSize);
- } else {
- free(m_xcb_image->data);
+ if (m_xcb_image) {
+ if (m_xcb_image->data) {
+ if (m_shm_info.shmaddr) {
+ if (destroyShm)
+ destroyShmSegment();
+ } else {
+ free(m_xcb_image->data);
+ }
}
+ xcb_image_destroy(m_xcb_image);
}
- xcb_image_destroy(m_xcb_image);
-
if (m_gc) {
xcb_free_gc(xcb_connection(), m_gc);
m_gc = 0;
@@ -276,8 +304,12 @@ void QXcbBackingStoreImage::destroy(bool destroyShm)
delete m_graphics_buffer;
m_graphics_buffer = nullptr;
- xcb_free_pixmap(xcb_connection(), m_xcb_pixmap);
- m_xcb_pixmap = 0;
+ if (m_xcb_pixmap) {
+ xcb_free_pixmap(xcb_connection(), m_xcb_pixmap);
+ m_xcb_pixmap = 0;
+ }
+
+ m_qimage = QImage();
}
void QXcbBackingStoreImage::flushScrolledRegion(bool clientSideScroll)
@@ -420,11 +452,8 @@ bool QXcbBackingStoreImage::createSystemVShmSegment(QXcbConnection *c, size_t se
return true;
}
-void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize)
+void QXcbBackingStoreImage::destroyShmSegment()
{
-#ifndef XCB_USE_SHM_FD
- Q_UNUSED(segmentSize)
-#endif
auto cookie = xcb_shm_detach_checked(xcb_connection(), m_shm_info.shmseg);
xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
if (error)
@@ -433,9 +462,9 @@ void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize)
#ifdef XCB_USE_SHM_FD
if (connection()->hasShmFd()) {
- if (munmap(m_shm_info.shmaddr, segmentSize) == -1) {
+ if (munmap(m_shm_info.shmaddr, m_segmentSize) == -1) {
qCWarning(lcQpaXcb, "munmap() failed (%d: %s) for %p with size %zu",
- errno, strerror(errno), m_shm_info.shmaddr, segmentSize);
+ errno, strerror(errno), m_shm_info.shmaddr, m_segmentSize);
}
} else
#endif
@@ -894,7 +923,7 @@ void QXcbBackingStore::recreateImage(QXcbWindow *win, const QSize &size)
if (m_image)
m_image->resize(size);
else
- m_image = new QXcbBackingStoreImage(win->xcbScreen(), size, win->depth(), win->imageFormat());
+ m_image = new QXcbBackingStoreImage(this, size);
// Slow path for bgr888 VNC: Create an additional image, paint into that and
// swap R and B while copying to m_image after each paint.
@@ -1024,7 +1053,7 @@ void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &siz
if (m_image)
m_image->resize(size);
else
- m_image = new QXcbBackingStoreImage(screen, size, 32, QImage::Format_ARGB32_Premultiplied);
+ m_image = new QXcbBackingStoreImage(this, size, 32, QImage::Format_ARGB32_Premultiplied);
#endif // QT_CONFIG(xcb_render)
}
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
index e18a08755b..44c7d22344 100644
--- a/src/plugins/platforms/xcb/qxcbimage.cpp
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -69,7 +69,7 @@ QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask,
if (red_mask == 0xff && blue_mask == 0xff0000)
return QImage::Format_RGBA8888_Premultiplied;
#else
- if (red_mask == 0xff000000 && blue_mask == 0xff00)
+ if (unsigned(red_mask) == unsigned(0xff000000) && blue_mask == 0xff00)
return QImage::Format_RGBA8888_Premultiplied;
#endif
if (red_mask == 0x3ff && blue_mask == 0x3ff00000)
@@ -90,7 +90,7 @@ QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask,
if (red_mask == 0xff && blue_mask == 0xff0000)
return QImage::Format_RGBX8888;
#else
- if (red_mask == 0xff000000 && blue_mask == 0xff00)
+ if (unsigned(red_mask) == unsigned(0xff000000) && blue_mask == 0xff00)
return QImage::Format_RGBX8888;
#endif
break;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 52ca88891e..6de952a1d3 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -1022,6 +1022,16 @@ void QMessageBoxPrivate::detectEscapeButton()
return;
}
+ // If there are two buttons and one of them is the "Show Details..."
+ // button, then make the other one the escape button
+ if (buttons.count() == 2 && detailsButton) {
+ auto idx = buttons.indexOf(detailsButton);
+ if (idx != -1) {
+ detectedEscapeButton = buttons.at(1 - idx);
+ return;
+ }
+ }
+
// if the message box has one RejectRole button, make it the escape button
for (auto *button : buttons) {
if (buttonBox->buttonRole(button) == QDialogButtonBox::RejectRole) {
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index ec75ec7caf..7f685b0338 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -153,3 +153,4 @@ if (NOT CMAKE_VERSION VERSION_LESS 3.8)
# /usr/bin/ld: CMakeFiles/mywidget.dir/moc_mywidget.cpp.o: previous definition here
# Reason: SKIP_* properties were added in CMake 3.8 only
expect_pass(test_QTBUG-63422)
+endif()
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index 4e3d1da8fe..9c477589f9 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -137,6 +137,7 @@ private slots:
void nbspWithFormat();
void noModificationOfInputString();
void superscriptCrash_qtbug53911();
+ void showLineAndParagraphSeparatorsCrash();
private:
QFont testFont;
@@ -2199,6 +2200,23 @@ void tst_QTextLayout::noModificationOfInputString()
}
}
+void tst_QTextLayout::showLineAndParagraphSeparatorsCrash()
+{
+ QString s = QString(100000, QChar('a')) + QChar(QChar::LineSeparator);
+ {
+ QTextLayout layout;
+ layout.setText(s);
+
+ QTextOption option;
+ option.setFlags(QTextOption::ShowLineAndParagraphSeparators);
+ layout.setTextOption(option);
+
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+ }
+}
+
void tst_QTextLayout::superscriptCrash_qtbug53911()
{
static int fontSizes = 64;
diff --git a/tests/auto/other/qfocusevent/qfocusevent.pro b/tests/auto/other/qfocusevent/qfocusevent.pro
index 5f799291c6..95445f30fa 100644
--- a/tests/auto/other/qfocusevent/qfocusevent.pro
+++ b/tests/auto/other/qfocusevent/qfocusevent.pro
@@ -1,4 +1,4 @@
CONFIG += testcase
TARGET = tst_qfocusevent
-QT += widgets testlib
+QT += widgets testlib gui-private
SOURCES += tst_qfocusevent.cpp
diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
index 1b02c9e8ab..260ba12a97 100644
--- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
+++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
@@ -38,6 +38,9 @@
#include <QBoxLayout>
#include <QSysInfo>
+#include <qpa/qplatformintegration.h>
+#include <private/qguiapplication_p.h>
+
QT_FORWARD_DECLARE_CLASS(QWidget)
class FocusLineEdit : public QLineEdit
@@ -92,13 +95,16 @@ private slots:
void checkReason_ActiveWindow();
private:
- QWidget* testFocusWidget;
+ QWidget* testFocusWidget = nullptr;
FocusLineEdit* childFocusWidgetOne;
FocusLineEdit* childFocusWidgetTwo;
};
void tst_QFocusEvent::initTestCase()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("QWindow::requestActivate() is not supported on this platform.");
+
testFocusWidget = new QWidget( 0 );
childFocusWidgetOne = new FocusLineEdit( testFocusWidget );
childFocusWidgetOne->setGeometry( 10, 10, 180, 20 );
diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
index 5c9e0a46cf..049468fd7c 100644
--- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
+++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
@@ -331,6 +331,12 @@ void tst_QMessageBox::escapeButton()
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox2);
msgBox2.exec();
QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
+
+ QMessageBox msgBox3;
+ msgBox3.setDetailedText("Details");
+ closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox3);
+ msgBox3.exec();
+ QVERIFY(msgBox3.clickedButton() == msgBox3.button(QMessageBox::Ok)); // auto detected
}
void tst_QMessageBox::statics()