diff options
Diffstat (limited to 'src/plugins/platforms/qnx')
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.cpp | 143 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxintegration.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxwindow.cpp | 14 |
4 files changed, 138 insertions, 26 deletions
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 8c8521325c..a45dcabeb7 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -72,6 +72,9 @@ # endif #endif +#include <qpa/qplatforminputcontextfactory_p.h> +#include <qpa/qplatforminputcontext.h> + #include "private/qgenericunixfontdatabase_p.h" #include "private/qgenericunixeventdispatcher_p.h" @@ -88,7 +91,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) @@ -149,6 +155,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) , m_inputContext(0) , m_buttonsNotifier(new QQnxButtonEventNotifier()) #endif + , m_qpaInputContext(0) , m_services(0) , m_fontDatabase(new QGenericUnixFontDatabase()) , m_eventDispatcher(createUnixEventDispatcher()) @@ -191,13 +198,17 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) m_screenEventHandler->setScreenEventThread(m_screenEventThread); m_screenEventThread->start(); + m_qpaInputContext = QPlatformInputContextFactory::create(); + #if QT_CONFIG(qqnx_pps) - // Create/start the keyboard class. - m_virtualKeyboard = new QQnxVirtualKeyboardPps(); + if (!m_qpaInputContext) { + // Create/start the keyboard class. + m_virtualKeyboard = new QQnxVirtualKeyboardPps(); - // delay invocation of start() to the time the event loop is up and running - // needed to have the QThread internals of the main thread properly initialized - QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); + } #endif #if QT_CONFIG(qqnx_pps) @@ -278,6 +289,7 @@ QQnxIntegration::~QQnxIntegration() // Destroy input context delete m_inputContext; #endif + delete m_qpaInputContext; // Destroy the keyboard class. delete m_virtualKeyboard; @@ -394,13 +406,13 @@ QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLCont } #endif -#if QT_CONFIG(qqnx_pps) QPlatformInputContext *QQnxIntegration::inputContext() const { qIntegrationDebug(); + if (m_qpaInputContext) + return m_qpaInputContext; return m_inputContext; } -#endif void QQnxIntegration::moveToScreen(QWindow *window, int screen) { @@ -490,6 +502,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 +622,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 +641,7 @@ void QQnxIntegration::createDisplays() } qIntegrationDebug("Creating screen for display %d", i); - createDisplay(displays[i], /*isPrimary=*/false); + createDisplay(*orderedDisplays[i], /*isPrimary=*/false); } // of displays iteration } @@ -534,7 +649,7 @@ void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary) { QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary); m_screens.append(screen); - screenAdded(screen); + QWindowSystemInterface::handleScreenAdded(screen); screen->adjustOrientation(); QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void*)), @@ -554,14 +669,14 @@ void QQnxIntegration::removeDisplay(QQnxScreen *screen) Q_CHECK_PTR(screen); Q_ASSERT(m_screens.contains(screen)); m_screens.removeAll(screen); - destroyScreen(screen); + QWindowSystemInterface::handleScreenRemoved(screen); } void QQnxIntegration::destroyDisplays() { qIntegrationDebug(); Q_FOREACH (QQnxScreen *screen, m_screens) { - QPlatformIntegration::destroyScreen(screen); + QWindowSystemInterface::handleScreenRemoved(screen); } m_screens.clear(); } diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 2993607489..366556dc4b 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -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; @@ -151,6 +153,7 @@ private: QQnxInputContext *m_inputContext; QQnxButtonEventNotifier *m_buttonsNotifier; #endif + QPlatformInputContext *m_qpaInputContext; QQnxServices *m_services; QPlatformFontDatabase *m_fontDatabase; mutable QAbstractEventDispatcher *m_eventDispatcher; diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index f29e11489b..c2471751f5 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -242,7 +242,11 @@ void QQnxScreenEventHandler::processEvents() break; ++count; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qintptr result = 0; +#else long result = 0; +#endif QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); bool handled = dispatcher && dispatcher->filterNativeEvent(QByteArrayLiteral("screen_event_t"), event, &result); if (!handled) diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 7c98b29348..7644e28b44 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -132,22 +132,12 @@ DECLARE_DEBUG_VAR(statistics) setWindowProperty function of the native interface to set the \e qnxWindowGroup property to the desired value, for example: - \code - QQuickView *view = new QQuickView(parent); - view->create(); - QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", - group); - \endcode + \snippet code/src_plugins_platforms_qnx_qqnxwindow.cpp 0 To leave the current window group, one passes a null value for the property value, for example: - \code - QQuickView *view = new QQuickView(parent); - view->create(); - QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", - QVariant()); - \endcode + \snippet code/src_plugins_platforms_qnx_qqnxwindow.cpp 1 \section1 Window Id |