Changeset 252976 in webkit


Ignore:
Timestamp:
Dec 1, 2019 7:19:14 PM (4 years ago)
Author:
Fujii Hironori
Message:

[Win] Retrieve all following WM_CHAR events at the beginning of processing WM_KEYDOWN event
https://bugs.webkit.org/show_bug.cgi?id=204694

Reviewed by Ross Kirsling.

Source/WebKit:

In Windows ports, WM_KEYDOWN dispatches keydown event, and
WM_CHAR dispatches keypress event. If a keydown event is canceled
by calling preventDefault, the following corresponding keypress
events shouldn't be dispatched.

WebKit1 implemented it by removing WM_CHAR events if the keydown
event is consumed. However, WebKit2 can't do so because WebKit2
processes key events asynchronously. Thus, retrieve all following
WM_CHAR events, and dispatch them after processing the keydown
and if it is not consumed.

In addition to that, retrieving following WM_CHAR events is needed
to fix Bug 204672 because the events are needed for 'key' property
of keydown KeyboardEvent for dead key combination.

Gecko and Chromium also implements 'key' property in the same approach.

Test: Covered by existing fast/events/inputText-never-fired-on-keydown-cancel.html and fast/events/keydown-keypress-preventDefault.html

  • Shared/NativeWebKeyboardEvent.h: Added m_pendingCharEvents as Vector<MSG>.

(WebKit::NativeWebKeyboardEvent::pendingCharEvents const):

  • Shared/win/NativeWebKeyboardEventWin.cpp:

(WebKit::NativeWebKeyboardEvent::NativeWebKeyboardEvent):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::didReceiveEvent):

  • UIProcess/WebPageProxy.h:
  • UIProcess/win/WebPageProxyWin.cpp:

(WebKit::WebPageProxy::dispatchPendingCharEvents):

  • UIProcess/win/WebView.cpp:

(WebKit::WebView::onKeyEvent):

Source/WebKitLegacy/win:

  • WebView.cpp:

(WebView::keyDown): Added a variable pendingCharEvents of
Vector<MSG> to preserve following WM_CHAR events. Dispatch them if
the WM_KEYDOWN isn't consumed.

Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r252965 r252976  
     12019-12-01  Fujii Hironori  <Hironori.Fujii@sony.com>
     2
     3        [Win] Retrieve all following WM_CHAR events at the beginning of processing WM_KEYDOWN event
     4        https://bugs.webkit.org/show_bug.cgi?id=204694
     5
     6        Reviewed by Ross Kirsling.
     7
     8        In Windows ports, WM_KEYDOWN dispatches keydown event, and
     9        WM_CHAR dispatches keypress event. If a keydown event is canceled
     10        by calling preventDefault, the following corresponding keypress
     11        events shouldn't be dispatched.
     12
     13        WebKit1 implemented it by removing WM_CHAR events if the keydown
     14        event is consumed. However, WebKit2 can't do so because WebKit2
     15        processes key events asynchronously. Thus, retrieve all following
     16        WM_CHAR events, and dispatch them after processing the keydown
     17        and if it is not consumed.
     18
     19        In addition to that, retrieving following WM_CHAR events is needed
     20        to fix Bug 204672 because the events are needed for 'key' property
     21        of keydown KeyboardEvent for dead key combination.
     22
     23        Gecko and Chromium also implements 'key' property in the same approach.
     24
     25        Test: Covered by existing fast/events/inputText-never-fired-on-keydown-cancel.html and fast/events/keydown-keypress-preventDefault.html
     26
     27        * Shared/NativeWebKeyboardEvent.h: Added m_pendingCharEvents as Vector<MSG>.
     28        (WebKit::NativeWebKeyboardEvent::pendingCharEvents const):
     29        * Shared/win/NativeWebKeyboardEventWin.cpp:
     30        (WebKit::NativeWebKeyboardEvent::NativeWebKeyboardEvent):
     31        * UIProcess/WebPageProxy.cpp:
     32        (WebKit::WebPageProxy::didReceiveEvent):
     33        * UIProcess/WebPageProxy.h:
     34        * UIProcess/win/WebPageProxyWin.cpp:
     35        (WebKit::WebPageProxy::dispatchPendingCharEvents):
     36        * UIProcess/win/WebView.cpp:
     37        (WebKit::WebView::onKeyEvent):
     38
    1392019-11-30  Tim Horton  <timothy_horton@apple.com>
    240
  • trunk/Source/WebKit/Shared/NativeWebKeyboardEvent.h

    r251650 r252976  
    7777    NativeWebKeyboardEvent(struct wpe_input_keyboard_event*);
    7878#elif PLATFORM(WIN)
    79     NativeWebKeyboardEvent(HWND, UINT message, WPARAM, LPARAM);
     79    NativeWebKeyboardEvent(HWND, UINT message, WPARAM, LPARAM, Vector<MSG>&& pendingCharEvents);
    8080#endif
    8181
     
    9191#elif PLATFORM(WIN)
    9292    const MSG* nativeEvent() const { return &m_nativeEvent; }
     93    const Vector<MSG>& pendingCharEvents() const { return m_pendingCharEvents; }
    9394#else
    9495    const void* nativeEvent() const { return nullptr; }
     
    107108#elif PLATFORM(WIN)
    108109    MSG m_nativeEvent;
     110    Vector<MSG> m_pendingCharEvents;
    109111#endif
    110112};
  • trunk/Source/WebKit/Shared/win/NativeWebKeyboardEventWin.cpp

    r239550 r252976  
    3434using namespace WebCore;
    3535
    36 NativeWebKeyboardEvent::NativeWebKeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     36NativeWebKeyboardEvent::NativeWebKeyboardEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, Vector<MSG>&& pendingCharEvents)
    3737    : WebKeyboardEvent(WebEventFactory::createWebKeyboardEvent(hwnd, message, wParam, lParam))
    3838    , m_nativeEvent(createNativeEvent(hwnd, message, wParam, lParam))
     39    , m_pendingCharEvents(WTFMove(pendingCharEvents))
    3940{
    4041}
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r252692 r252976  
    65766576        MESSAGE_CHECK(m_process, type == event.type());
    65776577
     6578#if PLATFORM(WIN)
     6579        if (!handled && type == WebEvent::RawKeyDown)
     6580            dispatchPendingCharEvents(event);
     6581#endif
     6582
    65786583        bool canProcessMoreKeyEvents = !m_keyEventQueue.isEmpty();
    65796584        if (canProcessMoreKeyEvents) {
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r252692 r252976  
    866866    bool isProcessingKeyboardEvents() const;
    867867    void handleKeyboardEvent(const NativeWebKeyboardEvent&);
     868#if PLATFORM(WIN)
     869    void dispatchPendingCharEvents(const NativeWebKeyboardEvent&);
     870#endif
    868871
    869872#if ENABLE(MAC_GESTURE_EVENTS)
  • trunk/Source/WebKit/UIProcess/win/WebPageProxyWin.cpp

    r249335 r252976  
    2828#include "WebPageProxy.h"
    2929
     30#include "NativeWebKeyboardEvent.h"
    3031#include "PageClientImpl.h"
    3132#include <WebCore/SearchPopupMenuDB.h>
     
    8788#endif
    8889
     90void WebPageProxy::dispatchPendingCharEvents(const NativeWebKeyboardEvent& keydownEvent)
     91{
     92    auto& pendingCharEvents = keydownEvent.pendingCharEvents();
     93    for (auto it = pendingCharEvents.rbegin(); it != pendingCharEvents.rend(); it++)
     94        m_keyEventQueue.prepend(NativeWebKeyboardEvent(it->hwnd, it->message, it->wParam, it->lParam, { }));
     95}
    8996
    9097} // namespace WebKit
  • trunk/Source/WebKit/UIProcess/win/WebView.cpp

    r250534 r252976  
    468468LRESULT WebView::onKeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
    469469{
    470     m_page->handleKeyboardEvent(NativeWebKeyboardEvent(hWnd, message, wParam, lParam));
     470    Vector<MSG> pendingCharEvents;
     471    if (message == WM_KEYDOWN) {
     472        MSG msg;
     473        // WM_SYSCHAR events should not be removed, because WebKit is using WM_SYSCHAR for access keys and they can't be canceled.
     474        while (PeekMessage(&msg, hWnd, WM_CHAR, WM_DEADCHAR, PM_REMOVE)) {
     475            if (msg.message == WM_CHAR)
     476                pendingCharEvents.append(msg);
     477        }
     478    }
     479    m_page->handleKeyboardEvent(NativeWebKeyboardEvent(hWnd, message, wParam, lParam, WTFMove(pendingCharEvents)));
    471480
    472481    // We claim here to always have handled the event. If the event is not in fact handled, we will
  • trunk/Source/WebKitLegacy/win/ChangeLog

    r252973 r252976  
     12019-12-01  Fujii Hironori  <Hironori.Fujii@sony.com>
     2
     3        [Win] Retrieve all following WM_CHAR events at the beginning of processing WM_KEYDOWN event
     4        https://bugs.webkit.org/show_bug.cgi?id=204694
     5
     6        Reviewed by Ross Kirsling.
     7
     8        * WebView.cpp:
     9        (WebView::keyDown): Added a variable pendingCharEvents of
     10        Vector<MSG> to preserve following WM_CHAR events. Dispatch them if
     11        the WM_KEYDOWN isn't consumed.
     12
    1132019-12-01  Fujii Hironori  <Hironori.Fujii@sony.com>
    214
  • trunk/Source/WebKitLegacy/win/WebView.cpp

    r252965 r252976  
    23772377    Frame& frame = m_page->focusController().focusedOrMainFrame();
    23782378
     2379    Vector<MSG> pendingCharEvents;
     2380    MSG msg;
     2381    while (PeekMessage(&msg, m_viewWindow, WM_CHAR, WM_DEADCHAR, PM_REMOVE)) {
     2382        // FIXME: remove WM_UNICHAR, too
     2383        // WM_SYSCHAR events should not be removed, because WebKit is using WM_SYSCHAR for access keys and they can't be canceled.
     2384        if (msg.message == WM_CHAR)
     2385            pendingCharEvents.append(msg);
     2386    }
     2387
    23792388    PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, PlatformEvent::RawKeyDown, systemKeyDown);
    23802389    bool handled = frame.eventHandler().keyEvent(keyEvent);
     
    23852394        return false;
    23862395
    2387     if (handled) {
    2388         // FIXME: remove WM_UNICHAR, too
    2389         MSG msg;
    2390         // WM_SYSCHAR events should not be removed, because access keys are implemented in WebCore in WM_SYSCHAR handler.
    2391         if (!systemKeyDown)
    2392             ::PeekMessage(&msg, m_viewWindow, WM_CHAR, WM_CHAR, PM_REMOVE);
     2396    if (handled)
    23932397        return true;
    2394     }
    23952398
    23962399    // We need to handle back/forward using either Ctrl+Left/Right Arrow keys.
     
    24032406
    24042407    // Need to scroll the page if the arrow keys, pgup/dn, or home/end are hit.
    2405     ScrollDirection direction;
    2406     ScrollGranularity granularity;
     2408    bool willScroll = true;
     2409    ScrollDirection direction { };
     2410    ScrollGranularity granularity { };
    24072411    switch (virtualKeyCode) {
    24082412        case VK_LEFT:
     
    24392443            break;
    24402444        default:
    2441             return false;
    2442     }
    2443 
    2444     return frame.eventHandler().scrollRecursively(direction, granularity);
     2445            willScroll = false;
     2446            break;
     2447    }
     2448
     2449    if (willScroll) {
     2450        handled = frame.eventHandler().scrollRecursively(direction, granularity);
     2451        if (handled)
     2452            return true;
     2453    }
     2454
     2455    for (auto& msg : pendingCharEvents)
     2456        DispatchMessage(&msg);
     2457    return false;
    24452458}
    24462459
Note: See TracChangeset for help on using the changeset viewer.