141 bool hasConfigFile =
false;
142 QString configFilePath;
143 for (
const QString ¶m : paramList) {
145 QString configPrefix(
"configfile="_L1);
146 if (param.startsWith(configPrefix)) {
147 hasConfigFile =
true;
148 configFilePath = param.mid(configPrefix.size());
155 if (configFilePath.isEmpty())
156 qFatal(
"Missing file path for -configfile platform option");
157 QFile configFile(configFilePath);
158 if (!configFile.exists())
159 qFatal(
"Could not find platform config file %s", qPrintable(configFilePath));
160 if (!configFile.open(QIODevice::ReadOnly))
161 qFatal(
"Could not open platform config file for reading %s, %s", qPrintable(configFilePath), qPrintable(configFile.errorString()));
163 QByteArray json = configFile.readAll();
164 QJsonParseError error;
165 QJsonDocument config = QJsonDocument::fromJson(json, &error);
167 qFatal(
"Platform config file parse error: %s", qPrintable(error.errorString()));
169 return config.object();
177 const bool synchronousWindowSystemEvents = configuration[
"synchronousWindowSystemEvents"].toBool(
178 m_configuration[
"synchronousWindowSystemEvents"].toBool(
false));
179 QWindowSystemInterface::setSynchronousWindowSystemEvents(synchronousWindowSystemEvents);
182 m_configuration[
"windowFrameMargins"].toBool(
true));
185 QJsonArray currentScreens = m_configuration[
"screens"].toArray();
186 QJsonArray newScreens = configuration[
"screens"].toArray();
188 auto getScreenNames = [](
const QJsonArray &screens) -> QList<QString> {
189 QList<QString> names;
190 for (QJsonValue screen : screens) {
191 names.append(screen[
"name"].toString());
193 std::sort(names.begin(), names.end());
197 auto currentNames = getScreenNames(currentScreens);
198 auto newNames = getScreenNames(newScreens);
200 QList<QString> present;
201 std::set_intersection(currentNames.begin(), currentNames.end(), newNames.begin(), newNames.end(),
202 std::inserter(present, present.begin()));
203 QList<QString> added;
204 std::set_difference(newNames.begin(), newNames.end(), currentNames.begin(), currentNames.end(),
205 std::inserter(added, added.begin()));
206 QList<QString> removed;
207 std::set_difference(currentNames.begin(), currentNames.end(), newNames.begin(), newNames.end(),
208 std::inserter(removed, removed.begin()));
210 auto platformScreenByName = [](
const QString &name, QList<QOffscreenScreen *> screens) ->
QOffscreenScreen * {
211 for (QOffscreenScreen *screen : screens) {
212 if (screen->m_name == name)
218 auto screenConfigByName = [](
const QString &name, QJsonArray screenConfigs) -> QJsonValue {
219 for (QJsonValue screenConfig : screenConfigs) {
220 if (screenConfig[
"name"].toString() == name)
226 auto geometryFromConfig = [](
const QJsonObject &config) -> QRect {
227 return QRect(config[
"x"].toInt(0), config[
"y"].toInt(0), config[
"width"].toInt(640), config[
"height"].toInt(480));
231 for (
const QString &remove : removed) {
232 QOffscreenScreen *screen = platformScreenByName(remove, m_screens);
233 m_screens.removeAll(screen);
234 QWindowSystemInterface::handleScreenRemoved(screen);
238 for (
const QString &add : added) {
239 QJsonValue configValue = screenConfigByName(add, newScreens);
240 QJsonObject config = configValue.toObject();
241 if (config.isEmpty()) {
242 qWarning(
"empty screen object");
245 QOffscreenScreen *offscreenScreen =
new QOffscreenScreen(
this);
246 offscreenScreen->m_name = config[
"name"].toString();
247 offscreenScreen->m_geometry = geometryFromConfig(config);
248 offscreenScreen->m_logicalDpi = config[
"logicalDpi"].toInt(96);
249 offscreenScreen->m_logicalBaseDpi = config[
"logicalBaseDpi"].toInt(96);
250 offscreenScreen->m_dpr = config[
"dpr"].toDouble(1.0);
251 m_screens.append(offscreenScreen);
252 QWindowSystemInterface::handleScreenAdded(offscreenScreen);
256 for (
const QString &pres : present) {
257 QOffscreenScreen *screen = platformScreenByName(pres, m_screens);
259 QJsonObject currentConfig = screenConfigByName(pres, currentScreens).toObject();
260 QJsonObject newConfig = screenConfigByName(pres, newScreens).toObject();
263 Q_ASSERT(currentConfig[
"name"] == newConfig[
"name"]);
266 QRect currentGeomtry = geometryFromConfig(currentConfig);
267 QRect newGeomtry = geometryFromConfig(newConfig);
268 if (currentGeomtry != newGeomtry) {
269 screen->m_geometry = newGeomtry;
270 QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), newGeomtry, newGeomtry);
274 int currentLogicalDpi = currentConfig[
"logicalDpi"].toInt(96);
275 int newLogicalDpi = newConfig[
"logicalDpi"].toInt(96);
276 if (currentLogicalDpi != newLogicalDpi) {
277 screen->m_logicalDpi = newLogicalDpi;
278 QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->screen(), newLogicalDpi, newLogicalDpi);
283 int currentLogicalBaseDpi = currentConfig[
"logicalBaseDpi"].toInt(96);
284 int newLogicalBaseDpi = newConfig[
"logicalBaseDpi"].toInt(96);
285 if (currentLogicalBaseDpi != newLogicalBaseDpi) {
286 screen->m_logicalBaseDpi = newLogicalBaseDpi;
287 qWarning(
"You ain't supposed to change logicalBaseDpi - its a platform constant. Qt may not react to the change");
293 double currentDpr = currentConfig[
"dpr"].toDouble(1);
294 double newDpr = newConfig[
"dpr"].toDouble(1);
295 if (currentDpr != newDpr) {
296 screen->m_dpr = newDpr;
297 qWarning(
"DPR change notifications is not implemented - Qt may not react to the change");
302 m_configuration = configuration;