summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire@kdab.com>2012-03-27 15:22:25 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-04-03 13:08:41 (GMT)
commit45c6fc890c226c9021d41373c7718d596eb888d1 (patch)
tree9fce51d647454495c1c01ff8603ea0da9d64db4c /src
parentdcacb8833a92bf6f28a9f709fb6b88a733ba2101 (diff)
downloadQt-45c6fc890c226c9021d41373c7718d596eb888d1.zip
Qt-45c6fc890c226c9021d41373c7718d596eb888d1.tar.gz
Qt-45c6fc890c226c9021d41373c7718d596eb888d1.tar.bz2
Add support for screen overlays / foreign windows
We're not the only one creating native windows. When using the multimedia API, the multimedia library creates a video window for video display. Here we need to deal with giving this video window overlay a proper z-order, otherwise it will never get visible. Cherry-picked from qtbase 4efd61c3cf3d25db1c60bf5c842837c5b24a05fa Change-Id: If2e2a6e51ae6553fdf645e578f68e41c7b43336a Reviewed-by: Sean Harmer <sean.harmer@kdab.com> Reviewed-by: Kevin Krammer <kevin.krammer@kdab.com> Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/blackberry/qbbeventthread.cpp9
-rw-r--r--src/plugins/platforms/blackberry/qbbeventthread.h8
-rw-r--r--src/plugins/platforms/blackberry/qbbintegration.cpp17
-rw-r--r--src/plugins/platforms/blackberry/qbbintegration.h2
-rw-r--r--src/plugins/platforms/blackberry/qbbscreen.cpp48
-rw-r--r--src/plugins/platforms/blackberry/qbbscreen.h8
-rw-r--r--src/plugins/platforms/blackberry/qbbscreeneventhandler.cpp31
-rw-r--r--src/plugins/platforms/blackberry/qbbscreeneventhandler.h8
8 files changed, 112 insertions, 19 deletions
diff --git a/src/plugins/platforms/blackberry/qbbeventthread.cpp b/src/plugins/platforms/blackberry/qbbeventthread.cpp
index ae3d44d..2593223 100644
--- a/src/plugins/platforms/blackberry/qbbeventthread.cpp
+++ b/src/plugins/platforms/blackberry/qbbeventthread.cpp
@@ -48,9 +48,10 @@
QT_BEGIN_NAMESPACE
-QBBEventThread::QBBEventThread(screen_context_t context)
+QBBEventThread::QBBEventThread(screen_context_t context, QBBScreenEventHandler *eventHandler)
: mContext(context),
- mQuit(false)
+ mQuit(false),
+ mEventHandler(eventHandler)
{
}
@@ -67,7 +68,7 @@ void QBBEventThread::injectKeyboardEvent(int flags, int sym, int mod, int scan,
void QBBEventThread::injectPointerMoveEvent(int x, int y)
{
- mEventHandler.injectPointerMoveEvent(x, y);
+ mEventHandler->injectPointerMoveEvent(x, y);
}
void QBBEventThread::run()
@@ -107,7 +108,7 @@ void QBBEventThread::run()
#endif
mQuit = true;
} else {
- mEventHandler.handleEvent(event, qnxType);
+ mEventHandler->handleEvent(event, qnxType);
}
}
diff --git a/src/plugins/platforms/blackberry/qbbeventthread.h b/src/plugins/platforms/blackberry/qbbeventthread.h
index 23bb249..df8c0ea 100644
--- a/src/plugins/platforms/blackberry/qbbeventthread.h
+++ b/src/plugins/platforms/blackberry/qbbeventthread.h
@@ -40,18 +40,18 @@
#ifndef QBBEVENTTHREAD_H
#define QBBEVENTTHREAD_H
-#include "qbbscreeneventhandler.h"
-
#include <QThread>
#include <screen/screen.h>
QT_BEGIN_NAMESPACE
+class QBBScreenEventHandler;
+
class QBBEventThread : public QThread
{
public:
- explicit QBBEventThread(screen_context_t context);
+ QBBEventThread(screen_context_t context, QBBScreenEventHandler *eventHandler);
virtual ~QBBEventThread();
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
@@ -63,7 +63,7 @@ protected:
private:
screen_context_t mContext;
bool mQuit;
- QBBScreenEventHandler mEventHandler;
+ QBBScreenEventHandler *mEventHandler;
void shutdown();
};
diff --git a/src/plugins/platforms/blackberry/qbbintegration.cpp b/src/plugins/platforms/blackberry/qbbintegration.cpp
index 840ae1f..5ca3833 100644
--- a/src/plugins/platforms/blackberry/qbbintegration.cpp
+++ b/src/plugins/platforms/blackberry/qbbintegration.cpp
@@ -47,6 +47,7 @@
#include "qbbnavigatoreventhandler.h"
#include "qbbrasterwindowsurface.h"
#include "qbbscreen.h"
+#include "qbbscreeneventhandler.h"
#include "qbbwindow.h"
#include "qbbvirtualkeyboard.h"
#include "qgenericunixfontdatabase.h"
@@ -69,11 +70,16 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_METATYPE(screen_window_t);
+
QBBIntegration::QBBIntegration() :
mFontDb(new QGenericUnixFontDatabase()),
+ mScreenEventHandler(new QBBScreenEventHandler()),
mPaintUsingOpenGL(getenv("QBB_USE_OPENGL") != NULL),
mVirtualKeyboard(0)
{
+ qRegisterMetaType<screen_window_t>();
+
if (mPaintUsingOpenGL) {
// Set default window API to OpenGL
QPlatformWindowFormat format = QPlatformWindowFormat::defaultFormat();
@@ -95,7 +101,7 @@ QBBIntegration::QBBIntegration() :
createDisplays();
// create/start event thread
- mEventThread = new QBBEventThread(mContext);
+ mEventThread = new QBBEventThread(mContext, mScreenEventHandler);
mEventThread->start();
// Create/start navigator event handler
@@ -138,6 +144,8 @@ QBBIntegration::~QBBIntegration()
#if defined(QBBINTEGRATION_DEBUG)
qDebug() << "QBB: platform plugin shutdown begin";
#endif
+
+
// destroy the keyboard class.
delete mVirtualKeyboard;
@@ -152,6 +160,8 @@ QBBIntegration::~QBBIntegration()
// stop/destroy navigator thread
delete mNavigatorEventHandler;
+ delete mScreenEventHandler;
+
// destroy all displays
destroyDisplays();
@@ -271,6 +281,11 @@ void QBBIntegration::createDisplays()
#endif
QBBScreen *screen = new QBBScreen(mContext, displays[i], i);
mScreens.push_back(screen);
+
+ QObject::connect(mScreenEventHandler, SIGNAL(newWindowCreated(screen_window_t)),
+ screen, SLOT(newWindowCreated(screen_window_t)));
+ QObject::connect(mScreenEventHandler, SIGNAL(windowClosed(screen_window_t)),
+ screen, SLOT(windowClosed(screen_window_t)));
}
}
diff --git a/src/plugins/platforms/blackberry/qbbintegration.h b/src/plugins/platforms/blackberry/qbbintegration.h
index 355008c..2d81184 100644
--- a/src/plugins/platforms/blackberry/qbbintegration.h
+++ b/src/plugins/platforms/blackberry/qbbintegration.h
@@ -51,6 +51,7 @@ class QBBNavigatorEventHandler;
class QBBLocaleThread;
class QBBAbstractVirtualKeyboard;
class QBBScreen;
+class QBBScreenEventHandler;
class QBBIntegration : public QPlatformIntegration
{
@@ -87,6 +88,7 @@ private:
QBBLocaleThread *mLocaleThread;
QPlatformFontDatabase *mFontDb;
QList<QPlatformScreen*> mScreens;
+ QBBScreenEventHandler *mScreenEventHandler;
bool mPaintUsingOpenGL;
QBBAbstractVirtualKeyboard *mVirtualKeyboard;
};
diff --git a/src/plugins/platforms/blackberry/qbbscreen.cpp b/src/plugins/platforms/blackberry/qbbscreen.cpp
index fd075d1..5c91979 100644
--- a/src/plugins/platforms/blackberry/qbbscreen.cpp
+++ b/src/plugins/platforms/blackberry/qbbscreen.cpp
@@ -44,6 +44,7 @@
#include "qbbwindow.h"
#include <QDebug>
+#include <QtCore/QThread>
#include <QtGui/QWindowSystemInterface>
#include <errno.h>
@@ -135,6 +136,31 @@ void QBBScreen::ensureDisplayCreated()
mRootWindow = QSharedPointer<QBBRootWindow>(new QBBRootWindow(this));
}
+void QBBScreen::newWindowCreated(screen_window_t window)
+{
+ Q_ASSERT(thread() == QThread::currentThread());
+ screen_display_t display = 0;
+ if (screen_get_window_property_pv(window, SCREEN_PROPERTY_DISPLAY, (void**)&display) != 0) {
+ qWarning("QBBScreen: Failed to get screen for window, errno=%d", errno);
+ return;
+ }
+
+ if (display == nativeDisplay()) {
+ // A window was created on this screen. If we don't know about this window yet, it means
+ // it was not created by Qt, but by some foreign library like the multimedia renderer, which
+ // creates an overlay window when playing a video.
+ // Treat all foreign windows as overlays here.
+ if (!findWindow(window))
+ addOverlayWindow(window);
+ }
+}
+
+void QBBScreen::windowClosed(screen_window_t window)
+{
+ Q_ASSERT(thread() == QThread::currentThread());
+ removeOverlayWindow(window);
+}
+
QRect QBBScreen::availableGeometry() const
{
// available geometry = total geometry - keyboard
@@ -269,6 +295,15 @@ void QBBScreen::updateHierarchy()
(*it)->updateZorder(topZorder);
}
+ topZorder++;
+ Q_FOREACH (screen_window_t overlay, mOverlays) {
+ // Do nothing when this fails. This can happen if we have stale windows in mOverlays,
+ // which in turn can happen because a window was removed but we didn't get a notification
+ // yet.
+ screen_set_window_property_iv(overlay, SCREEN_PROPERTY_ZORDER, &topZorder);
+ topZorder++;
+ }
+
// After a hierarchy update, we need to force a flush on all screens.
// Right now, all screens share a context.
screen_flush_context( mContext, 0 );
@@ -297,4 +332,17 @@ void QBBScreen::keyboardHeightChanged(int height)
QWindowSystemInterface::handleScreenAvailableGeometryChange(mScreenIndex);
}
+void QBBScreen::addOverlayWindow(screen_window_t window)
+{
+ mOverlays.append(window);
+ updateHierarchy();
+}
+
+void QBBScreen::removeOverlayWindow(screen_window_t window)
+{
+ const int numOverlaysRemoved = mOverlays.removeAll(window);
+ if (numOverlaysRemoved > 0)
+ updateHierarchy();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/blackberry/qbbscreen.h b/src/plugins/platforms/blackberry/qbbscreen.h
index 0f8f839..22d210a 100644
--- a/src/plugins/platforms/blackberry/qbbscreen.h
+++ b/src/plugins/platforms/blackberry/qbbscreen.h
@@ -85,10 +85,17 @@ public:
QSharedPointer<QBBRootWindow> rootWindow() const { return mRootWindow; }
+public Q_SLOTS:
+ void newWindowCreated(screen_window_t window);
+ void windowClosed(screen_window_t window);
+
private Q_SLOTS:
void keyboardHeightChanged(int height);
private:
+ void addOverlayWindow(screen_window_t window);
+ void removeOverlayWindow(screen_window_t window);
+
screen_context_t mContext;
screen_display_t mDisplay;
QSharedPointer<QBBRootWindow> mRootWindow;
@@ -105,6 +112,7 @@ private:
QRect mCurrentGeometry;
QList<QBBWindow*> mChildren;
+ QList<screen_window_t> mOverlays;
int mScreenIndex;
bool isPrimaryDisplay() { return mPrimaryDisplay; }
diff --git a/src/plugins/platforms/blackberry/qbbscreeneventhandler.cpp b/src/plugins/platforms/blackberry/qbbscreeneventhandler.cpp
index 567d572..1a87c7e 100644
--- a/src/plugins/platforms/blackberry/qbbscreeneventhandler.cpp
+++ b/src/plugins/platforms/blackberry/qbbscreeneventhandler.cpp
@@ -105,6 +105,10 @@ bool QBBScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
handleCloseEvent(event);
break;
+ case SCREEN_EVENT_CREATE:
+ handleCreateEvent(event);
+ break;
+
default:
// event ignored
#if defined(QBBEVENTTHREAD_DEBUG)
@@ -511,18 +515,27 @@ void QBBScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
void QBBScreenEventHandler::handleCloseEvent(screen_event_t event)
{
- // Query the window that was closed
- void *qnxWindow;
- int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &qnxWindow);
- if (result != 0) {
- qFatal("QBB: failed to query event window, errno=%d", errno);
- }
+ screen_window_t window = 0;
+ if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
+ qFatal("QBB: failed to query event window property, errno=%d", errno);
+
+ emit windowClosed(window);
// map window to top-level widget
- QWidget* w = QWidget::find( (WId)qnxWindow );
- if (w != NULL) {
+ QWidget* w = QWidget::find( (WId)window );
+ if (w != NULL)
QWindowSystemInterface::handleCloseEvent(w);
- }
}
+void QBBScreenEventHandler::handleCreateEvent(screen_event_t event)
+{
+ screen_window_t window = 0;
+ if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
+ qFatal("QBB: failed to query event window property, errno=%d", errno);
+
+ emit newWindowCreated(window);
+}
+
+#include "moc_qbbscreeneventhandler.cpp"
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/blackberry/qbbscreeneventhandler.h b/src/plugins/platforms/blackberry/qbbscreeneventhandler.h
index 2e5851e..d6c253d 100644
--- a/src/plugins/platforms/blackberry/qbbscreeneventhandler.h
+++ b/src/plugins/platforms/blackberry/qbbscreeneventhandler.h
@@ -46,8 +46,9 @@
QT_BEGIN_NAMESPACE
-class QBBScreenEventHandler
+class QBBScreenEventHandler : public QObject
{
+ Q_OBJECT
public:
QBBScreenEventHandler();
@@ -57,11 +58,16 @@ public:
bool handleEvent(screen_event_t event);
bool handleEvent(screen_event_t event, int qnxType);
+Q_SIGNALS:
+ void newWindowCreated(screen_window_t window);
+ void windowClosed(screen_window_t window);
+
private:
void handleKeyboardEvent(screen_event_t event);
void handlePointerEvent(screen_event_t event);
void handleTouchEvent(screen_event_t event, int type);
void handleCloseEvent(screen_event_t event);
+ void handleCreateEvent(screen_event_t event);
private:
enum {