Full translucent background support in xcb and xlib backend.
authorSamuel Rødal <samuel.rodal@nokia.com>
Thu, 19 May 2011 14:18:21 +0000 (16:18 +0200)
committerSamuel Rødal <samuel.rodal@nokia.com>
Thu, 19 May 2011 17:03:23 +0000 (19:03 +0200)
Make sure to pick an alpha visual also for non-GL surface types, and to
ask for alpha in the window format if the WA_TranslucentBackground
attribute is set.

Reviewed-by: Janusz Lewandowski
(cherry picked from commit 6241e39cff9311c943430ff2f31236b13618f2ac)

src/gui/kernel/qwidget_qpa.cpp
src/opengl/qgl_qpa.cpp
src/opengl/qwindowsurface_gl.cpp
src/plugins/platforms/xcb/qxcbwindow.cpp
src/plugins/platforms/xcb/qxcbwindowsurface.cpp
src/plugins/platforms/xlib/qxlibwindow.cpp
src/plugins/platforms/xlib/qxlibwindowsurface.cpp

index 001810e..960073c 100644 (file)
@@ -731,12 +731,19 @@ QPlatformWindowFormat QWidget::platformWindowFormat() const
 {
     Q_D(const QWidget);
 
+    QPlatformWindowFormat format;
+
     QTLWExtra *extra = d->maybeTopData();
     if (extra){
-        return extra->platformWindowFormat;
+        format = extra->platformWindowFormat;
     } else {
-        return QPlatformWindowFormat::defaultFormat();
+        format = QPlatformWindowFormat::defaultFormat();
     }
+
+    if (testAttribute(Qt::WA_TranslucentBackground))
+        format.setAlpha(true);
+
+    return format;
 }
 
 void QWidgetPrivate::createSysExtra()
index 994344c..9da650f 100644 (file)
@@ -150,6 +150,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
             if (shareContext) {
                 winFormat.setSharedContext(shareContext->d_func()->platformContext);
             }
+            if (widget->testAttribute(Qt::WA_TranslucentBackground))
+                winFormat.setAlpha(true);
             winFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
             winFormat.setWindowSurface(false);
             widget->setPlatformWindowFormat(winFormat);
index 49b3dc2..ff57446 100644 (file)
@@ -542,19 +542,27 @@ void QGLWindowSurface::beginPaint(const QRegion &)
     d_ptr->did_paint = true;
     updateGeometry();
 
-    if (!context())
-        return;
-
     int clearFlags = 0;
 
-    if (context()->d_func()->workaround_needsFullClearOnEveryFrame)
+    QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
+
+    if (!ctx)
+        return;
+
+    if (ctx->d_func()->workaround_needsFullClearOnEveryFrame)
         clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
-    else if (context()->format().alpha())
+    else if (ctx->format().alpha())
         clearFlags = GL_COLOR_BUFFER_BIT;
 
     if (clearFlags) {
+        if (d_ptr->fbo)
+            d_ptr->fbo->bind();
+
         glClearColor(0.0, 0.0, 0.0, 0.0);
         glClear(clearFlags);
+
+        if (d_ptr->fbo)
+            d_ptr->fbo->release();
     }
 }
 
index 3365c22..0dd29eb 100644 (file)
@@ -113,7 +113,8 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
 
 #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
     if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
-        && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+        && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
+        || tlw->platformWindowFormat().alpha())
     {
 #if defined(XCB_USE_GLX)
         XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
index 38c01f9..88a54dc 100644 (file)
@@ -54,6 +54,7 @@
 #include <stdio.h>
 
 #include <qdebug.h>
+#include <qpainter.h>
 
 class QXcbShmImage : public QXcbObject
 {
@@ -189,6 +190,16 @@ QPaintDevice *QXcbWindowSurface::paintDevice()
 void QXcbWindowSurface::beginPaint(const QRegion &region)
 {
     m_image->preparePaint(region);
+
+    if (m_image->image()->hasAlphaChannel()) {
+        QPainter p(m_image->image());
+        p.setCompositionMode(QPainter::CompositionMode_Source);
+        const QVector<QRect> rects = region.rects();
+        const QColor blank = Qt::transparent;
+        for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+            p.fillRect(*it, blank);
+        }
+    }
 }
 
 void QXcbWindowSurface::endPaint(const QRegion &)
index 4efcb11..50ea7b5 100644 (file)
@@ -81,9 +81,10 @@ QXlibWindow::QXlibWindow(QWidget *window)
     int w = window->width();
     int h = window->height();
 
-    if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
-            && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) ) {
 #if !defined(QT_NO_OPENGL)
+    if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
+            && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
+            || window->platformWindowFormat().alpha()) {
 #if !defined(QT_OPENGL_ES_2)
         XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
 #else
@@ -117,8 +118,9 @@ QXlibWindow::QXlibWindow(QWidget *window)
         } else {
             qFatal("no window!");
         }
+    } else
 #endif //!defined(QT_NO_OPENGL)
-    } else {
+    {
         mDepth = mScreen->depth();
         mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
         mVisual = mScreen->defaultVisual();
index 78fe387..a917f45 100644 (file)
@@ -49,6 +49,8 @@
 #include "qxlibscreen.h"
 #include "qxlibdisplay.h"
 
+#include "qpainter.h"
+
 # include <sys/ipc.h>
 # include <sys/shm.h>
 # include <X11/extensions/XShm.h>
@@ -108,7 +110,7 @@ void QXlibWindowSurface::resizeShmImage(int width, int height)
 
     Q_ASSERT(shm_attach_status == True);
 
-    shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, QImage::Format_RGB32 );
+    shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() );
 #endif
     painted = false;
 }
@@ -213,6 +215,16 @@ void QXlibWindowSurface::beginPaint(const QRegion &region)
 {
     Q_UNUSED(region);
     resizeBuffer(size());
+
+    if (shm_img.hasAlphaChannel()) {
+        QPainter p(&shm_img);
+        p.setCompositionMode(QPainter::CompositionMode_Source);
+        const QVector<QRect> rects = region.rects();
+        const QColor blank = Qt::transparent;
+        for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
+            p.fillRect(*it, blank);
+        }
+    }
 }
 
 void QXlibWindowSurface::endPaint(const QRegion &region)