Title: [149260] trunk/Source/WebKit2
Revision
149260
Author
[email protected]
Date
2013-04-28 13:31:22 -0700 (Sun, 28 Apr 2013)

Log Message

[WebKit2] Adopt new API for detecting window occlusion
https://bugs.webkit.org/show_bug.cgi?id=115334

Reviewed by Simon Fraser.

Switch off of WKSI for window occlusion and use the new NSWindowDidChangeOcclusionState notification
instead.

* UIProcess/API/mac/WKView.mm:
(-[WKView dealloc]):
(-[WKView addWindowObserversForWindow:]):
(-[WKView removeWindowObservers]):
(-[WKView viewWillMoveToWindow:]):
(-[WKView viewDidMoveToWindow]):
(-[WKView _windowDidOrderOnScreen:]):
(-[WKView _windowDidChangeOcclusionState:]):
(-[WKView _setIsWindowOccluded:]):
(-[WKView initWithFrame:contextRef:pageGroupRef:relatedToPage:]):
(-[WKView windowOcclusionDetectionEnabled]):
(-[WKView setWindowOcclusionDetectionEnabled:]):
Only compile occlusion detection code where supported and remove calls to register/deregister
for detection callbacks, now that NSWindow will handle that for us. We also no longer need to
track all the WKViews, as that was only required to lookup the view that matched the window number
returned from the occlusion callback.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (149259 => 149260)


--- trunk/Source/WebKit2/ChangeLog	2013-04-28 18:17:18 UTC (rev 149259)
+++ trunk/Source/WebKit2/ChangeLog	2013-04-28 20:31:22 UTC (rev 149260)
@@ -1,3 +1,30 @@
+2013-04-28  Sam Weinig  <[email protected]>
+
+        [WebKit2] Adopt new API for detecting window occlusion
+        https://bugs.webkit.org/show_bug.cgi?id=115334
+
+        Reviewed by Simon Fraser.
+
+        Switch off of WKSI for window occlusion and use the new NSWindowDidChangeOcclusionState notification
+        instead.
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView dealloc]):
+        (-[WKView addWindowObserversForWindow:]):
+        (-[WKView removeWindowObservers]):
+        (-[WKView viewWillMoveToWindow:]):
+        (-[WKView viewDidMoveToWindow]):
+        (-[WKView _windowDidOrderOnScreen:]):
+        (-[WKView _windowDidChangeOcclusionState:]):
+        (-[WKView _setIsWindowOccluded:]):
+        (-[WKView initWithFrame:contextRef:pageGroupRef:relatedToPage:]):
+        (-[WKView windowOcclusionDetectionEnabled]):
+        (-[WKView setWindowOcclusionDetectionEnabled:]):
+        Only compile occlusion detection code where supported and remove calls to register/deregister
+        for detection callbacks, now that NSWindow will handle that for us. We also no longer need to
+        track all the WKViews, as that was only required to lookup the view that matched the window number
+        returned from the occlusion callback.
+
 2013-04-26  Anders Carlsson  <[email protected]>
 
         Use OwnPtr<PluginControllerProxy> for storing plug-in controllers in WebProcessConnection

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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to