summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@digia.com>2014-04-01 18:18:17 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-18 11:05:25 +0200
commitc7bd85e97df1b188bcbd4a2a511313d221c5bb83 (patch)
tree757f1fea25705524b6fbdf280fd68dadb5aa602d /src/plugins/platforms
parent454dc332b3856c1726683595575c34281650a469 (diff)
Cocoa: NSMenu views never get viewDidUnhide called
This is the case for QWidgets added as native menu items with QWidgetAction. According to Cocoa's documentation [1], we should rely on -[QNSView viewDidMoveToWindow] instead. On 10.9 however, we receive NSWindowDidChangeOcclusionStateNotification from the NSMenu window, which is preferable to using -[QNSView viewDidMoveToWindow] as it guarantees the view is actually visible. We do runtime symbol lookup to get this to work on 10.9 regardless of the build SDK version. [1] https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/MenuList/Articles/ViewsInMenuItems.html Task-number: QTBUG-19840 Change-Id: If4676df5d79c359965f09ef2e5eddf4c925e3533 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 0b9683a3ef..e2572d607a 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -42,6 +42,7 @@
#include <QtCore/qglobal.h>
#include <Carbon/Carbon.h>
+#include <dlfcn.h>
#include "qnsview.h"
#include "qcocoawindow.h"
@@ -65,6 +66,9 @@
static QTouchDevice *touchDevice = 0;
+// ### HACK Remove once 10.8 is unsupported
+static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
+
@interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
- (CGFloat)deviceDeltaX;
- (CGFloat)deviceDeltaY;
@@ -73,6 +77,13 @@ static QTouchDevice *touchDevice = 0;
@implementation QNSView
++ (void)initialize
+{
+ NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification");
+ if (notificationNameVar)
+ _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar;
+}
+
- (id) init
{
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
@@ -192,6 +203,19 @@ static QTouchDevice *touchDevice = 0;
}
}
+- (void)viewDidMoveToWindow
+{
+ if (self.window) {
+ // This is the case of QWidgetAction's generated QWidget inserted in an NSMenu.
+ // 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification
+ if (!_q_NSWindowDidChangeOcclusionStateNotification
+ && [self.window.className isEqualToString:@"NSCarbonMenuWindow"])
+ m_platformWindow->exposeWindow();
+ } else {
+ m_platformWindow->obscureWindow();
+ }
+}
+
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
{
// ### Merge "normal" window code path with this one for 5.1.
@@ -325,6 +349,23 @@ static QTouchDevice *touchDevice = 0;
m_platformWindow->obscureWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
m_platformWindow->exposeWindow();
+ } else if (_q_NSWindowDidChangeOcclusionStateNotification
+ && [notificationName isEqualToString:_q_NSWindowDidChangeOcclusionStateNotification]) {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
+// ### HACK Remove the enum declaration, the warning disabling and the cast further down once 10.8 is unsupported
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-method-access"
+ enum { NSWindowOcclusionStateVisible = 1UL << 1 };
+#endif
+ // Older versions managed in -[QNSView viewDidMoveToWindow].
+ // Support QWidgetAction in NSMenu. Mavericks only sends this notification.
+ // Ideally we should support this in Qt as well, in order to disable animations
+ // when the window is occluded.
+ if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible)
+ m_platformWindow->exposeWindow();
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
+#pragma clang diagnostic pop
+#endif
} else if (notificationName == NSWindowDidChangeScreenNotification) {
if (m_window) {
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];