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.cpp174
1 files changed, 164 insertions, 10 deletions
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index 57bd4515ad..2eb2d84504 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#define QT_STATICPLUGIN
#include <QtWidgets/qstyleplugin.h>
@@ -23,6 +23,7 @@
#include <QtGui/QFontDatabase>
#include <QtGui/QClipboard>
+#include <QtGui/QStyleHints>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMessageBox>
@@ -94,7 +95,9 @@ private slots:
void libraryPaths_qt_plugin_path_2();
#endif
+#ifdef QT_BUILD_INTERNAL
void sendPostedEvents();
+#endif // ifdef QT_BUILD_INTERNAL
void thread();
void desktopSettingsAware();
@@ -117,6 +120,7 @@ private slots:
void style();
void applicationPalettePolish();
+ void setColorScheme();
void allWidgets();
void topLevelWidgets();
@@ -164,6 +168,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));
}
@@ -294,10 +313,8 @@ void tst_QApplication::alert()
QApplication::alert(&widget, -1);
QApplication::alert(&widget, 250);
widget2.activateWindow();
- QApplicationPrivate::setActiveWindow(&widget2);
QApplication::alert(&widget, 0);
widget.activateWindow();
- QApplicationPrivate::setActiveWindow(&widget);
QApplication::alert(&widget, 200);
}
@@ -886,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;
@@ -1125,6 +1143,7 @@ void tst_QApplication::libraryPaths_qt_plugin_path_2()
}
#endif
+#ifdef QT_BUILD_INTERNAL
class SendPostedEventsTester : public QObject
{
Q_OBJECT
@@ -1146,7 +1165,7 @@ 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);
@@ -1170,6 +1189,7 @@ void tst_QApplication::sendPostedEvents()
(void) QCoreApplication::exec();
QVERIFY(p.isNull());
}
+#endif
void tst_QApplication::thread()
{
@@ -1314,9 +1334,6 @@ 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, &QGuiApplication::lastWindowClosed, &app, &QCoreApplication::quit);
@@ -1607,7 +1624,6 @@ void tst_QApplication::focusWidget()
QTextEdit te;
te.show();
- QApplicationPrivate::setActiveWindow(&te);
QVERIFY(QTest::qWaitForWindowActive(&te));
const auto focusWidget = QApplication::focusWidget();
@@ -1623,7 +1639,6 @@ void tst_QApplication::focusWidget()
QTextEdit te(&w);
w.show();
- QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
const auto focusWidget = QApplication::focusWidget();
@@ -2038,6 +2053,122 @@ void tst_QApplication::applicationPalettePolish()
}
}
+void tst_QApplication::setColorScheme()
+{
+ int argc = 1;
+ QApplication app(argc, &argv0);
+
+ if (QStringList{"minimal", "offscreen", "wayland", "xcb", "wasm", "webassembly"}
+ .contains(QGuiApplication::platformName(), Qt::CaseInsensitive)) {
+ QSKIP("Setting the colorScheme is not implemented on this platform.");
+ }
+ qDebug() << "Testing setColorScheme on platform" << QGuiApplication::platformName();
+
+ if (QByteArrayView(app.style()->metaObject()->className()) == "QWindowsVistaStyle")
+ QSKIP("Setting the colorScheme is not supported with the Windows Vista style.");
+
+ const Qt::ColorScheme defaultColorScheme = QApplication::styleHints()->colorScheme();
+ // if we implement setColorScheme, then we must be able to read it
+ QVERIFY(defaultColorScheme != Qt::ColorScheme::Unknown);
+ const Qt::ColorScheme newColorScheme = defaultColorScheme == Qt::ColorScheme::Light
+ ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
+
+ class TopLevelWidget : public QWidget
+ {
+ QList<QEvent::Type> events;
+ public:
+ TopLevelWidget()
+ {
+ setObjectName("colorScheme TopLevelWidget");
+ }
+
+ void clearEvents()
+ {
+ events.clear();
+ }
+ qsizetype eventCount(QEvent::Type type) const
+ {
+ return events.count(type);
+ }
+ protected:
+ bool event(QEvent *event) override
+ {
+ switch (event->type()) {
+ case QEvent::ApplicationPaletteChange:
+ case QEvent::PaletteChange:
+ case QEvent::ThemeChange:
+ events << event->type();
+ break;
+ default:
+ break;
+ }
+
+ return QWidget::event(event);
+ }
+ } topLevelWidget;
+ topLevelWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevelWidget));
+
+ QSignalSpy colorSchemeChangedSpy(app.styleHints(), &QStyleHints::colorSchemeChanged);
+
+ // always start with a clean list
+ topLevelWidget.clearEvents();
+ const QPalette defaultPalette = topLevelWidget.palette();
+
+ bool oldPaletteWhenSchemeChanged = false;
+ connect(app.styleHints(), &QStyleHints::colorSchemeChanged, this,
+ [defaultPalette, &topLevelWidget, &oldPaletteWhenSchemeChanged]{
+ oldPaletteWhenSchemeChanged = defaultPalette == topLevelWidget.palette();
+ });
+
+ app.styleHints()->setColorScheme(newColorScheme);
+ QTRY_COMPARE(colorSchemeChangedSpy.count(), 1);
+ // We have not yet updated the palette when we emit the colorSchemeChanged
+ // signal, so the toplevel widget should still use the previous palette
+ QVERIFY(oldPaletteWhenSchemeChanged);
+ QCOMPARE(topLevelWidget.eventCount(QEvent::ThemeChange), 1);
+ // We can't guarantee that there is only one ApplicationPaletteChange,
+ // and they might arrive asynchronously in response to ThemeChange
+ QTRY_COMPARE_GE(topLevelWidget.eventCount(QEvent::ApplicationPaletteChange), 1);
+ // But we can guarantee a single PaletteChange event for the widget
+ QCOMPARE(topLevelWidget.eventCount(QEvent::PaletteChange), 1);
+ // The palette should have changed
+ QCOMPARE_NE(topLevelWidget.palette(), defaultPalette);
+
+ topLevelWidget.clearEvents();
+ colorSchemeChangedSpy.clear();
+
+ // verify that a widget shown with a color scheme override in place respect that
+ QWidget newWidget;
+ newWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&newWidget));
+ QCOMPARE(newWidget.palette(), topLevelWidget.palette());
+
+ // Setting to Unknown should follow the system preference again
+ app.styleHints()->setColorScheme(Qt::ColorScheme::Unknown);
+ QTRY_COMPARE(colorSchemeChangedSpy.count(), 1);
+ QCOMPARE(app.styleHints()->colorScheme(), defaultColorScheme);
+ QTRY_COMPARE(topLevelWidget.eventCount(QEvent::PaletteChange), 1);
+
+ auto debugPalette = qScopeGuard([defaultPalette, &topLevelWidget]{
+ qDebug() << "Inspecting palettes for differences";
+ const QPalette palette = topLevelWidget.palette();
+ for (int g = 0; g < QPalette::NColorGroups; ++g) {
+ for (int r = 0; r < QPalette::NColorRoles; ++r) {
+ const auto group = static_cast<QPalette::ColorGroup>(g);
+ const auto role = static_cast<QPalette::ColorRole>(r);
+ qDebug() << "...Checking" << group << role;
+ const auto actualBrush = palette.brush(group, role);
+ const auto expectedBrush = defaultPalette.brush(group, role);
+ if (palette.brush(group, role) != defaultPalette.brush(group, role))
+ qWarning() << "...Difference in" << group << role << actualBrush << expectedBrush;
+ }
+ }
+ });
+ QCOMPARE(topLevelWidget.palette(), defaultPalette);
+ debugPalette.dismiss();
+}
+
void tst_QApplication::allWidgets()
{
int argc = 1;
@@ -2557,8 +2688,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:
@@ -2574,16 +2723,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);
}