Title: [239496] trunk
Revision
239496
Author
[email protected]
Date
2018-12-21 00:37:57 -0800 (Fri, 21 Dec 2018)

Log Message

<rdar://problem/46194315> macOS: WebKit1 does not handle occlusion changes
https://bugs.webkit.org/show_bug.cgi?id=192821

Reviewed by Chris Dumez.

Source/WebKitLegacy/mac:

When a window becomes occluded, the window server informs the application.
This should be used to suspend any work that is not visible by the user.

WebKit2 handles it just fine, but WebKit1 did not handle the notification.
In some cases, that lead to performance impact (see radar).

This patch adds an observer for the occlusion notification. I tried to stick
with the same names used by WebKit2.

* WebView/WebView.mm:
(-[WebView _isViewVisible]):
(-[WebView addWindowObserversForWindow:]):
(-[WebView removeWindowObservers]):
(-[WebView _windowDidChangeOcclusionState:]):

Tools:

* DumpRenderTree/mac/DumpRenderTree.mm:
(createWebViewAndOffscreenWindow):
* TestWebKitAPI/mac/WebKitAgnosticTest.mm:

Modified Paths

Diff

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (239495 => 239496)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2018-12-21 08:37:57 UTC (rev 239496)
@@ -1,3 +1,25 @@
+2018-12-21  Benjamin Poulain  <[email protected]>
+
+        <rdar://problem/46194315> macOS: WebKit1 does not handle occlusion changes
+        https://bugs.webkit.org/show_bug.cgi?id=192821
+
+        Reviewed by Chris Dumez.
+
+        When a window becomes occluded, the window server informs the application.
+        This should be used to suspend any work that is not visible by the user.
+
+        WebKit2 handles it just fine, but WebKit1 did not handle the notification.
+        In some cases, that lead to performance impact (see radar).
+
+        This patch adds an observer for the occlusion notification. I tried to stick
+        with the same names used by WebKit2.
+
+        * WebView/WebView.mm:
+        (-[WebView _isViewVisible]):
+        (-[WebView addWindowObserversForWindow:]):
+        (-[WebView removeWindowObservers]):
+        (-[WebView _windowDidChangeOcclusionState:]):
+
 2018-12-20  Jiewen Tan  <[email protected]>
 
         [WebAuthN] Add a runtime flag for local authenticator

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebView.mm (239495 => 239496)


--- trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2018-12-21 08:37:57 UTC (rev 239496)
@@ -4670,15 +4670,21 @@
 
 - (BOOL)_isViewVisible
 {
-    if (![self window])
+    NSWindow *window = [self window];
+    if (!window)
         return false;
 
-    if (![[self window] isVisible])
+    if (![window isVisible])
         return false;
 
     if ([self isHiddenOrHasHiddenAncestor])
         return false;
 
+#if !PLATFORM(IOS_FAMILY)
+    if (_private->windowOcclusionDetectionEnabled && (window.occlusionState & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible)
+        return false;
+#endif
+
     return true;
 }
 
@@ -5067,6 +5073,18 @@
     }
 }
 
+#if !PLATFORM(IOS_FAMILY)
+- (BOOL)windowOcclusionDetectionEnabled
+{
+    return _private->windowOcclusionDetectionEnabled;
+}
+
+- (void)setWindowOcclusionDetectionEnabled:(BOOL)flag
+{
+    _private->windowOcclusionDetectionEnabled = flag;
+}
+#endif
+
 - (void)_setPaginationBehavesLikeColumns:(BOOL)behavesLikeColumns
 {
     Page* page = core(self);
@@ -6002,22 +6020,26 @@
 - (void)addWindowObserversForWindow:(NSWindow *)window
 {
     if (window) {
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowKeyStateChanged:)
+        NSNotificationCenter *defaultNotificationCenter = [NSNotificationCenter defaultCenter];
+
+        [defaultNotificationCenter addObserver:self selector:@selector(windowKeyStateChanged:)
             name:NSWindowDidBecomeKeyNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowKeyStateChanged:)
+        [defaultNotificationCenter addObserver:self selector:@selector(windowKeyStateChanged:)
             name:NSWindowDidResignKeyNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillOrderOnScreen:)
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowWillOrderOnScreen:)
             name:NSWindowWillOrderOnScreenNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowWillOrderOffScreen:)
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowWillOrderOffScreen:)
             name:NSWindowWillOrderOffScreenNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeBackingProperties:)
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowDidChangeBackingProperties:)
             name:windowDidChangeBackingPropertiesNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeScreen:)
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowDidChangeScreen:)
             name:NSWindowDidChangeScreenNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowVisibilityChanged:) 
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowVisibilityChanged:)
             name:NSWindowDidMiniaturizeNotification object:window];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowVisibilityChanged:)
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowVisibilityChanged:)
             name:NSWindowDidDeminiaturizeNotification object:window];
+        [defaultNotificationCenter addObserver:self selector:@selector(_windowDidChangeOcclusionState:)
+            name:NSWindowDidChangeOcclusionStateNotification object:window];
         [_private->windowVisibilityObserver startObserving:window];
     }
 }
@@ -6026,22 +6048,26 @@
 {
     NSWindow *window = [self window];
     if (window) {
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        NSNotificationCenter *defaultNotificationCenter = [NSNotificationCenter defaultCenter];
+
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowDidBecomeKeyNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowDidResignKeyNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowWillOrderOnScreenNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowWillOrderOffScreenNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:windowDidChangeBackingPropertiesNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowDidChangeScreenNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowDidMiniaturizeNotification object:window];
-        [[NSNotificationCenter defaultCenter] removeObserver:self
+        [defaultNotificationCenter removeObserver:self
             name:NSWindowDidDeminiaturizeNotification object:window];
+        [defaultNotificationCenter removeObserver:self
+            name:NSWindowDidChangeOcclusionStateNotification object:window];
         [_private->windowVisibilityObserver stopObserving:window];
     }
 }
@@ -6192,6 +6218,12 @@
 
     _private->page->setDeviceScaleFactor(newBackingScaleFactor);
 }
+
+- (void)_windowDidChangeOcclusionState:(NSNotification *)notification
+{
+    [self _updateVisibilityState];
+}
+
 #else
 - (void)_wakWindowScreenScaleChanged:(NSNotification *)notification
 {

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebViewData.h (239495 => 239496)


--- trunk/Source/WebKitLegacy/mac/WebView/WebViewData.h	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebViewData.h	2018-12-21 08:37:57 UTC (rev 239496)
@@ -211,6 +211,7 @@
     std::unique_ptr<WebCore::TextIndicatorWindow> textIndicatorWindow;
     BOOL hasInitializedLookupObserver;
     RetainPtr<WebWindowVisibilityObserver> windowVisibilityObserver;
+    BOOL windowOcclusionDetectionEnabled;
     RetainPtr<NSEvent> pressureEvent;
 #endif // PLATFORM(MAC)
 

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebViewData.mm (239495 => 239496)


--- trunk/Source/WebKitLegacy/mac/WebView/WebViewData.mm	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebViewData.mm	2018-12-21 08:37:57 UTC (rev 239496)
@@ -183,6 +183,10 @@
     usesPageCache = YES;
     shouldUpdateWhileOffscreen = YES;
 
+#if !PLATFORM(IOS_FAMILY)
+    windowOcclusionDetectionEnabled = YES;
+#endif
+
     zoomMultiplier = 1;
     zoomsTextOnly = NO;
 

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebViewPrivate.h (239495 => 239496)


--- trunk/Source/WebKitLegacy/mac/WebView/WebViewPrivate.h	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebViewPrivate.h	2018-12-21 08:37:57 UTC (rev 239496)
@@ -852,6 +852,11 @@
 - (WebPageVisibilityState)_visibilityState;
 - (void)_setVisibilityState:(WebPageVisibilityState)visibilityState isInitialState:(BOOL)isInitialState;
 
+#if !TARGET_OS_IPHONE
+- (BOOL)windowOcclusionDetectionEnabled;
+- (void)setWindowOcclusionDetectionEnabled:(BOOL)flag;
+#endif
+
 // Whether the column-break-{before,after} properties are respected instead of the
 // page-break-{before,after} properties.
 - (void)_setPaginationBehavesLikeColumns:(BOOL)behavesLikeColumns;

Modified: trunk/Tools/ChangeLog (239495 => 239496)


--- trunk/Tools/ChangeLog	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Tools/ChangeLog	2018-12-21 08:37:57 UTC (rev 239496)
@@ -1,3 +1,14 @@
+2018-12-21  Benjamin Poulain  <[email protected]>
+
+        <rdar://problem/46194315> macOS: WebKit1 does not handle occlusion changes
+        https://bugs.webkit.org/show_bug.cgi?id=192821
+
+        Reviewed by Chris Dumez.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (createWebViewAndOffscreenWindow):
+        * TestWebKitAPI/mac/WebKitAgnosticTest.mm:
+
 2018-12-20  Fujii Hironori  <[email protected]>
 
         [Win][Clang] Fix compilation warnings of DumpRenderTree

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (239495 => 239496)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2018-12-21 08:37:57 UTC (rev 239496)
@@ -724,6 +724,7 @@
     [WebView registerURLSchemeAsLocal:@"feedsearch"];
 
 #if PLATFORM(MAC)
+    [webView setWindowOcclusionDetectionEnabled:NO];
     [WebView _setFontWhitelist:fontWhitelist()];
 #endif
 

Modified: trunk/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.mm (239495 => 239496)


--- trunk/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.mm	2018-12-21 03:04:52 UTC (rev 239495)
+++ trunk/Tools/TestWebKitAPI/mac/WebKitAgnosticTest.mm	2018-12-21 08:37:57 UTC (rev 239496)
@@ -28,6 +28,7 @@
 
 #include <WebKit/WKURLCF.h>
 #include <WebKit/WKViewPrivate.h>
+#include <WebKit/WebViewPrivate.h>
 #include <wtf/RetainPtr.h>
 
 @interface FrameLoadDelegate : NSObject <WebFrameLoadDelegate> {
@@ -85,6 +86,12 @@
 void WebKitAgnosticTest::runWebKit1Test()
 {
     RetainPtr<WebView> webView = adoptNS([[WebView alloc] initWithFrame:viewFrame]);
+#if !TARGET_OS_IPHONE
+    // The tests can be run concurrently. In that case, window can occlude each other and change visibility results.
+    // Occlusion problems also happen from other windows unrelated to WebKit testing.
+    [webView setWindowOcclusionDetectionEnabled:NO];
+#endif
+
     RetainPtr<FrameLoadDelegate> delegate = adoptNS([[FrameLoadDelegate alloc] initWithDidFinishLoadBoolean:&didFinishLoad]);
     [webView.get() setFrameLoadDelegate:delegate.get()];
     initializeView(webView.get());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to