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;
|
||||
}
|
||||
|
||||
if (paramList.contains("desktop"_L1)) {
|
||||
options |= QQnxIntegration::Desktop;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,8 @@ public:
|
||||
FullScreenApplication = 0x1,
|
||||
RootWindow = 0x2,
|
||||
AlwaysFlushScreenContext = 0x4,
|
||||
SurfacelessEGLContext = 0x8
|
||||
SurfacelessEGLContext = 0x8,
|
||||
Desktop = 0x10
|
||||
};
|
||||
Q_DECLARE_FLAGS(Options, Option)
|
||||
explicit QQnxIntegration(const QStringList ¶mList);
|
||||
|
@ -192,6 +192,10 @@ bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
|
||||
handlePropertyEvent(event);
|
||||
break;
|
||||
|
||||
case SCREEN_EVENT_MANAGER:
|
||||
handleManagerEvent(event);
|
||||
break;
|
||||
|
||||
default:
|
||||
// event ignored
|
||||
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))
|
||||
qFatal("QQnx: failed to query window property, errno=%d", errno);
|
||||
|
||||
if (window == 0) {
|
||||
qCDebug(lcQpaScreenEvents) << "handlePositionEvent on NULL window";
|
||||
return;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
int property;
|
||||
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
|
||||
|
||||
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"
|
||||
|
@ -54,6 +54,7 @@ private:
|
||||
void handlePropertyEvent(screen_event_t event);
|
||||
void handleKeyboardFocusPropertyEvent(screen_window_t window);
|
||||
void handleGeometryPropertyEvent(screen_window_t window);
|
||||
void handleManagerEvent(screen_event_t event);
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
@ -119,7 +119,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootW
|
||||
m_exposed(true),
|
||||
m_foreign(false),
|
||||
m_windowState(Qt::WindowNoState),
|
||||
m_firstActivateHandled(false)
|
||||
m_firstActivateHandled(false),
|
||||
m_desktopNotify(0)
|
||||
{
|
||||
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;
|
||||
if (Q_UNLIKELY(debug_fps())) {
|
||||
debug |= SCREEN_DEBUG_GRAPH_FPS;
|
||||
@ -308,12 +329,17 @@ void QQnxWindow::setGeometryHelper(const QRect &rect)
|
||||
// Call base class method
|
||||
QPlatformWindow::setGeometry(rect);
|
||||
|
||||
// Set window geometry equal to widget geometry
|
||||
int val[2];
|
||||
val[0] = rect.x();
|
||||
val[1] = rect.y();
|
||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
|
||||
"Failed to set window position");
|
||||
|
||||
// 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[1] = rect.y();
|
||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
|
||||
"Failed to set window position");
|
||||
}
|
||||
|
||||
val[0] = rect.width();
|
||||
val[1] = rect.height();
|
||||
@ -373,8 +399,12 @@ void QQnxWindow::updateVisibility(bool parentVisible)
|
||||
qCDebug(lcQpaWindow) << "parentVisible =" << parentVisible << "window =" << window();
|
||||
// Set window visibility
|
||||
int val = (m_visible && parentVisible) ? 1 : 0;
|
||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
|
||||
"Failed to set window visibility");
|
||||
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),
|
||||
"Failed to set window visibility");
|
||||
}
|
||||
|
||||
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
|
||||
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),
|
||||
"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() };
|
||||
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
|
||||
"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),
|
||||
"Failed to create window buffers");
|
||||
|
||||
@ -930,6 +960,33 @@ void QQnxWindow::addContextPermission()
|
||||
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()
|
||||
{
|
||||
QByteArray revokeString("context:");
|
||||
|
@ -75,6 +75,8 @@ public:
|
||||
void windowPosted();
|
||||
void handleActivationEvent();
|
||||
|
||||
void setWindowTitle(const QString &title);
|
||||
|
||||
protected:
|
||||
virtual int pixelFormat() const = 0;
|
||||
virtual void resetBuffers() = 0;
|
||||
@ -95,6 +97,7 @@ private:
|
||||
void setFocus(screen_window_t newFocusWindow);
|
||||
bool showWithoutActivating() const;
|
||||
bool focusable() const;
|
||||
void notifyManager(const QString &msg);
|
||||
|
||||
void addContextPermission();
|
||||
void removeContextPermission();
|
||||
@ -119,6 +122,13 @@ private:
|
||||
|
||||
bool m_isTopLevel;
|
||||
bool m_firstActivateHandled;
|
||||
int m_desktopNotify;
|
||||
|
||||
enum {
|
||||
DesktopNotifyTitle = 0x1,
|
||||
DesktopNotifyPosition = 0x2,
|
||||
DesktopNotifyVisible = 0x2
|
||||
};
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
x
Reference in New Issue
Block a user