diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 836d4a92ed..3d83c2a646 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -296,6 +296,7 @@ public: Desktop = 0x00000010 | Window, SubWindow = 0x00000012, ForeignWindow = 0x00000020 | Window, + CoverWindow = 0x00000040 | Window, WindowType_Mask = 0x000000ff, MSWindowsFixedSizeDialogHint = 0x00000100, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index c1dde19a2e..5398740316 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1997,6 +1997,10 @@ representing a native platform window created by another process or by manually using native code. + \value CoverWindow Indicates that the window represents a cover window, + which is shown when the application is minimized + on the BlackBerry platform for instance. + There are also a number of flags which you can use to customize the appearance of top-level windows. These have no effect on other windows: diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index c9d83272e8..f5a4e0735f 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -73,6 +73,7 @@ HEADERS = main.h \ qqnxnavigatoreventhandler.h \ qqnxabstractnavigator.h \ qqnxabstractvirtualkeyboard.h \ + qqnxabstractcover.h \ qqnxservices.h \ qqnxcursor.h \ qqnxrasterwindow.h @@ -119,9 +120,11 @@ CONFIG(blackberry-playbook) { } else { CONFIG(blackberry) { SOURCES += qqnxfiledialoghelper_bb10.cpp \ - qqnxfilepicker.cpp + qqnxfilepicker.cpp \ + qqnxnavigatorcover.cpp - HEADERS += qqnxfilepicker.h + HEADERS += qqnxfilepicker.h \ + qqnxnavigatorcover.h } } diff --git a/src/plugins/platforms/qnx/qqnxabstractcover.h b/src/plugins/platforms/qnx/qqnxabstractcover.h new file mode 100644 index 0000000000..84139b6db0 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxabstractcover.h @@ -0,0 +1,53 @@ +/*************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXABSTRACTCOVER_H +#define QQNXABSTRACTCOVER_H + +class QQnxAbstractCover +{ +public: + virtual ~QQnxAbstractCover() {} + + virtual void updateCover() = 0; +}; + +#endif // QQNXABSTRACTCOVER_H diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp index 9a947d7fad..e8fcdd692b 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp @@ -126,6 +126,9 @@ void QQnxEglWindow::swapEGLBuffers() eglResult = eglSwapBuffers(m_platformOpenGLContext->getEglDisplay(), m_eglSurface); if (eglResult != EGL_TRUE) qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError()); + + if (m_cover) + m_cover->updateCover(); } EGLSurface QQnxEglWindow::getSurface() diff --git a/src/plugins/platforms/qnx/qqnxnavigatorcover.cpp b/src/plugins/platforms/qnx/qqnxnavigatorcover.cpp new file mode 100644 index 0000000000..61caa623f5 --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxnavigatorcover.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqnxnavigatorcover.h" + +QQnxNavigatorCover::QQnxNavigatorCover() +{ + navigator_window_cover_attribute_create(&m_coverAttribute); +} + +QQnxNavigatorCover::~QQnxNavigatorCover() +{ + if (m_coverAttribute) + navigator_window_cover_attribute_destroy(m_coverAttribute); + + navigator_window_cover_reset(); +} + +void QQnxNavigatorCover::updateCover() +{ + if (m_coverAttribute) { + navigator_window_cover_attribute_set_transition(m_coverAttribute, + NAVIGATOR_WINDOW_COVER_TRANSITION_NONE); + navigator_window_cover_attribute_set_alternate_window(m_coverAttribute); + navigator_window_cover_update(m_coverAttribute); + } +} diff --git a/src/plugins/platforms/qnx/qqnxnavigatorcover.h b/src/plugins/platforms/qnx/qqnxnavigatorcover.h new file mode 100644 index 0000000000..cc35d0bf2a --- /dev/null +++ b/src/plugins/platforms/qnx/qqnxnavigatorcover.h @@ -0,0 +1,60 @@ +/*************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQNXNAVIGATORCOVER_H +#define QQNXNAVIGATORCOVER_H + +#include "qqnxabstractcover.h" +#include + +class QQnxNavigatorCover : public QQnxAbstractCover +{ +public: + QQnxNavigatorCover(); + ~QQnxNavigatorCover(); + + void updateCover(); + +private: + navigator_window_cover_attribute_t *m_coverAttribute; +}; + +#endif // QQNXNAVIGATORCOVER_H diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp index fa54b341a5..16ff9d7519 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp @@ -118,6 +118,9 @@ void QQnxRasterWindow::post(const QRegion &dirty) // Notify screen that window posted if (screen() != 0) screen()->onWindowPost(this); + + if (m_cover) + m_cover->updateCover(); } } diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 69e672aefc..6c3fd08a41 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -126,6 +126,7 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, m_posted(false), m_keyboardHeight(0), m_nativeOrientation(Qt::PrimaryOrientation), + m_coverWindow(0), m_cursor(new QQnxCursor()) { qScreenDebug() << Q_FUNC_INFO; @@ -431,45 +432,59 @@ void QQnxScreen::addWindow(QQnxWindow *window) if (m_childWindows.contains(window)) return; - // Ensure that the desktop window is at the bottom of the zorder. - // If we do not do this then we may end up activating the desktop - // when the navigator service gets an event that our window group - // has been activated (see QQnxScreen::activateWindowGroup()). - // Such a situation would strangely break focus handling due to the - // invisible desktop widget window being layered on top of normal - // windows - if (window->window()->type() == Qt::Desktop) - m_childWindows.push_front(window); - else - m_childWindows.push_back(window); - updateHierarchy(); + if (window->window()->type() != Qt::CoverWindow) { + // Ensure that the desktop window is at the bottom of the zorder. + // If we do not do this then we may end up activating the desktop + // when the navigator service gets an event that our window group + // has been activated (see QQnxScreen::activateWindowGroup()). + // Such a situation would strangely break focus handling due to the + // invisible desktop widget window being layered on top of normal + // windows + if (window->window()->type() == Qt::Desktop) + m_childWindows.push_front(window); + else + m_childWindows.push_back(window); + updateHierarchy(); + } else { +#if !defined(Q_OS_BLACKBERRY_TABLET) + m_coverWindow = window; +#endif + } } void QQnxScreen::removeWindow(QQnxWindow *window) { qScreenDebug() << Q_FUNC_INFO << "window =" << window; - const int numWindowsRemoved = m_childWindows.removeAll(window); - if (numWindowsRemoved > 0) - updateHierarchy(); + if (window != m_coverWindow) { + const int numWindowsRemoved = m_childWindows.removeAll(window); + if (numWindowsRemoved > 0) + updateHierarchy(); + } else { + m_coverWindow = 0; + } } void QQnxScreen::raiseWindow(QQnxWindow *window) { qScreenDebug() << Q_FUNC_INFO << "window =" << window; - removeWindow(window); - m_childWindows.push_back(window); - updateHierarchy(); + if (window != m_coverWindow) { + removeWindow(window); + m_childWindows.push_back(window); + updateHierarchy(); + } } void QQnxScreen::lowerWindow(QQnxWindow *window) { qScreenDebug() << Q_FUNC_INFO << "window =" << window; - removeWindow(window); - m_childWindows.push_front(window); - updateHierarchy(); + if (window != m_coverWindow) { + removeWindow(window); + m_childWindows.push_front(window); + updateHierarchy(); + } } void QQnxScreen::updateHierarchy() @@ -652,6 +667,9 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id) Q_FOREACH (QQnxWindow *childWindow, m_childWindows) childWindow->setExposed(true); + if (m_coverWindow) + m_coverWindow->setExposed(false); + QWindowSystemInterface::handleWindowActivated(window); } @@ -662,6 +680,9 @@ void QQnxScreen::deactivateWindowGroup(const QByteArray &id) if (!rootWindow() || id != rootWindow()->groupName()) return; + if (m_coverWindow) + m_coverWindow->setExposed(true); + Q_FOREACH (QQnxWindow *childWindow, m_childWindows) childWindow->setExposed(false); diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index fd97e2e58f..e11030ea0a 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -139,6 +139,7 @@ private: QRect m_currentGeometry; QList m_childWindows; + QQnxWindow *m_coverWindow; QList m_overlays; QList m_underlays; diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index a5e899aa7e..a129380575 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -51,13 +51,16 @@ #include -#include - #if defined(Q_OS_BLACKBERRY) +#if !defined(Q_OS_BLACKBERRY_TABLET) +#include "qqnxnavigatorcover.h" +#endif #include #include #endif +#include + #if defined(QQNXWINDOW_DEBUG) #define qWindowDebug qDebug #else @@ -81,7 +84,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) // Create child QNX window errno = 0; - if (static_cast(window->screen()->handle())->isPrimaryScreen()) { + if (static_cast(window->screen()->handle())->isPrimaryScreen() + && window->type() != Qt::CoverWindow) { result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW); } else { result = screen_create_window(&m_window, m_screenContext); @@ -352,7 +356,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) qFatal("QQnxWindow: failed to set window display, errno=%d", errno); - if (m_screen->isPrimaryScreen()) { + if (m_screen->isPrimaryScreen() && window()->type() != Qt::CoverWindow) { // Add window to display's window group errno = 0; result = screen_join_window_group(m_window, platformScreen->windowGroupName()); @@ -361,8 +365,7 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) Q_FOREACH (QQnxWindow *childWindow, m_childWindows) { // Only subwindows and tooltips need necessarily be moved to another display with the window. - if ((window()->type() & Qt::WindowType_Mask) == Qt::SubWindow || - (window()->type() & Qt::WindowType_Mask) == Qt::ToolTip) + if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip) childWindow->setScreen(platformScreen); } } @@ -558,6 +561,17 @@ void QQnxWindow::initWindow() setScreen(static_cast(window()->screen()->handle())); + if (window()->type() == Qt::CoverWindow) { +#if !defined(Q_OS_BLACKBERRY_TABLET) + screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(), + SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window); +#if defined(Q_OS_BLACKBERRY) + m_cover.reset(new QQnxNavigatorCover); +#endif +#endif // Q_OS_BLACKBERRY_TABLET + m_exposed = false; + } + // Add window to plugin's window mapper QQnxIntegration::addWindow(m_window, window()); diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index a63a215511..f96280848a 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -43,6 +43,9 @@ #define QQNXWINDOW_H #include +#include "qqnxabstractcover.h" + +#include #if !defined(QT_NO_OPENGL) #include @@ -112,6 +115,7 @@ protected: void initWindow(); screen_context_t m_screenContext; + QScopedPointer m_cover; private: QRect setGeometryHelper(const QRect &rect); diff --git a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc index 9315acb85f..8bba18b2b7 100644 --- a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc +++ b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc @@ -139,6 +139,19 @@ depends on the result of QWidget::frameGeometry() and the capability of the window manager to do proper window placement, neither of which can be guaranteed. + + \section2 BlackBerry Peculiarities + + On the BlackBerry platform it is possible to set an alternate + cover window that is shown when the application is minimized. + The cover window must be a separate window with the + \l{Qt::CoverWindow} flag set. + + The window should have a fixed size depending on the screen + resolution (e.g. for a 768x1280 screen, 334 pixels wide by 396 + pixels high). The window can be rendered to as usual, however + updates should occur very infrequently (a few updates per minute + at most) in order save battery. */ /*!