Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (149259 => 149260)
--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm 2013-04-28 18:17:18 UTC (rev 149259)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm 2013-04-28 20:31:22 UTC (rev 149260)
@@ -105,10 +105,6 @@
return x == WKContentAnchorBottomLeft || x == WKContentAnchorBottomRight;
}
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
-static BOOL windowOcclusionNotificationsAreRegistered = NO;
-#endif
-
@interface NSApplication (WKNSApplicationDetails)
- (void)speakString:(NSString *)string;
- (void)_setCurrentEvent:(NSEvent *)event;
@@ -150,14 +146,10 @@
- (void)_setDrawingAreaSize:(NSSize)size;
- (void)_setPluginComplexTextInputState:(PluginComplexTextInputState)pluginComplexTextInputState;
- (BOOL)_shouldUseTiledDrawingArea;
-- (void)_setIsWindowOccluded:(BOOL)isWindowOccluded;
-- (void)_enableWindowOcclusionNotifications;
-- (void)_disableWindowOcclusionNotifications;
+
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
-+ (BOOL)_registerWindowOcclusionNotificationHandlers;
-+ (BOOL)_unregisterWindowOcclusionNotificationHandlers;
+- (void)_setIsWindowOccluded:(BOOL)isWindowOccluded;
#endif
-+ (Vector<WKView *>&)_allViews;
@end
@interface WKViewData : NSObject {
@@ -244,8 +236,11 @@
NSSize _intrinsicContentSize;
BOOL _expandsToFitContentViaAutoLayout;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
BOOL _isWindowOccluded;
BOOL _windowOcclusionDetectionEnabled;
+#endif
}
@end
@@ -253,7 +248,6 @@
@implementation WKViewData
@end
-
@interface WKResponderChainSink : NSResponder {
NSResponder *_lastResponderInChain;
bool _didReceiveUnhandledCommand;
@@ -296,9 +290,6 @@
[_data release];
_data = nil;
- Vector<WKView *>& allViews = [WKView _allViews];
- allViews.remove(allViews.find(self));
-
NSNotificationCenter* workspaceNotificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
[workspaceNotificationCenter removeObserver:self name:NSWorkspaceActiveSpaceDidChangeNotification object:nil];
@@ -1889,8 +1880,6 @@
name:NSWindowDidMoveNotification object:window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResize:)
name:NSWindowDidResizeNotification object:window];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillOrderOffScreen:)
- name:@"NSWindowWillOrderOffScreenNotification" object:window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidOrderOffScreen:)
name:@"NSWindowDidOrderOffScreenNotification" object:window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidOrderOnScreen:)
@@ -1899,6 +1888,10 @@
name:windowDidChangeBackingPropertiesNotification object:window];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeScreen:)
name:NSWindowDidChangeScreenNotification object:window];
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeOcclusionState:)
+ name:NSWindowDidChangeOcclusionStateNotification object:window];
+#endif
}
}
@@ -1919,6 +1912,9 @@
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"_NSWindowDidBecomeVisible" object:window];
[[NSNotificationCenter defaultCenter] removeObserver:self name:windowDidChangeBackingPropertiesNotification object:window];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeScreenNotification object:window];
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeOcclusionStateNotification object:window];
+#endif
}
- (void)viewWillMoveToWindow:(NSWindow *)window
@@ -1940,13 +1936,10 @@
[self removeWindowObservers];
[self addWindowObserversForWindow:window];
- [self _disableWindowOcclusionNotifications];
}
- (void)viewDidMoveToWindow
{
- [self _enableWindowOcclusionNotifications];
-
// We want to make sure to update the active state while hidden, so if the view is about to become visible, we
// update the active state first and then make it visible. If the view is about to be hidden, we hide it first and then
// update the active state.
@@ -2051,11 +2044,6 @@
[self _updateWindowAndViewFrames];
}
-- (void)_windowWillOrderOffScreen:(NSNotification *)notification
-{
- [self _disableWindowOcclusionNotifications];
-}
-
- (void)_windowDidOrderOffScreen:(NSNotification *)notification
{
[self _updateWindowVisibility];
@@ -2069,7 +2057,6 @@
- (void)_windowDidOrderOnScreen:(NSNotification *)notification
{
[self _updateWindowVisibility];
- [self _enableWindowOcclusionNotifications];
// We want to make sure to update the active state while hidden, so since the view is about to become visible,
// we update the active state first and then make it visible.
@@ -2088,6 +2075,16 @@
_data->_page->setIntrinsicDeviceScaleFactor(newBackingScaleFactor);
}
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+- (void)_windowDidChangeOcclusionState:(NSNotification *)notification
+{
+ if (!_data->_windowOcclusionDetectionEnabled)
+ return;
+
+ [self _setIsWindowOccluded:[self.window occlusionState] != NSWindowOcclusionStateVisible];
+}
+#endif
+
static void drawPageBackground(CGContextRef context, WebPageProxy* page, const IntRect& rect)
{
if (!page->drawsBackground())
@@ -2314,6 +2311,7 @@
}
#endif
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
- (void)_setIsWindowOccluded:(BOOL)isWindowOccluded
{
if (_data->_isWindowOccluded == isWindowOccluded)
@@ -2322,126 +2320,8 @@
_data->_isWindowOccluded = isWindowOccluded;
_data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible);
}
-
-- (void)_enableWindowOcclusionNotifications
-{
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
- if (![self windowOcclusionDetectionEnabled])
- return;
-
- NSWindow *window = [self window];
- if (!window)
- return;
-
- NSInteger windowID = [window windowNumber];
- if (windowID <= 0)
- return;
-
- if (![WKView _registerWindowOcclusionNotificationHandlers])
- return;
-
- bool isWindowOccluded = false;
- if (!WKEnableWindowOcclusionNotifications(windowID, &isWindowOccluded)) {
- WTFLogAlways("Enabling window occlusion notifications for window %ld failed.\n", windowID);
- return;
- }
-
- if (isWindowOccluded)
- [self _setIsWindowOccluded:YES];
#endif
-}
-- (void)_disableWindowOcclusionNotifications
-{
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
- [self _setIsWindowOccluded:NO];
-
- // Occlusion notifications for a given window might also be used else where in the
- // application, hence unregister notification handlers instead.
- Vector<WKView *>& allViews = [WKView _allViews];
- if ((allViews.size() == 1) && (allViews[0] == self))
- [WKView _unregisterWindowOcclusionNotificationHandlers];
-#endif
-}
-
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
-
-static void windowBecameVisible(uint32_t, void* data, uint32_t dataLength, void*, uint32_t)
-{
- ASSERT(dataLength == sizeof(WKWindowID));
- NSInteger windowID = *(WKWindowID *)data;
-
- Vector<WKView *>& allViews = [WKView _allViews];
- for (size_t i = 0, size = allViews.size(); i < size; ++i) {
- WKView *view = allViews[i];
- if ([[view window] windowNumber] == windowID)
- [view _setIsWindowOccluded:NO];
- }
-}
-
-static void windowBecameOccluded(uint32_t, void* data, uint32_t dataLength, void*, uint32_t)
-{
- ASSERT(dataLength == sizeof(WKWindowID));
- NSInteger windowID = *(WKWindowID *)data;
-
- Vector<WKView *>& allViews = [WKView _allViews];
- for (size_t i = 0, size = allViews.size(); i < size; ++i) {
- WKView *view = allViews[i];
- if ([[view window] windowNumber] == windowID && [view windowOcclusionDetectionEnabled])
- [view _setIsWindowOccluded:YES];
- }
-}
-
-+ (BOOL)_registerWindowOcclusionNotificationHandlers
-{
- // Disable window occlusion notifications for App Store until <rdar://problem/13255270> is resolved.
- static bool isAppStore = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.appstore"];
- if (isAppStore)
- return NO;
-
- if (windowOcclusionNotificationsAreRegistered)
- return YES;
-
- if (!WKRegisterOcclusionNotificationHandler(WKOcclusionNotificationTypeWindowBecameVisible, windowBecameVisible)) {
- WTFLogAlways("Registeration of \"Window Became Visible\" notification handler failed.\n");
- return NO;
- }
-
- if (!WKRegisterOcclusionNotificationHandler(WKOcclusionNotificationTypeWindowBecameOccluded, windowBecameOccluded)) {
- WTFLogAlways("Registeration of \"Window Became Occluded\" notification handler failed.\n");
- return NO;
- }
-
- windowOcclusionNotificationsAreRegistered = YES;
- return YES;
-}
-
-+ (BOOL)_unregisterWindowOcclusionNotificationHandlers
-{
- if (!windowOcclusionNotificationsAreRegistered)
- return YES;
-
- if (!WKUnregisterOcclusionNotificationHandler(WKOcclusionNotificationTypeWindowBecameOccluded, windowBecameOccluded)) {
- WTFLogAlways("Unregisteration of \"Window Became Occluded\" notification handler failed.\n");
- return NO;
- }
-
- if (!WKUnregisterOcclusionNotificationHandler(WKOcclusionNotificationTypeWindowBecameVisible, windowBecameVisible)) {
- WTFLogAlways("Unregisteration of \"Window Became Visible\" notification handler failed.\n");
- return NO;
- }
-
- windowOcclusionNotificationsAreRegistered = NO;
- return YES;
-}
-#endif
-
-+ (Vector<WKView *>&)_allViews
-{
- DEFINE_STATIC_LOCAL(Vector<WKView *>, vector, ());
- return vector;
-}
-
@end
@implementation WKView (Internal)
@@ -3142,7 +3022,11 @@
- (BOOL)_isWindowOccluded
{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
return _data->_isWindowOccluded;
+#else
+ return NO;
+#endif
}
@end
@@ -3201,7 +3085,11 @@
_data->_expandsToFitContentViaAutoLayout = NO;
_data->_intrinsicContentSize = NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric);
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ _data->_isWindowOccluded = NO;
_data->_windowOcclusionDetectionEnabled = YES;
+#endif
_data->_frameOrigin = NSZeroPoint;
_data->_contentAnchor = WKContentAnchorTopLeft;
@@ -3215,8 +3103,6 @@
self.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft;
}
- [WKView _allViews].append(self);
-
WebContext::statistics().wkViewCount++;
NSNotificationCenter* workspaceNotificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
@@ -3439,18 +3325,32 @@
- (BOOL)windowOcclusionDetectionEnabled
{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
return _data->_windowOcclusionDetectionEnabled;
+#else
+ return NO;
+#endif
}
- (void)setWindowOcclusionDetectionEnabled:(BOOL)flag
{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
if (_data->_windowOcclusionDetectionEnabled == flag)
return;
+
_data->_windowOcclusionDetectionEnabled = flag;
- if (flag)
- [self _enableWindowOcclusionNotifications];
- else
- [self _disableWindowOcclusionNotifications];
+
+ if (flag) {
+ // When enabling window occlusion detection, update the view's current occluded state
+ // immediately, as the notification only fires when it changes.
+ if (self.window)
+ [self _setIsWindowOccluded:[self.window occlusionState] != NSWindowOcclusionStateVisible];
+ } else {
+ // When disabling window occlusion detection, force the view to think it is not occluded,
+ // as it may already be occluded at the time of calling.
+ [self _setIsWindowOccluded:NO];
+ }
+#endif
}
- (void)setContentAnchor:(WKContentAnchor)contentAnchor