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>
This commit is contained in:
parent
454dc332b3
commit
c7bd85e97d
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user