Add possibility to configure QNX display order
Add environmental variable QT_QPA_QNX_DISPLAY_CONFIG for pointing
to a file containing display order. Configuration file format is:
{
"displayOrder": [ 3, 1 ]
}
Task-number: QTBUG-66394
Change-Id: I8c20eb2b5cf35617d5a030213f5d4d68e62ace85
Reviewed-by: Kari Oikarinen <kari.oikarinen@qt.io>
Reviewed-by: Pasi Petäjäjärvi <pasi.petajajarvi@qt.io>
bb10
parent
3a74a3b5a6
commit
b45c1e1c0e
|
|
@ -88,7 +88,10 @@
|
|||
#include <private/qsimpledrag_p.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QFile>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(QQNXINTEGRATION_DEBUG)
|
||||
|
|
@ -490,6 +493,108 @@ void QQnxIntegration::removeWindow(screen_window_t qnxWindow)
|
|||
m_windowMapper.remove(qnxWindow);
|
||||
}
|
||||
|
||||
/*!
|
||||
Get display ID for given \a display
|
||||
|
||||
Returns -1 for failure, otherwise returns display ID
|
||||
*/
|
||||
static int getIdOfDisplay(screen_display_t display)
|
||||
{
|
||||
int displayId;
|
||||
if (screen_get_display_property_iv(display,
|
||||
SCREEN_PROPERTY_ID,
|
||||
&displayId) == 0) {
|
||||
return displayId;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Read JSON configuration file for the QNX display order
|
||||
|
||||
Returns true if file was read successfully and fills \a requestedDisplays
|
||||
*/
|
||||
static bool getRequestedDisplays(QJsonArray &requestedDisplays)
|
||||
{
|
||||
// Check if display configuration file is provided
|
||||
QByteArray json = qgetenv("QT_QPA_QNX_DISPLAY_CONFIG");
|
||||
if (json.isEmpty())
|
||||
return false;
|
||||
|
||||
// Check if configuration file exists
|
||||
QFile file(QString::fromUtf8(json));
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Could not open config file" << json << "for reading";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read config file and check it's json
|
||||
const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
|
||||
if (!doc.isObject()) {
|
||||
qWarning() << "Invalid config file" << json
|
||||
<< "- no top-level JSON object";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the requested display order
|
||||
const QJsonObject object = doc.object();
|
||||
requestedDisplays = object.value(QLatin1String("displayOrder")).toArray();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
Match \a availableDisplays with display order defined in a json file
|
||||
pointed to by QT_QPA_QNX_DISPLAY_CONFIG. Display order must use same
|
||||
identifiers as defined for displays in graphics.conf. Number of
|
||||
available displays must be specified in \a displayCount
|
||||
|
||||
An example configuration is below:
|
||||
\badcode
|
||||
{
|
||||
"displayOrder": [ 3, 1 ]
|
||||
}
|
||||
\endcode
|
||||
|
||||
Returns ordered list of displays. If no order was specified, returns
|
||||
displays in the same order as in the original list.
|
||||
*/
|
||||
QList<screen_display_t *> QQnxIntegration::sortDisplays(screen_display_t *availableDisplays, int displayCount)
|
||||
{
|
||||
// Intermediate list for sorting
|
||||
QList<screen_display_t *> allDisplays;
|
||||
for (int i = 0; i < displayCount; i++)
|
||||
allDisplays.append(&availableDisplays[i]);
|
||||
|
||||
// Read requested display order if available
|
||||
QJsonArray requestedDisplays;
|
||||
if (!getRequestedDisplays(requestedDisplays))
|
||||
return allDisplays;
|
||||
|
||||
// Go through all the requested displays IDs
|
||||
QList<screen_display_t *> orderedDisplays;
|
||||
for (const QJsonValue &value : qAsConst(requestedDisplays)) {
|
||||
int requestedValue = value.toInt();
|
||||
|
||||
// Move all displays with matching ID from the intermediate list
|
||||
// to the beginning of the ordered list
|
||||
QMutableListIterator<screen_display_t *> iter(allDisplays);
|
||||
while (iter.hasNext()) {
|
||||
screen_display_t *display = iter.next();
|
||||
if (getIdOfDisplay(*display) == requestedValue) {
|
||||
orderedDisplays.append(display);
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Place all unordered displays to the end of list
|
||||
orderedDisplays.append(allDisplays);
|
||||
|
||||
return orderedDisplays;
|
||||
}
|
||||
|
||||
void QQnxIntegration::createDisplays()
|
||||
{
|
||||
qIntegrationDebug();
|
||||
|
|
@ -508,15 +613,16 @@ void QQnxIntegration::createDisplays()
|
|||
screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
|
||||
result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS,
|
||||
(void **)displays);
|
||||
QList<screen_display_t *> orderedDisplays = sortDisplays(displays, displayCount);
|
||||
Q_SCREEN_CRITICALERROR(result, "Failed to query displays");
|
||||
|
||||
// If it's primary, we create a QScreen for it even if it's not attached
|
||||
// since Qt will dereference QGuiApplication::primaryScreen()
|
||||
createDisplay(displays[0], /*isPrimary=*/true);
|
||||
createDisplay(*orderedDisplays[0], /*isPrimary=*/true);
|
||||
|
||||
for (int i=1; i<displayCount; i++) {
|
||||
int isAttached = 1;
|
||||
result = screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_ATTACHED,
|
||||
result = screen_get_display_property_iv(*orderedDisplays[i], SCREEN_PROPERTY_ATTACHED,
|
||||
&isAttached);
|
||||
Q_SCREEN_CHECKERROR(result, "Failed to query display attachment");
|
||||
|
||||
|
|
@ -526,7 +632,7 @@ void QQnxIntegration::createDisplays()
|
|||
}
|
||||
|
||||
qIntegrationDebug("Creating screen for display %d", i);
|
||||
createDisplay(displays[i], /*isPrimary=*/false);
|
||||
createDisplay(*orderedDisplays[i], /*isPrimary=*/false);
|
||||
} // of displays iteration
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ private:
|
|||
|
||||
void addWindow(screen_window_t qnxWindow, QWindow *window);
|
||||
void removeWindow(screen_window_t qnxWindow);
|
||||
QList<screen_display_t *> sortDisplays(screen_display_t *displays,
|
||||
int displayCount);
|
||||
|
||||
screen_context_t m_screenContext;
|
||||
QQnxScreenEventThread *m_screenEventThread;
|
||||
|
|
|
|||
Loading…
Reference in New Issue