diff options
-rw-r--r-- | src/gui/widgets/qmenu_mac.mm | 19 | ||||
-rw-r--r-- | tests/auto/macnativeevents/nativeeventlist.cpp | 5 | ||||
-rw-r--r-- | tests/auto/macnativeevents/nativeeventlist.h | 1 | ||||
-rw-r--r-- | tests/auto/macnativeevents/tst_macnativeevents.cpp | 67 |
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) |