summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@digia.com>2014-02-13 14:14:44 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-20 22:12:47 +0100
commit3b8b47db6aaeb333f106cff57cc712b01d828302 (patch)
treeddc23c12694293279f0fb5aba33f23d5b280e13d
parent2bc7a40048ada41c59ddac0988bb2e04c227a18d (diff)
Set unified toolbar height accurately.
Add registerContentBorderArea() to the Cocoa native interface which allows registering multiple "unified toolbar" areas for each window. Use this function in QToolBarLayout::setGeometry() to register the area for each TopToolBarArea toolbar. Task-number: QTBUG-36700 Change-Id: I52efcc5662556bb94f25f504be3710d0491f79b9 Reviewed-by: Jake Petroules <jake.petroules@petroules.com> Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com> Reviewed-by: Denis Dzyubenko <denis@ddenis.info>
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm23
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h12
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm37
-rw-r--r--src/widgets/widgets/qmainwindow.cpp14
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp37
-rw-r--r--src/widgets/widgets/qtoolbarlayout_p.h1
7 files changed, 121 insertions, 12 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index bf7e85619a..efdd433d8f 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -136,10 +136,19 @@ private:
// Request a unified title and toolbar look for the window.
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
+ // Request a unified title and toolbar look for the window by registering
+ // an area. Multiple callers can register areas and the platform plugin
+ // will extend the "unified" area to cover them.
+ static void registerContentBorderArea(QWindow *window, quintptr identifer, int upper, int lower);
+
+ // Enable the unified title and toolbar area.
+ static void enableContentBorderArea(QWindow *window, bool enable);
+
// Sets a NSToolbar instance for the given QWindow. The
// toolbar will be attached to the native NSWindow when
// that is created;
static void setNSToolbar(QWindow *window, void *nsToolbar);
+
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 5e57200ebc..d6a5be8d52 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -125,6 +125,10 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView);
if (resource.toLower() == "setcontentborderthickness")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
+ if (resource.toLower() == "registercontentborderarea")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerContentBorderArea);
+ if (resource.toLower() == "enablecontentborderarea")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::enableContentBorderArea);
if (resource.toLower() == "setnstoolbar")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
@@ -287,11 +291,28 @@ void QCocoaNativeInterface::setContentBorderThickness(QWindow *window, int topTh
cocoaWindow->setContentBorderThickness(topThickness, bottomThickness);
}
-void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
+void QCocoaNativeInterface::registerContentBorderArea(QWindow *window, quintptr identifier, int upper, int lower)
{
if (!window)
return;
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->registerContentBorderArea(identifier, upper, lower);
+}
+
+void QCocoaNativeInterface::enableContentBorderArea(QWindow *window, bool enable)
+{
+ if (!window)
+ return;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->enableContentBorderArea(enable);
+}
+
+void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
+{
QCocoaIntegration::instance()->setToolbar(window, static_cast<NSToolbar *>(nsToolbar));
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index fe82edd618..96df3f4c59 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -208,6 +208,8 @@ public:
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
+ void registerContentBorderArea(quintptr identifier, int upper, int lower);
+ void enableContentBorderArea(bool enable);
void applyContentBorderThickness(NSWindow *window);
void updateNSToolbar();
@@ -282,6 +284,16 @@ public: // for QNSView
QRect m_normalGeometry;
Qt::WindowFlags m_oldWindowFlags;
NSApplicationPresentationOptions m_presentationOptions;
+
+ struct BorderRange {
+ BorderRange(int u, int l) : upper(u), lower(l) { }
+ int upper;
+ int lower;
+ bool operator<(BorderRange const& right) const {
+ return upper < right.upper;
+ }
+ };
+ QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index d8ec144ad2..bbd5dd7311 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1540,15 +1540,46 @@ void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickne
applyContentBorderThickness(m_nsWindow);
}
+void QCocoaWindow::registerContentBorderArea(quintptr identifier, int upper, int lower)
+{
+ m_contentBorderAreas.insert(identifier, BorderRange(upper, lower));
+
+ // Find consecutive registered border areas, starting from the top.
+ QList<BorderRange> ranges = m_contentBorderAreas.values();
+ std::sort(ranges.begin(), ranges.end());
+ m_topContentBorderThickness = 0;
+ foreach (BorderRange range, ranges) {
+ // Is this sub-range adjacent to or overlaping the
+ // existing total border area range? If so merge
+ // it into the total range,
+ if (range.upper <= (m_topContentBorderThickness + 1))
+ m_topContentBorderThickness = qMax(m_topContentBorderThickness, range.lower);
+ else
+ break;
+ }
+
+ m_bottomContentBorderThickness = 0; // (not supported)
+ if (m_drawContentBorderGradient)
+ applyContentBorderThickness(m_nsWindow);
+}
+
+void QCocoaWindow::enableContentBorderArea(bool enable)
+{
+ m_drawContentBorderGradient = enable;
+ applyContentBorderThickness(m_nsWindow);
+}
+
void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
{
if (!window)
return;
- if (m_drawContentBorderGradient)
- [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
- else
+ if (!m_drawContentBorderGradient) {
[window setStyleMask:[window styleMask] & ~NSTexturedBackgroundWindowMask];
+ return;
+ }
+
+ [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
if (m_topContentBorderThickness > 0) {
[window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge];
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 07db78c06c..1d0268a244 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1508,19 +1508,17 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
#ifdef Q_OS_OSX
Q_D(QMainWindow);
if (isWindow()) {
+ d->useUnifiedToolBar = set;
+ createWinId();
+
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
- nativeInterface->nativeResourceFunctionForIntegration("setContentBorderThickness");
+ nativeInterface->nativeResourceFunctionForIntegration("enableContentBorderArea");
if (!function)
return; // Not Cocoa platform plugin.
- createWinId();
-
- d->useUnifiedToolBar = set;
-
- const int toolBarHeight = 50;
- typedef void (*SetContentBorderThicknessFunction)(QWindow *window, int topThickness, int bottomThickness);
- (reinterpret_cast<SetContentBorderThicknessFunction>(function))(window()->windowHandle(), toolBarHeight, 0);
+ typedef void (*EnableContentBorderAreaFunction)(QWindow *window, bool enable);
+ (reinterpret_cast<EnableContentBorderAreaFunction>(function))(window()->windowHandle(), set);
}
#endif
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index fe919feba9..020d180778 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <qapplication.h>
#include <qaction.h>
#include <qwidgetaction.h>
#include <qtoolbar.h>
@@ -47,6 +48,9 @@
#include <qmenu.h>
#include <qdebug.h>
#include <qmath.h>
+#ifdef Q_OS_OSX
+#include <qpa/qplatformnativeinterface.h>
+#endif
#include "qmainwindowlayout_p.h"
#include "qtoolbarextension_p.h"
@@ -341,6 +345,37 @@ static bool defaultWidgetAction(QToolBarItem *item)
return a != 0 && a->defaultWidget() == item->widget();
}
+void QToolBarLayout::updateMacBorderMetrics()
+{
+#ifdef Q_OS_OSX
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return;
+
+ QRect rect = geometry();
+
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(tb->parentWidget());
+ if (!mainWindow || !mainWindow->isWindow() || !mainWindow->unifiedTitleAndToolBarOnMac())
+ return;
+
+ QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("registerContentBorderArea");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+
+ QPoint upper = tb->mapToParent(rect.topLeft());
+ QPoint lower = tb->mapToParent(rect.bottomLeft() + QPoint(0, 1));
+
+ typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, void *identifier, int upper, int lower);
+ if (mainWindow->toolBarArea(tb) == Qt::TopToolBarArea) {
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, upper.y(), lower.y());
+ } else {
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, 0, 0);
+ }
+#endif
+}
+
void QToolBarLayout::setGeometry(const QRect &rect)
{
QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
@@ -355,6 +390,8 @@ void QToolBarLayout::setGeometry(const QRect &rect)
QLayout::setGeometry(rect);
+ updateMacBorderMetrics();
+
bool ranOutOfSpace = false;
if (!animating)
ranOutOfSpace = layoutActions(rect.size());
diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h
index 8605a9a6ac..b250f3adee 100644
--- a/src/widgets/widgets/qtoolbarlayout_p.h
+++ b/src/widgets/widgets/qtoolbarlayout_p.h
@@ -111,6 +111,7 @@ public:
void updateMarginAndSpacing();
bool hasExpandFlag() const;
+ void updateMacBorderMetrics();
public Q_SLOTS:
void setExpanded(bool b);