From e03d1ae953cef9f7ef8ce551c767de3e9d97fb52 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 8 Jun 2012 12:29:46 +0200 Subject: 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 --- .../platforms/windows/qwindowsbackingstore.cpp | 39 +++++++++++++++++----- src/plugins/platforms/windows/qwindowswindow.cpp | 3 +- src/plugins/platforms/windows/qwindowswindow.h | 3 ++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 9bd32811a3..a81386d752 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -80,21 +80,42 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion, 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; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 4e93d2b258..1266004f85 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -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 diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 208c0d2c38..270756d55e 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -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 m_staticEglContext; -- cgit v1.2.3