Changeset 238526 in webkit


Ignore:
Timestamp:
Nov 26, 2018 2:57:44 PM (5 years ago)
Author:
dbates@webkit.org
Message:

REGRESSION (r237738): Command Down Arrow doesn't scroll to the end of a page anymore
https://bugs.webkit.org/show_bug.cgi?id=191967
<rdar://problem/45976390>

Reviewed by Tim Horton.

Source/WebKit:

Fixes an issue where pressing Command + Down Arrow does not scroll the view to the end of the page.

Following r237738 the value of the enumerations used to identify modifier keys (e.g. Shift) changed
to match the values of the corresponding enumerations in GraphicsServices, which are the
enumerations UIKit uses to computes the modifier flags bitmask when instantiating a WebEvent to
pass to WebKit. Before r237738 WebKit was using enumerations whose values matched the values
of the corresponding UIKit public API UIKeyModifier* enumerations. For non-content editable elements,
WebKit intercepts UIKit events in -_handleKeyUIEvent, synthesizes and dispatches its own WebEvent.
However it was creating WebEvents with a modifier flags bitmask built from the UIKeyModifier* enumerations,
-_modifierFlags, as opposed to a bitmask from the GraphicsServices enumerations, -_gsModifierFlags.
Instead WebKit should call -_gsModifierFlags to compute the GraphicsServices-compatible modifier
flags bitmask when instantiating a WebEvent.

  • Platform/spi/ios/UIKitSPI.h: Expose -_gsModifierFlags and remove -_modifierFlags.
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView _handleKeyUIEvent:]): Remove unnecessary code to update the current modifier state.
This will be done by the WebProcess when it receives the keyboard event.
(-[WKContentView _didHandleKeyEvent:eventWasHandled:]): Do not pass modifier flags changed events
to the scrolling animator as it does not know how to handle these kinds of events and triggers an
assertion failure when it tries to read the input string from the event (calls -charactersIgnoringModifiers).
FlagsChanged WebEvents events do not have an input string just like a FlagsChanged NSEvent that
they model on Mac.

  • UIProcess/ios/WKWebEvent.mm:

(-[WKWebEvent initWithEvent:]): Pass the value of -_gsModifierFlags for the modifier flags bitmask
instead of the value of -_modifierFlags.

Tools:

Add more test infrastructure to dispatch key up events.

  • WebKitTestRunner/ios/HIDEventGenerator.h:
  • WebKitTestRunner/ios/HIDEventGenerator.mm:

(createHIDKeyEvent): Renamed from createHIDKeyDownEvent() and modified to take a boolean as
to whether to create an event for a key down or key up.
(createHIDKeyDownEvent): Deleted; renamed to createHIDKeyEvent().

  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::createUIPhysicalKeyboardEvent): Added. Convenience function to create a UIPhysicalKeyboardEvent.
(WTR::UIScriptController::keyDown): Modified to dispatch a key up event in addition to dispatching
a key down event.

LayoutTests:

Add tests to ensure that Command + Down Arrow and Command + Up Arrow scroll to the end of
the page and the top of the page, respectively.

  • fast/scrolling/ios/key-command-scroll-to-bottom-expected.html: Added.
  • fast/scrolling/ios/key-command-scroll-to-bottom.html: Added.
  • fast/scrolling/ios/key-command-scroll-to-top-expected.html: Added.
  • fast/scrolling/ios/key-command-scroll-to-top.html: Added.
  • resources/ui-helper.js:

(window.UIHelper.keyDown): Pass the modifiers array to EventSender.keyDown() to make
this function work on Mac.

Location:
trunk
Files:
4 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r238524 r238526  
     12018-11-26  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r237738): Command Down Arrow doesn't scroll to the end of a page anymore
     4        https://bugs.webkit.org/show_bug.cgi?id=191967
     5        <rdar://problem/45976390>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add tests to ensure that Command + Down Arrow and Command + Up Arrow scroll to the end of
     10        the page and the top of the page, respectively.
     11
     12        * fast/scrolling/ios/key-command-scroll-to-bottom-expected.html: Added.
     13        * fast/scrolling/ios/key-command-scroll-to-bottom.html: Added.
     14        * fast/scrolling/ios/key-command-scroll-to-top-expected.html: Added.
     15        * fast/scrolling/ios/key-command-scroll-to-top.html: Added.
     16        * resources/ui-helper.js:
     17        (window.UIHelper.keyDown): Pass the modifiers array to EventSender.keyDown() to make
     18        this function work on Mac.
     19
    1202018-11-24  Ryosuke Niwa  <rniwa@webkit.org>
    221
  • trunk/LayoutTests/resources/ui-helper.js

    r238512 r238526  
    5858    {
    5959        if (!this.isWebKit2() || !this.isIOS()) {
    60             eventSender.keyDown(key);
     60            eventSender.keyDown(key, modifiers);
    6161            return Promise.resolve();
    6262        }
  • trunk/Source/WebKit/ChangeLog

    r238525 r238526  
     12018-11-26  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r237738): Command Down Arrow doesn't scroll to the end of a page anymore
     4        https://bugs.webkit.org/show_bug.cgi?id=191967
     5        <rdar://problem/45976390>
     6
     7        Reviewed by Tim Horton.
     8
     9        Fixes an issue where pressing Command + Down Arrow does not scroll the view to the end of the page.
     10
     11        Following r237738 the value of the enumerations used to identify modifier keys (e.g. Shift) changed
     12        to match the values of the corresponding enumerations in GraphicsServices, which are the
     13        enumerations UIKit uses to computes the modifier flags bitmask when instantiating a WebEvent to
     14        pass to WebKit. Before r237738 WebKit was using enumerations whose values matched the values
     15        of the corresponding UIKit public API UIKeyModifier* enumerations. For non-content editable elements,
     16        WebKit intercepts UIKit events in -_handleKeyUIEvent, synthesizes and dispatches its own WebEvent.
     17        However it was creating WebEvents with a modifier flags bitmask built from the UIKeyModifier* enumerations,
     18        -_modifierFlags, as opposed to a bitmask from the GraphicsServices enumerations, -_gsModifierFlags.
     19        Instead WebKit should call -_gsModifierFlags to compute the GraphicsServices-compatible modifier
     20        flags bitmask when instantiating a WebEvent.
     21
     22        * Platform/spi/ios/UIKitSPI.h: Expose -_gsModifierFlags and remove -_modifierFlags.
     23        * UIProcess/ios/WKContentViewInteraction.mm:
     24        (-[WKContentView _handleKeyUIEvent:]): Remove unnecessary code to update the current modifier state.
     25        This will be done by the WebProcess when it receives the keyboard event.
     26        (-[WKContentView _didHandleKeyEvent:eventWasHandled:]): Do not pass modifier flags changed events
     27        to the scrolling animator as it does not know how to handle these kinds of events and triggers an
     28        assertion failure when it tries to read the input string from the event (calls -charactersIgnoringModifiers).
     29        FlagsChanged WebEvents events do not have an input string just like a FlagsChanged NSEvent that
     30        they model on Mac.
     31        * UIProcess/ios/WKWebEvent.mm:
     32        (-[WKWebEvent initWithEvent:]): Pass the value of -_gsModifierFlags for the modifier flags bitmask
     33        instead of the value of -_modifierFlags.
     34
    1352018-11-26  Chris Dumez  <cdumez@apple.com>
    236
  • trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h

    r238360 r238526  
    200200- (NSString *)_unmodifiedInput;
    201201- (NSString *)_modifiedInput;
    202 - (NSInteger)_modifierFlags;
    203202- (BOOL)_isKeyDown;
    204203@end
     
    10271026@property (nonatomic, readonly) UIKeyboardInputFlags _inputFlags;
    10281027@property (nonatomic, readonly) CFIndex _keyCode;
     1028@property (nonatomic, readonly) NSInteger _gsModifierFlags;
    10291029@end
    10301030
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r238475 r238526  
    38433843{
    38443844    bool isHardwareKeyboardEvent = !!event._hidEvent;
    3845     if (isHardwareKeyboardEvent && ((UIPhysicalKeyboardEvent *)event)._inputFlags & kUIKeyboardInputModifierFlagsChanged)
    3846         _page->updateCurrentModifierState();
    38473845
    38483846    // We only want to handle key event from the hardware keyboard when we are
     
    38803878- (void)_didHandleKeyEvent:(::WebEvent *)event eventWasHandled:(BOOL)eventWasHandled
    38813879{
    3882     [_keyboardScrollingAnimator handleKeyEvent:event];
     3880    if (!(event.keyboardFlags & WebEventKeyboardInputModifierFlagsChanged))
     3881        [_keyboardScrollingAnimator handleKeyEvent:event];
    38833882   
    38843883    if (auto handler = WTFMove(_keyWebEventHandler)) {
  • trunk/Source/WebKit/UIProcess/ios/WKWebEvent.mm

    r237266 r238526  
    4040    uint16_t keyCode;
    4141    UIKeyboardInputFlags inputFlags;
     42    NSInteger modifierFlags;
    4243    BOOL isHardwareKeyboardEvent = !!event._hidEvent;
    4344    if (!isHardwareKeyboardEvent) {
    4445        keyCode = 0;
    4546        inputFlags = (UIKeyboardInputFlags)0;
     47        modifierFlags = 0;
    4648    } else {
    4749        UIPhysicalKeyboardEvent *keyEvent = (UIPhysicalKeyboardEvent *)event;
    4850        keyCode = keyEvent._keyCode;
    4951        inputFlags = keyEvent._inputFlags;
     52        modifierFlags = keyEvent._gsModifierFlags;
    5053        event = [[keyEvent _cloneEvent] autorelease]; // UIKit uses a singleton for hardware keyboard events.
    5154    }
    5255
    53     self = [super initWithKeyEventType:(event._isKeyDown ? WebEventKeyDown : WebEventKeyUp) timeStamp:event.timestamp characters:event._modifiedInput charactersIgnoringModifiers:event._unmodifiedInput modifiers:event._modifierFlags isRepeating:(inputFlags & kUIKeyboardInputRepeat) withFlags:inputFlags keyCode:keyCode isTabKey:[event._modifiedInput isEqualToString:@"\t"] characterSet:WebEventCharacterSetUnicode];
     56    self = [super initWithKeyEventType:(event._isKeyDown ? WebEventKeyDown : WebEventKeyUp) timeStamp:event.timestamp characters:event._modifiedInput charactersIgnoringModifiers:event._unmodifiedInput modifiers:modifierFlags isRepeating:(inputFlags & kUIKeyboardInputRepeat) withFlags:inputFlags keyCode:keyCode isTabKey:[event._modifiedInput isEqualToString:@"\t"] characterSet:WebEventCharacterSetUnicode];
    5457    if (!self)
    5558        return nil;
  • trunk/Tools/ChangeLog

    r238518 r238526  
     12018-11-26  Daniel Bates  <dabates@apple.com>
     2
     3        REGRESSION (r237738): Command Down Arrow doesn't scroll to the end of a page anymore
     4        https://bugs.webkit.org/show_bug.cgi?id=191967
     5        <rdar://problem/45976390>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add more test infrastructure to dispatch key up events.
     10
     11        * WebKitTestRunner/ios/HIDEventGenerator.h:
     12        * WebKitTestRunner/ios/HIDEventGenerator.mm:
     13        (createHIDKeyEvent): Renamed from createHIDKeyDownEvent() and modified to take a boolean as
     14        to whether to create an event for a key down or key up.
     15        (createHIDKeyDownEvent): Deleted; renamed to createHIDKeyEvent().
     16        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     17        (WTR::createUIPhysicalKeyboardEvent): Added. Convenience function to create a UIPhysicalKeyboardEvent.
     18        (WTR::UIScriptController::keyDown): Modified to dispatch a key up event in addition to dispatching
     19        a key down event.
     20
    1212018-11-26  Aakash Jain  <aakash_jain@apple.com>
    222
  • trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.h

    r238235 r238526  
    7070extern NSUInteger const HIDMaxTouchCount;
    7171
    72 RetainPtr<IOHIDEventRef> createHIDKeyDownEvent(NSString *, uint64_t timestamp);
     72RetainPtr<IOHIDEventRef> createHIDKeyEvent(NSString *, uint64_t timestamp, bool isKeyDown);
    7373
    7474@interface HIDEventGenerator : NSObject
  • trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.mm

    r238235 r238526  
    974974}
    975975
    976 RetainPtr<IOHIDEventRef> createHIDKeyDownEvent(NSString *character, uint64_t timestamp)
    977 {
    978     return adoptCF(IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, timestamp, kHIDPage_KeyboardOrKeypad, hidUsageCodeForCharacter(character), true /* key down */, kIOHIDEventOptionNone));
     976RetainPtr<IOHIDEventRef> createHIDKeyEvent(NSString *character, uint64_t timestamp, bool isKeyDown)
     977{
     978    return adoptCF(IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, timestamp, kHIDPage_KeyboardOrKeypad, hidUsageCodeForCharacter(character), isKeyDown, kIOHIDEventOptionNone));
    979979}
    980980
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r238512 r238526  
    401401}
    402402
     403static UIPhysicalKeyboardEvent *createUIPhysicalKeyboardEvent(const String& hidInputString, const String& uiEventInputString, UIKeyModifierFlags modifierFlags, bool isKeyDown)
     404{
     405    auto* keyboardEvent = [getUIPhysicalKeyboardEventClass() _eventWithInput:uiEventInputString inputFlags:(UIKeyboardInputFlags)0];
     406    keyboardEvent._modifierFlags = modifierFlags;
     407    auto hidEvent = createHIDKeyEvent(hidInputString, keyboardEvent.timestamp, isKeyDown);
     408    [keyboardEvent _setHIDEvent:hidEvent.get() keyboard:nullptr];
     409    return keyboardEvent;
     410}
     411
    403412void UIScriptController::keyDown(JSStringRef character, JSValueRef modifierArray)
    404413{
     
    413422    String inputString = toWTFString(toWK(character));
    414423    String uiEventInputString = inputString.length() > 1 ? emptyString() : inputString;
    415     auto *keyboardEvent = [getUIPhysicalKeyboardEventClass() _eventWithInput:uiEventInputString inputFlags:(UIKeyboardInputFlags)0];
    416     keyboardEvent._modifierFlags = parseModifierArray(m_context->jsContext(), modifierArray);
    417     auto hidEvent = createHIDKeyDownEvent(inputString, keyboardEvent.timestamp);
    418     [keyboardEvent _setHIDEvent:hidEvent.get() keyboard:nullptr];
     424    auto modifierFlags = parseModifierArray(m_context->jsContext(), modifierArray);
     425
     426    // Note that UIKit will call -release on the passed UIPhysicalKeyboardEvent.
     427
     428    // Key down
     429    auto* keyboardEvent = createUIPhysicalKeyboardEvent(inputString, uiEventInputString, modifierFlags, true /* isKeyDown */);
     430    [[UIApplication sharedApplication] handleKeyUIEvent:keyboardEvent];
     431
     432    // Key up
     433    keyboardEvent = createUIPhysicalKeyboardEvent(inputString, uiEventInputString, modifierFlags, false /* isKeyDown */);
    419434    [[UIApplication sharedApplication] handleKeyUIEvent:keyboardEvent];
    420435}
Note: See TracChangeset for help on using the changeset viewer.