156 bool hasConfigFile =
false;
157 QString configFilePath;
158 for (
const QString ¶m : paramList) {
160 QString configPrefix(
"configfile="_L1);
161 if (param.startsWith(configPrefix)) {
162 hasConfigFile =
true;
163 configFilePath = param.mid(configPrefix.size());
170 if (configFilePath.isEmpty())
171 qFatal(
"Missing file path for -configfile platform option");
172 QFile configFile(configFilePath);
173 if (!configFile.exists())
174 qFatal(
"Could not find platform config file %s", qPrintable(configFilePath));
175 if (!configFile.open(QIODevice::ReadOnly))
176 qFatal(
"Could not open platform config file for reading %s, %s", qPrintable(configFilePath), qPrintable(configFile.errorString()));
178 QByteArray json = configFile.readAll();
179 QJsonParseError error;
180 QJsonDocument config = QJsonDocument::fromJson(json, &error);
182 qFatal(
"Platform config file parse error: %s", qPrintable(error.errorString()));
184 return config.object();
192 const bool synchronousWindowSystemEvents = configuration[
"synchronousWindowSystemEvents"].toBool(
193 m_configuration[
"synchronousWindowSystemEvents"].toBool(
false));
194 QWindowSystemInterface::setSynchronousWindowSystemEvents(synchronousWindowSystemEvents);
197 m_configuration[
"windowFrameMargins"].toBool(
true));
200 QJsonArray currentScreens = m_configuration[
"screens"].toArray();
201 QJsonArray newScreens = configuration[
"screens"].toArray();
203 auto getScreenNames = [](
const QJsonArray &screens) -> QList<QString> {
204 QList<QString> names;
205 for (
const QJsonValue &screen : screens) {
206 names.append(screen[
"name"].toString());
208 std::sort(names.begin(), names.end());
212 auto currentNames = getScreenNames(currentScreens);
213 auto newNames = getScreenNames(newScreens);
215 QList<QString> present;
216 std::set_intersection(currentNames.begin(), currentNames.end(), newNames.begin(), newNames.end(),
217 std::inserter(present, present.begin()));
218 QList<QString> added;
219 std::set_difference(newNames.begin(), newNames.end(), currentNames.begin(), currentNames.end(),
220 std::inserter(added, added.begin()));
221 QList<QString> removed;
222 std::set_difference(currentNames.begin(), currentNames.end(), newNames.begin(), newNames.end(),
223 std::inserter(removed, removed.begin()));
225 auto platformScreenByName = [](
const QString &name,
const QList<QOffscreenScreen *> &screens) ->
QOffscreenScreen * {
226 for (QOffscreenScreen *screen : screens) {
227 if (screen->m_name == name)
233 auto screenConfigByName = [](
const QString &name,
const QJsonArray &screenConfigs) -> QJsonValue {
234 for (
const QJsonValue &screenConfig : screenConfigs) {
235 if (screenConfig[
"name"].toString() == name)
241 auto geometryFromConfig = [](
const QJsonObject &config) -> QRect {
242 return QRect(config[
"x"].toInt(0), config[
"y"].toInt(0), config[
"width"].toInt(640), config[
"height"].toInt(480));
246 for (
const QString &remove : std::as_const(removed)) {
247 QOffscreenScreen *screen = platformScreenByName(remove, m_screens);
248 m_screens.removeAll(screen);
249 QWindowSystemInterface::handleScreenRemoved(screen);
253 for (
const QString &add : std::as_const(added)) {
254 QJsonValue configValue = screenConfigByName(add, newScreens);
255 QJsonObject config = configValue.toObject();
256 if (config.isEmpty()) {
257 qWarning(
"empty screen object");
260 QOffscreenScreen *offscreenScreen =
new QOffscreenScreen(
this);
261 offscreenScreen->m_name = config[
"name"].toString();
262 offscreenScreen->m_geometry = geometryFromConfig(config);
263 offscreenScreen->m_logicalDpi = config[
"logicalDpi"].toInt(96);
264 offscreenScreen->m_logicalBaseDpi = config[
"logicalBaseDpi"].toInt(96);
265 offscreenScreen->m_dpr = config[
"dpr"].toDouble(1.0);
266 m_screens.append(offscreenScreen);
267 QWindowSystemInterface::handleScreenAdded(offscreenScreen);
271 for (
const QString &pres : std::as_const(present)) {
272 QOffscreenScreen *screen = platformScreenByName(pres, m_screens);
274 QJsonObject currentConfig = screenConfigByName(pres, currentScreens).toObject();
275 QJsonObject newConfig = screenConfigByName(pres, newScreens).toObject();
278 Q_ASSERT(currentConfig[
"name"] == newConfig[
"name"]);
281 QRect currentGeomtry = geometryFromConfig(currentConfig);
282 QRect newGeomtry = geometryFromConfig(newConfig);
283 if (currentGeomtry != newGeomtry) {
284 screen->m_geometry = newGeomtry;
285 QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), newGeomtry, newGeomtry);
289 int currentLogicalDpi = currentConfig[
"logicalDpi"].toInt(96);
290 int newLogicalDpi = newConfig[
"logicalDpi"].toInt(96);
291 if (currentLogicalDpi != newLogicalDpi) {
292 screen->m_logicalDpi = newLogicalDpi;
293 QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->screen(), newLogicalDpi, newLogicalDpi);
298 int currentLogicalBaseDpi = currentConfig[
"logicalBaseDpi"].toInt(96);
299 int newLogicalBaseDpi = newConfig[
"logicalBaseDpi"].toInt(96);
300 if (currentLogicalBaseDpi != newLogicalBaseDpi) {
301 screen->m_logicalBaseDpi = newLogicalBaseDpi;
302 qWarning(
"You ain't supposed to change logicalBaseDpi - its a platform constant. Qt may not react to the change");
308 double currentDpr = currentConfig[
"dpr"].toDouble(1);
309 double newDpr = newConfig[
"dpr"].toDouble(1);
310 if (currentDpr != newDpr) {
311 screen->m_dpr = newDpr;
312 qWarning(
"DPR change notifications is not implemented - Qt may not react to the change");
317 m_configuration = configuration;