QNX desktop support
Adds functionality to communicate with a desktop manager. This feature is only enabled if "desktop" is added to the QT_QPA_PLATFORM environment variable (e.g., "QT_QPA_PLATFORM=qnx:no-fullscreen:desktop"). Pick-to: 6.8 Change-Id: If98e0dda43692abce47f2d8f5f340bd7276ec901 Reviewed-by: James McDonnell <jmcdonnell@blackberry.com> (cherry picked from commit 70b1db9c0e0a53ec7e47ba296a534d38559c702f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
12f59b27e1
commit
ef2200e327
@ -93,6 +93,10 @@ static inline QQnxIntegration::Options parseOptions(const QStringList ¶mList
|
|||||||
options |= QQnxIntegration::SurfacelessEGLContext;
|
options |= QQnxIntegration::SurfacelessEGLContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (paramList.contains("desktop"_L1)) {
|
||||||
|
options |= QQnxIntegration::Desktop;
|
||||||
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ public:
|
|||||||
FullScreenApplication = 0x1,
|
FullScreenApplication = 0x1,
|
||||||
RootWindow = 0x2,
|
RootWindow = 0x2,
|
||||||
AlwaysFlushScreenContext = 0x4,
|
AlwaysFlushScreenContext = 0x4,
|
||||||
SurfacelessEGLContext = 0x8
|
SurfacelessEGLContext = 0x8,
|
||||||
|
Desktop = 0x10
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Options, Option)
|
Q_DECLARE_FLAGS(Options, Option)
|
||||||
explicit QQnxIntegration(const QStringList ¶mList);
|
explicit QQnxIntegration(const QStringList ¶mList);
|
||||||
|
@ -192,6 +192,10 @@ bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
|
|||||||
handlePropertyEvent(event);
|
handlePropertyEvent(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SCREEN_EVENT_MANAGER:
|
||||||
|
handleManagerEvent(event);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// event ignored
|
// event ignored
|
||||||
qCDebug(lcQpaScreenEvents) << Q_FUNC_INFO << "Unknown event" << qnxType;
|
qCDebug(lcQpaScreenEvents) << Q_FUNC_INFO << "Unknown event" << qnxType;
|
||||||
@ -698,6 +702,11 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
|
|||||||
if (Q_UNLIKELY(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0))
|
if (Q_UNLIKELY(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0))
|
||||||
qFatal("QQnx: failed to query window property, errno=%d", errno);
|
qFatal("QQnx: failed to query window property, errno=%d", errno);
|
||||||
|
|
||||||
|
if (window == 0) {
|
||||||
|
qCDebug(lcQpaScreenEvents) << "handlePositionEvent on NULL window";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
int property;
|
int property;
|
||||||
if (Q_UNLIKELY(screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0))
|
if (Q_UNLIKELY(screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0))
|
||||||
@ -768,4 +777,30 @@ void QQnxScreenEventHandler::timerEvent(QTimerEvent *event)
|
|||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
void QQnxScreenEventHandler::handleManagerEvent(screen_event_t event)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
int subtype;
|
||||||
|
Q_SCREEN_CHECKERROR(
|
||||||
|
screen_get_event_property_iv(event, SCREEN_PROPERTY_SUBTYPE, &subtype),
|
||||||
|
"Failed to query object type property");
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
screen_window_t window = 0;
|
||||||
|
if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
|
||||||
|
qFatal("QQnx: failed to query window property, errno=%d", errno);
|
||||||
|
|
||||||
|
switch (subtype) {
|
||||||
|
case SCREEN_EVENT_CLOSE: {
|
||||||
|
QWindow *closeWindow = QQnxIntegration::instance()->window(window);
|
||||||
|
closeWindow->close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// event ignored
|
||||||
|
qCDebug(lcQpaScreenEvents) << "Ignore manager event for subtype: " << subtype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_qqnxscreeneventhandler.cpp"
|
#include "moc_qqnxscreeneventhandler.cpp"
|
||||||
|
@ -54,6 +54,7 @@ private:
|
|||||||
void handlePropertyEvent(screen_event_t event);
|
void handlePropertyEvent(screen_event_t event);
|
||||||
void handleKeyboardFocusPropertyEvent(screen_window_t window);
|
void handleKeyboardFocusPropertyEvent(screen_window_t window);
|
||||||
void handleGeometryPropertyEvent(screen_window_t window);
|
void handleGeometryPropertyEvent(screen_window_t window);
|
||||||
|
void handleManagerEvent(screen_event_t event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
@ -119,7 +119,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
|
|||||||
m_exposed(true),
|
m_exposed(true),
|
||||||
m_foreign(false),
|
m_foreign(false),
|
||||||
m_windowState(Qt::WindowNoState),
|
m_windowState(Qt::WindowNoState),
|
||||||
m_firstActivateHandled(false)
|
m_firstActivateHandled(false),
|
||||||
|
m_desktopNotify(0)
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaWindow) << "window =" << window << ", size =" << window->size();
|
qCDebug(lcQpaWindow) << "window =" << window << ", size =" << window->size();
|
||||||
|
|
||||||
@ -201,6 +202,26 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QNX desktop integration.
|
||||||
|
if (QQnxIntegration::instance()->options() & QQnxIntegration::Desktop) {
|
||||||
|
// Determine if the window needs a frame.
|
||||||
|
switch (window->type()) {
|
||||||
|
case Qt::Popup:
|
||||||
|
case Qt::ToolTip:
|
||||||
|
m_desktopNotify = DesktopNotifyPosition | DesktopNotifyVisible;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
m_desktopNotify = DesktopNotifyTitle | DesktopNotifyVisible;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the window manager to acknowledge the window's creation.
|
||||||
|
// The call returns immediately if there is no window manager.
|
||||||
|
screen_manage_window(m_window,
|
||||||
|
(m_desktopNotify & DesktopNotifyTitle) ? "Frame=Y" : "Frame=N");
|
||||||
|
}
|
||||||
|
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
if (Q_UNLIKELY(debug_fps())) {
|
if (Q_UNLIKELY(debug_fps())) {
|
||||||
debug |= SCREEN_DEBUG_GRAPH_FPS;
|
debug |= SCREEN_DEBUG_GRAPH_FPS;
|
||||||
@ -308,12 +329,17 @@ void QQnxWindow::setGeometryHelper(const QRect &rect)
|
|||||||
// Call base class method
|
// Call base class method
|
||||||
QPlatformWindow::setGeometry(rect);
|
QPlatformWindow::setGeometry(rect);
|
||||||
|
|
||||||
// Set window geometry equal to widget geometry
|
|
||||||
int val[2];
|
int val[2];
|
||||||
|
|
||||||
|
// Set window geometry equal to widget geometry
|
||||||
|
if (m_desktopNotify & DesktopNotifyPosition) {
|
||||||
|
notifyManager(QString::asprintf("Pos=%d,%d", rect.x(), rect.y()));
|
||||||
|
} else {
|
||||||
val[0] = rect.x();
|
val[0] = rect.x();
|
||||||
val[1] = rect.y();
|
val[1] = rect.y();
|
||||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
|
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
|
||||||
"Failed to set window position");
|
"Failed to set window position");
|
||||||
|
}
|
||||||
|
|
||||||
val[0] = rect.width();
|
val[0] = rect.width();
|
||||||
val[1] = rect.height();
|
val[1] = rect.height();
|
||||||
@ -373,8 +399,12 @@ void QQnxWindow::updateVisibility(bool parentVisible)
|
|||||||
qCDebug(lcQpaWindow) << "parentVisible =" << parentVisible << "window =" << window();
|
qCDebug(lcQpaWindow) << "parentVisible =" << parentVisible << "window =" << window();
|
||||||
// Set window visibility
|
// Set window visibility
|
||||||
int val = (m_visible && parentVisible) ? 1 : 0;
|
int val = (m_visible && parentVisible) ? 1 : 0;
|
||||||
|
if (m_desktopNotify & DesktopNotifyVisible) {
|
||||||
|
notifyManager(QString("Visible=") + (val ? "Y" : "N"));
|
||||||
|
} else {
|
||||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
|
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
|
||||||
"Failed to set window visibility");
|
"Failed to set window visibility");
|
||||||
|
}
|
||||||
|
|
||||||
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
|
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
|
||||||
childWindow->updateVisibility(m_visible && parentVisible);
|
childWindow->updateVisibility(m_visible && parentVisible);
|
||||||
@ -421,16 +451,16 @@ void QQnxWindow::setBufferSize(const QSize &size)
|
|||||||
screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
|
screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
|
||||||
"Failed to set window format");
|
"Failed to set window format");
|
||||||
|
|
||||||
if (m_bufferSize.isValid()) {
|
|
||||||
// destroy buffers first, if resized
|
|
||||||
Q_SCREEN_CRITICALERROR(screen_destroy_window_buffers(m_window),
|
|
||||||
"Failed to destroy window buffers");
|
|
||||||
}
|
|
||||||
|
|
||||||
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
|
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
|
||||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
|
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
|
||||||
"Failed to set window buffer size");
|
"Failed to set window buffer size");
|
||||||
|
|
||||||
|
if (m_bufferSize.isValid()) {
|
||||||
|
m_bufferSize = nonEmptySize;
|
||||||
|
resetBuffers();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
|
Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
|
||||||
"Failed to create window buffers");
|
"Failed to create window buffers");
|
||||||
|
|
||||||
@ -930,6 +960,33 @@ void QQnxWindow::addContextPermission()
|
|||||||
grantString.data());
|
grantString.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQnxWindow::setWindowTitle(const QString &title)
|
||||||
|
{
|
||||||
|
if (m_desktopNotify & DesktopNotifyTitle) {
|
||||||
|
QString titleStr = "Title=" + title;
|
||||||
|
notifyManager(titleStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QQnxWindow::notifyManager(const QString &msg)
|
||||||
|
{
|
||||||
|
screen_event_t ev;
|
||||||
|
screen_create_event(&ev);
|
||||||
|
|
||||||
|
std::string str = msg.toStdString();
|
||||||
|
screen_set_event_property_iv(ev, SCREEN_PROPERTY_TYPE,
|
||||||
|
(const int[]){ SCREEN_EVENT_MANAGER });
|
||||||
|
screen_set_event_property_cv(ev, SCREEN_PROPERTY_USER_DATA, str.length(),
|
||||||
|
str.c_str());
|
||||||
|
screen_set_event_property_pv(ev, SCREEN_PROPERTY_WINDOW,
|
||||||
|
reinterpret_cast<void **>(&m_window));
|
||||||
|
screen_set_event_property_pv(ev, SCREEN_PROPERTY_CONTEXT,
|
||||||
|
reinterpret_cast<void **>(&m_screenContext));
|
||||||
|
|
||||||
|
Q_SCREEN_CHECKERROR(screen_inject_event(NULL, ev),
|
||||||
|
"Failed to send a message to the window manager");
|
||||||
|
}
|
||||||
|
|
||||||
void QQnxWindow::removeContextPermission()
|
void QQnxWindow::removeContextPermission()
|
||||||
{
|
{
|
||||||
QByteArray revokeString("context:");
|
QByteArray revokeString("context:");
|
||||||
|
@ -75,6 +75,8 @@ public:
|
|||||||
void windowPosted();
|
void windowPosted();
|
||||||
void handleActivationEvent();
|
void handleActivationEvent();
|
||||||
|
|
||||||
|
void setWindowTitle(const QString &title);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int pixelFormat() const = 0;
|
virtual int pixelFormat() const = 0;
|
||||||
virtual void resetBuffers() = 0;
|
virtual void resetBuffers() = 0;
|
||||||
@ -95,6 +97,7 @@ private:
|
|||||||
void setFocus(screen_window_t newFocusWindow);
|
void setFocus(screen_window_t newFocusWindow);
|
||||||
bool showWithoutActivating() const;
|
bool showWithoutActivating() const;
|
||||||
bool focusable() const;
|
bool focusable() const;
|
||||||
|
void notifyManager(const QString &msg);
|
||||||
|
|
||||||
void addContextPermission();
|
void addContextPermission();
|
||||||
void removeContextPermission();
|
void removeContextPermission();
|
||||||
@ -119,6 +122,13 @@ private:
|
|||||||
|
|
||||||
bool m_isTopLevel;
|
bool m_isTopLevel;
|
||||||
bool m_firstActivateHandled;
|
bool m_firstActivateHandled;
|
||||||
|
int m_desktopNotify;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DesktopNotifyTitle = 0x1,
|
||||||
|
DesktopNotifyPosition = 0x2,
|
||||||
|
DesktopNotifyVisible = 0x2
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user