Convert sticky keys to a chromeos::EventRewriter phase.

BUG=354035
TEST=unit_tests,ash_unittests,manual
R=sadrul@chromium.org,derat@chromium.org

Review URL: https://codereview.chromium.org/255033003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278342 0039d316-1c4b-4281-b951-d872f2087c98
parent 0dade4d2
......@@ -889,13 +889,6 @@ void Shell::Init(const ShellInitParams& init_params) {
// The order in which event filters are added is significant.
#if defined(OS_CHROMEOS)
// The StickyKeysController also rewrites events and must be added
// before observers, but after the EventRewriterEventFilter.
sticky_keys_controller_.reset(new StickyKeysController);
AddPreTargetHandler(sticky_keys_controller_.get());
#endif
// wm::UserActivityDetector passes events to observers, so let them get
// rewritten first.
user_activity_detector_.reset(new ::wm::UserActivityDetector);
......@@ -930,6 +923,10 @@ void Shell::Init(const ShellInitParams& init_params) {
keyboard::InitializeKeyboard();
#endif
#if defined(OS_CHROMEOS)
sticky_keys_controller_.reset(new StickyKeysController);
#endif
lock_state_controller_.reset(new LockStateController);
power_button_controller_.reset(new PowerButtonController(
lock_state_controller_.get()));
......
This diff is collapsed.
This diff is collapsed.
......@@ -7,47 +7,14 @@
#include "ash/shell.h"
#include "ash/sticky_keys/sticky_keys_controller.h"
#include "ash/test/ash_test_base.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event.h"
#include "ui/events/event_processor.h"
namespace ash {
class StickyKeysOverlayTest : public test::AshTestBase {
public:
StickyKeysOverlayTest() :
controller_(NULL),
overlay_(NULL) {}
StickyKeysOverlayTest() {}
virtual ~StickyKeysOverlayTest() {}
virtual void SetUp() OVERRIDE {
test::AshTestBase::SetUp();
controller_ = Shell::GetInstance()->sticky_keys_controller();
controller_->Enable(true);
overlay_ = controller_->GetOverlayForTest();
ASSERT_TRUE(overlay_);
}
void PressAndReleaseKey(ui::KeyboardCode code) {
SendKeyEvent(ui::ET_KEY_PRESSED, code);
SendKeyEvent(ui::ET_KEY_RELEASED, code);
}
void SendKeyEvent(ui::EventType type, ui::KeyboardCode code) {
ui::KeyEvent event(type, code, 0, false);
ui::Event::DispatcherApi dispatcher(&event);
dispatcher.set_target(Shell::GetInstance()->GetPrimaryRootWindow());
ui::EventDispatchDetails details = Shell::GetPrimaryRootWindow()->
GetHost()->event_processor()->OnEventFromSource(&event);
CHECK(!details.dispatcher_destroyed);
}
StickyKeysController* controller_;
StickyKeysOverlay* overlay_;
};
TEST_F(StickyKeysOverlayTest, OverlayVisibility) {
......@@ -71,168 +38,7 @@ TEST_F(StickyKeysOverlayTest, ModifierKeyState) {
overlay.GetModifierKeyState(ui::EF_CONTROL_DOWN));
}
TEST_F(StickyKeysOverlayTest, OneModifierEnabled) {
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
// Pressing modifier key should show overlay.
PressAndReleaseKey(ui::VKEY_CONTROL);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
// Pressing a normal key should hide overlay.
PressAndReleaseKey(ui::VKEY_T);
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
}
TEST_F(StickyKeysOverlayTest, TwoModifiersEnabled) {
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
// Pressing two modifiers should show overlay.
PressAndReleaseKey(ui::VKEY_SHIFT);
PressAndReleaseKey(ui::VKEY_CONTROL);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_ENABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
// Pressing a normal key should hide overlay.
PressAndReleaseKey(ui::VKEY_N);
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
}
TEST_F(StickyKeysOverlayTest, LockedModifier) {
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
// Pressing a modifier key twice should lock modifier and show overlay.
PressAndReleaseKey(ui::VKEY_LMENU);
PressAndReleaseKey(ui::VKEY_LMENU);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED,
overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
// Pressing a normal key should not hide overlay.
PressAndReleaseKey(ui::VKEY_D);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED,
overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
}
TEST_F(StickyKeysOverlayTest, LockedAndNormalModifier) {
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
// Pressing a modifier key twice should lock modifier and show overlay.
PressAndReleaseKey(ui::VKEY_CONTROL);
PressAndReleaseKey(ui::VKEY_CONTROL);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
// Pressing another modifier key should still show overlay.
PressAndReleaseKey(ui::VKEY_SHIFT);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_ENABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
// Pressing a normal key should not hide overlay but disable normal modifier.
PressAndReleaseKey(ui::VKEY_D);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
}
TEST_F(StickyKeysOverlayTest, ModifiersDisabled) {
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
// Enable modifiers.
PressAndReleaseKey(ui::VKEY_CONTROL);
PressAndReleaseKey(ui::VKEY_SHIFT);
PressAndReleaseKey(ui::VKEY_SHIFT);
PressAndReleaseKey(ui::VKEY_LMENU);
EXPECT_TRUE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_LOCKED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_ENABLED,
overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
// Disable modifiers and overlay should be hidden.
PressAndReleaseKey(ui::VKEY_CONTROL);
PressAndReleaseKey(ui::VKEY_CONTROL);
PressAndReleaseKey(ui::VKEY_SHIFT);
PressAndReleaseKey(ui::VKEY_LMENU);
PressAndReleaseKey(ui::VKEY_LMENU);
EXPECT_FALSE(overlay_->is_visible());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_CONTROL_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_SHIFT_DOWN));
EXPECT_EQ(STICKY_KEY_STATE_DISABLED,
overlay_->GetModifierKeyState(ui::EF_ALT_DOWN));
}
TEST_F(StickyKeysOverlayTest, ModifierVisibility) {
// All but AltGr and Mod3 should initially be visible.
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN));
EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
// Turn all modifiers on.
controller_->SetModifiersEnabled(true, true);
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_CONTROL_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_SHIFT_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALT_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
// Turn off Mod3.
controller_->SetModifiersEnabled(false, true);
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
// Turn off AltGr.
controller_->SetModifiersEnabled(true, false);
EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
EXPECT_TRUE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
// Turn off AltGr and Mod3.
controller_->SetModifiersEnabled(false, false);
EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_ALTGR_DOWN));
EXPECT_FALSE(overlay_->GetModifierVisible(ui::EF_MOD3_DOWN));
}
// Additional sticky key overlay tests that depend on chromeos::EventRewriter
// are now in chrome/browser/chromeos/events/event_rewriter_unittest.cc .
} // namespace ash
This diff is collapsed.
......@@ -730,11 +730,6 @@ void ChromeBrowserMainPartsChromeos::PreBrowserStart() {
// Start the CrOS input device UMA watcher
DeviceUMA::GetInstance();
#endif
keyboard_event_rewriters_.reset(new EventRewriterController());
keyboard_event_rewriters_->AddEventRewriter(
scoped_ptr<ui::EventRewriter>(new KeyboardDrivenEventRewriter()));
keyboard_event_rewriters_->AddEventRewriter(
scoped_ptr<ui::EventRewriter>(new EventRewriter()));
// -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
// -- immediately after ChildProcess::WaitForDebugger().
......@@ -757,7 +752,13 @@ void ChromeBrowserMainPartsChromeos::PostBrowserStart() {
// These are dependent on the ash::Shell singleton already having been
// initialized.
power_button_observer_.reset(new PowerButtonObserver);
data_promo_notification_.reset(new DataPromoNotification()),
data_promo_notification_.reset(new DataPromoNotification());
keyboard_event_rewriters_.reset(new EventRewriterController());
keyboard_event_rewriters_->AddEventRewriter(
scoped_ptr<ui::EventRewriter>(new KeyboardDrivenEventRewriter()));
keyboard_event_rewriters_->AddEventRewriter(scoped_ptr<ui::EventRewriter>(
new EventRewriter(ash::Shell::GetInstance()->sticky_keys_controller())));
keyboard_event_rewriters_->Init();
ChromeBrowserMainPartsLinux::PostBrowserStart();
......
......@@ -6,10 +6,12 @@
#include <vector>
#include "ash/sticky_keys/sticky_keys_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
#include "base/sys_info.h"
......@@ -153,12 +155,24 @@ void UpdateX11EventMask(int ui_flags, unsigned int* x_flags) {
}
#endif
bool IsSendEvent(const ui::Event& event) {
#if defined(USE_X11)
// Do not rewrite an event sent by ui_controls::SendKeyPress(). See
// crbug.com/136465.
XEvent* xev = event.native_event();
if (xev && xev->xany.send_event)
return true;
#endif
return false;
}
} // namespace
EventRewriter::EventRewriter()
EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller)
: last_device_id_(kBadDeviceId),
ime_keyboard_for_testing_(NULL),
pref_service_for_testing_(NULL) {
pref_service_for_testing_(NULL),
sticky_keys_controller_(sticky_keys_controller) {
#if defined(USE_X11)
ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
if (base::SysInfo::IsRunningOnChromeOS()) {
......@@ -190,35 +204,38 @@ void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event,
ui::EventRewriteStatus EventRewriter::RewriteEvent(
const ui::Event& event,
scoped_ptr<ui::Event>* rewritten_event) {
#if defined(USE_X11)
// Do not rewrite an event sent by ui_controls::SendKeyPress(). See
// crbug.com/136465.
XEvent* xev = event.native_event();
if (xev && xev->xany.send_event)
return ui::EVENT_REWRITE_CONTINUE;
#endif
switch (event.type()) {
case ui::ET_KEY_PRESSED:
case ui::ET_KEY_RELEASED:
return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event),
if ((event.type() == ui::ET_KEY_PRESSED) ||
(event.type() == ui::ET_KEY_RELEASED)) {
return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event),
rewritten_event);
}
if (event.IsMouseEvent()) {
return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event),
rewritten_event);
case ui::ET_MOUSE_PRESSED:
case ui::ET_MOUSE_RELEASED:
return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event),
rewritten_event);
case ui::ET_TOUCH_PRESSED:
case ui::ET_TOUCH_RELEASED:
return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event),
rewritten_event);
default:
return ui::EVENT_REWRITE_CONTINUE;
}
NOTREACHED();
if ((event.type() == ui::ET_TOUCH_PRESSED) ||
(event.type() == ui::ET_TOUCH_RELEASED)) {
return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event),
rewritten_event);
}
if (event.IsScrollEvent()) {
return RewriteScrollEvent(static_cast<const ui::ScrollEvent&>(event),
rewritten_event);
}
return ui::EVENT_REWRITE_CONTINUE;
}
ui::EventRewriteStatus EventRewriter::NextDispatchEvent(
const ui::Event& last_event,
scoped_ptr<ui::Event>* new_event) {
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
// know that they don't have to be passed through the post-sticky key
// rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|,
// because those phases do nothing with modifier key releases.
return sticky_keys_controller_->NextDispatchEvent(new_event);
}
NOTREACHED();
return ui::EVENT_REWRITE_CONTINUE;
}
......@@ -333,14 +350,33 @@ ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
const ui::KeyEvent& key_event,
scoped_ptr<ui::Event>* rewritten_event) {
MutableKeyState state = {key_event.flags(), key_event.key_code()};
RewriteModifierKeys(key_event, &state);
RewriteNumPadKeys(key_event, &state);
RewriteExtendedKeys(key_event, &state);
RewriteFunctionKeys(key_event, &state);
bool is_send_event = IsSendEvent(key_event);
if (!is_send_event) {
RewriteModifierKeys(key_event, &state);
RewriteNumPadKeys(key_event, &state);
}
ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
if (sticky_keys_controller_) {
status = sticky_keys_controller_->RewriteKeyEvent(
key_event, state.key_code, &state.flags);
if (status == ui::EVENT_REWRITE_DISCARD)
return ui::EVENT_REWRITE_DISCARD;
}
if (!is_send_event) {
RewriteExtendedKeys(key_event, &state);
RewriteFunctionKeys(key_event, &state);
}
if ((key_event.flags() == state.flags) &&
(key_event.key_code() == state.key_code)) {
(key_event.key_code() == state.key_code) &&
(status == ui::EVENT_REWRITE_CONTINUE)) {
return ui::EVENT_REWRITE_CONTINUE;
}
// Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|,
// in which case we need to preserve that return status. Alternatively, we
// might be here because key_event changed, in which case we need to return
// |EVENT_REWRITE_REWRITTEN|.
if (status == ui::EVENT_REWRITE_CONTINUE)
status = ui::EVENT_REWRITE_REWRITTEN;
ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event);
rewritten_event->reset(rewritten_key_event);
rewritten_key_event->set_flags(state.flags);
......@@ -360,16 +396,26 @@ ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
state.key_code, state.flags & ui::EF_SHIFT_DOWN));
}
#endif
return ui::EVENT_REWRITE_REWRITTEN;
return status;
}
ui::EventRewriteStatus EventRewriter::RewriteMouseEvent(
const ui::MouseEvent& mouse_event,
scoped_ptr<ui::Event>* rewritten_event) {
int flags = mouse_event.flags();
RewriteLocatedEvent(mouse_event, &flags);
if (mouse_event.flags() == flags)
if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) ||
(mouse_event.type() == ui::ET_MOUSE_RELEASED)) {
RewriteLocatedEvent(mouse_event, &flags);
}
ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
if (sticky_keys_controller_)
status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags);
if ((mouse_event.flags() == flags) &&
(status == ui::EVENT_REWRITE_CONTINUE)) {
return ui::EVENT_REWRITE_CONTINUE;
}
if (status == ui::EVENT_REWRITE_CONTINUE)
status = ui::EVENT_REWRITE_REWRITTEN;
ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event);
rewritten_event->reset(rewritten_mouse_event);
rewritten_mouse_event->set_flags(flags);
......@@ -397,7 +443,7 @@ ui::EventRewriteStatus EventRewriter::RewriteMouseEvent(
}
}
#endif
return ui::EVENT_REWRITE_REWRITTEN;
return status;
}
ui::EventRewriteStatus EventRewriter::RewriteTouchEvent(
......@@ -424,6 +470,32 @@ ui::EventRewriteStatus EventRewriter::RewriteTouchEvent(
return ui::EVENT_REWRITE_REWRITTEN;
}
ui::EventRewriteStatus EventRewriter::RewriteScrollEvent(
const ui::ScrollEvent& scroll_event,
scoped_ptr<ui::Event>* rewritten_event) {
int flags = scroll_event.flags();
ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
if (sticky_keys_controller_)
status = sticky_keys_controller_->RewriteScrollEvent(scroll_event, &flags);
if (status == ui::EVENT_REWRITE_CONTINUE)
return status;
ui::ScrollEvent* rewritten_scroll_event = new ui::ScrollEvent(scroll_event);
rewritten_event->reset(rewritten_scroll_event);
rewritten_scroll_event->set_flags(flags);
#if defined(USE_X11)
XEvent* xev = rewritten_scroll_event->native_event();
if (xev) {
XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
if (xievent) {
UpdateX11EventMask(
rewritten_scroll_event->flags(),
reinterpret_cast<unsigned int*>(&xievent->mods.effective));
}
}
#endif
return status;
}
void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event,
MutableKeyState* state) {
DCHECK(key_event.type() == ui::ET_KEY_PRESSED ||
......
......@@ -23,6 +23,10 @@ typedef union _XEvent XEvent;
class PrefService;
namespace ash {
class StickyKeysController;
}
namespace chromeos {
namespace input_method {
class ImeKeyboard;
......@@ -51,7 +55,10 @@ class EventRewriter
kDeviceAppleKeyboard,
};
EventRewriter();
// Does not take ownership of the |sticky_keys_controller|, which may also
// be NULL (for testing without ash), in which case sticky key operations
// don't happen.
explicit EventRewriter(ash::StickyKeysController* sticky_keys_controller);
virtual ~EventRewriter();
// Calls DeviceAddedInternal.
......@@ -98,7 +105,7 @@ class EventRewriter
#endif
private:
// Things that internal rewriter phases can change about an Event.
// Things that keyboard-related rewriter phases can change about an Event.
struct MutableKeyState {
int flags;
ui::KeyboardCode key_code;
......@@ -157,6 +164,9 @@ class EventRewriter
ui::EventRewriteStatus RewriteTouchEvent(
const ui::TouchEvent& touch_event,
scoped_ptr<ui::Event>* rewritten_event);
ui::EventRewriteStatus RewriteScrollEvent(
const ui::ScrollEvent& scroll_event,
scoped_ptr<ui::Event>* rewritten_event);
// Rewriter phases. These can inspect the original |event|, but operate using
// the current |state|, which may have been modified by previous phases.
......@@ -175,6 +185,10 @@ class EventRewriter
chromeos::input_method::ImeKeyboard* ime_keyboard_for_testing_;
const PrefService* pref_service_for_testing_;
// The sticky keys controller is not owned here;
// at time of writing it is a singleton in ash::Shell>
ash::StickyKeysController* sticky_keys_controller_;
DISALLOW_COPY_AND_ASSIGN(EventRewriter);
};
......
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