diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 38 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_mac.mm | 19 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_p.h | 4 |
4 files changed, 60 insertions, 2 deletions
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 4cf39b3bb5..403ebe7f49 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -50,6 +50,9 @@ #include "qlayout.h" #include "qpainter.h" #include <qpa/qplatformtheme.h> +#ifdef Q_OS_OSX +#include "qmacnativewidget_mac.h" +#endif #include "qapplication.h" #include "qdesktopwidget.h" #ifndef QT_NO_ACCESSIBILITY @@ -163,7 +166,7 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu) platformMenu = menu; if (!platformMenu.isNull()) { - QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow())); + QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SLOT(_q_platformMenuAboutToShow())); QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide())); } } @@ -1104,6 +1107,8 @@ void QMenuPrivate::_q_actionTriggered() Q_Q(QMenu); if (QAction *action = qobject_cast<QAction *>(q->sender())) { QPointer<QAction> actionGuard = action; + if (platformMenu && widgetItems.value(action)) + platformMenu->dismiss(); emit q->triggered(action); if (!activationRecursionGuard && actionGuard) { //in case the action has not been activated by the mouse @@ -1134,6 +1139,24 @@ void QMenuPrivate::_q_actionHovered() } } +void QMenuPrivate::_q_platformMenuAboutToShow() +{ + Q_Q(QMenu); + +#ifdef Q_OS_OSX + if (platformMenu) + Q_FOREACH (QAction *action, q->actions()) + if (QWidget *widget = widgetItems.value(const_cast<QAction *>(action))) + if (widget->parent() == q) { + QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast<quintptr>(action)); + moveWidgetToPlatformItem(widget, menuItem); + platformMenu->syncMenuItem(menuItem); + } +#endif + + emit q->aboutToShow(); +} + bool QMenuPrivate::hasMouseMoved(const QPoint &globalPos) { //determines if the mouse has moved (ie its initial position has @@ -2996,8 +3019,19 @@ void QMenu::actionEvent(QActionEvent *e) if (e->action() == d->currentAction) d->currentAction = 0; if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) { - if (QWidget *widget = d->widgetItems.value(wa)) + if (QWidget *widget = d->widgetItems.value(wa)) { +#ifdef Q_OS_OSX + QWidget *p = widget->parentWidget(); + if (p != this && qobject_cast<QMacNativeWidget *>(p)) { + // This widget was reparented into a native Mac view + // (see QMenuPrivate::moveWidgetToPlatformItem). + // Reset the parent and delete the native widget. + widget->setParent(this); + p->deleteLater(); + } +#endif wa->releaseWidget(widget); + } } d->widgetItems.remove(e->action()); } diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 8a8eaf3bae..fef7903278 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -195,6 +195,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered()) Q_PRIVATE_SLOT(d_func(), void _q_actionHovered()) Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed()) + Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow()) protected: QMenu(QMenuPrivate &dd, QWidget* parent = 0); diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index 41c4481b74..5e304d058b 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -44,6 +44,8 @@ #include "qmenu.h" #include "qmenubar.h" +#include "qmenubar_p.h" +#include "qmacnativewidget_mac.h" #include <QtCore/QDebug> #include <QtGui/QGuiApplication> @@ -115,6 +117,23 @@ void QMenu::setAsDockMenu() \sa QMenu:setAsDockMenu() */ +void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item) +{ + QMacNativeWidget *container = new QMacNativeWidget; + QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater())); + container->resize(widget->sizeHint()); + widget->setParent(container); + + NSView *containerView = container->nativeView(); + QWindow *containerWindow = container->windowHandle(); + Qt::WindowFlags wf = containerWindow->flags(); + containerWindow->setFlags(wf | Qt::SubWindow); + [(NSView *)widget->winId() setAutoresizingMask:NSViewWidthSizable]; + + item->setNativeContents((WId)containerView); + container->show(); +} + #endif //QT_NO_MENU #ifndef QT_NO_MENUBAR diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 9d9851af64..71bf33e1ce 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -110,6 +110,9 @@ public: void init(); void setPlatformMenu(QPlatformMenu *menu); void syncPlatformMenu(); +#ifdef Q_OS_OSX + void moveWidgetToPlatformItem(QWidget *w, QPlatformMenuItem* item); +#endif static QMenuPrivate *get(QMenu *m) { return m->d_func(); } int scrollerHeight() const; @@ -223,6 +226,7 @@ public: void _q_actionTriggered(); void _q_actionHovered(); + void _q_platformMenuAboutToShow(); bool hasMouseMoved(const QPoint &globalPos); |