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>
This commit is contained in:
parent
b5f343b367
commit
4efd61c3cf
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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 *)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user