Changeset 244220 in webkit


Ignore:
Timestamp:
Apr 12, 2019 10:30:00 AM (5 years ago)
Author:
Wenson Hsieh
Message:

[iOS] Software keyboard is shown too frequently on some websites
https://bugs.webkit.org/show_bug.cgi?id=195856
<rdar://problem/49191395>

Reviewed by Darin Adler.

Source/WebCore/PAL:

Declare new GraphicsServices SPI.

  • pal/spi/ios/GraphicsServicesSPI.h:

Source/WebKit:

On some websites, hidden editable elements are very frequently focused upon user interaction. Currently, this
causes the software keyboard to pop in and out unexpectedly; luckily, these same sites also apply
inputmode="none" to the hidden editable element, which ought to ensure that the software keyboard doesn't appear
when the element is focused.

However, since we disabled support for inputmode="none" in r240497, the software keyboard is no longer
suppressed, and becomes a big nuissance. r240497 removed support for this feature because, when using a hardware
keyboard, pressing the globe key no longer showed UI for switching languages. However, support for inputmode
none makes a much larger impact when a software keyboard is used (since the entire software keyboard animates in
and out), whereas a hardware keyboard only displays an input accessory view. For this reason, we can mitigate
this bug without reintroducing <rdar://problem/47406553> by re-enabling inputmode="none", but only when a
hardware keyboard is not attached.

  • UIProcess/API/Cocoa/WKWebView.mm:

(hardwareKeyboardAvailabilityChangedCallback):

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView shouldShowAutomaticKeyboardUI]):

Don't show the keyboard if inputmode is none and a hardware keyboard is not attached.

(-[WKContentView _hardwareKeyboardAvailabilityChanged]):

Reload input views if the inputmode is none to ensure that if a hardware keyboard is attached while editing an
element with inputmode="none", we'll show the input accessory view once again.

Tools:

Add support for attaching or detaching the hardware keyboard on iOS in layout tests.

  • DumpRenderTree/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::setHardwareKeyboardAttached):

  • TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
  • TestRunnerShared/UIScriptContext/UIScriptController.cpp:

(WTR::UIScriptController::setHardwareKeyboardAttached):

  • TestRunnerShared/UIScriptContext/UIScriptController.h:
  • WebKitTestRunner/Configurations/WebKitTestRunnerApp.xcconfig:

Additionally link against GraphicsServices in WebKitTestRunner.

  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::TestController::platformResetStateToConsistentValues):
(WTR::UIScriptController::setHardwareKeyboardAttached):

WebKitLibraries:

Add a symbol for GSEventSetHardwareKeyboardAttached.

  • WebKitPrivateFrameworkStubs/iOS/12/GraphicsServices.framework/GraphicsServices.tbd:

LayoutTests:

Fix a failing layout test, which (among other reasons) is currently failing because support for inputmode="none"
is disabled.

  • fast/forms/ios/inputmode-none-expected.txt:
  • fast/forms/ios/inputmode-none.html:
  • resources/ui-helper.js:

Add a UIHelper method for attaching or detaching the hardware keyboard.

(window.UIHelper.setHardwareKeyboardAttached):
(window.UIHelper):

Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244219 r244220  
     12019-04-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard is shown too frequently on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195856
     5        <rdar://problem/49191395>
     6
     7        Reviewed by Darin Adler.
     8
     9        Fix a failing layout test, which (among other reasons) is currently failing because support for inputmode="none"
     10        is disabled.
     11
     12        * fast/forms/ios/inputmode-none-expected.txt:
     13        * fast/forms/ios/inputmode-none.html:
     14        * resources/ui-helper.js:
     15
     16        Add a UIHelper method for attaching or detaching the hardware keyboard.
     17
     18        (window.UIHelper.setHardwareKeyboardAttached):
     19        (window.UIHelper):
     20
    1212019-04-12  Ryan Haddad  <ryanhaddad@apple.com>
    222
  • trunk/LayoutTests/fast/forms/ios/inputmode-none-expected.txt

    r240497 r244220  
     1
     2
    13This test verifies that the system keyboard is not visible when tapping on an input field with inputmode=none.
    24
     
    46
    57
    6 
    78ACTIVATE input with inputmode=text
    8 PASS textKeyboardHeight = systemKeyboardRect.height; systemKeyboardRect.height > 0 is true
    9 PASS inputWithSystemKeyboard.value is "Text"
     9PASS systemKeyboardRect.height > 0 is true
     10PASS inputWithSystemKeyboard.value is 'Text'
    1011
    1112ACTIVATE input with inputmode=none
    12 PASS systemKeyboardRect.height is textKeyboardHeight
     13PASS Successfully dismissed keyboard
    1314
    1415TEST enter text in input with inputmode=none
    15 PASS inputWithoutSystemKeyboard.value is "None"
     16PASS inputWithoutSystemKeyboard.value is 'None'
    1617
    1718TEST selection in input with inputmode=none
    1819PASS selectionRects.length is 1
    19 PASS selectionRects[0].left is 159
    20 PASS selectionRects[0].top is 261
    21 PASS selectionRects[0].width is 28
     20PASS selectionRects[0].left is 16
     21PASS selectionRects[0].top is 38
     22PASS selectionRects[0].width is 27
    2223PASS selectionRects[0].height is 15
    23 
    2424PASS successfullyParsed is true
    2525
    2626TEST COMPLETE
    27  
     27
  • trunk/LayoutTests/fast/forms/ios/inputmode-none.html

    r240497 r244220  
    1 <!DOCTYPE html>
     1<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
    22<html>
    33<head>
    4 <meta name="viewport" content="width=device-width, initial-scale=1">
     4<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    55<script src="../../../resources/js-test.js"></script>
    66<script src="../../../resources/ui-helper.js"></script>
    77</head>
    88<body onload="runTest()">
    9 <input id="input-keyboard" inputmode="text">
    10 <input id="input-nokeyboard" inputmode="none">
     9<div><input id="input-keyboard" inputmode="text"></div>
     10<div><input id="input-nokeyboard" inputmode="none"></div>
     11<pre id="description"></pre>
     12<pre id="console"></pre>
    1113<script>
    1214jsTestIsAsync = true;
    1315
    1416async function runTest() {
     17    await UIHelper.setHardwareKeyboardAttached(false);
    1518    inputWithSystemKeyboard = document.getElementById("input-keyboard");
    1619    inputWithoutSystemKeyboard = document.getElementById("input-nokeyboard");
    1720
    18     description('This test verifies that the system keyboard is not visible when tapping on an input field with inputmode=none.');
     21    description("This test verifies that the system keyboard is not visible when tapping on an input field with inputmode=none.");
    1922
    20     debug('\nACTIVATE input with inputmode=text');
    21     await UIHelper.activateFormControl(inputWithSystemKeyboard);
     23    debug("\nACTIVATE input with inputmode=text");
     24    await UIHelper.activateElementAndWaitForInputSession(inputWithSystemKeyboard);
    2225    systemKeyboardRect = await UIHelper.inputViewBounds();
    23     shouldBe('textKeyboardHeight = systemKeyboardRect.height; systemKeyboardRect.height > 0', 'true');
     26    shouldBe("systemKeyboardRect.height > 0", "true");
    2427    await UIHelper.enterText("Text");
    25     shouldBe('inputWithSystemKeyboard.value', '"Text"');
     28    shouldBe("inputWithSystemKeyboard.value", "'Text'");
    2629
    27     debug('\nACTIVATE input with inputmode=none');
    28     await UIHelper.activateFormControl(inputWithoutSystemKeyboard);
    29     systemKeyboardRect = await UIHelper.inputViewBounds();
    30     shouldBe('systemKeyboardRect.height', 'textKeyboardHeight');
     30    debug("\nACTIVATE input with inputmode=none");
     31    await UIHelper.activateElement(inputWithoutSystemKeyboard);
     32    await UIHelper.waitForKeyboardToHide();
     33    testPassed("Successfully dismissed keyboard");
    3134
    32     debug('\nTEST enter text in input with inputmode=none');
     35    debug("\nTEST enter text in input with inputmode=none");
    3336    await UIHelper.enterText("None");
    34     shouldBe('inputWithoutSystemKeyboard.value', '"None"');
     37    shouldBe("inputWithoutSystemKeyboard.value", "'None'");
    3538
    36     debug('\nTEST selection in input with inputmode=none');
    37     inputWithoutSystemKeyboard.setSelectionRange(0, inputWithSystemKeyboard.value.length);
    38     selectionRects = await UIHelper.getUISelectionRects();
    39     shouldBe('selectionRects.length', '1');
    40     shouldBe('selectionRects[0].left', '159');
    41     shouldBe('selectionRects[0].top', '261');
    42     shouldBe('selectionRects[0].width', '28');
    43     shouldBe('selectionRects[0].height', '15');
     39    debug("\nTEST selection in input with inputmode=none");
     40    inputWithoutSystemKeyboard.select();
    4441
    45     debug('');
     42    selectionRects = [];
     43    while (!selectionRects.length)
     44        selectionRects = await UIHelper.getUISelectionViewRects();
     45
     46    shouldBe("selectionRects.length", "1");
     47    shouldBe("selectionRects[0].left", "16");
     48    shouldBe("selectionRects[0].top", "38");
     49    shouldBe("selectionRects[0].width", "27");
     50    shouldBe("selectionRects[0].height", "15");
    4651    finishJSTest();
    4752}
  • trunk/LayoutTests/resources/ui-helper.js

    r244096 r244220  
    834834        });
    835835    }
     836
     837    static setHardwareKeyboardAttached(attached)
     838    {
     839        return new Promise(resolve => testRunner.runUIScript(`uiController.setHardwareKeyboardAttached(${attached ? "true" : "false"})`, resolve));
     840    }
    836841}
  • trunk/Source/WebCore/PAL/ChangeLog

    r244114 r244220  
     12019-04-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard is shown too frequently on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195856
     5        <rdar://problem/49191395>
     6
     7        Reviewed by Darin Adler.
     8
     9        Declare new GraphicsServices SPI.
     10
     11        * pal/spi/ios/GraphicsServicesSPI.h:
     12
    1132019-04-10  Antoine Quint  <graouts@apple.com>
    214
  • trunk/Source/WebCore/PAL/pal/spi/ios/GraphicsServicesSPI.h

    r238078 r244220  
    4747uint32_t GSKeyboardGetModifierState(GSKeyboardRef);
    4848Boolean GSEventIsHardwareKeyboardAttached();
     49void GSEventSetHardwareKeyboardAttached(Boolean attached, uint8_t country);
    4950
    5051extern const char *kGSEventHardwareKeyboardAvailabilityChangedNotification;
  • trunk/Source/WebKit/ChangeLog

    r244218 r244220  
     12019-04-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard is shown too frequently on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195856
     5        <rdar://problem/49191395>
     6
     7        Reviewed by Darin Adler.
     8
     9        On some websites, hidden editable elements are very frequently focused upon user interaction. Currently, this
     10        causes the software keyboard to pop in and out unexpectedly; luckily, these same sites also apply
     11        inputmode="none" to the hidden editable element, which ought to ensure that the software keyboard doesn't appear
     12        when the element is focused.
     13
     14        However, since we disabled support for inputmode="none" in r240497, the software keyboard is no longer
     15        suppressed, and becomes a big nuissance. r240497 removed support for this feature because, when using a hardware
     16        keyboard, pressing the globe key no longer showed UI for switching languages. However, support for inputmode
     17        none makes a much larger impact when a software keyboard is used (since the entire software keyboard animates in
     18        and out), whereas a hardware keyboard only displays an input accessory view. For this reason, we can mitigate
     19        this bug without reintroducing <rdar://problem/47406553> by re-enabling inputmode="none", but only when a
     20        hardware keyboard is not attached.
     21
     22        * UIProcess/API/Cocoa/WKWebView.mm:
     23        (hardwareKeyboardAvailabilityChangedCallback):
     24        * UIProcess/ios/WKContentViewInteraction.h:
     25        * UIProcess/ios/WKContentViewInteraction.mm:
     26        (-[WKContentView shouldShowAutomaticKeyboardUI]):
     27
     28        Don't show the keyboard if inputmode is none and a hardware keyboard is not attached.
     29
     30        (-[WKContentView _hardwareKeyboardAvailabilityChanged]):
     31
     32        Reload input views if the inputmode is none to ensure that if a hardware keyboard is attached while editing an
     33        element with inputmode="none", we'll show the input accessory view once again.
     34
    1352019-04-12  Antoine Quint  <graouts@apple.com>
    236
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r244203 r244220  
    33363336    ASSERT(observer);
    33373337    WKWebView *webView = (__bridge WKWebView *)observer;
     3338    [webView->_contentView _hardwareKeyboardAvailabilityChanged];
    33383339    webView._page->hardwareKeyboardAvailabilityChanged(GSEventIsHardwareKeyboardAttached());
    33393340}
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r244096 r244220  
    416416- (void)_didUpdateInputMode:(WebCore::InputMode)mode;
    417417- (void)_didReceiveEditorStateUpdateAfterFocus;
     418- (void)_hardwareKeyboardAvailabilityChanged;
    418419- (void)_selectionChanged;
    419420- (void)_updateChangedSelection;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r244141 r244220  
    101101#import <pal/spi/cocoa/DataDetectorsCoreSPI.h>
    102102#import <pal/spi/ios/DataDetectorsUISPI.h>
     103#import <pal/spi/ios/GraphicsServicesSPI.h>
    103104#import <wtf/Optional.h>
    104105#import <wtf/RetainPtr.h>
     
    119120#import <UIKit/UIHoverGestureRecognizer.h>
    120121#import <UIKit/_UILookupGestureRecognizer.h>
    121 #import <pal/spi/ios/GraphicsServicesSPI.h>
    122122#endif
    123123
     
    15961596- (BOOL)shouldShowAutomaticKeyboardUI
    15971597{
    1598     // FIXME: Make this function knowledgeable about the HTML attribute inputmode.
     1598    // FIXME: We should support inputmode="none" when the hardware keyboard is attached.
     1599    // We currently refrain from doing so because that would prevent UIKit from showing
     1600    // the language picker when pressing the globe key to change the input language.
     1601    if (_focusedElementInformation.inputMode == WebCore::InputMode::None && !GSEventIsHardwareKeyboardAttached())
     1602        return NO;
     1603
    15991604    switch (_focusedElementInformation.elementType) {
    16001605    case WebKit::InputType::None:
     
    51345139}
    51355140
     5141- (void)_hardwareKeyboardAvailabilityChanged
     5142{
     5143    if (hasFocusedElement(_focusedElementInformation) && _focusedElementInformation.inputMode == WebCore::InputMode::None)
     5144        [self reloadInputViews];
     5145}
     5146
    51365147- (void)_didUpdateInputMode:(WebCore::InputMode)mode
    51375148{
  • trunk/Tools/ChangeLog

    r244214 r244220  
     12019-04-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard is shown too frequently on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195856
     5        <rdar://problem/49191395>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add support for attaching or detaching the hardware keyboard on iOS in layout tests.
     10
     11        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
     12        (WTR::UIScriptController::setHardwareKeyboardAttached):
     13        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
     14        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
     15        (WTR::UIScriptController::setHardwareKeyboardAttached):
     16        * TestRunnerShared/UIScriptContext/UIScriptController.h:
     17        * WebKitTestRunner/Configurations/WebKitTestRunnerApp.xcconfig:
     18
     19        Additionally link against GraphicsServices in WebKitTestRunner.
     20
     21        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     22        (WTR::TestController::platformResetStateToConsistentValues):
     23        (WTR::UIScriptController::setHardwareKeyboardAttached):
     24
    1252019-04-12  Ludovico de Nittis  <ludovico.denittis@collabora.com>
    226
  • trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm

    r244096 r244220  
    536536}
    537537
     538void UIScriptController::setHardwareKeyboardAttached(bool)
     539{
     540}
     541
    538542}
    539543
  • trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl

    r244096 r244220  
    312312    readonly attribute boolean isWindowContentViewFirstResponder;
    313313
     314    void setHardwareKeyboardAttached(boolean attached);
     315
    314316    object attachmentInfo(DOMString attachmentIdentifier);
    315317
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp

    r244096 r244220  
    639639}
    640640
     641void UIScriptController::setHardwareKeyboardAttached(bool)
     642{
     643}
     644
    641645#endif
    642646
  • trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h

    r244096 r244220  
    241241    JSObjectRef attachmentInfo(JSStringRef attachmentIdentifier);
    242242
     243    void setHardwareKeyboardAttached(bool);
     244
    243245private:
    244246    UIScriptController(UIScriptContext&);
  • trunk/Tools/WebKitTestRunner/Configurations/WebKitTestRunnerApp.xcconfig

    r235099 r244220  
    3131GCC_ENABLE_OBJC_EXCEPTIONS = YES;
    3232
    33 OTHER_LDFLAGS = $(inherited) -lWebKitTestRunner -lWebCoreTestSupport -framework JavaScriptCore -framework CoreGraphics -framework QuartzCore -framework ImageIO -framework IOKit -framework UIKit -framework WebKit -framework Foundation;
     33OTHER_LDFLAGS = $(inherited) -lWebKitTestRunner -lWebCoreTestSupport -framework JavaScriptCore -framework CoreGraphics -framework QuartzCore -framework ImageIO -framework IOKit -framework UIKit -framework WebKit -framework Foundation -framework GraphicsServices;
    3434
    3535SKIP_INSTALL[sdk=macosx*] = YES;
  • trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm

    r243657 r244220  
    4444#import <WebKit/WKWebViewPrivate.h>
    4545#import <objc/runtime.h>
     46#import <pal/spi/ios/GraphicsServicesSPI.h>
    4647#import <wtf/MainThread.h>
    4748
     
    142143    [[UIApplication sharedApplication] _cancelAllTouches];
    143144    [[UIDevice currentDevice] setOrientation:UIDeviceOrientationPortrait animated:NO];
     145    GSEventSetHardwareKeyboardAttached(true, 0);
    144146
    145147    m_inputModeSwizzlers.clear();
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r244096 r244220  
    4343#import <WebKit/WKWebViewPrivate.h>
    4444#import <WebKit/WebKit.h>
     45#import <pal/spi/ios/GraphicsServicesSPI.h>
    4546#import <wtf/SoftLinking.h>
    4647#import <wtf/Vector.h>
     
    11411142}
    11421143
     1144void UIScriptController::setHardwareKeyboardAttached(bool attached)
     1145{
     1146    GSEventSetHardwareKeyboardAttached(attached, 0);
     1147}
     1148
    11431149}
    11441150
  • trunk/WebKitLibraries/ChangeLog

    r239568 r244220  
     12019-04-12  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Software keyboard is shown too frequently on some websites
     4        https://bugs.webkit.org/show_bug.cgi?id=195856
     5        <rdar://problem/49191395>
     6
     7        Reviewed by Darin Adler.
     8
     9        Add a symbol for GSEventSetHardwareKeyboardAttached.
     10
     11        * WebKitPrivateFrameworkStubs/iOS/12/GraphicsServices.framework/GraphicsServices.tbd:
     12
    1132019-01-01  Jeff Miller  <jeffm@apple.com>
    214
  • trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/12/GraphicsServices.framework/GraphicsServices.tbd

    r238078 r244220  
    1717      - _GSCurrentEventTimestamp
    1818      - _GSEventIsHardwareKeyboardAttached
     19      - _GSEventSetHardwareKeyboardAttached
    1920      - _GSFontInitialize
    2021      - _GSFontPurgeFontCache
Note: See TracChangeset for help on using the changeset viewer.