Changeset 233905 in webkit


Ignore:
Timestamp:
Jul 17, 2018 8:50:12 PM (6 years ago)
Author:
timothy_horton@apple.com
Message:

REGRESSION (iOS 12): Can't scroll to the bottom of the page in WKWebView while keyboard is up on pages with viewport-fit=cover
https://bugs.webkit.org/show_bug.cgi?id=187743
<rdar://problem/41651546>

Reviewed by Simon Fraser.

UIScrollView's _systemContentInset no longer includes keyboard insets
in apps linked on iOS 12+ when contentInsetAdjustmentBehavior is None.

We use contentInsetAdjustmentBehavior to control adjustment of other
sources of insets, but expect the keyboard inset to always be applied.

For now, barring a more comprehensive way to separate insets, re-add
the keyboard inset in cases where UIKit does not.

  • Platform/spi/ios/UIKitSPI.h:

Move some IPI to the SPI header.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _haveSetObscuredInsets]):

  • UIProcess/API/Cocoa/WKWebViewInternal.h:

Make it possible for WKScrollView to check whether the client is overriding insets.

  • UIProcess/Cocoa/VersionChecks.h:

Add a linkedOnOrAfter() version for this new UIScrollView behavior.

  • UIProcess/ios/WKScrollView.mm:

(-[WKScrollView initWithFrame:]):
Force WKScrollView's scroll indicator to always respect insets. We always
want the scroll bars in a sensible place, even if the page sets
viewport-fit=cover.

(-[WKScrollView _adjustForAutomaticKeyboardInfo:animated:lastAdjustment:]):
Store the bottom inset due to the keyboard.

(-[WKScrollView _systemContentInset]):
Add the bottom inset due to the keyboard to the systemContentInset
in all cases where UIKit does not. Also avoid adding it if the client takes
full control of the insets, because the only client that does (MobileSafari)
includes insets-due-to-keyboard in their custom insets.

Location:
trunk/Source/WebKit
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r233904 r233905  
     12018-07-17  Tim Horton  <timothy_horton@apple.com>
     2
     3        REGRESSION (iOS 12): Can't scroll to the bottom of the page in WKWebView while keyboard is up on pages with viewport-fit=cover
     4        https://bugs.webkit.org/show_bug.cgi?id=187743
     5        <rdar://problem/41651546>
     6
     7        Reviewed by Simon Fraser.
     8
     9        UIScrollView's _systemContentInset no longer includes keyboard insets
     10        in apps linked on iOS 12+ when contentInsetAdjustmentBehavior is None.
     11
     12        We use contentInsetAdjustmentBehavior to control adjustment of other
     13        sources of insets, but expect the keyboard inset to always be applied.
     14
     15        For now, barring a more comprehensive way to separate insets, re-add
     16        the keyboard inset in cases where UIKit does not.
     17
     18        * Platform/spi/ios/UIKitSPI.h:
     19        Move some IPI to the SPI header.
     20
     21        * UIProcess/API/Cocoa/WKWebView.mm:
     22        (-[WKWebView _haveSetObscuredInsets]):
     23        * UIProcess/API/Cocoa/WKWebViewInternal.h:
     24        Make it possible for WKScrollView to check whether the client is overriding insets.
     25
     26        * UIProcess/Cocoa/VersionChecks.h:
     27        Add a linkedOnOrAfter() version for this new UIScrollView behavior.
     28
     29        * UIProcess/ios/WKScrollView.mm:
     30        (-[WKScrollView initWithFrame:]):
     31        Force WKScrollView's scroll indicator to always respect insets. We always
     32        want the scroll bars in a sensible place, even if the page sets
     33        viewport-fit=cover.
     34
     35        (-[WKScrollView _adjustForAutomaticKeyboardInfo:animated:lastAdjustment:]):
     36        Store the bottom inset due to the keyboard.
     37
     38        (-[WKScrollView _systemContentInset]):
     39        Add the bottom inset due to the keyboard to the systemContentInset
     40        in all cases where UIKit does not. Also avoid adding it if the client takes
     41        full control of the insets, because the only client that does (MobileSafari)
     42        includes insets-due-to-keyboard in their custom insets.
     43
    1442018-07-17  Chris Dumez  <cdumez@apple.com>
    245
  • trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h

    r233501 r233905  
    316316@end
    317317
     318typedef NS_ENUM(NSInteger, UIScrollViewIndicatorInsetAdjustmentBehavior) {
     319    UIScrollViewIndicatorInsetAdjustmentAutomatic,
     320    UIScrollViewIndicatorInsetAdjustmentAlways,
     321    UIScrollViewIndicatorInsetAdjustmentNever
     322};
     323
    318324@interface UIScrollView ()
    319325- (void)_stopScrollingAndZoomingAnimations;
     
    327333@property (nonatomic, readonly) BOOL _isInterruptingDeceleration;
    328334@property (nonatomic, getter=_contentScrollInset, setter=_setContentScrollInset:) UIEdgeInsets contentScrollInset;
     335@property (nonatomic, getter=_indicatorInsetAdjustmentBehavior, setter=_setIndicatorInsetAdjustmentBehavior:) UIScrollViewIndicatorInsetAdjustmentBehavior indicatorInsetAdjustmentBehavior;
    329336#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
    330337@property (nonatomic, readonly) UIEdgeInsets _systemContentInset;
     
    977984@end
    978985
     986@interface UIScrollView (IPI)
     987- (CGFloat)_rubberBandOffsetForOffset:(CGFloat)newOffset maxOffset:(CGFloat)maxOffset minOffset:(CGFloat)minOffset range:(CGFloat)range outside:(BOOL *)outside;
     988- (void)_adjustForAutomaticKeyboardInfo:(NSDictionary *)info animated:(BOOL)animated lastAdjustment:(CGFloat*)lastAdjustment;
     989- (BOOL)_isScrollingToTop;
     990- (CGPoint)_animatedTargetOffset;
     991@end
     992
    979993@interface UIPeripheralHost (IPI)
    980994- (void)_beginIgnoringReloadInputViews;
    981995- (int)_endIgnoringReloadInputViews;
    982996- (void)forceReloadInputViews;
     997- (CGFloat)getVerticalOverlapForView:(UIView *)view usingKeyboardInfo:(NSDictionary *)info;
    983998@end
    984999
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r233828 r233905  
    155155#define RELEASE_LOG_IF_ALLOWED(...) RELEASE_LOG_IF(_page && _page->isAlwaysOnLoggingAllowed(), ViewState, __VA_ARGS__)
    156156
    157 @interface UIScrollView (UIScrollViewInternal)
    158 - (void)_adjustForAutomaticKeyboardInfo:(NSDictionary*)info animated:(BOOL)animated lastAdjustment:(CGFloat*)lastAdjustment;
    159 - (BOOL)_isScrollingToTop;
    160 - (CGPoint)_animatedTargetOffset;
    161 @end
    162 
    163 @interface UIPeripheralHost(UIKitInternal)
    164 - (CGFloat)getVerticalOverlapForView:(UIView *)view usingKeyboardInfo:(NSDictionary *)info;
    165 @end
    166 
    167157@interface UIView (UIViewInternal)
    168158- (UIViewController *)_viewControllerForAncestor;
     
    31753165    if ([uiDelegate respondsToSelector:@selector(_webView:didChangeSafeAreaShouldAffectObscuredInsets:)])
    31763166        [uiDelegate _webView:self didChangeSafeAreaShouldAffectObscuredInsets:avoidsUnsafeArea];
     3167}
     3168
     3169- (BOOL)_haveSetObscuredInsets
     3170{
     3171    return _haveSetObscuredInsets;
    31773172}
    31783173
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h

    r233751 r233905  
    148148
    149149@property (nonatomic, readonly) BOOL _allowsDoubleTapGestures;
     150@property (nonatomic, readonly) BOOL _haveSetObscuredInsets;
    150151@property (nonatomic, readonly) UIEdgeInsets _computedObscuredInset;
    151152@property (nonatomic, readonly) UIEdgeInsets _computedUnobscuredSafeAreaInset;
  • trunk/Source/WebKit/UIProcess/Cocoa/VersionChecks.h

    r231322 r233905  
    4040    FirstThatDefaultsToPassiveTouchListenersOnDocument = DYLD_IOS_VERSION_11_3,
    4141    FirstWhereScrollViewContentInsetsAreNotObscuringInsets = DYLD_IOS_VERSION_12_0,
     42    FirstWhereUIScrollViewDoesNotApplyKeyboardInsetsUnconditionally = DYLD_IOS_VERSION_12_0,
    4243#elif PLATFORM(MAC)
    4344    FirstWithNetworkCache = DYLD_MACOSX_VERSION_10_11,
  • trunk/Source/WebKit/UIProcess/ios/WKScrollView.mm

    r232659 r233905  
    2929#if PLATFORM(IOS)
    3030
     31#import "UIKitSPI.h"
     32#import "VersionChecks.h"
    3133#import "WKWebViewInternal.h"
    3234#import <pal/spi/cg/CoreGraphicsSPI.h>
     
    3840
    3941using namespace WebKit;
    40 
    41 @interface UIScrollView (UIScrollViewInternalHack)
    42 - (CGFloat)_rubberBandOffsetForOffset:(CGFloat)newOffset maxOffset:(CGFloat)maxOffset minOffset:(CGFloat)minOffset range:(CGFloat)range outside:(BOOL *)outside;
    43 @end
    4442
    4543@interface WKScrollViewDelegateForwarder : NSObject <UIScrollViewDelegate>
     
    134132    BOOL _contentInsetAdjustmentBehaviorWasExternallyOverridden;
    135133#endif
     134    CGFloat _keyboardBottomInsetAdjustment;
    136135}
    137136
     
    145144    self.alwaysBounceVertical = YES;
    146145    self.directionalLockEnabled = YES;
     146    [self _setIndicatorInsetAdjustmentBehavior:UIScrollViewIndicatorInsetAdjustmentAlways];
    147147
    148148#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
     
    331331}
    332332
     333- (void)_adjustForAutomaticKeyboardInfo:(NSDictionary *)info animated:(BOOL)animated lastAdjustment:(CGFloat*)lastAdjustment
     334{
     335    [super _adjustForAutomaticKeyboardInfo:info animated:animated lastAdjustment:lastAdjustment];
     336
     337    _keyboardBottomInsetAdjustment = [[UIPeripheralHost sharedInstance] getVerticalOverlapForView:self usingKeyboardInfo:info];
     338}
     339
     340- (UIEdgeInsets)_systemContentInset
     341{
     342    UIEdgeInsets systemContentInset = [super _systemContentInset];
     343
     344    // Internal clients who use setObscuredInsets include the keyboard height in their
     345    // manually overriden insets, so we don't need to re-add it here.
     346    if (_internalDelegate._haveSetObscuredInsets)
     347        return systemContentInset;
     348
     349    // Match the inverse of the condition that UIScrollView uses to decide whether
     350    // to include keyboard insets in the systemContentInset. We always want
     351    // keyboard insets applied, even when web content has chosen to disable automatic
     352    // safe area inset adjustment.
     353    if (linkedOnOrAfter(SDKVersion::FirstWhereUIScrollViewDoesNotApplyKeyboardInsetsUnconditionally) && self.contentInsetAdjustmentBehavior == UIScrollViewContentInsetAdjustmentNever)
     354        systemContentInset.bottom += _keyboardBottomInsetAdjustment;
     355
     356    return systemContentInset;
     357}
     358
    333359#if PLATFORM(WATCHOS)
    334360
Note: See TracChangeset for help on using the changeset viewer.