summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@digia.com>2012-10-24 16:09:52 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-02 00:38:51 +0100
commit30542304f19fe967b29f71c67cdcc782dc1fa1a8 (patch)
treeffcc3f2d5ee004119def4c012fadb9139c5794b0 /src/plugins
parent733ac1f6e6b3155a594376ef99288c6117124000 (diff)
Mac: Add support for WindowMasks platform capability
Also brings back a working QWidgetPrivate::setMask_sys(). Change-Id: Idde9eea15d28bb0299258df81322a5a3ff0b9493 Reviewed-by: Liang Qi <liang.qi@digia.com> Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm13
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm10
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm105
5 files changed, 100 insertions, 32 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index b069446c50..100dc1962c 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -302,11 +302,14 @@ void QCocoaIntegration::updateScreens()
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL : return true;
- case ThreadedOpenGL : return true;
- case BufferQueueingOpenGL: return true;
- default: return QPlatformIntegration::hasCapability(cap);
+ case ThreadedPixmaps:
+ case OpenGL:
+ case ThreadedOpenGL:
+ case BufferQueueingOpenGL:
+ case WindowMasks:
+ return true;
+ default:
+ return QPlatformIntegration::hasCapability(cap);
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index d5dbe58de9..db3a20c2be 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -107,6 +107,7 @@ public:
void lower();
void propagateSizeHints();
void setOpacity(qreal level);
+ void setMask(const QRegion &region);
bool setKeyboardGrabEnabled(bool grab);
bool setMouseGrabEnabled(bool grab);
QMargins frameMargins() const;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index d6b4ee68a9..de6e7dc43e 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -509,6 +509,16 @@ void QCocoaWindow::setOpacity(qreal level)
[m_nsWindow setAlphaValue:level];
}
+void QCocoaWindow::setMask(const QRegion &region)
+{
+ if (m_nsWindow) {
+ [m_nsWindow setOpaque:NO];
+ [m_nsWindow setBackgroundColor:[NSColor clearColor]];
+ }
+
+ [m_contentView setMaskRegion:&region];
+}
+
bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
{
if (!m_nsWindow)
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 32e140f9ff..246d311f7b 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -54,6 +54,8 @@ QT_END_NAMESPACE
@interface QNSView : NSView <NSTextInputClient> {
CGImageRef m_cgImage;
+ CGImageRef m_maskImage;
+ uchar *m_maskData;
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
@@ -68,6 +70,7 @@ QT_END_NAMESPACE
- (id)initWithQWindow:(QWindow *)window platformWindow:(QCocoaWindow *) platformWindow;
- (void)setImage:(QImage *)image;
+- (void)setMaskRegion:(const QRegion *)region;
- (void)drawRect:(NSRect)dirtyRect;
- (void)updateGeometry;
- (void)windowNotification : (NSNotification *) windowNotification;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 33d0fb4bae..d62913a7af 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -75,6 +75,8 @@ static QTouchDevice *touchDevice = 0;
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
if (self) {
m_cgImage = 0;
+ m_maskImage = 0;
+ m_maskData = 0;
m_window = 0;
m_buttons = Qt::NoButton;
m_sendKeyEvent = false;
@@ -93,6 +95,10 @@ static QTouchDevice *touchDevice = 0;
{
CGImageRelease(m_cgImage);
m_cgImage = 0;
+ CGImageRelease(m_maskImage);
+ m_maskImage = 0;
+ delete[] m_maskData;
+ m_maskData = 0;
m_window = 0;
[super dealloc];
}
@@ -205,47 +211,86 @@ static QTouchDevice *touchDevice = 0;
}
}
-- (void) setImage:(QImage *)image
+static CGImageRef qt_mac_toCGImage(QImage *qImage, bool isMask, uchar **dataCopy)
{
- CGImageRelease(m_cgImage);
-
- int width = image->width();
- int height = image->height();
+ int width = qImage->width();
+ int height = qImage->height();
if (width <= 0 || height <= 0) {
qWarning() << Q_FUNC_INFO <<
"setting invalid size" << width << "x" << height << "for qnsview image";
- m_cgImage = 0;
- return;
+ return 0;
}
- const uchar *imageData = image->bits();
- int bitDepth = image->depth();
+ const uchar *imageData = qImage->bits();
+ if (dataCopy) {
+ delete[] *dataCopy;
+ *dataCopy = new uchar[qImage->byteCount()];
+ memcpy(*dataCopy, imageData, qImage->byteCount());
+ }
+ int bitDepth = qImage->depth();
int colorBufferSize = 8;
- int bytesPrLine = image->bytesPerLine();
-
- CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB();
+ int bytesPrLine = qImage->bytesPerLine();
CGDataProviderRef cgDataProviderRef = CGDataProviderCreateWithData(
NULL,
- imageData,
- image->byteCount(),
+ dataCopy ? *dataCopy : imageData,
+ qImage->byteCount(),
NULL);
- m_cgImage = CGImageCreate(width,
- height,
- colorBufferSize,
- bitDepth,
- bytesPrLine,
- cgColourSpaceRef,
- kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
- cgDataProviderRef,
- NULL,
- false,
- kCGRenderingIntentDefault);
+ CGImageRef cgImage = 0;
+ if (isMask) {
+ cgImage = CGImageMaskCreate(width,
+ height,
+ colorBufferSize,
+ bitDepth,
+ bytesPrLine,
+ cgDataProviderRef,
+ NULL,
+ false);
+ } else {
+ CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB();
+ cgImage = CGImageCreate(width,
+ height,
+ colorBufferSize,
+ bitDepth,
+ bytesPrLine,
+ cgColourSpaceRef,
+ kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
+ cgDataProviderRef,
+ NULL,
+ false,
+ kCGRenderingIntentDefault);
+ CGColorSpaceRelease(cgColourSpaceRef);
+ }
+ return cgImage;
+}
- CGColorSpaceRelease(cgColourSpaceRef);
+- (void) setImage:(QImage *)image
+{
+ CGImageRelease(m_cgImage);
+ m_cgImage = qt_mac_toCGImage(image, false, 0);
+}
+
+- (void) setMaskRegion:(const QRegion *)region
+{
+ if (m_maskImage)
+ CGImageRelease(m_maskImage);
+ if (region->isEmpty()) {
+ m_maskImage = 0;
+ }
+ const QRect &rect = qt_mac_toQRect([self frame]);
+ QImage maskImage(rect.size(), QImage::Format_RGB888);
+ maskImage.fill(Qt::white);
+ QPainter p(&maskImage);
+ p.setRenderHint(QPainter::Antialiasing);
+ p.setClipRegion(*region);
+ p.fillRect(rect, QBrush(Qt::black));
+ p.end();
+
+ maskImage = maskImage.convertToFormat(QImage::Format_Indexed8);
+ m_maskImage = qt_mac_toCGImage(&maskImage, true, &m_maskData);
}
- (void) drawRect:(NSRect)dirtyRect
@@ -263,13 +308,19 @@ static QTouchDevice *touchDevice = 0;
CGContextTranslateCTM(cgContext, 0, dy);
CGContextScaleCTM(cgContext, 1, -1);
+ CGImageRef subMask = 0;
+ if (m_maskImage) {
+ subMask = CGImageCreateWithImageInRect(m_maskImage, dirtyCGRect);
+ CGContextClipToMask(cgContext, dirtyCGRect, subMask);
+ }
+
CGImageRef subImage = CGImageCreateWithImageInRect(m_cgImage, dirtyCGRect);
CGContextDrawImage(cgContext,dirtyCGRect,subImage);
CGContextRestoreGState(cgContext);
CGImageRelease(subImage);
-
+ CGImageRelease(subMask);
}
- (BOOL) isFlipped