Commit 531197df authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Fix the bug that Launcher is triggered unexpectedly

The key code which is created by KeyEvent rewriting is stored
in AcceleratorHistory when the key button is pressed. However,
there is no code responsible for removing it when the key button
is released. Instead only the key code before KeyEvent rewriting
is erased. As result, the accelerators relying on the state of
AcceleratorHistory often have unexpected behavior when KeyEvent
rewriting is triggered (The comment under this issue gives detailed
explanation).

In this CL, EventRewriterChromeOS stores the pressed keys. Based on
it, EventRewriterChromeOS computes the rewritten event and the rewritten
status. In addition, the test on edge cases is added.

Bug: 913209
Test: unit_tests
Change-Id: Ie22fe2ba8a2bd296628032723acc721db2616a77
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1477959Reviewed-by: default avatarKevin Schoedel <kpschoedel@chromium.org>
Reviewed-by: default avatarWez <wez@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638756}
parent 64bf9fd3
......@@ -1038,13 +1038,12 @@ TEST_F(EventRewriterTest, TestRewriteModifiersRemapToEscape) {
CheckKeyTestCase(rewriter_, test);
}
TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
TEST_F(EventRewriterTest, TestRewriteModifiersRemapEscapeToAlt) {
// Remap Escape to Alt.
chromeos::Preferences::RegisterProfilePrefs(prefs()->registry());
IntegerPrefMember escape;
InitModifierKeyPref(&escape, prefs::kLanguageRemapEscapeKeyTo,
ui::chromeos::ModifierKey::kAltKey);
rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
KeyTestCase e2a_tests[] = {
......@@ -1061,13 +1060,17 @@ TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
for (const auto& test : e2a_tests)
CheckKeyTestCase(rewriter_, test);
}
TEST_F(EventRewriterTest, TestRewriteModifiersRemapAltToControl) {
// Remap Alt to Control.
chromeos::Preferences::RegisterProfilePrefs(prefs()->registry());
IntegerPrefMember alt;
InitModifierKeyPref(&alt, prefs::kLanguageRemapAltKeyTo,
ui::chromeos::ModifierKey::kControlKey);
rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
KeyTestCase a2c_tests[] = {
std::vector<KeyTestCase> a2c_tests = {
// Press left Alt. Confirm the event is now VKEY_CONTROL.
{ui::ET_KEY_PRESSED,
{ui::VKEY_MENU, ui::DomCode::ALT_LEFT, ui::EF_ALT_DOWN, ui::DomKey::ALT},
......@@ -1091,13 +1094,29 @@ TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
for (const auto& test : a2c_tests)
CheckKeyTestCase(rewriter_, test);
}
TEST_F(EventRewriterTest, TestRewriteModifiersRemapUnderEscapeControlAlt) {
chromeos::Preferences::RegisterProfilePrefs(prefs()->registry());
// Remap Escape to Alt.
IntegerPrefMember escape;
InitModifierKeyPref(&escape, prefs::kLanguageRemapEscapeKeyTo,
ui::chromeos::ModifierKey::kAltKey);
// Remap Alt to Control.
IntegerPrefMember alt;
InitModifierKeyPref(&alt, prefs::kLanguageRemapAltKeyTo,
ui::chromeos::ModifierKey::kControlKey);
// Remap Control to Search.
IntegerPrefMember control;
InitModifierKeyPref(&control, prefs::kLanguageRemapControlKeyTo,
ui::chromeos::ModifierKey::kSearchKey);
KeyTestCase c2s_tests[] = {
rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
std::vector<KeyTestCase> c2s_tests = {
// Press left Control. Confirm the event is now VKEY_LWIN.
{ui::ET_KEY_PRESSED,
{ui::VKEY_CONTROL, ui::DomCode::CONTROL_LEFT, ui::EF_CONTROL_DOWN,
......@@ -1136,15 +1155,46 @@ TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
for (const auto& test : c2s_tests)
CheckKeyTestCase(rewriter_, test);
}
TEST_F(EventRewriterTest,
TestRewriteModifiersRemapUnderEscapeControlAltSearch) {
chromeos::Preferences::RegisterProfilePrefs(prefs()->registry());
// Remap Escape to Alt.
IntegerPrefMember escape;
InitModifierKeyPref(&escape, prefs::kLanguageRemapEscapeKeyTo,
ui::chromeos::ModifierKey::kAltKey);
// Remap Alt to Control.
IntegerPrefMember alt;
InitModifierKeyPref(&alt, prefs::kLanguageRemapAltKeyTo,
ui::chromeos::ModifierKey::kControlKey);
// Remap Control to Search.
IntegerPrefMember control;
InitModifierKeyPref(&control, prefs::kLanguageRemapControlKeyTo,
ui::chromeos::ModifierKey::kSearchKey);
// Remap Search to Backspace.
IntegerPrefMember search;
InitModifierKeyPref(&search, prefs::kLanguageRemapSearchKeyTo,
ui::chromeos::ModifierKey::kBackspaceKey);
KeyTestCase s2b_tests[] = {
rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
std::vector<KeyTestCase> s2b_tests = {
// Release Control and Escape, as Search and Alt would transform Backspace
// to Delete.
{ui::ET_KEY_PRESSED,
{ui::VKEY_CONTROL, ui::DomCode::CONTROL_LEFT, ui::EF_NONE,
ui::DomKey::CONTROL},
{ui::VKEY_LWIN, ui::DomCode::META_LEFT, ui::EF_COMMAND_DOWN,
ui::DomKey::META}},
{ui::ET_KEY_PRESSED,
{ui::VKEY_ESCAPE, ui::DomCode::ESCAPE, ui::EF_NONE, ui::DomKey::ESCAPE},
{ui::VKEY_MENU, ui::DomCode::ALT_LEFT, ui::EF_ALT_DOWN,
ui::DomKey::ALT}},
{ui::ET_KEY_RELEASED,
{ui::VKEY_CONTROL, ui::DomCode::CONTROL_LEFT, ui::EF_NONE,
ui::DomKey::CONTROL},
......@@ -1163,13 +1213,18 @@ TEST_F(EventRewriterTest, TestRewriteModifiersRemapMany) {
for (const auto& test : s2b_tests)
CheckKeyTestCase(rewriter_, test);
}
TEST_F(EventRewriterTest, TestRewriteModifiersRemapBackspaceToEscape) {
// Remap Backspace to Escape.
chromeos::Preferences::RegisterProfilePrefs(prefs()->registry());
IntegerPrefMember backspace;
InitModifierKeyPref(&backspace, prefs::kLanguageRemapBackspaceKeyTo,
ui::chromeos::ModifierKey::kEscapeKey);
KeyTestCase b2e_tests[] = {
rewriter_->KeyboardDeviceAddedForTesting(kKeyboardDeviceId, "PC Keyboard");
std::vector<KeyTestCase> b2e_tests = {
// Press Backspace. Confirm the event is now VKEY_ESCAPE.
{ui::ET_KEY_PRESSED,
{ui::VKEY_BACK, ui::DomCode::BACKSPACE, ui::EF_NONE,
......@@ -2156,8 +2211,15 @@ class EventRewriterAshTest : public ChromeAshTestBase {
ui::KeyboardCode key_code,
ui::DomCode code,
ui::DomKey key) {
ui::KeyEvent press(type, key_code, code, ui::EF_NONE, key,
ui::EventTimeForNow());
SendKeyEvent(type, key_code, code, key, ui::EF_NONE);
}
void SendKeyEvent(ui::EventType type,
ui::KeyboardCode key_code,
ui::DomCode code,
ui::DomKey key,
int flags) {
ui::KeyEvent press(type, key_code, code, flags, key, ui::EventTimeForNow());
ui::EventDispatchDetails details = Send(&press);
CHECK(!details.dispatcher_destroyed);
}
......@@ -2533,6 +2595,55 @@ TEST_F(EventRewriterAshTest, MouseWheelEventModifiersRewritten) {
EXPECT_TRUE(events[0]->flags() & ui::EF_ALT_DOWN);
}
// Tests edge cases of key event rewriting (see https://crbug.com/913209).
TEST_F(EventRewriterAshTest, KeyEventRewritingEdgeCases) {
std::vector<std::unique_ptr<ui::Event>> events;
// Edge case 1: Press the Launcher button first. Then press the Up Arrow
// button.
SendKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_COMMAND, ui::DomCode::META_LEFT,
ui::DomKey::META);
SendKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::DomCode::ARROW_UP,
ui::DomKey::ARROW_UP, ui::EF_COMMAND_DOWN);
PopEvents(&events);
EXPECT_EQ(2u, events.size());
events.clear();
SendKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_COMMAND, ui::DomCode::META_LEFT,
ui::DomKey::META);
PopEvents(&events);
// When releasing the Launcher button, the rewritten event should be released
// as well.
EXPECT_EQ(2u, events.size());
EXPECT_EQ(ui::VKEY_COMMAND,
static_cast<ui::KeyEvent*>(events[0].get())->key_code());
EXPECT_EQ(ui::VKEY_PRIOR,
static_cast<ui::KeyEvent*>(events[1].get())->key_code());
events.clear();
// Edge case 2: Press the Up Arrow button first. Then press the Launch button.
SendKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::DomCode::ARROW_UP,
ui::DomKey::ARROW_UP);
SendKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_COMMAND, ui::DomCode::META_LEFT,
ui::DomKey::META);
PopEvents(&events);
EXPECT_EQ(2u, events.size());
events.clear();
SendKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_UP, ui::DomCode::ARROW_UP,
ui::DomKey::ARROW_UP, ui::EF_COMMAND_DOWN);
PopEvents(&events);
// When releasing the Up Arrow button, the rewritten event should be blocked.
EXPECT_EQ(1u, events.size());
EXPECT_EQ(ui::VKEY_UP,
static_cast<ui::KeyEvent*>(events[0].get())->key_code());
}
class StickyKeysOverlayTest : public EventRewriterAshTest {
public:
StickyKeysOverlayTest() : overlay_(NULL) {}
......
......@@ -285,6 +285,30 @@ bool GetDeviceProperty(const base::FilePath& device_path,
} // namespace
///////////////////////////////////////////////////////////////////////////////
EventRewriterChromeOS::MutableKeyState::MutableKeyState()
: MutableKeyState(0, ui::DomCode::NONE, 0, ui::KeyboardCode::VKEY_NONAME) {}
EventRewriterChromeOS::MutableKeyState::MutableKeyState(
const ui::KeyEvent* key_event)
: MutableKeyState(key_event->flags(),
key_event->code(),
key_event->GetDomKey(),
key_event->key_code()) {}
EventRewriterChromeOS::MutableKeyState::MutableKeyState(
int input_flags,
ui::DomCode input_code,
ui::DomKey::Base input_key,
ui::KeyboardCode input_key_code)
: flags(input_flags),
code(input_code),
key(input_key),
key_code(input_key_code) {}
///////////////////////////////////////////////////////////////////////////////
EventRewriterChromeOS::EventRewriterChromeOS(
Delegate* delegate,
ui::EventRewriter* sticky_keys_controller)
......@@ -365,8 +389,11 @@ ui::EventRewriteStatus EventRewriterChromeOS::RewriteEvent(
std::unique_ptr<ui::Event>* rewritten_event) {
if ((event.type() == ui::ET_KEY_PRESSED) ||
(event.type() == ui::ET_KEY_RELEASED)) {
return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event),
rewritten_event);
ui::EventRewriteStatus status =
RewriteKeyEvent(*((&event)->AsKeyEvent()), rewritten_event);
RewriteKeyEventInContext(*((&event)->AsKeyEvent()), rewritten_event,
&status);
return status;
}
if ((event.type() == ui::ET_MOUSE_PRESSED) ||
(event.type() == ui::ET_MOUSE_RELEASED)) {
......@@ -392,6 +419,15 @@ ui::EventRewriteStatus EventRewriterChromeOS::RewriteEvent(
ui::EventRewriteStatus EventRewriterChromeOS::NextDispatchEvent(
const ui::Event& last_event,
std::unique_ptr<ui::Event>* new_event) {
if (dispatched_key_events_.size()) {
*new_event = std::move(dispatched_key_events_.back());
dispatched_key_events_.pop_back();
if (dispatched_key_events_.size())
return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
return ui::EVENT_REWRITE_REWRITTEN;
}
if (sticky_keys_controller_) {
// In the case of sticky keys, we know what the events obtained here are:
// modifier key releases that match the ones previously discarded. So, we
......@@ -1220,6 +1256,123 @@ int EventRewriterChromeOS::RewriteModifierClick(
return ui::EF_NONE;
}
void EventRewriterChromeOS::RewriteKeyEventInContext(
const ui::KeyEvent& key_event,
std::unique_ptr<ui::Event>* rewritten_event,
ui::EventRewriteStatus* status) {
DCHECK(status);
if (*status == EventRewriteStatus::EVENT_REWRITE_DISCARD)
return;
MutableKeyState current_key_state;
auto key_state_comparator =
[&current_key_state](
const std::pair<MutableKeyState, MutableKeyState>& key_state) {
return (current_key_state.code == key_state.first.code) &&
(current_key_state.key == key_state.first.key) &&
(current_key_state.key_code == key_state.first.key_code);
};
const int mapped_flag = ModifierDomKeyToEventFlag(key_event.GetDomKey());
if (key_event.type() == ET_KEY_PRESSED) {
current_key_state = MutableKeyState(
rewritten_event->get()
? static_cast<const ui::KeyEvent*>(rewritten_event->get())
: &key_event);
MutableKeyState original_key_state(&key_event);
auto iter = std::find_if(pressed_key_states_.begin(),
pressed_key_states_.end(), key_state_comparator);
// When a key is pressed, store |current_key_state| if it is not stored
// before.
if (iter == pressed_key_states_.end()) {
pressed_key_states_.push_back(
std::make_pair(current_key_state, original_key_state));
}
return;
}
DCHECK_EQ(key_event.type(), ET_KEY_RELEASED);
if (mapped_flag != EF_NONE) {
// The released key is a modifier
DomKey::Base current_key = key_event.GetDomKey();
auto key_state_iter = pressed_key_states_.begin();
int event_flags = rewritten_event->get() ? (*rewritten_event)->flags()
: key_event.flags();
rewritten_event->reset();
// Iterate the keys being pressed. Release the key events which satisfy one
// of the following conditions:
// (1) the key event's original key code (before key event rewriting if
// any) is the same with the key to be released.
// (2) the key event is rewritten and its original flags are influenced by
// the key to be released.
// Example: Press the Launcher button, Press the Up Arrow button, Release
// the Launcher button. When Launcher is released: the key event whose key
// code is Launcher should be released because it satisfies the condition 1;
// the key event whose key code is PageUp should be released because it
// satisfies the condition 2.
while (key_state_iter != pressed_key_states_.end()) {
const bool is_rewritten =
(key_state_iter->first.key != key_state_iter->second.key);
const bool flag_affected = key_state_iter->second.flags & mapped_flag;
const bool should_release = key_state_iter->second.key == current_key ||
(flag_affected && is_rewritten);
if (should_release) {
// If the key should be released, create a key event for it.
std::unique_ptr<ui::KeyEvent> dispatched_event =
std::make_unique<ui::KeyEvent>(
key_event.type(), key_state_iter->first.key_code,
key_state_iter->first.code, event_flags,
key_state_iter->first.key, key_event.time_stamp());
if (!rewritten_event->get())
*rewritten_event = std::move(dispatched_event);
else
dispatched_key_events_.push_back(std::move(dispatched_event));
key_state_iter = pressed_key_states_.erase(key_state_iter);
continue;
}
key_state_iter++;
}
if (dispatched_key_events_.empty()) {
*status = rewritten_event->get()
? EventRewriteStatus::EVENT_REWRITE_REWRITTEN
: EventRewriteStatus::EVENT_REWRITE_DISCARD;
} else {
*status = EventRewriteStatus::EVENT_REWRITE_DISPATCH_ANOTHER;
}
} else {
// The released key is not a modifier
current_key_state = MutableKeyState(
rewritten_event->get()
? static_cast<const ui::KeyEvent*>(rewritten_event->get())
: &key_event);
auto iter = std::find_if(pressed_key_states_.begin(),
pressed_key_states_.end(), key_state_comparator);
if (iter != pressed_key_states_.end()) {
pressed_key_states_.erase(iter);
} else {
// Event rewriting may create a meaningless key event.
// For example: press the Up Arrow button, press the Launcher button,
// release the Up Arrow. When the Up Arrow button is released, key event
// rewriting happens. However, the rewritten event is not among
// |pressed_key_states_|. So it should be blocked and the original event
// should be propagated.
rewritten_event->reset();
*status = EventRewriteStatus::EVENT_REWRITE_CONTINUE;
}
}
}
void EventRewriterChromeOS::KeyboardDeviceAddedInternal(
int device_id,
DeviceType type,
......
......@@ -5,10 +5,13 @@
#ifndef UI_CHROMEOS_EVENTS_EVENT_REWRITER_CHROMEOS_H_
#define UI_CHROMEOS_EVENTS_EVENT_REWRITER_CHROMEOS_H_
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/files/file_path.h"
#include "base/macros.h"
......@@ -64,6 +67,13 @@ class EventRewriterChromeOS : public ui::EventRewriter {
// Things that keyboard-related rewriter phases can change about an Event.
struct MutableKeyState {
MutableKeyState();
explicit MutableKeyState(const ui::KeyEvent* key_event);
MutableKeyState(int input_flags,
ui::DomCode input_code,
ui::DomKey::Base input_key,
ui::KeyboardCode input_key_code);
int flags;
ui::DomCode code;
ui::DomKey::Base key;
......@@ -215,6 +225,13 @@ class EventRewriterChromeOS : public ui::EventRewriter {
void RewriteLocatedEvent(const ui::Event& event, int* flags);
int RewriteModifierClick(const ui::MouseEvent& event, int* flags);
// Take the keys being pressed into consideration, in contrast to
// RewriteKeyEvent which computes the rewritten event and event rewrite status
// in stateless way.
void RewriteKeyEventInContext(const ui::KeyEvent& event,
std::unique_ptr<ui::Event>* rewritten_event,
ui::EventRewriteStatus* status);
// A set of device IDs whose press event has been rewritten.
// This is to ensure that press and release events are rewritten consistently.
std::set<int> pressed_device_ids_;
......@@ -229,6 +246,14 @@ class EventRewriterChromeOS : public ui::EventRewriter {
Delegate* const delegate_;
// For each pair, the first element is the rewritten key state and the second
// one is the original key state. If no key event rewriting happens, the first
// element and the second element are identical.
std::list<std::pair<MutableKeyState, MutableKeyState>> pressed_key_states_;
// Store key events when there are more than one key events to be dispatched.
std::vector<std::unique_ptr<ui::KeyEvent>> dispatched_key_events_;
// The sticky keys controller is not owned here;
// at time of writing it is a singleton in ash::Shell.
ui::EventRewriter* const sticky_keys_controller_;
......
......@@ -263,4 +263,34 @@ KeyboardCode DomCodeToUsLayoutNonLocatedKeyboardCode(DomCode dom_code) {
DomCodeToUsLayoutKeyboardCode(dom_code));
}
int ModifierDomKeyToEventFlag(DomKey key) {
switch (key) {
case DomKey::ALT:
return EF_ALT_DOWN;
case DomKey::ALT_GRAPH:
return EF_ALTGR_DOWN;
case DomKey::CAPS_LOCK:
return EF_CAPS_LOCK_ON;
case DomKey::CONTROL:
return EF_CONTROL_DOWN;
case DomKey::META:
return EF_COMMAND_DOWN;
case DomKey::SHIFT:
return EF_SHIFT_DOWN;
case DomKey::SHIFT_LEVEL5:
return EF_MOD3_DOWN;
default:
return EF_NONE;
}
// Not represented:
// DomKey::ACCEL
// DomKey::FN
// DomKey::FN_LOCK
// DomKey::HYPER
// DomKey::NUM_LOCK
// DomKey::SCROLL_LOCK
// DomKey::SUPER
// DomKey::SYMBOL_LOCK
}
} // namespace ui
......@@ -107,6 +107,10 @@ EVENTS_BASE_EXPORT KeyboardCode DomCodeToUsLayoutKeyboardCode(DomCode dom_code);
EVENTS_BASE_EXPORT KeyboardCode
DomCodeToUsLayoutNonLocatedKeyboardCode(DomCode dom_code);
// Returns the ui::EventFlags value associated with a modifier key,
// or 0 (EF_NONE) if the key is not a modifier.
EVENTS_BASE_EXPORT int ModifierDomKeyToEventFlag(DomKey key);
} // namespace ui
#endif // UI_EVENTS_KEYCODES_KEYBOARD_CODE_CONVERSION_H_
......@@ -188,8 +188,6 @@ component("events_ozone_layout") {
"layout/keyboard_layout_engine.h",
"layout/keyboard_layout_engine_manager.cc",
"layout/keyboard_layout_engine_manager.h",
"layout/layout_util.cc",
"layout/layout_util.h",
"layout/no/no_keyboard_layout_engine.cc",
"layout/no/no_keyboard_layout_engine.h",
"layout/stub/stub_keyboard_layout_engine.cc",
......
......@@ -12,10 +12,10 @@
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/ozone/evdev/keyboard_util_evdev.h"
#include "ui/events/ozone/layout/keyboard_layout_engine.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/layout_util.h"
namespace ui {
......
// Copyright 2014 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 "ui/events/ozone/layout/layout_util.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_key.h"
namespace ui {
int ModifierDomKeyToEventFlag(DomKey key) {
switch (key) {
case DomKey::ALT:
return EF_ALT_DOWN;
case DomKey::ALT_GRAPH:
return EF_ALTGR_DOWN;
case DomKey::CAPS_LOCK:
return EF_CAPS_LOCK_ON;
case DomKey::CONTROL:
return EF_CONTROL_DOWN;
case DomKey::META:
return EF_COMMAND_DOWN;
case DomKey::SHIFT:
return EF_SHIFT_DOWN;
case DomKey::SHIFT_LEVEL5:
return EF_MOD3_DOWN;
default:
return EF_NONE;
}
// Not represented:
// DomKey::ACCEL
// DomKey::FN
// DomKey::FN_LOCK
// DomKey::HYPER
// DomKey::NUM_LOCK
// DomKey::SCROLL_LOCK
// DomKey::SUPER
// DomKey::SYMBOL_LOCK
}
} // namespace ui
// Copyright 2014 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.
#ifndef UI_EVENTS_OZONE_LAYOUT_LAYOUT_UTIL_H_
#define UI_EVENTS_OZONE_LAYOUT_LAYOUT_UTIL_H_
// TODO(kpschoedel): consider moving this out of Ozone.
#include "base/strings/string16.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/ozone/layout/events_ozone_layout_export.h"
namespace ui {
// Returns the ui::EventFlags value associated with a modifier key,
// or 0 (EF_NONE) if the key is not a modifier.
EVENTS_OZONE_LAYOUT_EXPORT int ModifierDomKeyToEventFlag(DomKey key);
} // namespace ui
#endif // UI_EVENTS_OZONE_LAYOUT_LAYOUT_UTIL_H_
......@@ -8,7 +8,6 @@
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/ozone/layout/layout_util.h"
namespace ui {
......
......@@ -13,10 +13,10 @@
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/ozone/evdev/keyboard_util_evdev.h"
#include "ui/events/ozone/layout/keyboard_layout_engine.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/layout_util.h"
#include "ui/ozone/platform/wayland/wayland_connection.h"
#include "ui/ozone/platform/wayland/wayland_window.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment