Title: [170667] trunk
Revision
170667
Author
wei...@apple.com
Date
2014-07-01 14:16:14 -0700 (Tue, 01 Jul 2014)

Log Message

[Cocoa][Mac] WKWebView should automatically set topContentInset when beneath a toolbar
<rdar://problem/17523159>
https://bugs.webkit.org/show_bug.cgi?id=134496

Reviewed by Beth Dakin.


Source/WebKit2: 
- Adds _automaticallyAdjustsContentInsets SPI to both WKView and WKWebView.
- Defaults _automaticallyAdjustsContentInsets to NO for WKView to keep legacy clients working.
- Defaults _automaticallyAdjustsContentInsets to YES for WKWebView.

* UIProcess/API/Cocoa/WKViewPrivate.h:
Add _automaticallyAdjustsContentInsets SPI.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView initWithFrame:configuration:]):
Default _automaticallyAdjustsContentInsets to YES for WKWebView.

(-[WKWebView _setTopContentInset:]):
(-[WKWebView _topContentInset]):
Change to forward to the WKView, since we now do coalescing and caching there.

(-[WKWebView _setAutomaticallyAdjustsContentInsets:]):
(-[WKWebView _automaticallyAdjustsContentInsets]):
Forward to the WKView.

* UIProcess/API/Cocoa/WKWebViewPrivate.h:
Add _automaticallyAdjustsContentInsets SPI.

* UIProcess/API/mac/WKView.mm:
(-[WKView renewGState]):
Ensure the contentInset is updated when the view changes, as its relative location to the toolbar may have changed.

(-[WKView addWindowObserversForWindow:]):
(-[WKView removeWindowObservers]):
(-[WKView observeValueForKeyPath:ofObject:change:context:]):
Add observers for the contentLayoutRect and titlebarAppearsTransparent properties on the window. If either of them
change, we need to recalculate the content inset.

(-[WKView _updateContentInsetsIfAutomatic]):
If _automaticallyAdjustsContentInsets is YES, follow the same rules as AppKit in setting the top content inset. Like
AppKit this is only done when:
    - The window's style mask has the NSFullSizeContentViewWindowMask bit.
    - The window does not have titlebarAppearsTransparent set.
    - And we are not in an enclosing NSScrollView.

(-[WKView _setTopContentInset:]):
(-[WKView _topContentInset]):
Coalesce setting the topContentInset to avoid a visual lag when resizing the window that was caused by us sending
multiple topContentInsets to the WebContentProcess per runloop cycle. The reason for the lag was that at the time
we observe the contentLayoutRect changing, our view may not yet be in its final position yet, so the inset will be
temporarily wrong. When the view is finally positioned correctly, we will get a renewGState, at which point we will
again calculate the inset, which now will be correct. Since these both happen in the same runloop iteration, we can
just defer sending the inset to the WebContentProcess.

(-[WKView _setAutomaticallyAdjustsContentInsets:]):
(-[WKView _automaticallyAdjustsContentInsets]):
Add the new SPI.

Tools: 
* MiniBrowser/mac/BrowserWindowController.m:
(-[BrowserWindowController windowDidLoad]):
Use the NSFullSizeContentViewWindowMask bit on Yosemite and later to enable toolbar blurring.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (170666 => 170667)


--- trunk/Source/WebKit2/ChangeLog	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Source/WebKit2/ChangeLog	2014-07-01 21:16:14 UTC (rev 170667)
@@ -1,3 +1,63 @@
+2014-07-01  Sam Weinig  <s...@webkit.org>
+
+        [Cocoa][Mac] WKWebView should automatically set topContentInset when beneath a toolbar
+        <rdar://problem/17523159>
+        https://bugs.webkit.org/show_bug.cgi?id=134496
+
+        Reviewed by Beth Dakin.
+
+        - Adds _automaticallyAdjustsContentInsets SPI to both WKView and WKWebView.
+        - Defaults _automaticallyAdjustsContentInsets to NO for WKView to keep legacy clients working.
+        - Defaults _automaticallyAdjustsContentInsets to YES for WKWebView.
+
+        * UIProcess/API/Cocoa/WKViewPrivate.h:
+        Add _automaticallyAdjustsContentInsets SPI.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView initWithFrame:configuration:]):
+        Default _automaticallyAdjustsContentInsets to YES for WKWebView.
+
+        (-[WKWebView _setTopContentInset:]):
+        (-[WKWebView _topContentInset]):
+        Change to forward to the WKView, since we now do coalescing and caching there.
+
+        (-[WKWebView _setAutomaticallyAdjustsContentInsets:]):
+        (-[WKWebView _automaticallyAdjustsContentInsets]):
+        Forward to the WKView.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        Add _automaticallyAdjustsContentInsets SPI.
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView renewGState]):
+        Ensure the contentInset is updated when the view changes, as its relative location to the toolbar may have changed.
+
+        (-[WKView addWindowObserversForWindow:]):
+        (-[WKView removeWindowObservers]):
+        (-[WKView observeValueForKeyPath:ofObject:change:context:]):
+        Add observers for the contentLayoutRect and titlebarAppearsTransparent properties on the window. If either of them
+        change, we need to recalculate the content inset.
+
+        (-[WKView _updateContentInsetsIfAutomatic]):
+        If _automaticallyAdjustsContentInsets is YES, follow the same rules as AppKit in setting the top content inset. Like
+        AppKit this is only done when:
+            - The window's style mask has the NSFullSizeContentViewWindowMask bit.
+            - The window does not have titlebarAppearsTransparent set.
+            - And we are not in an enclosing NSScrollView.
+
+        (-[WKView _setTopContentInset:]):
+        (-[WKView _topContentInset]):
+        Coalesce setting the topContentInset to avoid a visual lag when resizing the window that was caused by us sending
+        multiple topContentInsets to the WebContentProcess per runloop cycle. The reason for the lag was that at the time
+        we observe the contentLayoutRect changing, our view may not yet be in its final position yet, so the inset will be
+        temporarily wrong. When the view is finally positioned correctly, we will get a renewGState, at which point we will
+        again calculate the inset, which now will be correct. Since these both happen in the same runloop iteration, we can
+        just defer sending the inset to the WebContentProcess.
+
+        (-[WKView _setAutomaticallyAdjustsContentInsets:]):
+        (-[WKView _automaticallyAdjustsContentInsets]):
+        Add the new SPI.
+
 2014-07-01  Anders Carlsson  <ander...@apple.com>
 
         Add a function for restoring page state given a SessionState object

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h (170666 => 170667)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h	2014-07-01 21:16:14 UTC (rev 170667)
@@ -83,6 +83,10 @@
 @property (readwrite) BOOL allowsBackForwardNavigationGestures;
 @property (nonatomic, setter=_setTopContentInset:) CGFloat _topContentInset;
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+@property (nonatomic, setter=_setAutomaticallyAdjustsContentInsets:) BOOL _automaticallyAdjustsContentInsets;
+#endif
+
 @property (readonly) NSColor *_pageExtendedBackgroundColor;
 @property(copy, nonatomic) NSColor *underlayColor;
 

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (170666 => 170667)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm	2014-07-01 21:16:14 UTC (rev 170667)
@@ -306,7 +306,11 @@
     _wkView = [[WKView alloc] initWithFrame:bounds context:context configuration:std::move(webPageConfiguration) webView:self];
     [self addSubview:_wkView.get()];
     _page = WebKit::toImpl([_wkView pageRef]);
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+    [_wkView _setAutomaticallyAdjustsContentInsets:YES];
 #endif
+#endif
 
     _page->setBackgroundExtendsBeyondPage(true);
 
@@ -2240,16 +2244,30 @@
 
 - (void)_setTopContentInset:(CGFloat)contentInset
 {
-    _page->setTopContentInset(contentInset);
+    [_wkView _setTopContentInset:contentInset];
 }
 
 - (CGFloat)_topContentInset
 {
-    return _page->topContentInset();
+    return [_wkView _topContentInset];
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+
+- (void)_setAutomaticallyAdjustsContentInsets:(BOOL)automaticallyAdjustsContentInsets
+{
+    [_wkView _setAutomaticallyAdjustsContentInsets:automaticallyAdjustsContentInsets];
+}
+
+- (BOOL)_automaticallyAdjustsContentInsets
+{
+    return [_wkView _automaticallyAdjustsContentInsets];
+}
+
 #endif
 
+#endif
+
 @end
 
 #if !TARGET_OS_IPHONE

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h (170666 => 170667)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h	2014-07-01 21:16:14 UTC (rev 170667)
@@ -146,7 +146,10 @@
 @property (readonly) NSColor *_pageExtendedBackgroundColor;
 @property (nonatomic, setter=_setDrawsTransparentBackground:) BOOL _drawsTransparentBackground;
 @property (nonatomic, setter=_setTopContentInset:) CGFloat _topContentInset;
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+@property (nonatomic, setter=_setAutomaticallyAdjustsContentInsets:) BOOL _automaticallyAdjustsContentInsets;
 #endif
+#endif
 
 - (void)_getMainResourceDataWithCompletionHandler:(void (^)(NSData *, NSError *))completionHandler;
 - (void)_getWebArchiveDataWithCompletionHandler:(void (^)(NSData *, NSError *))completionHandler;

Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (170666 => 170667)


--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2014-07-01 21:16:14 UTC (rev 170667)
@@ -241,6 +241,13 @@
 
     RetainPtr<CALayer> _rootLayer;
 
+    BOOL _didScheduleSetTopContentInset;
+    CGFloat _topContentInset;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+    BOOL _automaticallyAdjustsContentInsets;
+#endif
+
 #if WK_API_ENABLED
     _WKThumbnailView *_thumbnailView;
 #endif
@@ -481,6 +488,10 @@
     if ([self window])
         [self _updateWindowAndViewFrames];
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+    [self _updateContentInsetsIfAutomatic];
+#endif
+
     [super renewGState];
 }
 
@@ -2402,6 +2413,10 @@
     return NSMouseInRect(localPoint, visibleThumbRect, [self isFlipped]);
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+static void* keyValueObservingContext = &keyValueObservingContext;
+#endif
+
 - (void)addWindowObserversForWindow:(NSWindow *)window
 {
     if (window) {
@@ -2431,6 +2446,10 @@
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeOcclusionState:)
                                                      name:NSWindowDidChangeOcclusionStateNotification object:window];
 #endif
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+        [window addObserver:self forKeyPath:@"contentLayoutRect" options:NSKeyValueObservingOptionInitial context:keyValueObservingContext];
+        [window addObserver:self forKeyPath:@"titlebarAppearsTransparent" options:NSKeyValueObservingOptionInitial context:keyValueObservingContext];
+#endif
     }
 }
 
@@ -2455,6 +2474,10 @@
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
     [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeOcclusionStateNotification object:window];
 #endif
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+    [window removeObserver:self forKeyPath:@"contentLayoutRect" context:keyValueObservingContext];
+    [window removeObserver:self forKeyPath:@"titlebarAppearsTransparent" context:keyValueObservingContext];
+#endif
 }
 
 - (void)viewWillMoveToWindow:(NSWindow *)window
@@ -3550,6 +3573,35 @@
 }
 #endif // WK_API_ENABLED
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+
+- (void)_updateContentInsetsIfAutomatic
+{
+    if (!self._automaticallyAdjustsContentInsets)
+        return;
+
+    if ((self.window.styleMask & NSFullSizeContentViewWindowMask) && !self.window.titlebarAppearsTransparent && ![self enclosingScrollView]) {
+        NSRect contentLayoutRect = [self convertRect:self.window.contentLayoutRect fromView:nil];
+        CGFloat newTopContentInset = NSMaxY(contentLayoutRect) - NSHeight(contentLayoutRect);
+        if (self._topContentInset != newTopContentInset)
+            self._topContentInset = newTopContentInset;
+    } else
+        self._topContentInset = 0;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    if (context == keyValueObservingContext) {
+        if ([keyPath isEqualToString:@"contentLayoutRect"] || [keyPath isEqualToString:@"titlebarAppearsTransparent"])
+            [self _updateContentInsetsIfAutomatic];
+        return;
+    }
+
+    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+}
+
+#endif
+
 @end
 
 @implementation WKView (Private)
@@ -3835,12 +3887,23 @@
 
 - (void)_setTopContentInset:(CGFloat)contentInset
 {
-    _data->_page->setTopContentInset(contentInset);
+    _data->_topContentInset = contentInset;
+
+    if (_data->_didScheduleSetTopContentInset)
+        return;
+
+    _data->_didScheduleSetTopContentInset = YES;
+
+    dispatch_async(dispatch_get_main_queue(), ^{
+        _data->_didScheduleSetTopContentInset = NO;
+
+        _data->_page->setTopContentInset(_data->_topContentInset);
+    });
 }
 
 - (CGFloat)_topContentInset
 {
-    return _data->_page->topContentInset();
+    return _data->_topContentInset;
 }
 
 - (NSColor *)_pageExtendedBackgroundColor
@@ -3988,6 +4051,21 @@
     return handledEvent;
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+
+- (void)_setAutomaticallyAdjustsContentInsets:(BOOL)automaticallyAdjustsContentInsets
+{
+    _data->_automaticallyAdjustsContentInsets = automaticallyAdjustsContentInsets;
+    [self _updateContentInsetsIfAutomatic];
+}
+
+- (BOOL)_automaticallyAdjustsContentInsets
+{
+    return _data->_automaticallyAdjustsContentInsets;
+}
+
+#endif
+
 @end
 
 @implementation WKResponderChainSink

Modified: trunk/Tools/ChangeLog (170666 => 170667)


--- trunk/Tools/ChangeLog	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Tools/ChangeLog	2014-07-01 21:16:14 UTC (rev 170667)
@@ -1,3 +1,15 @@
+2014-07-01  Sam Weinig  <s...@webkit.org>
+
+        [Cocoa][Mac] WKWebView should automatically set topContentInset when beneath a toolbar
+        <rdar://problem/17523159>
+        https://bugs.webkit.org/show_bug.cgi?id=134496
+
+        Reviewed by Beth Dakin.
+
+        * MiniBrowser/mac/BrowserWindowController.m:
+        (-[BrowserWindowController windowDidLoad]):
+        Use the NSFullSizeContentViewWindowMask bit on Yosemite and later to enable toolbar blurring.
+
 2014-07-01  Zan Dobersek  <zdober...@igalia.com>
 
         [CMake] Add necessary support for building for the Wayland target

Modified: trunk/Tools/MiniBrowser/mac/BrowserWindowController.m (170666 => 170667)


--- trunk/Tools/MiniBrowser/mac/BrowserWindowController.m	2014-07-01 21:13:42 UTC (rev 170666)
+++ trunk/Tools/MiniBrowser/mac/BrowserWindowController.m	2014-07-01 21:16:14 UTC (rev 170667)
@@ -39,6 +39,10 @@
 
 - (void)windowDidLoad
 {
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+    self.window.styleMask |= NSFullSizeContentViewWindowMask;
+#endif
+
     [super windowDidLoad];
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to