summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@digia.com>2013-04-05 20:55:28 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-15 10:34:06 +0200
commite5e0ec42bbae0816b1bb6c93bf1b7d14b077c64d (patch)
treeaafdc890efc664a073aaa1d7702213791ea92da6 /src
parent11fdd8edcd6a45f5e6bb1cd6e02b06d8f61eb406 (diff)
Cocoa: Fix popup menus on modal windows
Previously, we used -popUpMenuPositioningItem:atLocation:inView: but this turns out not to work with modal windows. This can actually be reproduced in Cocoa. Change-Id: I9b750d1f97637f0cc30329d3da3acf5200f62206 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm36
1 files changed, 33 insertions, 3 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 0fe4c48510..e01af05ca9 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -97,7 +97,6 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader()
if (![menuItem tag])
return YES;
-
QCocoaMenuItem* cocoaItem = reinterpret_cast<QCocoaMenuItem *>([menuItem tag]);
return cocoaItem->isEnabled();
}
@@ -311,8 +310,39 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatf
QCocoaWindow *cocoaWindow = parentWindow ? static_cast<QCocoaWindow *>(parentWindow->handle()) : 0;
NSView *view = cocoaWindow ? cocoaWindow->contentView() : nil;
NSMenuItem *nsItem = item ? ((QCocoaMenuItem *)item)->nsItem() : nil;
- NSPoint nsPos = NSMakePoint(pos.x(), pos.y());
- [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:view];
+
+ // Ideally, we would call -popUpMenuPositioningItem:atLocation:inView:.
+ // However, this showed not to work with modal windows where the menu items
+ // would appear disabled. So, we resort to a more artisanal solution. Note
+ // that this implies several things.
+ //
+ // First, we need to transform 'pos' to window or screen coordinates.
+ NSPoint nsPos = NSMakePoint(pos.x() - 1, pos.y());
+ if (view) {
+ nsPos.y = view.frame.size.height - nsPos.y;
+ } else if (!QGuiApplication::screens().isEmpty()) {
+ QScreen *screen = QGuiApplication::screens().at(0);
+ nsPos.y = screen->availableVirtualSize().height() - nsPos.y;
+ }
+ if (nsItem) {
+ // Then, we need to position the menu ourselves to have the specified item
+ // at the specified position. This also means that we have to guess the menu
+ // item's height. (We could use HITheme to get it, but it looks like an overkill
+ // at this point).
+ CGFloat itemHeight = m_nativeMenu.font.pointSize == 13 ? 18.0 : 19.0;
+ nsPos.y += [m_nativeMenu indexOfItem:nsItem] * itemHeight;
+ }
+ // Last, we need to synthesize an event.
+ NSEvent *menuEvent = [NSEvent mouseEventWithType:NSRightMouseDown
+ location:nsPos
+ modifierFlags:0
+ timestamp:0
+ windowNumber:view ? view.window.windowNumber : 0
+ context:nil
+ eventNumber:0
+ clickCount:1
+ pressure:1.0];
+ [NSMenu popUpContextMenu:m_nativeMenu withEvent:menuEvent forView:view];
// The call above blocks, and also swallows any mouse release event,
// so we need to clear any mouse button that triggered the menu popup.