summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-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);