summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire@kdab.com>2012-03-29 16:13:52 +0200
committerQt by Nokia <qt-info@nokia.com>2012-03-30 21:51:14 +0200
commit4efd61c3cf3d25db1c60bf5c842837c5b24a05fa (patch)
treed9c45557d91bcda9198d28739da3931c489d7af8 /src/plugins
parentb5f343b3677a7c7f09d91d7d60f310717325e840 (diff)
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. Change-Id: Ibff0382ebee5cda87408b91c8181a4104fc4a1a3 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/plugins')
-rw-r--r--src/plugins/platforms/qnx/qqnxeventthread.cpp7
-rw-r--r--src/plugins/platforms/qnx/qqnxeventthread.h5
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp11
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp47
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h8
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp29
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h8
8 files changed, 103 insertions, 14 deletions
diff --git a/src/plugins/platforms/qnx/qqnxeventthread.cpp b/src/plugins/platforms/qnx/qqnxeventthread.cpp
index 1e08dbcd9c..768d508add 100644
--- a/src/plugins/platforms/qnx/qqnxeventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxeventthread.cpp
@@ -49,9 +49,11 @@
#include <cctype>
-QQnxEventThread::QQnxEventThread(screen_context_t context)
+QQnxEventThread::QQnxEventThread(screen_context_t context,
+ QQnxScreenEventHandler *screenEventHandler)
: QThread(),
m_screenContext(context),
+ m_screenEventHandler(screenEventHandler),
m_quit(false)
{
}
@@ -69,7 +71,6 @@ void QQnxEventThread::injectKeyboardEvent(int flags, int sym, int mod, int scan,
void QQnxEventThread::run()
{
- QQnxScreenEventHandler eventHandler;
screen_event_t event;
// create screen event
@@ -106,7 +107,7 @@ void QQnxEventThread::run()
#endif
m_quit = true;
} else {
- eventHandler.handleEvent(event, qnxType);
+ m_screenEventHandler->handleEvent(event, qnxType);
}
}
diff --git a/src/plugins/platforms/qnx/qqnxeventthread.h b/src/plugins/platforms/qnx/qqnxeventthread.h
index 0bb26c3c06..aa6186aa0d 100644
--- a/src/plugins/platforms/qnx/qqnxeventthread.h
+++ b/src/plugins/platforms/qnx/qqnxeventthread.h
@@ -48,10 +48,12 @@
QT_BEGIN_NAMESPACE
+class QQnxScreenEventHandler;
+
class QQnxEventThread : public QThread
{
public:
- explicit QQnxEventThread(screen_context_t context);
+ QQnxEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler);
virtual ~QQnxEventThread();
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
@@ -63,6 +65,7 @@ private:
void shutdown();
screen_context_t m_screenContext;
+ QQnxScreenEventHandler *m_screenEventHandler;
bool m_quit;
};
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 43f474a158..40e29981ce 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -46,6 +46,7 @@
#include "qqnxnavigatoreventhandler.h"
#include "qqnxrasterbackingstore.h"
#include "qqnxscreen.h"
+#include "qqnxscreeneventhandler.h"
#include "qqnxwindow.h"
#include "qqnxvirtualkeyboard.h"
#include "qqnxclipboard.h"
@@ -85,6 +86,7 @@ QQnxIntegration::QQnxIntegration()
, m_paintUsingOpenGL(false)
, m_eventDispatcher(createUnixEventDispatcher())
, m_services(0)
+ , m_screenEventHandler(new QQnxScreenEventHandler())
#ifndef QT_NO_CLIPBOARD
, m_clipboard(0)
#endif
@@ -106,7 +108,7 @@ QQnxIntegration::QQnxIntegration()
QQnxGLContext::initialize();
// Create/start event thread
- m_eventThread = new QQnxEventThread(m_screenContext);
+ m_eventThread = new QQnxEventThread(m_screenContext, m_screenEventHandler);
m_eventThread->start();
// Create/start navigator event handler
@@ -145,6 +147,8 @@ QQnxIntegration::~QQnxIntegration()
qDebug() << "QQnx: platform plugin shutdown begin";
#endif
+ delete m_screenEventHandler;
+
// Destroy input context
delete m_inputContext;
@@ -342,6 +346,11 @@ void QQnxIntegration::createDisplays()
QQnxScreen *screen = new QQnxScreen(m_screenContext, displays[i], i==0);
m_screens.append(screen);
screenAdded(screen);
+
+ QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void *)),
+ screen, SLOT(newWindowCreated(void *)));
+ QObject::connect(m_screenEventHandler, SIGNAL(windowClosed(void *)),
+ screen, SLOT(windowClosed(void *)));
}
}
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index ef654bf746..5a5e2c69c9 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -57,6 +57,7 @@ class QQnxAbstractVirtualKeyboard;
class QQnxWindow;
class QQnxServices;
class QQnxScreen;
+class QQnxScreenEventHandler;
#ifndef QT_NO_CLIPBOARD
class QQnxClipboard;
@@ -115,6 +116,7 @@ private:
QAbstractEventDispatcher *m_eventDispatcher;
QQnxServices *m_services;
QList<QQnxScreen*> m_screens;
+ QQnxScreenEventHandler *m_screenEventHandler;
#ifndef QT_NO_CLIPBOARD
mutable QQnxClipboard* m_clipboard;
#endif
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index c9ac00339b..183878bd07 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -42,6 +42,7 @@
#include "qqnxscreen.h"
#include "qqnxwindow.h"
+#include <QtCore/QThread>
#ifdef QQNXSCREEN_DEBUG
# include <QtCore/QDebug>
#endif
@@ -260,6 +261,13 @@ void QQnxScreen::updateHierarchy()
for (it = m_childWindows.constBegin(); it != m_childWindows.constEnd(); ++it)
(*it)->updateZorder(topZorder);
+ topZorder++;
+ Q_FOREACH (screen_window_t overlay, m_overlays) {
+ if (screen_set_window_property_iv(overlay, SCREEN_PROPERTY_ZORDER, &topZorder) != 0)
+ qWarning("QQnxScreen: failed to update z order for overlay, errno=%d", errno);
+ topZorder++;
+ }
+
// After a hierarchy update, we need to force a flush on all screens.
// Right now, all screens share a context.
screen_flush_context( m_screenContext, 0 );
@@ -291,5 +299,44 @@ void QQnxScreen::keyboardHeightChanged(int height)
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), availableGeometry());
}
+void QQnxScreen::addOverlayWindow(screen_window_t window)
+{
+ m_overlays.append(window);
+ updateHierarchy();
+}
+
+void QQnxScreen::removeOverlayWindow(screen_window_t window)
+{
+ const int numOverlaysRemoved = m_overlays.removeAll(window);
+ if (numOverlaysRemoved > 0)
+ updateHierarchy();
+}
+
+void QQnxScreen::newWindowCreated(void *window)
+{
+ Q_ASSERT(thread() == QThread::currentThread());
+ const screen_window_t windowHandle = reinterpret_cast<screen_window_t>(window);
+ screen_display_t display = NULL;
+ if (screen_get_window_property_pv(windowHandle, SCREEN_PROPERTY_DISPLAY, (void**)&display) != 0) {
+ qWarning("QQnx: 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(windowHandle))
+ addOverlayWindow(windowHandle);
+ }
+}
+
+void QQnxScreen::windowClosed(void *window)
+{
+ Q_ASSERT(thread() == QThread::currentThread());
+ const screen_window_t windowHandle = reinterpret_cast<screen_window_t>(window);
+ removeOverlayWindow(windowHandle);
+}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index a39689dd2c..fb05dfd730 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -91,10 +91,17 @@ public:
QSharedPointer<QQnxRootWindow> rootWindow() const { return m_rootWindow; }
+public Q_SLOTS:
+ void newWindowCreated(void *window);
+ void windowClosed(void *window);
+
private Q_SLOTS:
void keyboardHeightChanged(int height);
private:
+ void addOverlayWindow(screen_window_t window);
+ void removeOverlayWindow(screen_window_t window);
+
screen_context_t m_screenContext;
screen_display_t m_display;
QSharedPointer<QQnxRootWindow> m_rootWindow;
@@ -111,6 +118,7 @@ private:
QPlatformOpenGLContext *m_platformContext;
QList<QQnxWindow *> m_childWindows;
+ QList<screen_window_t> m_overlays;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 46780b6a60..9640c65bcb 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -106,6 +106,10 @@ bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType)
handlePointerEvent(event);
break;
+ case SCREEN_EVENT_CREATE:
+ handleCreateEvent(event);
+ break;
+
case SCREEN_EVENT_CLOSE:
handleCloseEvent(event);
break;
@@ -456,19 +460,28 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
{
- // Query the window that was closed
- void *handle;
- int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result != 0) {
- qFatal("QQNX: failed to query event window, errno=%d", errno);
- }
- screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
+ 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);
+
+ Q_EMIT windowClosed(window);
// Map window handle to top-level QWindow
- QWindow *w = QQnxIntegration::window(qnxWindow);
+ QWindow *w = QQnxIntegration::window(window);
if (w != 0) {
QWindowSystemInterface::handleCloseEvent(w);
}
}
+void QQnxScreenEventHandler::handleCreateEvent(screen_event_t event)
+{
+ 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);
+
+ Q_EMIT newWindowCreated(window);
+}
+
+#include "moc_qqnxscreeneventhandler.cpp"
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index 365351766c..06cc7a0b32 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -48,8 +48,9 @@
QT_BEGIN_NAMESPACE
-class QQnxScreenEventHandler
+class QQnxScreenEventHandler : public QObject
{
+ Q_OBJECT
public:
QQnxScreenEventHandler();
@@ -58,11 +59,16 @@ public:
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
+Q_SIGNALS:
+ void newWindowCreated(void *window);
+ void windowClosed(void *window);
+
private:
void handleKeyboardEvent(screen_event_t event);
void handlePointerEvent(screen_event_t event);
void handleTouchEvent(screen_event_t event, int qnxType);
void handleCloseEvent(screen_event_t event);
+ void handleCreateEvent(screen_event_t event);
private:
enum {