Merge pull request #7528 from electron/key-and-code-on-sent-input-events

Set key and code on sendInputEvent keyboard events
This commit is contained in:
Cheng Zhao 2016-10-11 19:34:05 +09:00 committed by GitHub
commit 0baa60caab
7 changed files with 140 additions and 7 deletions

View file

@ -7,6 +7,8 @@
#include "atom/common/keyboard_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/events/event_constants.h"
namespace atom {
@ -174,4 +176,33 @@ ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted) {
return KeyboardCodeFromKeyIdentifier(str, shifted);
}
int WebEventModifiersToEventFlags(int modifiers) {
int flags = 0;
if (modifiers & blink::WebInputEvent::ShiftKey)
flags |= ui::EF_SHIFT_DOWN;
if (modifiers & blink::WebInputEvent::ControlKey)
flags |= ui::EF_CONTROL_DOWN;
if (modifiers & blink::WebInputEvent::AltKey)
flags |= ui::EF_ALT_DOWN;
if (modifiers & blink::WebInputEvent::MetaKey)
flags |= ui::EF_COMMAND_DOWN;
if (modifiers & blink::WebInputEvent::CapsLockOn)
flags |= ui::EF_CAPS_LOCK_ON;
if (modifiers & blink::WebInputEvent::NumLockOn)
flags |= ui::EF_NUM_LOCK_ON;
if (modifiers & blink::WebInputEvent::ScrollLockOn)
flags |= ui::EF_SCROLL_LOCK_ON;
if (modifiers & blink::WebInputEvent::LeftButtonDown)
flags |= ui::EF_LEFT_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::MiddleButtonDown)
flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::RightButtonDown)
flags |= ui::EF_RIGHT_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::IsAutoRepeat)
flags |= ui::EF_IS_REPEAT;
return flags;
}
} // namespace atom

View file

@ -15,6 +15,9 @@ namespace atom {
// pressed.
ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted);
// Ported from ui/events/blink/blink_event_util.h
int WebEventModifiersToEventFlags(int modifiers);
} // namespace atom
#endif // ATOM_COMMON_KEYBOARD_UTIL_H_

View file

@ -18,6 +18,7 @@
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
namespace {
@ -166,15 +167,25 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(
return false;
std::string str;
bool shifted = false;
if (dict.Get("keyCode", &str))
out->windowsKeyCode = atom::KeyboardCodeFromStr(str, &shifted);
else
if (!dict.Get("keyCode", &str))
return false;
bool shifted = false;
ui::KeyboardCode keyCode = atom::KeyboardCodeFromStr(str, &shifted);
out->windowsKeyCode = keyCode;
if (shifted)
out->modifiers |= blink::WebInputEvent::ShiftKey;
out->setKeyIdentifierFromWindowsKeyCode();
ui::DomCode domCode = ui::UsLayoutKeyboardCodeToDomCode(keyCode);
out->domCode = static_cast<int>(domCode);
ui::DomKey domKey;
ui::KeyboardCode dummy_code;
int flags = atom::WebEventModifiersToEventFlags(out->modifiers);
if (ui::DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &dummy_code))
out->domKey = static_cast<int>(domKey);
if ((out->type == blink::WebInputEvent::Char ||
out->type == blink::WebInputEvent::RawKeyDown)) {
// Make sure to not read beyond the buffer in case some bad code doesn't

View file

@ -5,7 +5,7 @@ const path = require('path')
const {closeWindow} = require('./window-helpers')
const {remote} = require('electron')
const {BrowserWindow, webContents} = remote
const {BrowserWindow, webContents, ipcMain} = remote
const isCi = remote.getGlobal('isCi')
@ -97,4 +97,80 @@ describe('webContents module', function () {
})
})
})
describe('sendInputEvent(event)', function () {
beforeEach(function (done) {
w.loadURL('file://' + path.join(__dirname, 'fixtures', 'pages', 'key-events.html'))
w.webContents.once('did-finish-load', function () {
done()
})
})
it('can send keydown events', function (done) {
ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
assert.equal(key, 'a')
assert.equal(code, 'KeyA')
assert.equal(keyCode, 65)
assert.equal(shiftKey, false)
assert.equal(ctrlKey, false)
assert.equal(altKey, false)
done()
})
w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'})
})
it('can send keydown events with modifiers', function (done) {
ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
assert.equal(key, 'Z')
assert.equal(code, 'KeyZ')
assert.equal(keyCode, 90)
assert.equal(shiftKey, true)
assert.equal(ctrlKey, true)
assert.equal(altKey, false)
done()
})
w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z', modifiers: ['shift', 'ctrl']})
})
it('can send keydown events with special keys', function (done) {
ipcMain.once('keydown', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
assert.equal(key, 'Tab')
assert.equal(code, 'Tab')
assert.equal(keyCode, 9)
assert.equal(shiftKey, false)
assert.equal(ctrlKey, false)
assert.equal(altKey, true)
done()
})
w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Tab', modifiers: ['alt']})
})
it('can send char events', function (done) {
ipcMain.once('keypress', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
assert.equal(key, 'a')
assert.equal(code, 'KeyA')
assert.equal(keyCode, 65)
assert.equal(shiftKey, false)
assert.equal(ctrlKey, false)
assert.equal(altKey, false)
done()
})
w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'A'})
w.webContents.sendInputEvent({type: 'char', keyCode: 'A'})
})
it('can send char events with modifiers', function (done) {
ipcMain.once('keypress', function (event, key, code, keyCode, shiftKey, ctrlKey, altKey) {
assert.equal(key, 'Z')
assert.equal(code, 'KeyZ')
assert.equal(keyCode, 90)
assert.equal(shiftKey, true)
assert.equal(ctrlKey, true)
assert.equal(altKey, false)
done()
})
w.webContents.sendInputEvent({type: 'keyDown', keyCode: 'Z'})
w.webContents.sendInputEvent({type: 'char', keyCode: 'Z', modifiers: ['shift', 'ctrl']})
})
})
})

12
spec/fixtures/pages/key-events.html vendored Normal file
View file

@ -0,0 +1,12 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
document.onkeydown = function (e) {
require('electron').ipcRenderer.send('keydown', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
}
document.onkeypress = function (e) {
require('electron').ipcRenderer.send('keypress', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
}
</script>
</body>
</html>

View file

@ -2,7 +2,7 @@
<body>
<script type="text/javascript" charset="utf-8">
document.onkeyup = function(e) {
require('electron').ipcRenderer.sendToHost('keyup', e.keyCode, e.shiftKey, e.ctrlKey);
require('electron').ipcRenderer.sendToHost('keyup', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey);
}
</script>
</body>

View file

@ -776,7 +776,7 @@ describe('<webview> tag', function () {
it('can send keyboard event', function (done) {
webview.addEventListener('ipc-message', function (e) {
assert.equal(e.channel, 'keyup')
assert.deepEqual(e.args, [67, true, false])
assert.deepEqual(e.args, ['C', 'KeyC', 67, true, false])
done()
})
webview.addEventListener('dom-ready', function () {