Fix windows osr key event dom codes (#2597) #4215
Conversation
magreenblatt
left a comment
There was a problem hiding this comment.
Review findings from comparison with the current CEF implementation and Chromium Windows key-event conversion.
| ui::KeyboardCodeForWindowsKeyCode(key_event.windows_key_code); | ||
| ui::DomCode dom_code = | ||
| ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code); | ||
| ui::DomCode dom_code = ui::KeycodeConverter::NativeKeycodeToDomCode( |
There was a problem hiding this comment.
[P1] Please preserve the existing raw scan-code representation. This now unconditionally treats native_key_code as a Windows LPARAM. Before this patch, passing raw scan code 0x001E directly produced KeyA; after GetScanCodeFromLParam() it becomes zero and produces an unidentified DOM code. That representation is consistent with the current public description (the platform actual key code) and with the behavior of the existing implementation, even though cefclient passes LPARAM. Please accept both forms; for example, treat values confined to the low 16 bits as raw scan codes and values with an upper word as LPARAM; and document Windows LPARAM as the preferred form. Repeat-bit inference should likewise only apply to the LPARAM form; raw-code callers can use EVENTFLAG_IS_REPEAT.
There was a problem hiding this comment.
A concrete compatibility implementation could decode the two representations structurally:
namespace {
struct DecodedWindowsNativeKeyCode {
uint16_t scan_code;
bool is_lparam;
};
DecodedWindowsNativeKeyCode DecodeWindowsNativeKeyCode(int native_key_code) {
const uint32_t value = static_cast<uint32_t>(native_key_code);
// Legacy/raw Windows scan codes, including E0-prefixed extended codes such
// as 0xE01D, fit in the low 16 bits. A normal keyboard-message LPARAM stores
// its scan code in bits 16-23 and therefore has a non-zero upper word.
if ((value & 0xFFFF0000u) == 0) {
return {static_cast<uint16_t>(value), false};
}
return {ui::GetScanCodeFromLParam(
static_cast<LPARAM>(static_cast<int32_t>(value))),
true};
}
} // namespaceTranslateUiKeyEvent can then use the decoded scan code and only interpret bit 30 when the input was actually classified as an LPARAM:
const auto decoded =
DecodeWindowsNativeKeyCode(key_event.native_key_code);
ui::DomCode dom_code =
ui::KeycodeConverter::NativeKeycodeToDomCode(decoded.scan_code);
// Existing raw-scan-code callers can express repeat through
// EVENTFLAG_IS_REPEAT, which TranslateUiEventModifiers already handles.
if (decoded.is_lparam && type == ui::EventType::kKeyPressed &&
(static_cast<uint32_t>(key_event.native_key_code) & 0x40000000u)) {
flags |= ui::EF_IS_REPEAT;
}I would document Windows LPARAM as the preferred representation in cef_key_event_t::native_key_code, while explicitly retaining low-16-bit scan codes for compatibility. Suggested coverage:
0x001E(raw) and0x001E0001(LPARAM) both produceKeyA.0xE01D(raw extended) and0x011D0001(extendedLPARAM) both produceControlRight.0x401E0001producesKeyAwith repeat.- A raw
0x001Eevent withEVENTFLAG_IS_REPEATalso produces repeat.
The structural rule deliberately treats an upper-word-zero value as the legacy raw form. A malformed or synthetic LPARAM with no scan code is inherently ambiguous; favoring the previously accepted representation is the compatibility-preserving choice. I would avoid falling back based on DomCode::NONE, because that would make input interpretation depend on Chromium's evolving scan-code table.
| // native_key_code | ||
| // 2. event.repeat is true for a keydown whose lParam bit 30 is set | ||
| // 3. event.repeat is always false for keyup events. | ||
| TEST(KeyboardDomCodeTest, DomCodeAndRepeatFlags) { |
There was a problem hiding this comment.
[P2] Please cover the character-message path in this regression test. SendKeyDownUp sends only KEYEVENT_RAWKEYDOWN and KEYEVENT_KEYUP, so the test never exercises KEYEVENT_CHAR. Consequently it does not validate the accompanying cefclient/helper change for issue #2597 case 4, where a character such as a was incorrectly reported with NUMPAD location. Please send a character event and assert its code, location, and repeat, or add a focused test for the split modifier helper.
|
|
||
| // Verifies that: | ||
| // 1. event.code is correctly derived from the scan-code portion of | ||
| // native_key_code |
There was a problem hiding this comment.
[P3] Whitespace: This line has trailing whitespace, so the patch fails git diff --check.
There was a problem hiding this comment.
I've now pushed updates which I believe address the above points.
While testing the changes I had an occasional issue with OnLoadEnd not being called and the test timing out so I'm now using an OnPaint check to signify readiness instead. This is as per the OSR tests in osr_display_unittest.cc.
| } | ||
|
|
||
| TrackCallback got_paint_; | ||
| TrackCallback got_load_end_; // informational only |
There was a problem hiding this comment.
[P1] Please remove this unused field. After the readiness path was changed from OnLoadEnd to OnPaint, got_load_end_ is never referenced. Chromium’s Windows warning configuration (clang-cl /W4 /WX) diagnoses this as private field 'got_load_end_' is not used [-Werror,-Wunused-private-field], so the ceftests target will fail to compile.
|
Please rebase this branch cleanly onto the current |
d8fbd7d to
41d5dbb
Compare
This PR is a resubmission of https://bitbucket.org/chromiumembedded/cef/pull-requests/336 and fixes issue #2597.
It ensures that correct DOM codes are sent with osr key events.
The original PR code worked perfectly but it was never accepted due to lack of a unit test.
We have been patching CEF for many years with this code as some web sites do not work correctly without it.
Recently I noticed that CLAUDE_TEST_INSTRUCTIONS.md is now available so decided to have a go with it and this PR is the result.
I have checked that the new unit test fails with current CEF master and passes with this PR code.
Also that https://dvcs.w3.org/hg/d4e/raw-file/tip/key-event-test.html now reports correct DOM codes with cefclient --off-screen-rendering-enabled
This PR applies only to Windows builds, I believe that it will not affect Mac or Linux builds but I have been unable to test that.