diff options
author | Morten Johan Sørvig <morten.sorvig@digia.com> | 2014-02-13 14:14:44 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-20 22:12:47 +0100 |
commit | 3b8b47db6aaeb333f106cff57cc712b01d828302 (patch) | |
tree | ddc23c12694293279f0fb5aba33f23d5b280e13d | |
parent | 2bc7a40048ada41c59ddac0988bb2e04c227a18d (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.h | 9 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 23 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.h | 12 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 37 | ||||
-rw-r--r-- | src/widgets/widgets/qmainwindow.cpp | 14 | ||||
-rw-r--r-- | src/widgets/widgets/qtoolbarlayout.cpp | 37 | ||||
-rw-r--r-- | src/widgets/widgets/qtoolbarlayout_p.h | 1 |
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); |