diff options
-rw-r--r-- | src/plugins/platforms/qnx/qqnxnativeinterface.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/qnx/qqnxwindow.cpp | 103 |
2 files changed, 105 insertions, 2 deletions
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index b89c103a06..a245a0c43a 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -109,7 +109,7 @@ void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QStri if (name == QStringLiteral("mmRendererWindowName")) { qnxWindow->setMMRendererWindowName(value.toString()); - } else if (name == QStringLiteral("windowGroup")) { + } else if (name == QStringLiteral("qnxWindowGroup")) { if (value.isNull()) qnxWindow->joinWindowGroup(QByteArray()); else if (value.canConvert<QByteArray>()) @@ -124,6 +124,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QQnxNativeInterfa return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::setHighlightColor); if (resource == "blackberryIMFCheckSpelling") return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::checkSpelling); +#else + Q_UNUSED(resource) #endif return 0; } diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index f2b57aec9a..9ae2d01ab4 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -73,6 +73,88 @@ QT_BEGIN_NAMESPACE +/*! + \class QQnxWindow + \brief The QQnxWindow is the base class of the various classes used as instances of + QPlatformWindow in the QNX QPA plugin. + + The standard properties and methods available in Qt are not a perfect match for the + features provided by the QNX screen service. While for the majority of applications + the default behavior suffices, some circumstances require greater control over the + interaction with screen. + + \section1 Window types + + The QNX QPA plugin can operate in two modes, with or without a root window. The + selection of mode is made via the \e rootwindow and \e no-rootwindow options to the + plugin. The default mode is rootwindow for BlackBerry builds and no-rootwindow for + non-BlackBerry builds. + + Windows with parents are always created as child windows, the difference in the modes + is in the treatment of parentless windows. In no-rootwindow mode, these windows are + created as application windows while in rootwindow mode, the first window on a screen + is created as an application window while subsequent windows are created as child + windows. The only exception to this is any window of type Qt::Desktop or Qt::CoverWindow; + these are created as application windows, but will never become the root window, + even if they are the first window created. + + It is also possible to create a parentless child window. These may be useful to + create windows that are parented by windows from other processes. To do this, you + attach a dynamic property \e qnxInitialWindowGroup to the QWindow though this must be done + prior to the platform window class (this class) being created which typically happens + when the window is made visible. When the window is created in QML, it is acceptable + to have the \e visible property hardcoded to true so long as the qnxInitialWindowGroup + is also set. + + \section1 Joining Window Groups + + Window groups may be joined in a number of ways, some are automatic based on + predefined rules though an application is also able to provide explicit control. + + A QWindow that has a parent will join its parent's window group. When rootwindow mode + is in effect, all but the first parentless window on a screen will be child windows + and join the window group of the first parentless window, the root window. + + If a QWindow has a valid dynamic property called \e qnxInitialWindowGroup at the time the + QQnxWindow is created, the window will be created as a child window and, if the + qnxInitialWindowGroup property is a non-empty string, an attempt will be made to join that + window group. This has an effect only when the QQnxWindow is created, subsequent + changes to this property are ignored. Setting the property to an empty string + provides a means to create 'top level' child windows without automatically joining + any group. Typically when this property is used \e qnxWindowId should be used as well + so that the process that owns the window group being joined has some means to + identify the window. + + At any point following the creation of the QQnxWindow object, an application can + change the window group it has joined. This is done by using the \e + 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 + + 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 + + \section1 Window Id + + The screen window id string property can be set on a window by assigning the desired + value to a dynamic property \e qnxWindowId on the QWindow prior to the QQnxWindow having + been created. This is often wanted when one joins a window group belonging to a + different process. + +*/ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow) : QPlatformWindow(window), m_screenContext(context), @@ -88,12 +170,16 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle()); + // If a qnxInitialWindowGroup property is set on the window we'll take this as an + // indication that we want to create a child window and join that window group. + const QVariant windowGroup = window->property("qnxInitialWindowGroup"); + if (window->type() == Qt::CoverWindow || window->type() == Qt::Desktop) { // Cover windows have to be top level to be accessible to window delegate (i.e. navigator) // Desktop windows also need to be toplevel because they are not // supposed to be part of the window hierarchy tree m_isTopLevel = true; - } else if (parent() || (window->type() & Qt::Dialog) == Qt::Dialog) { + } else if (parent() || windowGroup.isValid()) { // If we have a parent we are a child window. Sometimes we have to be a child even if we // don't have a parent e.g. our parent might be in a different process. m_isTopLevel = false; @@ -117,6 +203,21 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW } createWindowGroup(); + + // If the window has a qnxWindowId property, set this as the string id property. This generally + // needs to be done prior to joining any group as it might be used by the owner of the + // group to identify the window. + const QVariant windowId = window->property("qnxWindowId"); + if (windowId.isValid() && windowId.canConvert<QByteArray>()) { + QByteArray id = windowId.toByteArray(); + Q_SCREEN_CHECKERROR(screen_set_window_property_cv(m_window, SCREEN_PROPERTY_ID_STRING, + id.size(), id), "Failed to set id"); + } + + // If a window group has been provided join it now. If it's an empty string that's OK too, + // it'll cause us not to join a group (the app will presumably join at some future time). + if (windowGroup.isValid() && windowGroup.canConvert<QByteArray>()) + joinWindowGroup(windowGroup.toByteArray()); } QQnxWindow::~QQnxWindow() |