1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qtest.h>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QTemporaryFile>
#include <QtQml/QQmlApplicationEngine>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <private/qquickwindow_p.h>
using namespace Qt::StringLiterals;
class tst_qquickwindow_appless: public QQmlDataTest
{
Q_OBJECT
public:
tst_qquickwindow_appless()
: QQmlDataTest(QT_QMLTEST_DATADIR)
{}
private slots:
void screenBindingsAreUpdatedAfterAScreenChange();
};
void tst_qquickwindow_appless::screenBindingsAreUpdatedAfterAScreenChange()
{
QJsonDocument configuration{
QJsonObject {
{
"screens", QJsonArray {
QJsonObject {
{"name", "firstScreen"},
{"x", 0},
{"y", 0},
{"width", 640},
{"height", 480},
{"logicalDpi", 96},
{"logicalBaseDpi", 96},
{"dpr", 1}
},
QJsonObject {
{"name", "secondScreen"},
{"x", 640},
{"y", 0},
{"width", 640},
{"height", 480},
{"logicalDpi", 96},
{"logicalBaseDpi", 96},
{"dpr", 1}
}
}
}
}};
// We would generally use a QTemporaryFile here.
// At the time of writing the argument parser for the platform plugin, which
// we are forcing to offscreen with the following file used for
// configuration, doesn't correctly handle colons (https://bugreports.qt.io/browse/QTBUG-130346).
// The usage of QTemporaryFile and its filename implementation showed to
// generally produce a path with a drive in it on Windows platforms in CI
// checks, which clashs with the current behavior of the argument parser.
// The following code is used as a substitute as it avoids the issue.
// The `QFile` code was taken from `tst_highdpi` in qtbase, which performs the same
// operation of configuring custom screens to the offscreen plugins.
QFile configurationFile(QLatin1String("qt-offscreen-test-config.json"));
if (!configurationFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
configurationFile.resize(0); // truncate
if (configurationFile.write(configuration.toJson()) == -1)
qFatal("Could not write config file: %s", qPrintable(configurationFile.errorString()));
configurationFile.close();
static QByteArray nameArgument = QByteArray("tst_qquickwindow_appless");
static QByteArray platformArgument = QByteArray("-platform");
static QByteArray offscreenAndConfigurationArgument;
offscreenAndConfigurationArgument = QByteArray("offscreen:configfile=") + configurationFile.fileName().toUtf8();
static int argc = 3;
static char *argv[3];
argv[0] = nameArgument.data();
argv[1] = platformArgument.data();
argv[2] = offscreenAndConfigurationArgument.data();
QGuiApplication app(argc, argv);
configurationFile.remove(); // config file is needed during QGuiApplication construction only.
QQmlApplicationEngine engine(testFileUrl("screenBindingsAreUpdatedAfterAScreenChange.qml"));
QVERIFY(!engine.rootObjects().isEmpty());
QQuickWindow *window = qobject_cast<QQuickWindow*>(engine.rootObjects().first());
QVERIFY(window);
// Ensure that we show the window so that screen changes based on
// position can be applied.
window->show();
QCOMPARE(window->property("screenName").toString(), u"secondScreen"_s);
QCOMPARE(window->property("attachedScreenName").toString(), u"secondScreen"_s);
}
#include "tst_qquickwindow_appless.moc"
QTEST_APPLESS_MAIN(tst_qquickwindow_appless);
|