Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.8.2
-
None
-
Qt/Cocoa 4.8.2 on OS X 10.7.4
-
d412f11cea4dc336c684aafcd8979d5cec751cb5
Description
If a top-level menu item is hidden (via menu->menuAction()->setVisible(false)) when its parent window is initially shown, the items in the menu remain disabled if the top-level menu item is later shown.
If the item is visible when the item is initially shown, the problem does not occur.
#include <QtGui/QApplication> #include <QtGui/QPushButton> #include <QtGui/QMenuBar> #include <QtGui/QMenu> #include <QtGui/QAction> int main(int argc, char** argv) { QApplication app(argc, argv); QWidget* widget = new QWidget; widget->resize(300,200); QMenuBar* menu = new QMenuBar(widget); // Populate the menu bar with a menu which is initially hidden. QMenu* testMenu = new QMenu("Test"); menu->addMenu(testMenu); testMenu->menuAction()->setVisible(false); QAction* testAction = new QAction("Test Action", testMenu); testMenu->addAction(testAction); // Add a button which shows the menu when pressed QPushButton* button = new QPushButton("Show Menu", widget); button->setCheckable(true); QObject::connect(button, SIGNAL(toggled(bool)), testMenu->menuAction(), SLOT(setVisible(bool))); // When the widget is shown, click the button to show the menu. The 'Test Action' item // will be disabled, though it should be enabled. // Un-comment this line to show the menu when the window is initially shown. // The problem will not occur in this case. //button->setChecked(true); widget->show(); return app.exec(); }
[NSMenuItem isEnabled] returns NO for the Test menu in this case, even though Qt sends it a [NSMenuItem setEnabled:YES] request. I believe this is because the top-level menu is using Cocoa's automatic menu item validation facility, though Qt turns this off using [NSMenuItem setAutoenablesItems:NO] for all other menus it creates itself.
Cocoa calls [QCocoaMenuLoader validateMenuItem:] for the item, which returns [menuItem isEnabled], which is NO, even though the action is enabled.
This patch fixes the issue, although I making a possibly unsafe assumption here that this method is only called for menu items which represent Qt actions:
--- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -268,7 +268,11 @@ QT_USE_NAMESPACE || [menuItem action] == @selector(unhideAllApplications:)) { return [NSApp validateMenuItem:menuItem]; } else { - return [menuItem isEnabled]; + if (QAction* action = reinterpret_cast<QAction*>([menuItem tag])) { + return action->isEnabled(); + } else { + return [menuItem isEnabled]; + } } }