summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/exportedfunctions.qdoc3
-rw-r--r--doc/src/qnamespace.qdoc8
-rw-r--r--src/corelib/global/qnamespace.h1
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp14
-rw-r--r--src/gui/kernel/qaction.cpp2
-rw-r--r--src/gui/kernel/qapplication_mac.mm4
-rw-r--r--src/gui/kernel/qshortcutmap.cpp6
-rw-r--r--src/gui/widgets/qmenu_mac.mm34
-rw-r--r--src/gui/widgets/qmenubar.cpp107
-rw-r--r--src/gui/widgets/qmenubar.h4
-rw-r--r--src/gui/widgets/qmenubar_p.h5
11 files changed, 133 insertions, 55 deletions
diff --git a/doc/src/exportedfunctions.qdoc b/doc/src/exportedfunctions.qdoc
index f67950c..b421086 100644
--- a/doc/src/exportedfunctions.qdoc
+++ b/doc/src/exportedfunctions.qdoc
@@ -129,6 +129,9 @@
on Mac OS X or be part of the main window. This feature is on by
default.
+ In Qt 4.6, this is equivalent to
+ \c { QApplication::instance()->setAttribute(Qt::AA_MacDontUseNativeMenuBar); }.
+
\section1 void qt_mac_set_press_and_hold_context(bool \e{enable})
Turns emulation of the right mouse button by clicking and holding
diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc
index 9ea6b52..8a1e5e6 100644
--- a/doc/src/qnamespace.qdoc
+++ b/doc/src/qnamespace.qdoc
@@ -149,7 +149,13 @@
\value AA_MacPluginApplication Stops the a Qt mac application from doing
specific initializations that do not necessarily make sense when using Qt
to author a plugin. This includes avoiding loading our nib for the main
- menu and not taking possession of the native menu bar.
+ menu and not taking possession of the native menu bar. When setting this
+ attribute to true will alse set the AA_MacDontUseNativeMenuBar attribute
+ to true.
+
+ \value AA_DontUseNativeMenuBar All menubars created while this attribute is
+ set to true won't be used as a native menubar (e.g, the menubar at
+ the top of the main screen on Mac OS X or at the bottom in Windows CE).
\omitvalue AA_AttributeCount
*/
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 9b26ef3..4873b17 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -503,6 +503,7 @@ public:
AA_NativeWindows = 3,
AA_DontCreateNativeWidgetSiblings = 4,
AA_MacPluginApplication = 5,
+ AA_DontUseNativeMenuBar = 6,
// Add new attributes before this line
AA_AttributeCount
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e4bd664..c21cf87 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -556,6 +556,20 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
QCoreApplicationPrivate::attribs |= 1 << attribute;
else
QCoreApplicationPrivate::attribs &= ~(1 << attribute);
+#ifdef Q_OS_MAC
+ // Turn on the no native menubar here, since we used to
+ // do this implicitly. We DO NOT flip it off if someone sets
+ // it to false.
+ // Ideally, we'd have magic that would be something along the lines of
+ // "follow MacPluginApplication" unless explicitly set.
+ // Considering this attribute isn't only at the beginning
+ // it's unlikely it will ever be a problem, but I want
+ // to have the behavior documented here.
+ if (attribute == Qt::AA_MacPluginApplication && on
+ && !testAttribute(Qt::AA_DontUseNativeMenuBar)) {
+ setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+ }
+#endif
}
/*!
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index c6addc1..b2afbd0 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -1370,7 +1370,7 @@ QAction::MenuRole QAction::menuRole() const
void QAction::setIconVisibleInMenu(bool visible)
{
Q_D(QAction);
- if (visible != (bool)d->iconVisibleInMenu) {
+ if (d->iconVisibleInMenu == -1 || visible != bool(d->iconVisibleInMenu)) {
int oldValue = d->iconVisibleInMenu;
d->iconVisibleInMenu = visible;
// Only send data changed if we really need to.
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 8d0b2c1..d5fa9ea 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1196,10 +1196,6 @@ void qt_init(QApplicationPrivate *priv, int)
[qtMenuLoader release];
}
#endif
- if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) {
- extern void qt_mac_set_native_menubar(bool);
- qt_mac_set_native_menubar(false);
- }
// Register for Carbon tablet proximity events on the event monitor target.
// This means that we should receive proximity events even when we aren't the active application.
if (!tablet_proximity_handler) {
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index ed9654b..b6703e2 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -61,8 +61,6 @@
QT_BEGIN_NAMESPACE
-extern bool qt_mac_no_native_menubar; // qmenu_mac.cpp
-
// To enable verbose output uncomment below
//#define DEBUG_QSHORTCUTMAP
@@ -660,7 +658,7 @@ bool QShortcutMap::correctWidgetContext(Qt::ShortcutContext context, QWidget *w,
{
bool visible = w->isVisible();
#ifdef Q_WS_MAC
- if (!qt_mac_no_native_menubar && qobject_cast<QMenuBar *>(w))
+ if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
visible = true;
#endif
@@ -723,7 +721,7 @@ bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGr
{
bool visible = w->isVisible();
#ifdef Q_WS_MAC
- if (!qt_mac_no_native_menubar && qobject_cast<QMenuBar *>(w))
+ if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w))
visible = true;
#endif
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index ad848c9..d2aad99 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -71,7 +71,6 @@ QT_BEGIN_NAMESPACE
/*****************************************************************************
QMenu globals
*****************************************************************************/
-bool qt_mac_no_native_menubar = false;
bool qt_mac_no_menubar_merge = false;
bool qt_mac_quit_menu_item_enabled = true;
int qt_mac_menus_open_count = 0;
@@ -166,7 +165,7 @@ bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent act
QMenuMergeList *list = 0;
GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyMergeList,
sizeof(list), 0, &list);
- if (!list && qt_mac_current_menubar.qmenubar) {
+ if (!list && qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
MenuRef apple_menu = qt_mac_current_menubar.qmenubar->d_func()->mac_menubar->apple_menu;
GetMenuItemProperty(apple_menu, 0, kMenuCreatorQt, kMenuPropertyMergeList, sizeof(list), 0, &list);
if (list)
@@ -728,6 +727,18 @@ QMacMenuAction::~QMacMenuAction()
{
#ifdef QT_MAC_USE_COCOA
[menu release];
+ if (action) {
+ QAction::MenuRole role = action->menuRole();
+ // Check if the item is owned by Qt, and should be hidden to keep it from causing
+ // problems. Do it for everything but the quit menu item since that should always
+ // be visible.
+ if (role > QAction::ApplicationSpecificRole && role < QAction::QuitRole) {
+ [menuItem setHidden:YES];
+ } else if (role == QAction::TextHeuristicRole
+ && menuItem != [getMenuLoader() quitMenuItem]) {
+ [menuItem setHidden:YES];
+ }
+ }
[menuItem setTag:nil];
[menuItem release];
#endif
@@ -931,7 +942,8 @@ static QKeySequence qt_mac_menu_merge_accel(QMacMenuAction *action)
void Q_GUI_EXPORT qt_mac_set_menubar_icons(bool b)
{ QApplication::instance()->setAttribute(Qt::AA_DontShowIconsInMenus, !b); }
-void Q_GUI_EXPORT qt_mac_set_native_menubar(bool b) { qt_mac_no_native_menubar = !b; }
+void Q_GUI_EXPORT qt_mac_set_native_menubar(bool b)
+{ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, !b); }
void Q_GUI_EXPORT qt_mac_set_menubar_merge(bool b) { qt_mac_no_menubar_merge = !b; }
/*****************************************************************************
@@ -1728,9 +1740,14 @@ QMenuBarPrivate::macCreateMenuBar(QWidget *parent)
{
Q_Q(QMenuBar);
static int checkEnv = -1;
+ // We call the isNativeMenuBar function here
+ // becasue that will make sure that local overrides
+ // are dealt with correctly.
+ bool qt_mac_no_native_menubar = !q->isNativeMenuBar();
if (qt_mac_no_native_menubar == false && checkEnv < 0) {
checkEnv = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty();
- qt_mac_no_native_menubar = checkEnv;
+ QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, checkEnv);
+ qt_mac_no_native_menubar = !q->isNativeMenuBar();
}
if (!qt_mac_no_native_menubar) {
extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp
@@ -1765,7 +1782,7 @@ void QMenuBarPrivate::macDestroyMenuBar()
OSMenuRef QMenuBarPrivate::macMenu()
{
Q_Q(QMenuBar);
- if (!mac_menubar) {
+ if (!q->isNativeMenuBar() || !mac_menubar) {
return 0;
} else if (!mac_menubar->menu) {
mac_menubar->menu = qt_mac_create_menu(q);
@@ -1886,9 +1903,6 @@ static void cancelAllMenuTracking()
*/
bool QMenuBar::macUpdateMenuBar()
{
- if (qt_mac_no_native_menubar) //nothing to be done..
- return true;
-
cancelAllMenuTracking();
QMenuBar *mb = 0;
//find a menu bar
@@ -1922,7 +1936,7 @@ bool QMenuBar::macUpdateMenuBar()
mb = fallback;
//now set it
bool ret = false;
- if (mb) {
+ if (mb && mb->isNativeMenuBar()) {
#ifdef QT_MAC_USE_COCOA
QMacCocoaAutoReleasePool pool;
#endif
@@ -1943,7 +1957,7 @@ bool QMenuBar::macUpdateMenuBar()
qt_mac_current_menubar.qmenubar = mb;
qt_mac_current_menubar.modal = QApplicationPrivate::modalState();
ret = true;
- } else if (qt_mac_current_menubar.qmenubar) {
+ } else if (qt_mac_current_menubar.qmenubar && qt_mac_current_menubar.qmenubar->isNativeMenuBar()) {
const bool modal = QApplicationPrivate::modalState();
if (modal != qt_mac_current_menubar.modal) {
ret = true;
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index f235cd5..d4de5bd 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -194,7 +194,7 @@ void QMenuBarPrivate::updateGeometries()
}
#ifdef Q_WS_MAC
- if(mac_menubar) {//nothing to see here folks, move along..
+ if(q->isNativeMenuBar()) {//nothing to see here folks, move along..
itemsDirty = false;
return;
}
@@ -1025,14 +1025,8 @@ void QMenuBar::paintEvent(QPaintEvent *e)
*/
void QMenuBar::setVisible(bool visible)
{
-#ifdef Q_WS_MAC
- Q_D(QMenuBar);
- if(d->mac_menubar)
- return;
-#endif
-#ifdef Q_WS_WINCE
- Q_D(QMenuBar);
- if(d->wce_menubar)
+#if defined(Q_WS_MAC) || defined(Q_OS_WINCE)
+ if (isNativeMenuBar())
return;
#endif
QWidget::setVisible(visible);
@@ -1272,24 +1266,19 @@ void QMenuBar::actionEvent(QActionEvent *e)
{
Q_D(QMenuBar);
d->itemsDirty = true;
+#if defined (Q_WS_MAC) || defined(Q_OS_WINCE)
+ if (isNativeMenuBar()) {
#ifdef Q_WS_MAC
- if(d->mac_menubar) {
- if(e->type() == QEvent::ActionAdded)
- d->mac_menubar->addAction(e->action(), d->mac_menubar->findAction(e->before()));
- else if(e->type() == QEvent::ActionRemoved)
- d->mac_menubar->removeAction(e->action());
- else if(e->type() == QEvent::ActionChanged)
- d->mac_menubar->syncAction(e->action());
- }
+ QMenuBarPrivate::QMacMenuBarPrivate *nativeMenuBar = d->mac_menubar;
+#else
+ QMenuBarPrivate::QWceMenuBarPrivate *nativeMenuBar = d->wce_menubar;
#endif
-#ifdef Q_WS_WINCE
- if(d->wce_menubar) {
if(e->type() == QEvent::ActionAdded)
- d->wce_menubar->addAction(e->action(), d->wce_menubar->findAction(e->before()));
+ nativeMenuBar->addAction(e->action(), nativeMenuBar->findAction(e->before()));
else if(e->type() == QEvent::ActionRemoved)
- d->wce_menubar->removeAction(e->action());
+ nativeMenuBar->removeAction(e->action());
else if(e->type() == QEvent::ActionChanged)
- d->wce_menubar->syncAction(e->action());
+ nativeMenuBar->syncAction(e->action());
}
#endif
if(e->type() == QEvent::ActionAdded) {
@@ -1612,10 +1601,8 @@ QRect QMenuBar::actionGeometry(QAction *act) const
QSize QMenuBar::minimumSizeHint() const
{
Q_D(const QMenuBar);
-#ifdef Q_WS_MAC
- const bool as_gui_menubar = !d->mac_menubar;
-#elif defined (Q_WS_WINCE)
- const bool as_gui_menubar = !d->wce_menubar;
+#if defined(Q_WS_MAC) || defined(Q_WS_WINCE)
+ const bool as_gui_menubar = !isNativeMenuBar();
#else
const bool as_gui_menubar = true;
#endif
@@ -1672,14 +1659,13 @@ QSize QMenuBar::minimumSizeHint() const
QSize QMenuBar::sizeHint() const
{
Q_D(const QMenuBar);
-#ifdef Q_WS_MAC
- const bool as_gui_menubar = !d->mac_menubar;
-#elif defined (Q_WS_WINCE)
- const bool as_gui_menubar = !d->wce_menubar;
+#if defined(Q_WS_MAC) || defined(Q_WS_WINCE)
+ const bool as_gui_menubar = !isNativeMenuBar();
#else
const bool as_gui_menubar = true;
#endif
+
ensurePolished();
QSize ret(0, 0);
const int hmargin = style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, this);
@@ -1735,13 +1721,12 @@ QSize QMenuBar::sizeHint() const
int QMenuBar::heightForWidth(int) const
{
Q_D(const QMenuBar);
-#ifdef Q_WS_MAC
- const bool as_gui_menubar = !d->mac_menubar;
-#elif defined (Q_WS_WINCE)
- const bool as_gui_menubar = !d->wce_menubar;
+#if defined(Q_WS_MAC) || defined(Q_WS_WINCE)
+ const bool as_gui_menubar = !isNativeMenuBar();
#else
const bool as_gui_menubar = true;
#endif
+
int height = 0;
const int vmargin = style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, this);
int fw = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, this);
@@ -1856,6 +1841,60 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const
}
/*!
+ \property QMenuBar::nativeMenuBar
+ \brief Whether or not a menubar will be used as a native menubar on platforms that support it
+ \since 4.6
+
+ This property specifies whether or not the menubar should be used as a native menubar on platforms
+ that support it. The currently supported platforms are Mac OS X and Windows CE. On these platforms
+ if this property is true, the menubar is used in the native menubar and is not in the window of
+ its parent, if false the menubar remains in the window. On other platforms the value of this
+ attribute has no effect.
+
+ The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute
+ is set for the application. Explicitly settings this property overrides
+ the presence (or abscence) of the attribute.
+*/
+
+void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
+{
+ Q_D(QMenuBar);
+ if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) {
+ d->nativeMenuBar = nativeMenuBar;
+#ifdef Q_WS_MAC
+ if (!d->nativeMenuBar) {
+ extern void qt_mac_clear_menubar();
+ qt_mac_clear_menubar();
+ d->macDestroyMenuBar();
+ const QList<QAction *> &menubarActions = actions();
+ for (int i = 0; i < menubarActions.size(); ++i) {
+ const QAction *action = menubarActions.at(i);
+ if (QMenu *menu = action->menu()) {
+ delete menu->d_func()->mac_menu;
+ menu->d_func()->mac_menu = 0;
+ }
+ }
+ } else {
+ d->macCreateMenuBar(parentWidget());
+ }
+ macUpdateMenuBar();
+ updateGeometry();
+ setVisible(false);
+ setVisible(true);
+#endif
+ }
+}
+
+bool QMenuBar::isNativeMenuBar() const
+{
+ Q_D(const QMenuBar);
+ if (d->nativeMenuBar == -1) {
+ return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar);
+ }
+ return d->nativeMenuBar;
+}
+
+/*!
\since 4.4
Sets the default action to \a act.
diff --git a/src/gui/widgets/qmenubar.h b/src/gui/widgets/qmenubar.h
index 8e6dfb5..58a03ff 100644
--- a/src/gui/widgets/qmenubar.h
+++ b/src/gui/widgets/qmenubar.h
@@ -64,6 +64,7 @@ class Q_GUI_EXPORT QMenuBar : public QWidget
Q_OBJECT
Q_PROPERTY(bool defaultUp READ isDefaultUp WRITE setDefaultUp)
+ Q_PROPERTY(bool nativeMenuBar READ isNativeMenuBar WRITE setNativeMenuBar)
public:
explicit QMenuBar(QWidget *parent = 0);
@@ -118,6 +119,9 @@ public:
static void wceRefresh();
#endif
+ bool isNativeMenuBar() const;
+ void setNativeMenuBar(bool nativeMenuBar);
+
public Q_SLOTS:
virtual void setVisible(bool visible);
diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h
index c0bcb00..5dab310 100644
--- a/src/gui/widgets/qmenubar_p.h
+++ b/src/gui/widgets/qmenubar_p.h
@@ -70,7 +70,8 @@ class QMenuBarPrivate : public QWidgetPrivate
Q_DECLARE_PUBLIC(QMenuBar)
public:
QMenuBarPrivate() : itemsDirty(0), itemsWidth(0), itemsStart(-1), currentAction(0), mouseDown(0),
- closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0)
+ closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0),
+ nativeMenuBar(-1)
#ifdef Q_WS_MAC
, mac_menubar(0)
#endif
@@ -119,6 +120,8 @@ public:
uint keyboardState : 1, altPressed : 1;
QPointer<QWidget> keyboardFocusWidget;
+
+ int nativeMenuBar : 3; // Only has values -1, 0, and 1
//firing of events
void activateAction(QAction *, QAction::ActionEvent);