summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/qnx/qqnxwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/qnx/qqnxwindow.cpp')
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp323
1 files changed, 169 insertions, 154 deletions
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 99071cf4f2..bb76efea64 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxwindow.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h"
@@ -73,36 +75,45 @@ QT_BEGIN_NAMESPACE
QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow)
: QPlatformWindow(window),
m_screenContext(context),
- m_parentWindow(0),
m_window(0),
m_screen(0),
+ m_parentWindow(0),
m_visible(false),
m_exposed(true),
m_windowState(Qt::WindowNoState),
m_mmRendererWindow(0)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
- int result;
QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle());
- m_isTopLevel = ( needRootWindow && !platformScreen->rootWindow())
- || (!needRootWindow && !parent())
- || window->type() == Qt::CoverWindow;
+ if (window->type() == Qt::CoverWindow) {
+ // Cover windows have to be top level to be accessible to window delegate (i.e. navigator)
+ m_isTopLevel = true;
+ } else if (parent() || (window->type() & Qt::Dialog) == Qt::Dialog) {
+ // 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;
+ } else {
+ // We're parentless. If we're not using a root window, we'll always be a top-level window
+ // otherwise only the first window is.
+ m_isTopLevel = !needRootWindow || !platformScreen->rootWindow();
+ }
- errno = 0;
if (m_isTopLevel) {
- result = screen_create_window(&m_window, m_screenContext); // Creates an application window
+ Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext),
+ "Could not create top level window"); // Creates an application window
if (window->type() != Qt::CoverWindow) {
if (needRootWindow)
platformScreen->setRootWindow(this);
- createWindowGroup();
}
} else {
- result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ Q_SCREEN_CHECKERROR(
+ screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW),
+ "Could not create child window");
}
- if (result != 0)
- qFatal("QQnxWindow: failed to create window, errno=%d", errno);
+
+ createWindowGroup();
}
QQnxWindow::~QQnxWindow()
@@ -130,7 +141,7 @@ void QQnxWindow::setGeometry(const QRect &rect)
if (screen()->rootWindow() == this) //If this is the root window, it has to be shown fullscreen
newGeometry = screen()->geometry();
- const QRect oldGeometry = setGeometryHelper(newGeometry);
+ setGeometryHelper(newGeometry);
// Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget).
@@ -140,71 +151,34 @@ void QQnxWindow::setGeometry(const QRect &rect)
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
-
- // Now move all children.
- if (!oldGeometry.isEmpty()) {
- const QPoint offset = newGeometry.topLeft() - oldGeometry.topLeft();
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
- childWindow->setOffset(offset);
- }
}
-QRect QQnxWindow::setGeometryHelper(const QRect &rect)
+void QQnxWindow::setGeometryHelper(const QRect &rect)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window()
<< ", (" << rect.x() << "," << rect.y()
<< "," << rect.width() << "," << rect.height() << ")";
// Call base class method
- QRect oldGeometry = QPlatformWindow::geometry();
QPlatformWindow::setGeometry(rect);
// Set window geometry equal to widget geometry
- errno = 0;
int val[2];
val[0] = rect.x();
val[1] = rect.y();
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
+ "Failed to set window position");
- errno = 0;
val[0] = rect.width();
val[1] = rect.height();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window size, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val),
+ "Failed to set window size");
// Set viewport size equal to window size
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window source size, errno=%d", errno);
-
- return oldGeometry;
-}
-
-void QQnxWindow::setOffset(const QPoint &offset)
-{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
- // Move self and then children.
- QRect newGeometry = geometry();
- newGeometry.translate(offset);
-
- // Call the base class
- QPlatformWindow::setGeometry(newGeometry);
-
- int val[2];
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val),
+ "Failed to set window source size");
- errno = 0;
- val[0] = newGeometry.x();
- val[1] = newGeometry.y();
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
-
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
- childWindow->setOffset(offset);
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::setVisible(bool visible)
@@ -214,6 +188,12 @@ void QQnxWindow::setVisible(bool visible)
if (m_visible == visible)
return;
+ // The first time through we join a window group if appropriate.
+ if (m_parentGroupName.isNull() && !m_isTopLevel) {
+ joinWindowGroup(parent() ? static_cast<QQnxWindow*>(parent())->groupName()
+ : QByteArray(m_screen->windowGroupName()));
+ }
+
m_visible = visible;
QQnxWindow *root = this;
@@ -222,8 +202,6 @@ void QQnxWindow::setVisible(bool visible)
root->updateVisibility(root->m_visible);
- window()->requestActivate();
-
QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
if (visible) {
@@ -238,11 +216,9 @@ void QQnxWindow::updateVisibility(bool parentVisible)
{
qWindowDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window();
// Set window visibility
- errno = 0;
int val = (m_visible && parentVisible) ? 1 : 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window visibility, errno=%d", errno);
+ 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);
@@ -252,14 +228,11 @@ void QQnxWindow::setOpacity(qreal level)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level;
// Set window global alpha
- errno = 0;
int val = (int)(level * 255);
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window global alpha, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
+ "Failed to set global alpha");
- // TODO: How to handle children of this window? If we change all the visibilities, then
- // the transparency will look wrong...
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::setExposed(bool exposed)
@@ -282,15 +255,12 @@ void QQnxWindow::setBufferSize(const QSize &size)
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
// Set window buffer size
- errno = 0;
-
// libscreen fails when creating empty buffers
const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window buffer size, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
+ "Failed to set window buffer size");
// Create window buffers if they do not exist
if (m_bufferSize.isEmpty()) {
@@ -298,24 +268,18 @@ void QQnxWindow::setBufferSize(const QSize &size)
if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede
return;
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window pixel format, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val),
+ "Failed to set window format");
- errno = 0;
- result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT);
- if (result != 0) {
- qWarning() << "QQnxWindow: Buffer size was" << size;
- qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno);
- }
+ Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
+ "Failed to create window buffers");
// check if there are any buffers available
int bufferCount = 0;
- result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount);
-
- if (result != 0)
- qFatal("QQnxWindow: failed to query window buffer count, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
+ "Failed to query render buffer count");
if (bufferCount != MAX_BUFFER_COUNT) {
qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d. You might experience problems.",
@@ -338,10 +302,8 @@ void QQnxWindow::setBufferSize(const QSize &size)
val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
}
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val),
+ "Failed to set window transparency");
// Cache new buffer size
m_bufferSize = nonEmptySize;
@@ -366,9 +328,8 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (m_screen) {
qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen";
m_screen->removeWindow(this);
- QQnxIntegration *platformIntegration = static_cast<QQnxIntegration*>(QGuiApplicationPrivate::platformIntegration());
- if ((platformIntegration->options() & QQnxIntegration::RootWindow)) {
+ if ((QQnxIntegration::options() & QQnxIntegration::RootWindow)) {
screen_leave_window_group(m_window);
}
}
@@ -378,25 +339,12 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
platformScreen->addWindow(this);
}
if (m_isTopLevel) {
- // Move window to proper screen/display
- errno = 0;
+ // Move window to proper screen/display
screen_display_t display = platformScreen->nativeDisplay();
- int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display),
+ "Failed to set window display");
} else {
- errno = 0;
- int result;
- if (!parent()) {
- result = screen_join_window_group(m_window, platformScreen->windowGroupName());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- } else {
- result = screen_join_window_group(m_window, static_cast<QQnxWindow*>(parent())->groupName().constData());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- }
-
Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
// Only subwindows and tooltips need necessarily be moved to another display with the window.
if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip)
@@ -430,6 +378,11 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
if (newParent == m_parentWindow)
return;
+ if (screen()->rootWindow() == this) {
+ qWarning() << "Application window cannot be reparented";
+ return;
+ }
+
removeFromParent();
m_parentWindow = newParent;
@@ -439,12 +392,12 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
setScreen(m_parentWindow->m_screen);
m_parentWindow->m_childWindows.push_back(this);
+ joinWindowGroup(m_parentWindow->groupName());
} else {
m_screen->addWindow(this);
+ joinWindowGroup(QByteArray());
}
- adjustBufferSize();
-
m_screen->updateHierarchy();
}
@@ -478,14 +431,59 @@ void QQnxWindow::lower()
void QQnxWindow::requestActivateWindow()
{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
+ QQnxWindow *focusWindow = 0;
+ if (QGuiApplication::focusWindow())
+ focusWindow = static_cast<QQnxWindow*>(QGuiApplication::focusWindow()->handle());
+
+ if (focusWindow == this)
+ return;
+
+ if (screen()->rootWindow() == this ||
+ (focusWindow && findWindow(focusWindow->nativeHandle()))) {
+ // If the focus window is a child, we can just set the focus of our own window
+ // group to our window handle
+ setFocus(nativeHandle());
+ } else {
+ // In order to receive focus the parent's window group has to give focus to the
+ // child. If we have several hierarchy layers, we have to do that several times
+ QQnxWindow *currentWindow = this;
+ QList<QQnxWindow*> windowList;
+ while (currentWindow) {
+ windowList.prepend(currentWindow);
+ // If we find the focus window, we don't have to go further
+ if (currentWindow == focusWindow)
+ break;
+
+ if (currentWindow->parent()){
+ currentWindow = static_cast<QQnxWindow*>(currentWindow->parent());
+ } else if (screen()->rootWindow() &&
+ screen()->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) {
+ currentWindow = screen()->rootWindow();
+ } else {
+ currentWindow = 0;
+ }
+ }
- // TODO: Tell screen to set keyboard focus to this window.
+ // We have to apply the focus from parent to child windows
+ for (int i = 1; i < windowList.size(); ++i)
+ windowList.at(i-1)->setFocus(windowList.at(i)->nativeHandle());
+
+ windowList.last()->setFocus(windowList.last()->nativeHandle());
+ }
- // Notify that we gained focus.
- gainedFocus();
+ screen_flush_context(m_screenContext, 0);
}
+void QQnxWindow::setFocus(screen_window_t newFocusWindow)
+{
+ screen_group_t screenGroup = 0;
+ screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP,
+ reinterpret_cast<void**>(&screenGroup));
+ if (screenGroup) {
+ screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_KEYBOARD_FOCUS,
+ reinterpret_cast<void**>(&newFocusWindow));
+ }
+}
void QQnxWindow::setWindowState(Qt::WindowState state)
{
@@ -507,14 +505,6 @@ void QQnxWindow::propagateSizeHints()
qWindowDebug() << Q_FUNC_INFO << ": ignored";
}
-void QQnxWindow::gainedFocus()
-{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
-
- // Got focus
- QWindowSystemInterface::handleWindowActivated(window());
-}
-
void QQnxWindow::setMMRendererWindowName(const QString &name)
{
m_mmRendererWindowName = name;
@@ -569,43 +559,43 @@ void QQnxWindow::minimize()
void QQnxWindow::setRotation(int rotation)
{
qWindowDebug() << Q_FUNC_INFO << "angle =" << rotation;
- errno = 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
+ "Failed to set window rotation");
}
void QQnxWindow::initWindow()
{
// Alpha channel is always pre-multiplied if present
- errno = 0;
int val = SCREEN_PRE_MULTIPLIED_ALPHA;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window alpha mode, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
+ "Failed to set alpha mode");
// Set the window swap interval
- errno = 0;
val = 1;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window swap interval, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
+ "Failed to set swap interval");
if (window()->flags() & Qt::WindowDoesNotAcceptFocus) {
- errno = 0;
val = SCREEN_SENSITIVITY_NO_FOCUS;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window sensitivity, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
+ "Failed to set window sensitivity");
}
- setScreen(static_cast<QQnxScreen *>(window()->screen()->handle()));
+ QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window()->screen()->handle());
+ setScreen(platformScreen);
if (window()->type() == Qt::CoverWindow) {
#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
- screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
- SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
- m_cover.reset(new QQnxNavigatorCover);
+ if (platformScreen->rootWindow()) {
+ screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
+ SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
+ m_cover.reset(new QQnxNavigatorCover);
+ } else {
+ qWarning("No root window for cover window");
+ }
#endif
m_exposed = false;
}
@@ -615,6 +605,8 @@ void QQnxWindow::initWindow()
// Qt never calls these setters after creating the window, so we need to do that ourselves here
setWindowState(window()->windowState());
+ setOpacity(window()->opacity());
+
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
@@ -632,10 +624,36 @@ void QQnxWindow::createWindowGroup()
m_windowGroupName = QUuid::createUuid().toString().toLatin1();
// Create window group so child windows can be parented by container window
- errno = 0;
- int result = screen_create_window_group(m_window, m_windowGroupName.constData());
- if (result != 0)
- qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_create_window_group(m_window, m_windowGroupName.constData()),
+ "Failed to create window group");
+}
+
+void QQnxWindow::joinWindowGroup(const QByteArray &groupName)
+{
+ bool changed = false;
+
+ qWindowDebug() << Q_FUNC_INFO << "group:" << groupName;
+
+ if (!groupName.isEmpty()) {
+ if (groupName != m_parentGroupName) {
+ screen_join_window_group(m_window, groupName);
+ m_parentGroupName = groupName;
+ changed = true;
+ }
+ } else {
+ if (!m_parentGroupName.isEmpty()) {
+ screen_leave_window_group(m_window);
+ changed = true;
+ }
+ // By setting to an empty string we'll stop setVisible from trying to
+ // change our group, we want that to happen only if joinWindowGroup has
+ // never been called. This allows windows to be created that are not initially
+ // part of any group.
+ m_parentGroupName = "";
+ }
+
+ if (changed)
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::updateZorder(int &topZorder)
@@ -651,12 +669,9 @@ void QQnxWindow::updateZorder(int &topZorder)
void QQnxWindow::updateZorder(screen_window_t window, int &topZorder)
{
- errno = 0;
- int result = screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder),
+ "Failed to set window z-order");
topZorder++;
-
- if (result != 0)
- qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, window);
}
void QQnxWindow::applyWindowState()