summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/widgets/qmenu.cpp38
-rw-r--r--src/widgets/widgets/qmenu.h1
-rw-r--r--src/widgets/widgets/qmenu_mac.mm19
-rw-r--r--src/widgets/widgets/qmenu_p.h4
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);