Skip to content

Commit

Permalink
fix: sendInputEvent keyCodes being incorrectly converted
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Sep 11, 2023
1 parent 792037b commit 2fd946e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
12 changes: 10 additions & 2 deletions shell/common/gin_converters/blink_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "base/containers/fixed_flat_map.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "base/strings/utf_string_conversions.h"
#include "gin/converter.h"
#include "gin/data_object_builder.h"
Expand Down Expand Up @@ -275,11 +276,18 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(v8::Isolate* isolate,

if ((out->GetType() == blink::WebInputEvent::Type::kChar ||
out->GetType() == blink::WebInputEvent::Type::kRawKeyDown)) {
// If the keyCode is e.g. Space or Plus we want to use the character
// instead of the keyCode: ' ' instead of 'Space', '+' instead of 'Plus'.
std::string character_str;
if (str.size() > 1 && domKey.IsCharacter())
base::WriteUnicodeCharacter(domKey.ToCharacter(), &character_str);

// Make sure to not read beyond the buffer in case some bad code doesn't
// NULL-terminate it (this is called from plugins).
size_t text_length_cap = blink::WebKeyboardEvent::kTextLengthCap;
std::u16string text16 = base::UTF8ToUTF16(str);

std::u16string text16 = character_str.empty()
? base::UTF8ToUTF16(str)
: base::UTF8ToUTF16(character_str);
std::fill_n(out->text, text_length_cap, 0);
std::fill_n(out->unmodified_text, text_length_cap, 0);
for (size_t i = 0; i < std::min(text_length_cap - 1, text16.size()); ++i) {
Expand Down
29 changes: 24 additions & 5 deletions spec/api-web-contents-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,8 @@ describe('webContents module', () => {
it('can send keydown events', async () => {
const keydown = once(ipcMain, 'keydown');
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' });
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keydown;
const [, data] = await keydown;
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = data;
expect(key).to.equal('a');
expect(code).to.equal('KeyA');
expect(keyCode).to.equal(65);
Expand All @@ -805,7 +806,8 @@ describe('webContents module', () => {
it('can send keydown events with modifiers', async () => {
const keydown = once(ipcMain, 'keydown');
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl'] });
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keydown;
const [, data] = await keydown;
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = data;
expect(key).to.equal('Z');
expect(code).to.equal('KeyZ');
expect(keyCode).to.equal(90);
Expand All @@ -817,7 +819,8 @@ describe('webContents module', () => {
it('can send keydown events with special keys', async () => {
const keydown = once(ipcMain, 'keydown');
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Tab', modifiers: ['alt'] });
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keydown;
const [, data] = await keydown;
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = data;
expect(key).to.equal('Tab');
expect(code).to.equal('Tab');
expect(keyCode).to.equal(9);
Expand All @@ -830,7 +833,8 @@ describe('webContents module', () => {
const keypress = once(ipcMain, 'keypress');
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'A' });
w.webContents.sendInputEvent({ type: 'char', keyCode: 'A' });
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keypress;
const [, data] = await keypress;
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = data;
expect(key).to.equal('a');
expect(code).to.equal('KeyA');
expect(keyCode).to.equal(65);
Expand All @@ -839,11 +843,26 @@ describe('webContents module', () => {
expect(altKey).to.be.false();
});

it('can correctly convert accelerators to key codes', async () => {
const keyup = once(ipcMain, 'keyup');
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Space', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Space', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'keyUp' });

await keyup;
const inputText = await w.webContents.executeJavaScript('document.getElementById("input").value');
expect(inputText).to.equal('+ + +');
});

it('can send char events with modifiers', async () => {
const keypress = once(ipcMain, 'keypress');
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z' });
w.webContents.sendInputEvent({ type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl'] });
const [, key, code, keyCode, shiftKey, ctrlKey, altKey] = await keypress;
const [, data] = await keypress;
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = data;
expect(key).to.equal('Z');
expect(code).to.equal('KeyZ');
expect(keyCode).to.equal(90);
Expand Down
13 changes: 11 additions & 2 deletions spec/fixtures/pages/key-events.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
<html>
<body>
<input type="text" id="input" autofocus/>
<script type="text/javascript" charset="utf-8">
const { ipcRenderer } = require('electron')

document.onkeydown = function (e) {
require('electron').ipcRenderer.send('keydown', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = e;
ipcRenderer.send('keydown', { key, code, keyCode, shiftKey, ctrlKey, altKey })
}
document.onkeypress = function (e) {
require('electron').ipcRenderer.send('keypress', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = e;
ipcRenderer.send('keypress', { key, code, keyCode, shiftKey, ctrlKey, altKey })
}
document.onkeyup = function (e) {
const { key, code, keyCode, shiftKey, ctrlKey, altKey } = e;
ipcRenderer.send('keyup', { key, code, keyCode, shiftKey, ctrlKey, altKey })
}
</script>
</body>
Expand Down

0 comments on commit 2fd946e

Please sign in to comment.