blob: 7c416533c4ad470dede79a8688389f24b5159b98 [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/browser/native_web_keyboard_event.h"
#include "base/logging.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
namespace {
// We need to copy |os_event| in NativeWebKeyboardEvent because it is
// queued in RenderWidgetHost and may be passed and used
// RenderViewHostDelegate::HandledKeybardEvent after the original aura
// event is destroyed.
ui::Event* CopyEvent(const ui::Event* event) {
return event ? ui::Event::Clone(*event).release() : nullptr;
}
int WebEventModifiersToEventFlags(int modifiers) {
int flags = 0;
if (modifiers & blink::WebInputEvent::kShiftKey)
flags |= ui::EF_SHIFT_DOWN;
if (modifiers & blink::WebInputEvent::kControlKey)
flags |= ui::EF_CONTROL_DOWN;
if (modifiers & blink::WebInputEvent::kAltKey)
flags |= ui::EF_ALT_DOWN;
if (modifiers & blink::WebInputEvent::kMetaKey)
flags |= ui::EF_COMMAND_DOWN;
if (modifiers & blink::WebInputEvent::kAltGrKey)
flags |= ui::EF_ALTGR_DOWN;
if (modifiers & blink::WebInputEvent::kNumLockOn)
flags |= ui::EF_NUM_LOCK_ON;
if (modifiers & blink::WebInputEvent::kCapsLockOn)
flags |= ui::EF_CAPS_LOCK_ON;
if (modifiers & blink::WebInputEvent::kScrollLockOn)
flags |= ui::EF_SCROLL_LOCK_ON;
if (modifiers & blink::WebInputEvent::kLeftButtonDown)
flags |= ui::EF_LEFT_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::kMiddleButtonDown)
flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::kRightButtonDown)
flags |= ui::EF_RIGHT_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::kBackButtonDown)
flags |= ui::EF_BACK_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::kForwardButtonDown)
flags |= ui::EF_FORWARD_MOUSE_BUTTON;
if (modifiers & blink::WebInputEvent::kIsAutoRepeat)
flags |= ui::EF_IS_REPEAT;
if (modifiers & blink::WebInputEvent::kIsTouchAccessibility)
flags |= ui::EF_TOUCH_ACCESSIBILITY;
return flags;
}
class TranslatedKeyEvent : public ui::KeyEvent {
public:
static TranslatedKeyEvent* Create(const blink::WebKeyboardEvent& web_event) {
ui::EventType type = ui::ET_KEY_RELEASED;
bool is_char = false;
if (web_event.GetType() == blink::WebInputEvent::kChar) {
is_char = true;
type = ui::ET_KEY_PRESSED;
} else if (web_event.GetType() == blink::WebInputEvent::kRawKeyDown ||
web_event.GetType() == blink::WebInputEvent::kKeyDown) {
type = ui::ET_KEY_PRESSED;
}
// look up the DomCode in the table because we can't trust the
// WebKeyboardEvent as it came from the renderer.
return new TranslatedKeyEvent(
type, static_cast<ui::KeyboardCode>(web_event.windows_key_code),
ui::KeycodeConverter::NativeKeycodeToDomCode(web_event.native_key_code),
WebEventModifiersToEventFlags(web_event.GetModifiers()),
web_event.dom_key, web_event.TimeStamp(), is_char);
}
private:
TranslatedKeyEvent(ui::EventType type,
ui::KeyboardCode keyboard_code,
ui::DomCode dom_code,
int flags,
ui::DomKey dom_key,
base::TimeTicks time,
bool is_char)
: KeyEvent(type, keyboard_code, dom_code, flags, dom_key, time) {
set_is_char(is_char);
}
};
} // namespace
using blink::WebKeyboardEvent;
namespace content {
NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type,
int modifiers,
base::TimeTicks timestamp)
: WebKeyboardEvent(type, modifiers, timestamp),
os_event(nullptr),
skip_in_browser(false) {}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(
const blink::WebKeyboardEvent& web_event,
gfx::NativeView native_view)
: WebKeyboardEvent(web_event), os_event(nullptr), skip_in_browser(false) {
os_event = TranslatedKeyEvent::Create(web_event);
}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
: NativeWebKeyboardEvent(static_cast<ui::KeyEvent&>(*native_event)) {
}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event)
: WebKeyboardEvent(ui::MakeWebKeyboardEvent(key_event)),
os_event(CopyEvent(&key_event)),
skip_in_browser(false) {}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(
const NativeWebKeyboardEvent& other)
: WebKeyboardEvent(other),
os_event(CopyEvent(other.os_event)),
skip_in_browser(other.skip_in_browser) {
}
NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event,
base::char16 character)
: WebKeyboardEvent(ui::MakeWebKeyboardEvent(key_event)),
os_event(nullptr),
skip_in_browser(false) {
type_ = blink::WebInputEvent::kChar;
windows_key_code = character;
text[0] = character;
unmodified_text[0] = character;
}
NativeWebKeyboardEvent& NativeWebKeyboardEvent::operator=(
const NativeWebKeyboardEvent& other) {
WebKeyboardEvent::operator=(other);
delete os_event;
os_event = CopyEvent(other.os_event);
skip_in_browser = other.skip_in_browser;
return *this;
}
NativeWebKeyboardEvent::~NativeWebKeyboardEvent() {
delete os_event;
}
} // namespace content