summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/widgets/qmenu_mac.mm19
-rw-r--r--tests/auto/macnativeevents/nativeeventlist.cpp5
-rw-r--r--tests/auto/macnativeevents/nativeeventlist.h1
-rw-r--r--tests/auto/macnativeevents/tst_macnativeevents.cpp67
4 files changed, 77 insertions, 15 deletions
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 6a0eb53..7645c23 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -665,6 +665,7 @@ void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bo
}
}
#else
+ bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
for (NSMenuItem *item in [menu itemArray]) {
OSMenuRef submenu = [item submenu];
if (submenu != merge) {
@@ -674,10 +675,20 @@ void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bo
// The item should follow what the QAction has.
if ([item tag]) {
QAction *action = reinterpret_cast<QAction *>([item tag]);
- syncNSMenuItemEnabled(item, action->isEnabled());
- } else {
- syncNSMenuItemEnabled(item, YES);
- }
+ syncNSMenuItemEnabled(item, action->isEnabled());
+ } else {
+ syncNSMenuItemEnabled(item, YES);
+ }
+ // We sneak in some extra code here to handle a menu problem:
+ // If there is no window on screen, we cannot set 'nil' as
+ // menu item target, because then cocoa will disable the item
+ // (guess it assumes that there will be no first responder to
+ // catch the trigger anyway?) OTOH, If we have a modal window,
+ // then setting the menu loader as target will make cocoa not
+ // deliver the trigger because the loader is then seen as modally
+ // shaddowed). So either way there are shortcomings. Instead, we
+ // decide the target as late as possible:
+ [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
} else {
syncNSMenuItemEnabled(item, NO);
}
diff --git a/tests/auto/macnativeevents/nativeeventlist.cpp b/tests/auto/macnativeevents/nativeeventlist.cpp
index d5d7b95..1a90ee0 100644
--- a/tests/auto/macnativeevents/nativeeventlist.cpp
+++ b/tests/auto/macnativeevents/nativeeventlist.cpp
@@ -88,11 +88,6 @@ void NativeEventList::append(int waitMs, QNativeEvent *event)
eventList.append(QPair<int, QNativeEvent *>(waitMs, event));
}
-void NativeEventList::append(int waitMs)
-{
- eventList.append(QPair<int, QNativeEvent *>(waitMs, 0));
-}
-
void NativeEventList::play(Playback playback)
{
waitNextEvent();
diff --git a/tests/auto/macnativeevents/nativeeventlist.h b/tests/auto/macnativeevents/nativeeventlist.h
index 688665d..efcca43 100644
--- a/tests/auto/macnativeevents/nativeeventlist.h
+++ b/tests/auto/macnativeevents/nativeeventlist.h
@@ -57,7 +57,6 @@ class NativeEventList : public QObject
void append(QNativeEvent *event);
void append(int waitMs, QNativeEvent *event = 0);
- void append(int waitMs);
void play(Playback playback = WaitUntilFinished);
void stop();
diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp
index 70a14f5..18fe81a 100644
--- a/tests/auto/macnativeevents/tst_macnativeevents.cpp
+++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp
@@ -39,10 +39,7 @@
**
****************************************************************************/
-#include <QApplication>
-#include <QWidget>
-#include <QDialog>
-#include <QPushButton>
+#include <QtGui>
#include <QtTest/QtTest>
#include "qnativeevents.h"
@@ -65,8 +62,10 @@ private slots:
void testMouseDragOutside();
void testMouseDragToNonClientArea();
void testDragWindow();
- void testMouseEnter();
void testChildDialogInFrontOfModalParent();
+ void testMouseEnter();
+ void testMenuBarWorksWithoutWindows();
+ void testMenuBarWorksForModalDialog();
};
void tst_MacNativeEvents::testMouseMoveLocation()
@@ -307,6 +306,64 @@ void tst_MacNativeEvents::testChildDialogInFrontOfModalParent()
QVERIFY(!child.isVisible());
}
+void tst_MacNativeEvents::testMenuBarWorksWithoutWindows()
+{
+ // Test that a global menu bar is enabled even
+ // when there is no window on screen (QTBUG-9209)
+ QEventLoop loop;
+ QMenuBar mb;
+ QMenu *fileMenu = mb.addMenu("Dummy");
+ fileMenu->addAction("Dummy", &loop, SLOT(quit()));
+ QPoint inside1(250, 10);
+ QPoint inside2 = inside1 + QPoint(0, 30);
+
+ // Post a click to press the menu item:
+ NativeEventList native;
+ native.append(new QNativeMouseButtonEvent(inside1, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside1, Qt::LeftButton, 0, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside2, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside2, Qt::LeftButton, 0, Qt::NoModifier));
+
+ // Add a backup timer to end the test if we fail:
+ QTimer dontHang;
+ dontHang.setSingleShot(true);
+ connect(&dontHang, SIGNAL(timeout()), &loop, SLOT(quit()));
+ dontHang.start(2000);
+
+ native.play(NativeEventList::ReturnImmediately);
+ loop.exec();
+ QVERIFY2(dontHang.isActive(), "The item was not triggered!");
+}
+
+void tst_MacNativeEvents::testMenuBarWorksForModalDialog()
+{
+ // Test that a global menu bar is enabled even
+ // when there is no window on screen (QTBUG-9209)
+ QDialog dialog;
+ QMenuBar mb;
+ QMenu *fileMenu = mb.addMenu("Dummy");
+ fileMenu->addAction("Dummy", &dialog, SLOT(hide()));
+ QPoint inside1(250, 10);
+ QPoint inside2 = inside1 + QPoint(0, 30);
+
+ // Post a click to press the menu item:
+ NativeEventList native;
+ native.append(new QNativeMouseButtonEvent(inside1, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside1, Qt::LeftButton, 0, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside2, Qt::LeftButton, 1, Qt::NoModifier));
+ native.append(new QNativeMouseButtonEvent(inside2, Qt::LeftButton, 0, Qt::NoModifier));
+
+ // Add a backup timer to end the test if we fail:
+ QTimer dontHang;
+ dontHang.setSingleShot(true);
+ connect(&dontHang, SIGNAL(timeout()), &dialog, SLOT(hide()));
+ dontHang.start(2000);
+
+ native.play(NativeEventList::ReturnImmediately);
+ dialog.exec();
+ QVERIFY2(dontHang.isActive(), "The item was not triggered!");
+}
+
#include "tst_macnativeevents.moc"
QTEST_MAIN(tst_MacNativeEvents)