summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp')
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp504
1 files changed, 361 insertions, 143 deletions
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index a62f6c5699..b71a7a0a31 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -1,37 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#define QT_STATICPLUGIN
#include <QtWidgets/qstyleplugin.h>
#include <qdebug.h>
-#include <QtTest/QtTest>
+#include <QTest>
+#include <QTimer>
+#include <QLibraryInfo>
+#include <QSignalSpy>
+#include <QFileSystemWatcher>
+#include <QSharedMemory>
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/QFileInfo>
@@ -54,9 +34,11 @@
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QScrollArea>
#include <QtWidgets/QScrollBar>
+#include <QtWidgets/QHeaderView>
#include <QtWidgets/private/qapplication_p.h>
#include <QtWidgets/QStyle>
#include <QtWidgets/qproxystyle.h>
+#include <QtWidgets/QTextEdit>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qwindowsysteminterface_p.h>
@@ -90,6 +72,7 @@ private slots:
void setFont_data();
void setFont();
+ void setFontForClass();
void args_data();
void args();
@@ -111,13 +94,17 @@ private slots:
void libraryPaths_qt_plugin_path_2();
#endif
+#ifdef QT_BUILD_INTERNAL
void sendPostedEvents();
+#endif // ifdef QT_BUILD_INTERNAL
void thread();
void desktopSettingsAware();
void setActiveWindow();
+ void activateDeactivateEvent();
+ void focusWidget();
void focusChanged();
void focusOut();
void focusMouseClick();
@@ -143,6 +130,7 @@ private slots:
void wheelEventPropagation();
void qtbug_12673();
+ void qtbug_103611();
void noQuitOnHide();
void globalStaticObjectDestruction(); // run this last
@@ -178,6 +166,21 @@ void tst_QApplication::sendEventsOnProcessEvents()
QCoreApplication::postEvent(&app, new QEvent(QEvent::Type(QEvent::User + 1)));
QCoreApplication::processEvents();
+
+#ifdef Q_OS_LINUX
+ if ((QSysInfo::productType() == "rhel" && QSysInfo::productVersion().startsWith(u'9'))
+ || (QSysInfo::productType() == "ubuntu" && QSysInfo::productVersion().startsWith(u'2')))
+ {
+ QFile f("/proc/self/maps");
+ QVERIFY(f.open(QIODevice::ReadOnly));
+
+ QByteArray libs = f.readAll();
+ if (libs.contains("libqgtk3.") || libs.contains("libqgtk3TestInfix.")) {
+ QEXPECT_FAIL("", "Fails if qgtk3 (Glib) is loaded, see QTBUG-87137", Abort);
+ }
+ }
+#endif
+
QVERIFY(spy.recordedEvents.contains(QEvent::User + 1));
}
@@ -213,19 +216,65 @@ void tst_QApplication::staticSetup()
QVERIFY(style);
QApplication::setStyle(style);
- bool palette_changed = false;
QPalette pal;
QApplication::setPalette(pal);
-
- /*QFont font;
- QApplication::setFont(font);*/
+ QFont font;
+ QApplication::setFont(font);
int argc = 0;
QApplication app(argc, nullptr);
- QObject::connect(&app, &QApplication::paletteChanged, [&palette_changed]{ palette_changed = true; });
- QVERIFY(!palette_changed);
+
+ class EventWatcher : public QObject
+ {
+ public:
+ int palette_changed = 0;
+ int font_changed = 0;
+
+ EventWatcher()
+ {
+ qApp->installEventFilter(this);
+#if QT_DEPRECATED_SINCE(6, 0)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ QObject::connect(qApp, &QApplication::paletteChanged, [&]{ ++palette_changed; });
+ QObject::connect(qApp, &QApplication::fontChanged, [&]{ ++font_changed; });
+QT_WARNING_POP
+#endif
+ }
+
+ protected:
+ bool eventFilter(QObject *, QEvent *event) override
+ {
+ switch (event->type()) {
+ case QEvent::ApplicationPaletteChange:
+ ++palette_changed;
+ break;
+ case QEvent::ApplicationFontChange:
+ ++font_changed;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+ }
+ };
+
+ EventWatcher watcher;
+
+ QCOMPARE(watcher.palette_changed, 0);
+ QCOMPARE(watcher.font_changed, 0);
qApp->setPalette(QPalette(Qt::red));
- QVERIFY(palette_changed);
+
+ font.setBold(!font.bold());
+ qApp->setFont(font);
+ QApplication::processEvents();
+#if QT_DEPRECATED_SINCE(6, 0)
+ QCOMPARE(watcher.palette_changed, 2);
+ QCOMPARE(watcher.font_changed, 2);
+#else
+ QCOMPARE(watcher.palette_changed, 1);
+ QCOMPARE(watcher.font_changed, 1);
+#endif
}
@@ -262,10 +311,10 @@ void tst_QApplication::alert()
QApplication::alert(&widget, -1);
QApplication::alert(&widget, 250);
widget2.activateWindow();
- QApplication::setActiveWindow(&widget2);
+ QApplicationPrivate::setActiveWindow(&widget2);
QApplication::alert(&widget, 0);
widget.activateWindow();
- QApplication::setActiveWindow(&widget);
+ QApplicationPrivate::setActiveWindow(&widget);
QApplication::alert(&widget, 200);
}
@@ -328,13 +377,12 @@ void tst_QApplication::setFont_data()
int argc = 0;
QApplication app(argc, nullptr); // Needed for QFontDatabase
- QFontDatabase fdb;
- const QStringList &families = fdb.families();
+ const QStringList &families = QFontDatabase::families();
for (int i = 0, count = qMin(3, families.size()); i < count; ++i) {
const auto &family = families.at(i);
- const QStringList &styles = fdb.styles(family);
+ const QStringList &styles = QFontDatabase::styles(family);
if (!styles.isEmpty()) {
- QList<int> sizes = fdb.pointSizes(family, styles.constFirst());
+ QList<int> sizes = QFontDatabase::pointSizes(family, styles.constFirst());
if (sizes.isEmpty())
sizes = QFontDatabase::standardSizes();
if (!sizes.isEmpty()) {
@@ -383,6 +431,46 @@ void tst_QApplication::setFont()
QCOMPARE( app.font(), font );
}
+class tstHeaderView : public QHeaderView
+{
+ Q_OBJECT
+public:
+ explicit tstHeaderView(Qt::Orientation orientation, QWidget *parent = nullptr)
+ : QHeaderView(orientation, parent)
+ {}
+};
+class tstFrame : public QFrame { Q_OBJECT };
+class tstWidget : public QWidget { Q_OBJECT };
+
+void tst_QApplication::setFontForClass()
+{
+ // QTBUG-89910
+ // If a default font was not registered for the widget's class,
+ // it returns the default font of its nearest registered superclass.
+ int argc = 0;
+ QApplication app(argc, nullptr);
+
+ QFont font;
+ int pointSize = 10;
+ const QByteArrayList classNames{"QHeaderView", "QAbstractItemView", "QAbstractScrollView", "QFrame", "QWidget", "QObject"};
+ for (auto className : classNames) {
+ font.setPointSizeF(pointSize++);
+ app.setFont(font, className.constData());
+ }
+
+ tstHeaderView headView(Qt::Horizontal);
+ tstFrame frame;
+ tstWidget widget;
+
+ QFont headViewFont = QApplication::font(&headView);
+ QFont frameFont = QApplication::font(&frame);
+ QFont widgetFont = QApplication::font(&widget);
+
+ QCOMPARE(headViewFont.pointSize(), QApplication::font("QHeaderView").pointSize());
+ QCOMPARE(frameFont.pointSize(), QApplication::font("QFrame").pointSize());
+ QCOMPARE(widgetFont.pointSize(), QApplication::font("QWidget").pointSize());
+}
+
void tst_QApplication::args_data()
{
QTest::addColumn<int>("argc_in");
@@ -414,8 +502,8 @@ static char **QString2cstrings(const QString &args)
{
static QByteArrayList cache;
- const auto &list = args.splitRef(' ');
- auto argarray = new char*[list.count() + 1];
+ const auto &list = QStringView{ args }.split(' ');
+ auto argarray = new char*[list.size() + 1];
int i = 0;
for (; i < list.size(); ++i ) {
@@ -504,7 +592,7 @@ void tst_QApplication::lastWindowClosed()
QTimer::singleShot(1000, dialog.data(), &QDialog::accept);
dialog->exec();
QVERIFY(dialog);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QPointer<CloseWidget>widget = new CloseWidget;
widget->setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String("CloseWidget"));
@@ -513,7 +601,7 @@ void tst_QApplication::lastWindowClosed()
QObject::connect(&app, &QGuiApplication::lastWindowClosed, widget.data(), &QObject::deleteLater);
QCoreApplication::exec();
QVERIFY(!widget);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
spy.clear();
delete dialog;
@@ -531,7 +619,7 @@ void tst_QApplication::lastWindowClosed()
QTimer::singleShot(1000, &app, &QApplication::closeAllWindows);
QCoreApplication::exec();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
class QuitOnLastWindowClosedDialog : public QDialog
@@ -564,8 +652,8 @@ public slots:
other.exec();
// verify that the eventloop ran and let the timer fire
- QCOMPARE(spy.count(), 1);
- QCOMPARE(appSpy.count(), 1);
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(appSpy.size(), 1);
}
private:
@@ -590,7 +678,7 @@ public slots:
timer1.setSingleShot(true);
timer1.start(1000);
dialog.exec();
- QCOMPARE(spy1.count(), 1);
+ QCOMPARE(spy1.size(), 1);
show();
}
@@ -611,7 +699,7 @@ void tst_QApplication::quitOnLastWindowClosed()
QCoreApplication::exec();
// lastWindowClosed() signal should only be sent after the last dialog is closed
- QCOMPARE(appSpy.count(), 2);
+ QCOMPARE(appSpy.size(), 2);
}
{
int argc = 0;
@@ -626,8 +714,8 @@ void tst_QApplication::quitOnLastWindowClosed()
timer1.setSingleShot(true);
timer1.start(1000);
dialog.exec();
- QCOMPARE(spy1.count(), 1);
- QCOMPARE(appSpy.count(), 0);
+ QCOMPARE(spy1.size(), 1);
+ QCOMPARE(appSpy.size(), 0);
QTimer timer2;
connect(&timer2, &QTimer::timeout, &app, &QCoreApplication::quit);
@@ -636,8 +724,8 @@ void tst_QApplication::quitOnLastWindowClosed()
timer2.start(1000);
int returnValue = QCoreApplication::exec();
QCOMPARE(returnValue, 0);
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(appSpy.count(), 0);
+ QCOMPARE(spy2.size(), 1);
+ QCOMPARE(appSpy.size(), 0);
}
{
int argc = 0;
@@ -668,14 +756,14 @@ void tst_QApplication::quitOnLastWindowClosed()
QCoreApplication::exec();
- QCOMPARE(spy.count(), 1);
- QVERIFY(spy2.count() < 15); // Should be around 10 if closing caused the quit
+ QCOMPARE(spy.size(), 1);
+ QVERIFY(spy2.size() < 15); // Should be around 10 if closing caused the quit
}
bool quitApplicationTriggered = false;
auto quitSlot = [&quitApplicationTriggered] () {
quitApplicationTriggered = true;
- QCoreApplication::quit();
+ QCoreApplication::exit();
};
{
@@ -699,13 +787,13 @@ void tst_QApplication::quitOnLastWindowClosed()
QCoreApplication::exec();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QVERIFY(quitApplicationTriggered);
}
{
int argc = 0;
QApplication app(argc, nullptr);
- QSignalSpy appSpy(&app, &QApplication::lastWindowClosed);
+ QSignalSpy appSpy(&app, &QGuiApplication::lastWindowClosed);
// exec a dialog for 1 second, then show the window
QuitOnLastWindowClosedWindow window;
@@ -721,8 +809,8 @@ void tst_QApplication::quitOnLastWindowClosed()
QCOMPARE(returnValue, 0);
// failure here means the timer above didn't fire, and the
// quit was caused the dialog being closed (not the window)
- QCOMPARE(timerSpy.count(), 1);
- QCOMPARE(appSpy.count(), 2);
+ QCOMPARE(timerSpy.size(), 1);
+ QCOMPARE(appSpy.size(), 2);
}
{
int argc = 0;
@@ -771,7 +859,7 @@ void tst_QApplication::quitOnLastWindowClosed()
QTimer::singleShot(100, &w1, &QWidget::close);
QCoreApplication::exec();
- QVERIFY(timerSpy.count() < 10);
+ QVERIFY(timerSpy.size() < 10);
}
}
@@ -815,6 +903,7 @@ void tst_QApplication::closeAllWindows()
{
int argc = 0;
QApplication app(argc, nullptr);
+ app.setAttribute(Qt::AA_DontUseNativeDialogs, true);
// create some windows
new QWidget;
@@ -823,7 +912,7 @@ void tst_QApplication::closeAllWindows()
// show all windows
auto topLevels = QApplication::topLevelWidgets();
- for (QWidget *w : qAsConst(topLevels)) {
+ for (QWidget *w : std::as_const(topLevels)) {
w->show();
QVERIFY(QTest::qWaitForWindowExposed(w));
}
@@ -840,14 +929,14 @@ void tst_QApplication::closeAllWindows()
PromptOnCloseWidget *promptOnCloseWidget = new PromptOnCloseWidget;
// show all windows
topLevels = QApplication::topLevelWidgets();
- for (QWidget *w : qAsConst(topLevels)) {
+ for (QWidget *w : std::as_const(topLevels)) {
w->show();
QVERIFY(QTest::qWaitForWindowExposed(w));
}
// close the last window to open the prompt (eventloop recurses)
promptOnCloseWidget->close();
// all windows should not be visible, except the one that opened the prompt
- for (QWidget *w : qAsConst(topLevels)) {
+ for (QWidget *w : std::as_const(topLevels)) {
if (w == promptOnCloseWidget)
QVERIFY(w->isVisible());
else
@@ -859,8 +948,8 @@ void tst_QApplication::closeAllWindows()
bool isPathListIncluded(const QStringList &l, const QStringList &r)
{
- int size = r.count();
- if (size > l.count())
+ int size = r.size();
+ if (size > l.size())
return false;
#if defined (Q_OS_WIN)
Qt::CaseSensitivity cs = Qt::CaseInsensitive;
@@ -868,22 +957,22 @@ bool isPathListIncluded(const QStringList &l, const QStringList &r)
Qt::CaseSensitivity cs = Qt::CaseSensitive;
#endif
int i = 0, j = 0;
- for ( ; i < l.count() && j < r.count(); ++i) {
+ for ( ; i < l.size() && j < r.size(); ++i) {
if (QDir::toNativeSeparators(l[i]).compare(QDir::toNativeSeparators(r[j]), cs) == 0) {
++j;
i = -1;
}
}
- return j == r.count();
+ return j == r.size();
}
#if QT_CONFIG(library)
void tst_QApplication::libraryPaths()
{
#ifndef BUILTIN_TESTDATA
- const QString testDir = QFileInfo(QFINDTESTDATA("test/test.pro")).absolutePath();
+ const QString testDir = QFileInfo(QFINDTESTDATA("test/CMakeLists.txt")).absolutePath();
#else
- const QString testDir = QFileInfo(QFINDTESTDATA("test.pro")).absolutePath();
+ const QString testDir = QFileInfo(QFINDTESTDATA("CMakeLists.txt")).absolutePath();
#endif
QVERIFY(!testDir.isEmpty());
{
@@ -911,7 +1000,7 @@ void tst_QApplication::libraryPaths()
int argc = 1;
QApplication app(argc, &argv0);
QString appDirPath = QCoreApplication::applicationDirPath();
- QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
+ QString installPathPlugins = QLibraryInfo::path(QLibraryInfo::PluginsPath);
QStringList actual = QApplication::libraryPaths();
actual.sort();
@@ -934,18 +1023,18 @@ void tst_QApplication::libraryPaths()
{
qCDebug(lcTests) << "Initial library path:" << QApplication::libraryPaths();
- int count = QApplication::libraryPaths().count();
+ int count = QApplication::libraryPaths().size();
#if 0
// this test doesn't work if KDE 4 is installed
QCOMPARE(count, 1); // before creating QApplication, only the PluginsPath is in the libraryPaths()
#endif
- QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
+ QString installPathPlugins = QLibraryInfo::path(QLibraryInfo::PluginsPath);
QApplication::addLibraryPath(installPathPlugins);
qCDebug(lcTests) << "installPathPlugins" << installPathPlugins;
qCDebug(lcTests) << "After adding plugins path:" << QApplication::libraryPaths();
- QCOMPARE(QApplication::libraryPaths().count(), count);
+ QCOMPARE(QApplication::libraryPaths().size(), count);
QApplication::addLibraryPath(testDir);
- QCOMPARE(QApplication::libraryPaths().count(), count + 1);
+ QCOMPARE(QApplication::libraryPaths().size(), count + 1);
// creating QApplication adds the applicationDirPath to the libraryPath
int argc = 1;
@@ -955,19 +1044,19 @@ void tst_QApplication::libraryPaths()
// On Windows CE these are identical and might also be the case for other
// systems too
if (appDirPath != installPathPlugins)
- QCOMPARE(QApplication::libraryPaths().count(), count + 2);
+ QCOMPARE(QApplication::libraryPaths().size(), count + 2);
}
{
int argc = 1;
QApplication app(argc, &argv0);
qCDebug(lcTests) << "Initial library path:" << QCoreApplication::libraryPaths();
- int count = QCoreApplication::libraryPaths().count();
- QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
+ int count = QCoreApplication::libraryPaths().size();
+ QString installPathPlugins = QLibraryInfo::path(QLibraryInfo::PluginsPath);
QCoreApplication::addLibraryPath(installPathPlugins);
qCDebug(lcTests) << "installPathPlugins" << installPathPlugins;
qCDebug(lcTests) << "After adding plugins path:" << QCoreApplication::libraryPaths();
- QCOMPARE(QCoreApplication::libraryPaths().count(), count);
+ QCOMPARE(QCoreApplication::libraryPaths().size(), count);
QString appDirPath = QCoreApplication::applicationDirPath();
@@ -975,14 +1064,14 @@ void tst_QApplication::libraryPaths()
QCoreApplication::addLibraryPath(appDirPath + "/..");
qCDebug(lcTests) << "appDirPath" << appDirPath;
qCDebug(lcTests) << "After adding appDirPath && appDirPath + /..:" << QCoreApplication::libraryPaths();
- QCOMPARE(QCoreApplication::libraryPaths().count(), count + 1);
+ QCOMPARE(QCoreApplication::libraryPaths().size(), count + 1);
#ifdef Q_OS_MACOS
QCoreApplication::addLibraryPath(appDirPath + "/../MacOS");
#else
QCoreApplication::addLibraryPath(appDirPath + "/tmp/..");
#endif
qCDebug(lcTests) << "After adding appDirPath + /tmp/..:" << QCoreApplication::libraryPaths();
- QCOMPARE(QCoreApplication::libraryPaths().count(), count + 1);
+ QCOMPARE(QCoreApplication::libraryPaths().size(), count + 1);
}
}
@@ -1024,7 +1113,7 @@ void tst_QApplication::libraryPaths_qt_plugin_path_2()
// library path list should contain the default plus the one valid path
QStringList expected =
QStringList()
- << QLibraryInfo::location(QLibraryInfo::PluginsPath)
+ << QLibraryInfo::path(QLibraryInfo::PluginsPath)
<< QDir(QCoreApplication::applicationDirPath()).canonicalPath()
<< QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath();
@@ -1045,15 +1134,16 @@ void tst_QApplication::libraryPaths_qt_plugin_path_2()
// library path list should contain the default
QStringList expected =
QStringList()
- << QLibraryInfo::location(QLibraryInfo::PluginsPath)
+ << QLibraryInfo::path(QLibraryInfo::PluginsPath)
<< QCoreApplication::applicationDirPath();
QVERIFY(isPathListIncluded(QCoreApplication::libraryPaths(), expected));
- qputenv("QT_PLUGIN_PATH", QByteArray());
+ qputenv("QT_PLUGIN_PATH", nullptr);
}
}
#endif
+#ifdef QT_BUILD_INTERNAL
class SendPostedEventsTester : public QObject
{
Q_OBJECT
@@ -1075,14 +1165,14 @@ void SendPostedEventsTester::doTest()
QPointer<SendPostedEventsTester> p = this;
QApplication::postEvent(this, new QEvent(QEvent::User));
// DeferredDelete should not be delivered until returning from this function
- QApplication::postEvent(this, new QDeferredDeleteEvent());
+ deleteLater();
QEventLoop eventLoop;
QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
eventLoop.exec();
QVERIFY(p != nullptr);
- QCOMPARE(eventSpy.count(), 2);
+ QCOMPARE(eventSpy.size(), 2);
QCOMPARE(eventSpy.at(0), int(QEvent::MetaCall));
QCOMPARE(eventSpy.at(1), int(QEvent::User));
eventSpy.clear();
@@ -1099,6 +1189,7 @@ void tst_QApplication::sendPostedEvents()
(void) QCoreApplication::exec();
QVERIFY(p.isNull());
}
+#endif
void tst_QApplication::thread()
{
@@ -1243,12 +1334,9 @@ void DeleteLaterWidget::checkDeleteLater()
void tst_QApplication::testDeleteLater()
{
-#ifdef Q_OS_MAC
- QSKIP("This test fails and then hangs on OS X, see QTBUG-24318");
-#endif
int argc = 0;
QApplication app(argc, nullptr);
- connect(&app, &QApplication::lastWindowClosed, &app, &QCoreApplication::quit);
+ connect(&app, &QGuiApplication::lastWindowClosed, &app, &QCoreApplication::quit);
DeleteLaterWidget *wgt = new DeleteLaterWidget(&app);
QTimer::singleShot(500, wgt, &DeleteLaterWidget::runTest);
@@ -1438,7 +1526,12 @@ void tst_QApplication::desktopSettingsAware()
{
#if QT_CONFIG(process)
QProcess testProcess;
- testProcess.start("desktopsettingsaware_helper");
+#ifdef Q_OS_MACOS
+ QStringList environment = QProcess::systemEnvironment();
+ environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
+ testProcess.setEnvironment(environment);
+#endif
+ testProcess.start("./desktopsettingsaware_helper");
QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(10000));
@@ -1466,11 +1559,99 @@ void tst_QApplication::setActiveWindow()
delete pb2;
w->show();
- QApplication::setActiveWindow(w); // needs this on twm (focus follows mouse)
+ QApplicationPrivate::setActiveWindow(w); // needs this on twm (focus follows mouse)
QVERIFY(pb1->hasFocus());
delete w;
}
+void tst_QApplication::activateDeactivateEvent()
+{
+ // Ensure that QWindows (other than QWidgetWindow)
+ // are activated / deactivated.
+ class Window : public QWindow
+ {
+ public:
+ using QWindow::QWindow;
+
+ int activateCount = 0;
+ int deactivateCount = 0;
+ protected:
+ bool event(QEvent *e) override
+ {
+ switch (e->type()) {
+ case QEvent::WindowActivate:
+ ++activateCount;
+ break;
+ case QEvent::WindowDeactivate:
+ ++deactivateCount;
+ break;
+ default:
+ break;
+ }
+ return QWindow::event(e);
+ }
+ };
+
+ int argc = 0;
+ QApplication app(argc, nullptr);
+
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("QWindow::requestActivate() is not supported.");
+
+ Window w1;
+ Window w2;
+
+ w1.show();
+ w1.requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(&w1));
+ QCOMPARE(w1.activateCount, 1);
+ QCOMPARE(w1.deactivateCount, 0);
+
+ w2.show();
+ w2.requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(&w2));
+ QCOMPARE(w1.deactivateCount, 1);
+ QCOMPARE(w2.activateCount, 1);
+}
+
+void tst_QApplication::focusWidget()
+{
+ int argc = 0;
+ QApplication app(argc, nullptr);
+
+ // The focus widget is the active window itself
+ {
+ QTextEdit te;
+ te.show();
+
+ QApplicationPrivate::setActiveWindow(&te);
+ QVERIFY(QTest::qWaitForWindowActive(&te));
+
+ const auto focusWidget = QApplication::focusWidget();
+ QVERIFY(focusWidget);
+ QVERIFY(focusWidget->hasFocus());
+ QVERIFY(te.hasFocus());
+ QCOMPARE(focusWidget, te.focusWidget());
+ }
+
+ // The focus widget is a child of the active window
+ {
+ QWidget w;
+ QTextEdit te(&w);
+ w.show();
+
+ QApplicationPrivate::setActiveWindow(&w);
+ QVERIFY(QTest::qWaitForWindowActive(&w));
+
+ const auto focusWidget = QApplication::focusWidget();
+ QVERIFY(focusWidget);
+ QVERIFY(focusWidget->hasFocus());
+ QVERIFY(!w.hasFocus());
+ QVERIFY(te.hasFocus());
+ QCOMPARE(te.focusWidget(), w.focusWidget());
+ QCOMPARE(focusWidget, w.focusWidget());
+ }
+}
/* This might fail on some X11 window managers? */
void tst_QApplication::focusChanged()
@@ -1492,22 +1673,22 @@ void tst_QApplication::focusChanged()
hbox1.addWidget(&le1);
hbox1.addWidget(&pb1);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
parent1.show();
- QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
- QCOMPARE(spy.count(), 1);
- QCOMPARE(spy.at(0).count(), 2);
+ QApplicationPrivate::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
+ QCOMPARE(spy.size(), 1);
+ QCOMPARE(spy.at(0).size(), 2);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &le1);
QCOMPARE(now, QApplication::focusWidget());
QVERIFY(!old);
spy.clear();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
pb1.setFocus();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &pb1);
@@ -1516,7 +1697,7 @@ void tst_QApplication::focusChanged()
spy.clear();
lb1.setFocus();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &lb1);
@@ -1525,7 +1706,7 @@ void tst_QApplication::focusChanged()
spy.clear();
lb1.clearFocus();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QVERIFY(!now);
@@ -1544,10 +1725,10 @@ void tst_QApplication::focusChanged()
hbox2.addWidget(&pb2);
parent2.show();
- QApplication::setActiveWindow(&parent2); // needs this on twm (focus follows mouse)
- QVERIFY(spy.count() > 0); // one for deactivation, one for activation on Windows
- old = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(0));
- now = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(1));
+ QApplicationPrivate::setActiveWindow(&parent2); // needs this on twm (focus follows mouse)
+ QVERIFY(spy.size() > 0); // one for deactivation, one for activation on Windows
+ old = qvariant_cast<QWidget*>(spy.at(spy.size()-1).at(0));
+ now = qvariant_cast<QWidget*>(spy.at(spy.size()-1).at(1));
QCOMPARE(now, &le2);
QCOMPARE(now, QApplication::focusWidget());
QVERIFY(!old);
@@ -1572,10 +1753,10 @@ void tst_QApplication::focusChanged()
tab.simulate(now);
if (!tabAllControls) {
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(now, QApplication::focusWidget());
} else {
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &pb2);
@@ -1585,11 +1766,11 @@ void tst_QApplication::focusChanged()
}
if (!tabAllControls) {
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(now, QApplication::focusWidget());
} else {
tab.simulate(now);
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &le2);
@@ -1599,11 +1780,11 @@ void tst_QApplication::focusChanged()
}
if (!tabAllControls) {
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(now, QApplication::focusWidget());
} else {
backtab.simulate(now);
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &pb2);
@@ -1614,12 +1795,12 @@ void tst_QApplication::focusChanged()
if (!tabAllControls) {
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(now, QApplication::focusWidget());
old = &pb2;
} else {
backtab.simulate(now);
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &le2);
@@ -1630,10 +1811,10 @@ void tst_QApplication::focusChanged()
click.simulate(old);
if (!(pb2.focusPolicy() & Qt::ClickFocus)) {
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QCOMPARE(now, QApplication::focusWidget());
} else {
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &pb2);
@@ -1642,7 +1823,7 @@ void tst_QApplication::focusChanged()
spy.clear();
click.simulate(old);
- QVERIFY(spy.count() > 0);
+ QVERIFY(spy.size() > 0);
old = qvariant_cast<QWidget*>(spy.at(0).at(0));
now = qvariant_cast<QWidget*>(spy.at(0).at(1));
QCOMPARE(now, &le2);
@@ -1652,16 +1833,16 @@ void tst_QApplication::focusChanged()
}
parent1.activateWindow();
- QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
- QVERIFY(spy.count() == 1 || spy.count() == 2); // one for deactivation, one for activation on Windows
+ QApplicationPrivate::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
+ QVERIFY(spy.size() == 1 || spy.size() == 2); // one for deactivation, one for activation on Windows
//on windows, the change of focus is made in 2 steps
//(the focusChanged SIGNAL is emitted twice)
- if (spy.count()==1)
- old = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(0));
+ if (spy.size()==1)
+ old = qvariant_cast<QWidget*>(spy.at(spy.size()-1).at(0));
else
- old = qvariant_cast<QWidget*>(spy.at(spy.count()-2).at(0));
- now = qvariant_cast<QWidget*>(spy.at(spy.count()-1).at(1));
+ old = qvariant_cast<QWidget*>(spy.at(spy.size()-2).at(0));
+ now = qvariant_cast<QWidget*>(spy.at(spy.size()-1).at(1));
QCOMPARE(now, &le1);
QCOMPARE(now, QApplication::focusWidget());
QCOMPARE(old, &le2);
@@ -1735,7 +1916,7 @@ void tst_QApplication::focusMouseClick()
// front most widget has Qt::TabFocus, parent widget accepts clicks as well
// now send a mouse button press event and check what happens with the focus
// it should be given to the parent widget
- QMouseEvent ev(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent ev(QEvent::MouseButtonPress, QPointF(), w.mapToGlobal(QPointF()), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QSpontaneKeyEvent::setSpontaneous(&ev);
QVERIFY(ev.spontaneous());
qApp->notify(&w2, &ev);
@@ -1807,7 +1988,7 @@ class CustomStyle : public QProxyStyle
public:
CustomStyle() : QProxyStyle("Windows") { Q_ASSERT(!polished); }
~CustomStyle() { polished = 0; }
- void polish(QPalette &palette)
+ void polish(QPalette &palette) override
{
polished++;
palette.setColor(QPalette::Active, QPalette::Link, Qt::red);
@@ -1822,7 +2003,7 @@ class CustomStylePlugin : public QStylePlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "customstyle.json")
public:
- QStyle *create(const QString &) { return new CustomStyle; }
+ QStyle *create(const QString &) override { return new CustomStyle; }
};
Q_IMPORT_PLUGIN(CustomStylePlugin)
@@ -1836,7 +2017,7 @@ void tst_QApplication::applicationPalettePolish()
qputenv("QT_DESKTOP_STYLE_KEY", "customstyle");
QApplication app(argc, &argv0);
QVERIFY(CustomStyle::polished);
- QVERIFY(!app.palette().resolve());
+ QVERIFY(!app.palette().resolveMask());
QCOMPARE(app.palette().color(QPalette::Link), Qt::red);
qunsetenv("QT_DESKTOP_STYLE_KEY");
}
@@ -1846,7 +2027,7 @@ void tst_QApplication::applicationPalettePolish()
QApplication::setStyle(new CustomStyle);
QApplication app(argc, &argv0);
QVERIFY(CustomStyle::polished);
- QVERIFY(!app.palette().resolve());
+ QVERIFY(!app.palette().resolveMask());
QCOMPARE(app.palette().color(QPalette::Link), Qt::red);
}
@@ -1854,13 +2035,13 @@ void tst_QApplication::applicationPalettePolish()
QApplication app(argc, &argv0);
app.setStyle(new CustomStyle);
QVERIFY(CustomStyle::polished);
- QVERIFY(!app.palette().resolve());
+ QVERIFY(!app.palette().resolveMask());
QCOMPARE(app.palette().color(QPalette::Link), Qt::red);
CustomStyle::polished = 0;
app.setPalette(QPalette());
QVERIFY(CustomStyle::polished);
- QVERIFY(!app.palette().resolve());
+ QVERIFY(!app.palette().resolveMask());
QCOMPARE(app.palette().color(QPalette::Link), Qt::red);
CustomStyle::polished = 0;
@@ -1868,7 +2049,7 @@ void tst_QApplication::applicationPalettePolish()
palette.setColor(QPalette::Active, QPalette::Highlight, Qt::green);
app.setPalette(palette);
QVERIFY(CustomStyle::polished);
- QVERIFY(app.palette().resolve());
+ QVERIFY(app.palette().resolveMask());
QCOMPARE(app.palette().color(QPalette::Link), Qt::red);
QCOMPARE(app.palette().color(QPalette::Highlight), Qt::green);
}
@@ -1896,11 +2077,11 @@ void tst_QApplication::topLevelWidgets()
#endif
QCoreApplication::processEvents();
QVERIFY(QApplication::topLevelWidgets().contains(w));
- QCOMPARE(QApplication::topLevelWidgets().count(), 1);
+ QCOMPARE(QApplication::topLevelWidgets().size(), 1);
delete w;
w = nullptr;
QCoreApplication::processEvents();
- QCOMPARE(QApplication::topLevelWidgets().count(), 0);
+ QCOMPARE(QApplication::topLevelWidgets().size(), 0);
}
@@ -2317,7 +2498,7 @@ void tst_QApplication::wheelEventPropagation()
int vcount = 0;
int hcount = 0;
- for (const auto &event : qAsConst(events)) {
+ for (const auto &event : std::as_const(events)) {
const QPoint pixelDelta = event.orientation == Qt::Vertical ? QPoint(0, -scrollStep) : QPoint(-scrollStep, 0);
const QPoint angleDelta = event.orientation == Qt::Vertical ? QPoint(0, -120) : QPoint(-120, 0);
QWindowSystemInterface::handleWheelEvent(outerArea.windowHandle(), center, global,
@@ -2328,10 +2509,10 @@ void tst_QApplication::wheelEventPropagation()
else
++hcount;
QCoreApplication::processEvents();
- QCOMPARE(innerVSpy.count(), innerScrolls ? vcount : 0);
- QCOMPARE(innerHSpy.count(), innerScrolls ? hcount : 0);
- QCOMPARE(outerVSpy.count(), innerScrolls ? 0 : vcount);
- QCOMPARE(outerHSpy.count(), innerScrolls ? 0 : hcount);
+ QCOMPARE(innerVSpy.size(), innerScrolls ? vcount : 0);
+ QCOMPARE(innerHSpy.size(), innerScrolls ? hcount : 0);
+ QCOMPARE(outerVSpy.size(), innerScrolls ? 0 : vcount);
+ QCOMPARE(outerHSpy.size(), innerScrolls ? 0 : hcount);
}
}
@@ -2340,7 +2521,7 @@ void tst_QApplication::qtbug_12673()
#if QT_CONFIG(process)
QProcess testProcess;
QStringList arguments;
- testProcess.start("modal_helper", arguments);
+ testProcess.start("./modal_helper", arguments);
QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(20000));
@@ -2350,6 +2531,20 @@ void tst_QApplication::qtbug_12673()
#endif
}
+void tst_QApplication::qtbug_103611()
+{
+ {
+ int argc = 0;
+ QApplication app(argc, nullptr);
+ auto ll = QLocale().uiLanguages();
+ }
+ {
+ int argc = 0;
+ QApplication app(argc, nullptr);
+ auto ll = QLocale().uiLanguages();
+ }
+}
+
class NoQuitOnHideWidget : public QWidget
{
Q_OBJECT
@@ -2379,8 +2574,26 @@ public:
explicit ShowCloseShowWidget(bool showAgain, QWidget *parent = nullptr)
: QWidget(parent), showAgain(showAgain)
{
+ int timeout = 500;
+#ifdef Q_OS_ANDROID
+ // On Android, CI Android emulator is not running HW accelerated graphics and can be slow,
+ // use a longer timeout to avoid flaky failures
+ timeout = 1000;
+#endif
+ QTimer::singleShot(timeout, this, [] () { QCoreApplication::exit(1); });
+ }
+
+ bool shown = false;
+
+protected:
+ void showEvent(QShowEvent *) override
+ {
QTimer::singleShot(0, this, &ShowCloseShowWidget::doClose);
- QTimer::singleShot(500, this, [] () { QCoreApplication::exit(1); });
+ shown = true;
+ }
+ void hideEvent(QHideEvent *) override
+ {
+ shown = false;
}
private slots:
@@ -2396,16 +2609,21 @@ private:
void tst_QApplication::abortQuitOnShow()
{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
+ QSKIP("Wayland: This crash, see QTBUG-123172.");
+
int argc = 0;
QApplication app(argc, nullptr);
ShowCloseShowWidget window1(false);
window1.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
window1.show();
+ QVERIFY(QTest::qWaitFor([&window1](){ return window1.shown; }));
QCOMPARE(QCoreApplication::exec(), 0);
ShowCloseShowWidget window2(true);
window2.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
window2.show();
+ QVERIFY(QTest::qWaitFor([&window2](){ return window2.shown; }));
QCOMPARE(QCoreApplication::exec(), 1);
}
@@ -2415,14 +2633,15 @@ void tst_QApplication::staticFunctions()
QApplication::setStyle(QStringLiteral("blub"));
QApplication::allWidgets();
QApplication::topLevelWidgets();
- QApplication::desktop();
QApplication::activePopupWidget();
+ QTest::ignoreMessage(QtWarningMsg, "Must construct a QGuiApplication first.");
QApplication::activeModalWidget();
QApplication::focusWidget();
QApplication::activeWindow();
- QApplication::setActiveWindow(nullptr);
+ QApplicationPrivate::setActiveWindow(nullptr);
QApplication::widgetAt(QPoint(0, 0));
QApplication::topLevelAt(QPoint(0, 0));
+ QTest::ignoreMessage(QtWarningMsg, "Must construct a QApplication first.");
QApplication::isEffectEnabled(Qt::UI_General);
QApplication::setEffectEnabled(Qt::UI_General, false);
}
@@ -2475,7 +2694,6 @@ Q_GLOBAL_STATIC(QWidget, tst_qapp_widget);
Q_GLOBAL_STATIC(QPixmap, tst_qapp_pixmap);
Q_GLOBAL_STATIC(QFont, tst_qapp_font);
Q_GLOBAL_STATIC(QRegion, tst_qapp_region);
-Q_GLOBAL_STATIC(QFontDatabase, tst_qapp_fontDatabase);
#ifndef QT_NO_CURSOR
Q_GLOBAL_STATIC(QCursor, tst_qapp_cursor);
#endif
@@ -2500,7 +2718,6 @@ void tst_QApplication::globalStaticObjectDestruction()
QVERIFY(tst_qapp_pixmap());
QVERIFY(tst_qapp_font());
QVERIFY(tst_qapp_region());
- QVERIFY(tst_qapp_fontDatabase());
#ifndef QT_NO_CURSOR
QVERIFY(tst_qapp_cursor());
#endif
@@ -2511,6 +2728,7 @@ int main(int argc, char *argv[])
{
tst_QApplication tc;
argv0 = argv[0];
+ QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&tc, argc, argv);
}