QNX: Manage foreign mmrenderer windows
Manage and correctly set the z-order of a foreign created mmrenderer window by QtMultimedia Task-number: QTBUG-33816 Change-Id: I46273b945bf10991462fa72eb1ec8d00b0648988 Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
This commit is contained in:
parent
ae52bba5d4
commit
cf239f69e1
@ -42,6 +42,7 @@
|
|||||||
#include "qqnxnativeinterface.h"
|
#include "qqnxnativeinterface.h"
|
||||||
|
|
||||||
#include "qqnxscreen.h"
|
#include "qqnxscreen.h"
|
||||||
|
#include "qqnxwindow.h"
|
||||||
|
|
||||||
#include <QtGui/QScreen>
|
#include <QtGui/QScreen>
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
@ -70,4 +71,12 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
|
||||||
|
{
|
||||||
|
if (name == QStringLiteral("mmRendererWindowName")) {
|
||||||
|
QQnxWindow *qnxWindow = static_cast<QQnxWindow*>(window);
|
||||||
|
qnxWindow->setMMRendererWindowName(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -51,6 +51,7 @@ class QQnxNativeInterface : public QPlatformNativeInterface
|
|||||||
public:
|
public:
|
||||||
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
|
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
|
||||||
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
|
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
|
||||||
|
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -119,6 +119,38 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QQnxWindow *findMultimediaWindow(const QList<QQnxWindow*> windows,
|
||||||
|
const QByteArray &mmWindowId)
|
||||||
|
{
|
||||||
|
Q_FOREACH (QQnxWindow *sibling, windows) {
|
||||||
|
if (sibling->mmRendererWindowName() == mmWindowId)
|
||||||
|
return sibling;
|
||||||
|
|
||||||
|
QQnxWindow *mmWindow = findMultimediaWindow(sibling->children(), mmWindowId);
|
||||||
|
|
||||||
|
if (mmWindow)
|
||||||
|
return mmWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QQnxWindow *findMultimediaWindow(const QList<QQnxWindow*> windows,
|
||||||
|
screen_window_t mmWindowId)
|
||||||
|
{
|
||||||
|
Q_FOREACH (QQnxWindow *sibling, windows) {
|
||||||
|
if (sibling->mmRendererWindow() == mmWindowId)
|
||||||
|
return sibling;
|
||||||
|
|
||||||
|
QQnxWindow *mmWindow = findMultimediaWindow(sibling->children(), mmWindowId);
|
||||||
|
|
||||||
|
if (mmWindow)
|
||||||
|
return mmWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen)
|
QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen)
|
||||||
: m_screenContext(screenContext),
|
: m_screenContext(screenContext),
|
||||||
m_display(display),
|
m_display(display),
|
||||||
@ -585,6 +617,19 @@ void QQnxScreen::addUnderlayWindow(screen_window_t window)
|
|||||||
updateHierarchy();
|
updateHierarchy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQnxScreen::addMultimediaWindow(const QByteArray &id, screen_window_t window)
|
||||||
|
{
|
||||||
|
// find the QnxWindow this mmrenderer window is related to
|
||||||
|
QQnxWindow *mmWindow = findMultimediaWindow(m_childWindows, id);
|
||||||
|
|
||||||
|
if (!mmWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mmWindow->setMMRendererWindow(window);
|
||||||
|
|
||||||
|
updateHierarchy();
|
||||||
|
}
|
||||||
|
|
||||||
void QQnxScreen::removeOverlayOrUnderlayWindow(screen_window_t window)
|
void QQnxScreen::removeOverlayOrUnderlayWindow(screen_window_t window)
|
||||||
{
|
{
|
||||||
const int numRemoved = m_overlays.removeAll(window) + m_underlays.removeAll(window);
|
const int numRemoved = m_overlays.removeAll(window) + m_underlays.removeAll(window);
|
||||||
@ -610,17 +655,35 @@ void QQnxScreen::newWindowCreated(void *window)
|
|||||||
zorder = 0;
|
zorder = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char windowNameBuffer[256] = { 0 };
|
||||||
|
QByteArray windowName;
|
||||||
|
|
||||||
|
if (screen_get_window_property_cv(windowHandle, SCREEN_PROPERTY_ID_STRING,
|
||||||
|
sizeof(windowNameBuffer) - 1, windowNameBuffer) != 0) {
|
||||||
|
qWarning("QQnx: Failed to get id for window, errno=%d", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
windowName = QByteArray(windowNameBuffer);
|
||||||
|
|
||||||
if (display == nativeDisplay()) {
|
if (display == nativeDisplay()) {
|
||||||
// A window was created on this screen. If we don't know about this window yet, it means
|
// 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
|
// it was not created by Qt, but by some foreign library like the multimedia renderer, which
|
||||||
// creates an overlay window when playing a video.
|
// creates an overlay window when playing a video.
|
||||||
//
|
//
|
||||||
// Treat all foreign windows as overlays or underlays here.
|
// Treat all foreign windows as overlays, underlays or as windows
|
||||||
|
// created by the BlackBerry QtMultimedia plugin.
|
||||||
//
|
//
|
||||||
// Assume that if a foreign window already has a Z-Order both negative and
|
// In the case of the BlackBerry QtMultimedia plugin, we need to
|
||||||
|
// "attach" the foreign created mmrenderer window to the correct
|
||||||
|
// platform window (usually the one belonging to QVideoWidget) to
|
||||||
|
// ensure proper z-ordering.
|
||||||
|
//
|
||||||
|
// Otherwise, assume that if a foreign window already has a Z-Order both negative and
|
||||||
// less than the default Z-Order installed by mmrender on windows it creates,
|
// less than the default Z-Order installed by mmrender on windows it creates,
|
||||||
// the windows should be treated as an underlay. Otherwise, we treat it as an overlay.
|
// the windows should be treated as an underlay. Otherwise, we treat it as an overlay.
|
||||||
if (!findWindow(windowHandle)) {
|
if (!windowName.isEmpty() && windowName.startsWith("BbVideoWindowControl")) {
|
||||||
|
addMultimediaWindow(windowName, windowHandle);
|
||||||
|
} else if (!findWindow(windowHandle)) {
|
||||||
if (zorder <= MAX_UNDERLAY_ZORDER)
|
if (zorder <= MAX_UNDERLAY_ZORDER)
|
||||||
addUnderlayWindow(windowHandle);
|
addUnderlayWindow(windowHandle);
|
||||||
else
|
else
|
||||||
@ -634,6 +697,12 @@ void QQnxScreen::windowClosed(void *window)
|
|||||||
{
|
{
|
||||||
Q_ASSERT(thread() == QThread::currentThread());
|
Q_ASSERT(thread() == QThread::currentThread());
|
||||||
const screen_window_t windowHandle = reinterpret_cast<screen_window_t>(window);
|
const screen_window_t windowHandle = reinterpret_cast<screen_window_t>(window);
|
||||||
|
|
||||||
|
QQnxWindow *mmWindow = findMultimediaWindow(m_childWindows, windowHandle);
|
||||||
|
|
||||||
|
if (mmWindow)
|
||||||
|
mmWindow->clearMMRendererWindow();
|
||||||
|
else
|
||||||
removeOverlayOrUnderlayWindow(windowHandle);
|
removeOverlayOrUnderlayWindow(windowHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ private:
|
|||||||
void resizeWindows(const QRect &previousScreenGeometry);
|
void resizeWindows(const QRect &previousScreenGeometry);
|
||||||
void addOverlayWindow(screen_window_t window);
|
void addOverlayWindow(screen_window_t window);
|
||||||
void addUnderlayWindow(screen_window_t window);
|
void addUnderlayWindow(screen_window_t window);
|
||||||
|
void addMultimediaWindow(const QByteArray &id, screen_window_t window);
|
||||||
void removeOverlayOrUnderlayWindow(screen_window_t window);
|
void removeOverlayOrUnderlayWindow(screen_window_t window);
|
||||||
|
|
||||||
QWindow *topMostChildWindow() const;
|
QWindow *topMostChildWindow() const;
|
||||||
|
@ -77,7 +77,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context)
|
|||||||
m_parentWindow(0),
|
m_parentWindow(0),
|
||||||
m_visible(false),
|
m_visible(false),
|
||||||
m_exposed(true),
|
m_exposed(true),
|
||||||
m_windowState(Qt::WindowNoState)
|
m_windowState(Qt::WindowNoState),
|
||||||
|
m_mmRendererWindow(0)
|
||||||
{
|
{
|
||||||
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
|
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
|
||||||
int result;
|
int result;
|
||||||
@ -489,6 +490,22 @@ void QQnxWindow::gainedFocus()
|
|||||||
QWindowSystemInterface::handleWindowActivated(window());
|
QWindowSystemInterface::handleWindowActivated(window());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQnxWindow::setMMRendererWindowName(const QString &name)
|
||||||
|
{
|
||||||
|
m_mmRendererWindowName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QQnxWindow::setMMRendererWindow(screen_window_t handle)
|
||||||
|
{
|
||||||
|
m_mmRendererWindow = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QQnxWindow::clearMMRendererWindow()
|
||||||
|
{
|
||||||
|
m_mmRendererWindowName.clear();
|
||||||
|
m_mmRendererWindow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle)
|
QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle)
|
||||||
{
|
{
|
||||||
if (m_window == windowHandle)
|
if (m_window == windowHandle)
|
||||||
@ -583,17 +600,25 @@ void QQnxWindow::initWindow()
|
|||||||
|
|
||||||
void QQnxWindow::updateZorder(int &topZorder)
|
void QQnxWindow::updateZorder(int &topZorder)
|
||||||
{
|
{
|
||||||
errno = 0;
|
updateZorder(m_window, topZorder);
|
||||||
int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder);
|
|
||||||
topZorder++;
|
|
||||||
|
|
||||||
if (result != 0)
|
if (m_mmRendererWindow)
|
||||||
qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window);
|
updateZorder(m_mmRendererWindow, topZorder);
|
||||||
|
|
||||||
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
|
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
|
||||||
childWindow->updateZorder(topZorder);
|
childWindow->updateZorder(topZorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQnxWindow::updateZorder(screen_window_t window, int &topZorder)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
int result = screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder);
|
||||||
|
topZorder++;
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, window);
|
||||||
|
}
|
||||||
|
|
||||||
void QQnxWindow::applyWindowState()
|
void QQnxWindow::applyWindowState()
|
||||||
{
|
{
|
||||||
switch (m_windowState) {
|
switch (m_windowState) {
|
||||||
|
@ -99,6 +99,9 @@ public:
|
|||||||
void propagateSizeHints();
|
void propagateSizeHints();
|
||||||
|
|
||||||
void gainedFocus();
|
void gainedFocus();
|
||||||
|
void setMMRendererWindowName(const QString &name);
|
||||||
|
void setMMRendererWindow(screen_window_t handle);
|
||||||
|
void clearMMRendererWindow();
|
||||||
|
|
||||||
QQnxScreen *screen() const { return m_screen; }
|
QQnxScreen *screen() const { return m_screen; }
|
||||||
const QList<QQnxWindow*>& children() const { return m_childWindows; }
|
const QList<QQnxWindow*>& children() const { return m_childWindows; }
|
||||||
@ -107,6 +110,10 @@ public:
|
|||||||
|
|
||||||
void minimize();
|
void minimize();
|
||||||
|
|
||||||
|
QString mmRendererWindowName() const { return m_mmRendererWindowName; }
|
||||||
|
|
||||||
|
screen_window_t mmRendererWindow() const { return m_mmRendererWindow; }
|
||||||
|
|
||||||
virtual WindowType windowType() const = 0;
|
virtual WindowType windowType() const = 0;
|
||||||
protected:
|
protected:
|
||||||
virtual int pixelFormat() const = 0;
|
virtual int pixelFormat() const = 0;
|
||||||
@ -123,6 +130,7 @@ private:
|
|||||||
void setOffset(const QPoint &setOffset);
|
void setOffset(const QPoint &setOffset);
|
||||||
void updateVisibility(bool parentVisible);
|
void updateVisibility(bool parentVisible);
|
||||||
void updateZorder(int &topZorder);
|
void updateZorder(int &topZorder);
|
||||||
|
void updateZorder(screen_window_t window, int &zOrder);
|
||||||
void applyWindowState();
|
void applyWindowState();
|
||||||
|
|
||||||
screen_window_t m_window;
|
screen_window_t m_window;
|
||||||
@ -135,6 +143,8 @@ private:
|
|||||||
bool m_exposed;
|
bool m_exposed;
|
||||||
QRect m_unmaximizedGeometry;
|
QRect m_unmaximizedGeometry;
|
||||||
Qt::WindowState m_windowState;
|
Qt::WindowState m_windowState;
|
||||||
|
QString m_mmRendererWindowName;
|
||||||
|
screen_window_t m_mmRendererWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user