From bc616641a1c3d2d79cf7c5ee9e80a59279edb756 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 20 Feb 2013 15:50:35 +0100 Subject: [PATCH] Make toplevel transparent windows work on Mac OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch includes a few different fixes to make transparent toplevels work on cocoa. - When setting alpha on the toplevel, it also needs setOpaque:NO - The OpenGL context needs a separate flag for this to work. - Make sure setOpaque fighting between setMask, setFormat and setOpacity ends up correctly Task-number: QTBUG-28214 Change-Id: Ic3a2d71193bb653e181c98787b4ebda002424092 Reviewed-by: Shawn Rutledge Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoaglcontext.mm | 4 ++++ src/plugins/platforms/cocoa/qcocoawindow.h | 2 ++ src/plugins/platforms/cocoa/qcocoawindow.mm | 24 +++++++++++++++---- src/plugins/platforms/cocoa/qnsview.h | 1 + src/plugins/platforms/cocoa/qnsview.mm | 5 ++++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 6c2fdf5470..d4673baaef 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -78,6 +78,10 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo const GLint interval = 1; [m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval]; + if (format.alphaBufferSize() > 0) { + int zeroOpacity = 0; + [m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity]; + } } QCocoaGLContext::~QCocoaGLContext() diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 291c688915..70df7451f7 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -157,6 +157,8 @@ protected: QCocoaWindow *parentCocoaWindow() const; void syncWindowState(Qt::WindowState newState); + void updateOpaque(); + // private: public: // for QNSView friend class QCocoaBackingStore; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 56ca2e0b14..fe6a9ad50b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -516,20 +516,30 @@ void QCocoaWindow::propagateSizeHints() } } +void QCocoaWindow::updateOpaque() +{ + bool translucent = window()->format().alphaBufferSize() > 0 + || window()->opacity() < 1 + || (m_contentView && [m_contentView hasMask]); + [m_nsWindow setOpaque:!translucent]; +} + + void QCocoaWindow::setOpacity(qreal level) { - if (m_nsWindow) + if (m_nsWindow) { [m_nsWindow setAlphaValue:level]; + updateOpaque(); + } } void QCocoaWindow::setMask(const QRegion ®ion) { - if (m_nsWindow) { - [m_nsWindow setOpaque:NO]; + if (m_nsWindow) [m_nsWindow setBackgroundColor:[NSColor clearColor]]; - } [m_contentView setMaskRegion:®ion]; + updateOpaque(); } bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) @@ -726,6 +736,12 @@ NSWindow * QCocoaWindow::createNSWindow() NSInteger level = windowLevel(flags); [createdWindow setLevel:level]; + + if (window()->format().alphaBufferSize() > 0) { + [createdWindow setBackgroundColor:[NSColor clearColor]]; + [createdWindow setOpaque:NO]; + } + m_windowModality = window()->modality(); return createdWindow; } diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index eec0cfe5f6..5fe0861e0a 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -83,6 +83,7 @@ QT_END_NAMESPACE - (BOOL)isFlipped; - (BOOL)acceptsFirstResponder; - (BOOL)becomeFirstResponder; +- (BOOL)hasMask; - (void)resetMouseButtons; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index cdbaa235e4..a8d8baa942 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -254,6 +254,11 @@ static QTouchDevice *touchDevice = 0; [self setNeedsDisplayInRect:NSMakeRect(br.x(), br.y(), br.width(), br.height())]; } +- (BOOL) hasMask +{ + return m_maskData != 0; +} + - (void) setMaskRegion:(const QRegion *)region { if (m_maskImage)