summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm13
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm6
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm57
-rw-r--r--src/widgets/widgets/qtabbar.cpp71
-rw-r--r--src/widgets/widgets/qtabbar_p.h1
7 files changed, 112 insertions, 41 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 0318c52628..54e45a1d99 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -147,6 +147,10 @@ private:
// Enables or disiables a content border area.
static void setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable);
+ // Returns true if the given coordinate is inside the current
+ // content border.
+ static bool testContentBorderPosition(QWindow *window, int position);
+
// Sets a NSToolbar instance for the given QWindow. The
// toolbar will be attached to the native NSWindow when
// that is created;
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index b18c586212..e09c31231d 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -133,6 +133,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderEnabled);
if (resource.toLower() == "setnstoolbar")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
+ if (resource.toLower() == "testcontentborderposition")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::testContentBorderPosition);
return 0;
}
@@ -332,4 +334,15 @@ void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
cocoaWindow->updateNSToolbar();
}
+bool QCocoaNativeInterface::testContentBorderPosition(QWindow *window, int position)
+{
+ if (!window)
+ return false;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ return cocoaWindow->testContentBorderAreaPosition(position);
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index d8eb0ed0bd..7a01835d5b 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -213,6 +213,7 @@ public:
void registerContentBorderArea(quintptr identifier, int upper, int lower);
void setContentBorderAreaEnabled(quintptr identifier, bool enable);
void setContentBorderEnabled(bool enable);
+ bool testContentBorderAreaPosition(int position) const;
void applyContentBorderThickness(NSWindow *window);
void updateNSToolbar();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 515e2bf132..5a4ac9b2cc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1665,6 +1665,12 @@ void QCocoaWindow::updateNSToolbar()
[m_nsWindow setShowsToolbarButton:YES];
}
+bool QCocoaWindow::testContentBorderAreaPosition(int position) const
+{
+ return m_nsWindow && m_drawContentBorderGradient &&
+ 0 <= position && position < [m_nsWindow contentBorderThicknessForEdge: NSMaxYEdge];
+}
+
qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 2d8489f47f..d35dd16f85 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -179,6 +179,19 @@ static bool isVerticalTabs(const QTabBar::Shape shape) {
|| shape == QTabBar::TriangularWest);
}
+static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY)
+{
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("testContentBorderPosition");
+ if (!function)
+ return false; // Not Cocoa platform plugin.
+
+ typedef bool (*TestContentBorderPositionFunction)(QWindow *, int);
+ return (reinterpret_cast<TestContentBorderPositionFunction>(function))(window, windowY);
+}
+
+
void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
{
// draw background circle
@@ -239,7 +252,7 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
return tabRect;
}
-void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
+void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt, bool isUnified)
{
QRect r = tabOpt->rect;
p->translate(tabOpt->rect.x(), tabOpt->rect.y());
@@ -256,7 +269,12 @@ void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
QRect rect(1, 0, width - 2, height);
// fill body
- if (active) {
+ if (tabOpt->documentMode && isUnified) {
+ p->save();
+ p->setCompositionMode(QPainter::CompositionMode_Source);
+ p->fillRect(rect, QColor(Qt::transparent));
+ p->restore();
+ } else if (active) {
int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
} else {
@@ -3733,8 +3751,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
if (tabOptV3->documentMode) {
p->save();
- // QRect tabRect = tabOptV3->rect;
- drawTabShape(p, tabOptV3);
+ bool isUnified = false;
+ if (w) {
+ QRect tabRect = tabOptV3->rect;
+ QPoint windowTabStart = w->mapTo(w->window(), tabRect.topLeft());
+ isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y());
+ }
+
+ drawTabShape(p, tabOptV3, isUnified);
p->restore();
return;
}
@@ -4442,15 +4466,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
p->fillRect(opt->rect, Qt::transparent);
p->restore();
- // drow horizontal sepearator line at toolBar bottom.
- SInt32 margin;
- GetThemeMetric(kThemeMetricSeparatorSize, &margin);
- CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
- HIThemeSeparatorDrawInfo separatorDrawInfo;
- separatorDrawInfo.version = 0;
- separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
- QMacCGContext cg(p);
- HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
+ // Drow a horizontal sepearator line at the toolBar bottom if the "unified" area ends here.
+ // There might be additional toolbars or other widgets such as tab bars in document
+ // mode below. Determine this by making a unified toolbar area test for the row below
+ // this toolbar.
+ QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft());
+ bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1);
+ if (isEndOfUnifiedArea) {
+ SInt32 margin;
+ GetThemeMetric(kThemeMetricSeparatorSize, &margin);
+ CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
+ HIThemeSeparatorDrawInfo separatorDrawInfo;
+ separatorDrawInfo.version = 0;
+ separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
+ QMacCGContext cg(p);
+ HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
+ }
break;
}
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index b47d65f561..789ec2f6fd 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -56,6 +56,9 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
+#ifdef Q_OS_OSX
+#include <qpa/qplatformnativeinterface.h>
+#endif
#include "qdebug.h"
#include "private/qtabbar_p.h"
@@ -80,35 +83,44 @@ inline static bool verticalTabs(QTabBar::Shape shape)
void QTabBarPrivate::updateMacBorderMetrics()
{
-#if defined(Q_WS_MAC)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- Q_Q(QTabBar);
- ::HIContentBorderMetrics metrics;
-
- // TODO: get metrics to preserve the bottom value
- // TODO: test tab bar position
-
- OSWindowRef window = qt_mac_window_for(q);
-
- // push base line separator down to the client are so we can paint over it (Carbon)
- metrics.top = (documentMode && q->isVisible()) ? 1 : 0;
- metrics.bottom = 0;
- metrics.left = 0;
- metrics.right = 0;
- qt_mac_updateContentBorderMetricts(window, metrics);
- // In Cocoa we need to keep track of the drawRect method.
- // If documentMode is enabled we need to change it, unless
- // a toolbar is present.
- // Notice that all the information is kept in the window,
- // that's why we get the private widget for it instead of
- // the private widget for this widget.
- QWidgetPrivate *privateWidget = qt_widget_private(q->window());
- if(privateWidget)
- privateWidget->changeMethods = documentMode;
- // Since in Cocoa there is no simple way to remove the baseline, so we just ask the
- // top level to do the magic for us.
- privateWidget->syncUnifiedMode();
+#if defined(Q_OS_OSX)
+ Q_Q(QTabBar);
+ // Extend the unified title and toolbar area to cover the tab bar iff
+ // 1) the tab bar is in document mode
+ // 2) the tab bar is directly below an "unified" area.
+ // The extending itself is done in the Cocoa platform plugin and Mac style,
+ // this function registers geometry and visibility state for the tab bar.
+
+ // Calculate geometry
+ int upper, lower;
+ if (documentMode) {
+ QPoint windowPos = q->mapTo(q->window(), QPoint(0,0));
+ upper = windowPos.y();
+ int tabStripHeight = q->tabSizeHint(0).height();
+ int pixelTweak = -3;
+ lower = upper + tabStripHeight + pixelTweak;
+ } else {
+ upper = 0;
+ lower = 0;
}
+
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ quintptr identifier = reinterpret_cast<quintptr>(q);
+
+ // Set geometry
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("registerContentBorderArea");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+ typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, quintptr identifier, int upper, int lower);
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(q->window()->windowHandle(), identifier, upper, lower);
+
+ // Set visibility state
+ function = nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
+ if (!function)
+ return;
+ typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, quintptr identifier, bool enable);
+ (reinterpret_cast<SetContentBorderAreaEnabledFunction>(function))(q->window()->windowHandle(), identifier, q->isVisible());
#endif
}
@@ -1502,6 +1514,9 @@ bool QTabBar::event(QEvent *event)
|| (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
if (!isEventInCornerButtons)
emit tabBarDoubleClicked(tabAt(pos));
+ } else if (event->type() == QEvent::Move) {
+ d->updateMacBorderMetrics();
+ return QWidget::event(event);
}
return QWidget::event(event);
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index b7b6998ca3..3228308bc6 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -182,6 +182,7 @@ public:
void layoutWidgets(int start = 0);
void layoutTab(int index);
void updateMacBorderMetrics();
+ bool isTabInMacUnifiedToolbarArea() const;
void setupMovableTab();
void makeVisible(int index);