Changeset 240757 in webkit


Ignore:
Timestamp:
Jan 30, 2019 8:41:35 PM (5 years ago)
Author:
dbates@webkit.org
Message:

[iOS] REGRESSION (r238635): Text area fails to re-focus after dismissal of keyboard on support.apple.com
https://bugs.webkit.org/show_bug.cgi?id=193987
<rdar://problem/47230785>

Reviewed by Tim Horton.

It is unnecessary to relinquish first responder status when a user explicitly dismissing
the keyboard. Moreover, doing so prevents key commands from being intercepted when a
hardware keyboard is subsequently attached.

Following r238635 a page becomes focused (accepting of keyboard input) and defocused
when the WKContentView becomes first responder and resigns first responder, respectively.
When a user explicitly dismisses the keyboard by tapping Done (iPhone) or the hide keyboard
button (iPad) then UIKit tells WKContentView to resign its first responder status only
to make its superview, WKWebView, first responder. When a person subsequently taps on the
page again, the WKContentView requests to become the first responder. However changes to
page focus are not guaranteed to be sent to the WebProcess immediately (WebPageProxy::activityStateDidChange()
will schedule an update). In particular, they are not guaranteed to be sent before the
WebProcess is told about a tap. Therefore, the WebProcess has out-of-date information on
focus state of the page. Instead we should detect when WKWebView is being asked to resign
as a result of the keyboard dismissal and refuse the request, taking care to end the current
editing session, blur the focused element, and dismiss the on-screen keyboard.

  • Platform/spi/ios/UIKitSPI.h: Expose some SPI.
  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView setupInteraction]): Register to receive notifications whenever a user
explicitly dismisses the keyboard.
(-[WKContentView resignFirstResponderForWebView]): If we are being asked to resign as a
result of a user explicitly dismissing the keyboard then refuse to resign.
(-[WKContentView _keyboardDidRequestDismissal:]): Update state, if applicable.

Location:
trunk/Source/WebKit
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r240747 r240757  
     12019-01-30  Daniel Bates  <dabates@apple.com>
     2
     3        [iOS] REGRESSION (r238635): Text area fails to re-focus after dismissal of keyboard on support.apple.com
     4        https://bugs.webkit.org/show_bug.cgi?id=193987
     5        <rdar://problem/47230785>
     6
     7        Reviewed by Tim Horton.
     8
     9        It is unnecessary to relinquish first responder status when a user explicitly dismissing
     10        the keyboard. Moreover, doing so prevents key commands from being intercepted when a
     11        hardware keyboard is subsequently attached.
     12       
     13        Following r238635 a page becomes focused (accepting of keyboard input) and defocused
     14        when the WKContentView becomes first responder and resigns first responder, respectively.
     15        When a user explicitly dismisses the keyboard by tapping Done (iPhone) or the hide keyboard
     16        button (iPad) then UIKit tells WKContentView to resign its first responder status only
     17        to make its superview, WKWebView, first responder. When a person subsequently taps on the
     18        page again, the WKContentView requests to become the first responder. However changes to
     19        page focus are not guaranteed to be sent to the WebProcess immediately (WebPageProxy::activityStateDidChange()
     20        will schedule an update). In particular, they are not guaranteed to be sent before the
     21        WebProcess is told about a tap. Therefore, the WebProcess has out-of-date information on
     22        focus state of the page. Instead we should detect when WKWebView is being asked to resign
     23        as a result of the keyboard dismissal and refuse the request, taking care to end the current
     24        editing session, blur the focused element, and dismiss the on-screen keyboard.
     25
     26        * Platform/spi/ios/UIKitSPI.h: Expose some SPI.
     27        * UIProcess/ios/WKContentViewInteraction.h:
     28        * UIProcess/ios/WKContentViewInteraction.mm:
     29        (-[WKContentView setupInteraction]): Register to receive notifications whenever a user
     30        explicitly dismisses the keyboard.
     31        (-[WKContentView resignFirstResponderForWebView]): If we are being asked to resign as a
     32        result of a user explicitly dismissing the keyboard then refuse to resign.
     33        (-[WKContentView _keyboardDidRequestDismissal:]): Update state, if applicable.
     34
    1352019-01-30  Keith Rollin  <krollin@apple.com>
    236
  • trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h

    r240466 r240757  
    11461146extern NSString * const UIWindowWillRotateNotification;
    11471147
     1148extern NSString * const UIKeyboardPrivateDidRequestDismissalNotification;
     1149
    11481150extern NSString * const UIKeyboardIsLocalUserInfoKey;
    11491151
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r240742 r240757  
    306306    BOOL _showDebugTapHighlightsForFastClicking;
    307307    BOOL _isZoomingToRevealFocusedElement;
     308
     309    BOOL _keyboardDidRequestDismissal;
    308310
    309311    BOOL _becomingFirstResponder;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r240742 r240757  
    742742#endif
    743743
    744     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_resetShowingTextStyle:) name:UIMenuControllerDidHideMenuNotification object:nil];
     744    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
     745    [center addObserver:self selector:@selector(_resetShowingTextStyle:) name:UIMenuControllerDidHideMenuNotification object:nil];
     746    [center addObserver:self selector:@selector(_keyboardDidRequestDismissal:) name:UIKeyboardPrivateDidRequestDismissalNotification object:nil];
     747
    745748    _showingTextStyleOptions = NO;
    746749
     
    11161119    // and do nothing if the return value is NO.
    11171120
    1118     _resigningFirstResponder = YES;
     1121    SetForScope<BOOL> resigningFirstResponderScope { _resigningFirstResponder, YES };
     1122
    11191123    if (!_webView._retainingActiveFocusedState) {
    11201124        // We need to complete the editing operation before we blur the element.
     
    11281132    _inputViewUpdateDeferrer = nullptr;
    11291133
     1134    // If the user explicitly dismissed the keyboard then we will lose first responder
     1135    // status only to gain it back again. Just don't resign in that case.
     1136    if (_keyboardDidRequestDismissal) {
     1137        _keyboardDidRequestDismissal = NO;
     1138        return NO;
     1139    }
     1140
    11301141    bool superDidResign = [super resignFirstResponder];
    11311142
    11321143    if (superDidResign)
    11331144        _page->activityStateDidChange(WebCore::ActivityState::IsFocused);
    1134 
    1135     _resigningFirstResponder = NO;
    11361145
    11371146    return superDidResign;
     
    27882797    _showingTextStyleOptions = NO;
    27892798    [_textSelectionAssistant hideTextStyleOptions];
     2799}
     2800
     2801- (void)_keyboardDidRequestDismissal:(NSNotification *)notification
     2802{
     2803    if (![self isFirstResponder])
     2804        return;
     2805    _keyboardDidRequestDismissal = YES;
    27902806}
    27912807
Note: See TracChangeset for help on using the changeset viewer.