implement Qt::TranslucentBackground for Windows

Adapted the Qt 4.8 implementation of translucent widgets in
the Windows platform plugin. This is only working for non-OpenGL
top level Windows.

Change-Id: Ic4c1c52d33b380f530f6a07e96c0c154a0571415
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
bb10
Joerg Bornemann 2012-06-08 12:29:46 +02:00 committed by Qt by Nokia
parent 14f45e535b
commit e03d1ae953
3 changed files with 35 additions and 10 deletions

View File

@ -80,21 +80,42 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
const QPoint &offset)
{
Q_ASSERT(window);
// TODO: Prepare paint for translucent windows.
const QRect br = region.boundingRect();
if (QWindowsContext::verboseBackingStore > 1)
qDebug() << __FUNCTION__ << window << offset << br;
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
const HDC dc = rw->getDC();
if (!dc) {
qErrnoWarning("%s: GetDC failed", __FUNCTION__);
return;
if (rw->format().hasAlpha() && (window->windowFlags() & Qt::FramelessWindowHint)) {
const long wl = GetWindowLong(rw->handle(), GWL_EXSTYLE);
if ((wl & WS_EX_LAYERED) == 0)
SetWindowLong(rw->handle(), GWL_EXSTYLE, wl | WS_EX_LAYERED);
QRect r = window->frameGeometry();
QPoint frameOffset(window->frameMargins().left(), window->frameMargins().top());
QRect dirtyRect = br.translated(offset + frameOffset);
SIZE size = {r.width(), r.height()};
POINT ptDst = {r.x(), r.y()};
POINT ptSrc = {0, 0};
BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * rw->opacity()), AC_SRC_ALPHA};
RECT dirty = {dirtyRect.x(), dirtyRect.y(),
dirtyRect.x() + dirtyRect.width(), dirtyRect.y() + dirtyRect.height()};
UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, &ptDst, &size, m_image->hdc(), &ptSrc, 0, &blend, ULW_ALPHA, &dirty};
QWindowsContext::user32dll.updateLayeredWindowIndirect(rw->handle(), &info);
} else {
const HDC dc = rw->getDC();
if (!dc) {
qErrnoWarning("%s: GetDC failed", __FUNCTION__);
return;
}
if (!BitBlt(dc, br.x(), br.y(), br.width(), br.height(),
m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY))
qErrnoWarning("%s: BitBlt failed", __FUNCTION__);
rw->releaseDC();
}
if (!BitBlt(dc, br.x(), br.y(), br.width(), br.height(),
m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY))
qErrnoWarning("%s: BitBlt failed", __FUNCTION__);
rw->releaseDC();
// Write image for debug purposes.
if (QWindowsContext::verboseBackingStore > 2) {
static int n = 0;

View File

@ -647,7 +647,8 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
m_mouseGrab(false),
m_cursor(QWindowsScreen::screenOf(aWindow)->windowsCursor()->standardWindowCursor()),
m_dropTarget(0),
m_savedStyle(0)
m_savedStyle(0),
m_format(aWindow->format())
#ifdef QT_OPENGL_ES_2
, m_eglSurface(0)
#endif

View File

@ -142,6 +142,7 @@ public:
QWindowsWindow(QWindow *window, const WindowData &data);
~QWindowsWindow();
virtual QSurfaceFormat format() const { return m_format; }
virtual void setGeometry(const QRect &rect);
virtual QRect geometry() const { return m_data.geometry; }
@ -165,6 +166,7 @@ public:
virtual QMargins frameMargins() const;
virtual void setOpacity(qreal level);
qreal opacity() const { return m_opacity; }
virtual void requestActivateWindow();
virtual bool setKeyboardGrabEnabled(bool grab);
@ -254,6 +256,7 @@ private:
QWindowsOleDropTarget *m_dropTarget;
unsigned m_savedStyle;
QRect m_savedFrameGeometry;
const QSurfaceFormat m_format;
#ifdef QT_OPENGL_ES_2
EGLSurface m_eglSurface;
QSharedPointer<QWindowsEGLStaticContext> m_staticEglContext;