Changeset 243606 in webkit


Ignore:
Timestamp:
Mar 28, 2019 9:36:18 AM (5 years ago)
Author:
dbates@webkit.org
Message:

[iPad] Tapping on a popup form control may not show a popover
https://bugs.webkit.org/show_bug.cgi?id=196322
<rdar://problem/49229632>

Reviewed by Wenson Hsieh.

Stop taking advantage of -[WKContentView inputView] being called when we invoke -reloadInputViews
to "lazily" allocate the input peripheral for the currently focused element. In theory, UIKit only
needs to call -inputView when it actually needs to display the input view (the keyboard). For
popup menu buttons, like <select>, no keyboard is needed. Instead we should create the peripheral
as part of the logic in the UI process to focus a new element before we call -reloadInputViews.

  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView inputView]): Extract logic to allocate the peripheral from here and moved it to createInputPeripheralWithView().
(-[WKContentView accessoryTab:]): While I am here, add a FIXME comment to explain why we need to
end the input sessions and nullify the input peripheral before we tell the web process to switch
focus as opposed to letting this happen after the web process tells us it focused a new element.
(createInputPeripheralWithView): Added.
(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
Write in terms of createInputPeripheralWithView(). Create the input peripheral after becoming
first responder because creating the peripheral has known side-effects: for popup buttons it
tells the popup controller to present the popover. For key input to popovers to work from the get-go,
the content view must be the first responder. See <https://bugs.webkit.org/show_bug.cgi?id=196272>
for more details.

Location:
trunk/Source/WebKit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r243603 r243606  
     12019-03-28  Daniel Bates  <dabates@apple.com>
     2
     3        [iPad] Tapping on a popup form control may not show a popover
     4        https://bugs.webkit.org/show_bug.cgi?id=196322
     5        <rdar://problem/49229632>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Stop taking advantage of -[WKContentView inputView] being called when we invoke -reloadInputViews
     10        to "lazily" allocate the input peripheral for the currently focused element. In theory, UIKit only
     11        needs to call -inputView when it actually needs to display the input view (the keyboard). For
     12        popup menu buttons, like <select>, no keyboard is needed. Instead we should create the peripheral
     13        as part of the logic in the UI process to focus a new element before we call -reloadInputViews.
     14
     15        * UIProcess/ios/WKContentViewInteraction.mm:
     16        (-[WKContentView inputView]): Extract logic to allocate the peripheral from here and moved it to createInputPeripheralWithView().
     17        (-[WKContentView accessoryTab:]): While I am here, add a FIXME comment to explain why we need to
     18        end the input sessions and nullify the input peripheral before we tell the web process to switch
     19        focus as opposed to letting this happen after the web process tells us it focused a new element.
     20        (createInputPeripheralWithView): Added.
     21        (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
     22        Write in terms of createInputPeripheralWithView(). Create the input peripheral after becoming
     23        first responder because creating the peripheral has known side-effects: for popup buttons it
     24        tells the popup controller to present the popover. For key input to popovers to work from the get-go,
     25        the content view must be the first responder. See <https://bugs.webkit.org/show_bug.cgi?id=196272>
     26        for more details.
     27
    1282019-03-28  Víctor Manuel Jáquez Leal  <vjaquez@igalia.com>
    229
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r243553 r243606  
    16431643        return nil;
    16441644
    1645     if (!_inputPeripheral) {
    1646         switch (_focusedElementInformation.elementType) {
    1647         case WebKit::InputType::Select:
    1648             _inputPeripheral = adoptNS([[WKFormSelectControl alloc] initWithView:self]);
    1649             break;
    1650 #if ENABLE(INPUT_TYPE_COLOR)
    1651         case WebKit::InputType::Color:
    1652             _inputPeripheral = adoptNS([[WKFormColorControl alloc] initWithView:self]);
    1653             break;
    1654 #endif
    1655         default:
    1656             _inputPeripheral = adoptNS([[WKFormInputControl alloc] initWithView:self]);
    1657             break;
    1658         }
    1659     } else {
     1645    if (_inputPeripheral) {
    16601646        // FIXME: UIKit may invoke -[WKContentView inputView] at any time when WKContentView is the first responder;
    16611647        // as such, it doesn't make sense to change the enclosing scroll view's zoom scale and content offset to reveal
     
    16671653        // rotation, when a select element is focused. See <https://webkit.org/b/192878> for more information.
    16681654        [self _zoomToRevealFocusedElement];
     1655
    16691656        [self _updateAccessory];
    16701657    }
     
    37713758- (void)accessoryTab:(BOOL)isNext
    37723759{
     3760    // The input peripheral may need to update the focused DOM node before we switch focus. The UI process does
     3761    // not maintain a handle to the actual focused DOM node – only the web process has such a handle. So, we need
     3762    // to end the editing session now before we tell the web process to switch focus. Once the web process tells
     3763    // us the newly focused element we are no longer are in a position to effect the previously focused element.
     3764    // See <https://bugs.webkit.org/show_bug.cgi?id=134409>.
    37733765    [self _endEditing];
    3774     _inputPeripheral = nil;
     3766    _inputPeripheral = nil; // Nullify so that we don't tell the input peripheral to end editing again in -_elementDidBlur.
    37753767
    37763768    _isChangingFocusUsingAccessoryTab = YES;
     
    48794871}
    48804872
     4873static RetainPtr<NSObject <WKFormPeripheral>> createInputPeripheralWithView(WebKit::InputType type, WKContentView *view)
     4874{
     4875    switch (type) {
     4876    case WebKit::InputType::Select:
     4877        return adoptNS([[WKFormSelectControl alloc] initWithView:view]);
     4878#if ENABLE(INPUT_TYPE_COLOR)
     4879    case WebKit::InputType::Color:
     4880        return adoptNS([[WKFormColorControl alloc] initWithView:view]);
     4881#endif
     4882    default:
     4883        return adoptNS([[WKFormInputControl alloc] initWithView:view]);
     4884    }
     4885}
     4886
    48814887- (void)_elementDidFocus:(const WebKit::FocusedElementInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode changingActivityState:(BOOL)changingActivityState userObject:(NSObject <NSSecureCoding> *)userObject
    48824888{
     
    49794985    BOOL editableChanged = [self setIsEditable:YES];
    49804986    _focusedElementInformation = information;
    4981     _inputPeripheral = nil;
    49824987    _traits = nil;
    49834988
    49844989    if (![self isFirstResponder])
    49854990        [self becomeFirstResponder];
     4991
     4992    _inputPeripheral = createInputPeripheralWithView(_focusedElementInformation.elementType, self);
    49864993
    49874994#if PLATFORM(WATCHOS)
Note: See TracChangeset for help on using the changeset viewer.