Cocoa: Add setContentBorderThickness().

Add setContentBorderThickness() to the Cocoa platform
plugin. This functions requests that the platform
plugin draws a gradient in the unified title and toolbar
area and/or the status bar area.

The background gradient is drawn before and under
the Qt backing store content. It is expected that
parts of the backing store will be filled with transparent
pixels to allow the  gradient to be visible. To facilitate
this the backing store image is created with an alpha
channel.

Task-number: QTBUG-34411
Change-Id: Iadc5e64ee9b9b42e92fb84a615817fdffd7a8802
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
bb10
Morten Johan Sørvig 2013-12-16 22:38:13 +01:00 committed by The Qt Project
parent 79b0780783
commit 0caaf9966a
6 changed files with 69 additions and 2 deletions

View File

@ -73,7 +73,8 @@ QPaintDevice *QCocoaBackingStore::paintDevice()
}
#endif
QImage::Format format = window()->format().hasAlpha()
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
m_qImage = QImage(m_requestedSize * scaleFactor, format);
m_qImage.setDevicePixelRatio(scaleFactor);

View File

@ -132,6 +132,9 @@ private:
// touch events, which then will be delivered until the widget
// deregisters.
static void registerTouchWindow(QWindow *window, bool enable);
// Request a unified title and toolbar look for the window.
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
};
#endif // QCOCOANATIVEINTERFACE_H

View File

@ -123,6 +123,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow);
if (resource.toLower() == "setembeddedinforeignview")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView);
if (resource.toLower() == "setcontentborderthickness")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
return 0;
}
@ -273,4 +275,14 @@ void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable)
cocoaWindow->registerTouch(enable);
}
void QCocoaNativeInterface::setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness)
{
if (!window)
return;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
if (cocoaWindow)
cocoaWindow->setContentBorderThickness(topThickness, bottomThickness);
}
QT_END_NAMESPACE

View File

@ -157,6 +157,8 @@ public:
void setWindowCursor(NSCursor *cursor);
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
void applyContentBorderThickness(NSWindow *window);
qreal devicePixelRatio() const;
bool isWindowExposable();
@ -214,6 +216,10 @@ public: // for QNSView
static const int NoAlertRequest;
NSInteger m_alertRequest;
id monitor;
bool m_drawContentBorderGradient;
int m_topContentBorderThickness;
int m_bottomContentBorderThickness;
};
QT_END_NAMESPACE

View File

@ -220,6 +220,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_overrideBecomeKey(false)
, m_alertRequest(NoAlertRequest)
, monitor(nil)
, m_drawContentBorderGradient(false)
, m_topContentBorderThickness(0)
, m_bottomContentBorderThickness(0)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@ -502,6 +505,9 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
}
}
if (m_drawContentBorderGradient)
styleMask |= NSTexturedBackgroundWindowMask;
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug("windowStyleMask of '%s': flags %X -> styleMask %lX", qPrintable(window()->title()), (int)flags, styleMask);
#endif
@ -927,6 +933,9 @@ NSWindow * QCocoaWindow::createNSWindow()
}
m_windowModality = window()->modality();
applyContentBorderThickness(createdWindow);
return createdWindow;
}
@ -1069,6 +1078,38 @@ void QCocoaWindow::registerTouch(bool enable)
[m_contentView setAcceptsTouchEvents:NO];
}
void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickness)
{
m_topContentBorderThickness = topThickness;
m_bottomContentBorderThickness = bottomThickness;
bool enable = (topThickness > 0 || bottomThickness > 0);
m_drawContentBorderGradient = enable;
applyContentBorderThickness(m_nsWindow);
}
void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
{
if (!window)
return;
if (m_drawContentBorderGradient)
[window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
else
[window setStyleMask:[window styleMask] & ~NSTexturedBackgroundWindowMask];
if (m_topContentBorderThickness > 0) {
[window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
}
if (m_bottomContentBorderThickness > 0) {
[window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMinYEdge];
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
}
}
qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7

View File

@ -408,6 +408,9 @@ static QTouchDevice *touchDevice = 0;
m_shouldSetGLContextinDrawRect = false;
}
if (m_platformWindow->m_drawContentBorderGradient)
NSDrawWindowBackground(dirtyRect);
if (!m_backingStore)
return;
@ -451,7 +454,8 @@ static QTouchDevice *touchDevice = 0;
// Optimization: Copy frame buffer content instead of blending for
// top-level windows where Qt fills the entire window content area.
if (m_platformWindow->m_nsWindow)
// (But don't overpaint the title-bar gradient)
if (m_platformWindow->m_nsWindow && !m_platformWindow->m_drawContentBorderGradient)
CGContextSetBlendMode(cgContext, kCGBlendModeCopy);
CGContextDrawImage(cgContext, dirtyWindowRect, cleanImg);