diff options
-rw-r--r-- | ash/accelerators/accelerator_controller_unittest.cc | 18 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_controller.cc | 4 | ||||
-rw-r--r-- | ash/wm/overlay_event_filter.cc | 4 | ||||
-rw-r--r-- | content/shell/browser/shell_platform_data_aura.cc | 14 | ||||
-rw-r--r-- | mojo/examples/launcher/launcher.cc | 14 | ||||
-rw-r--r-- | ui/events/event.cc | 52 | ||||
-rw-r--r-- | ui/events/event.h | 29 | ||||
-rw-r--r-- | ui/keyboard/keyboard_util.cc | 5 | ||||
-rw-r--r-- | ui/wm/core/input_method_event_filter.cc | 39 |
9 files changed, 93 insertions, 86 deletions
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 23d42d9..738c9d3 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc @@ -591,32 +591,38 @@ TEST_F(AcceleratorControllerTest, MAYBE_ProcessOnce) { Shell::GetPrimaryRootWindow()->GetHost()->event_processor(); #if defined(OS_WIN) MSG msg1 = { NULL, WM_KEYDOWN, ui::VKEY_A, 0 }; - ui::TranslatedKeyEvent key_event1(msg1, false); + ui::KeyEvent key_event1(msg1, false); + key_event1.SetTranslated(true); ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1); EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed); MSG msg2 = { NULL, WM_CHAR, L'A', 0 }; - ui::TranslatedKeyEvent key_event2(msg2, true); + ui::KeyEvent key_event2(msg2, true); + key_event2.SetTranslated(true); details = dispatcher->OnEventFromSource(&key_event2); EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed); MSG msg3 = { NULL, WM_KEYUP, ui::VKEY_A, 0 }; - ui::TranslatedKeyEvent key_event3(msg3, false); + ui::KeyEvent key_event3(msg3, false); + key_event3.SetTranslated(true); details = dispatcher->OnEventFromSource(&key_event3); EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed); #elif defined(USE_X11) ui::ScopedXI2Event key_event; key_event.InitKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_A, 0); - ui::TranslatedKeyEvent key_event1(key_event, false); + ui::KeyEvent key_event1(key_event, false); + key_event1.SetTranslated(true); ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&key_event1); EXPECT_TRUE(key_event1.handled() || details.dispatcher_destroyed); - ui::TranslatedKeyEvent key_event2(key_event, true); + ui::KeyEvent key_event2(key_event, true); + key_event2.SetTranslated(true); details = dispatcher->OnEventFromSource(&key_event2); EXPECT_FALSE(key_event2.handled() || details.dispatcher_destroyed); key_event.InitKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_A, 0); - ui::TranslatedKeyEvent key_event3(key_event, false); + ui::KeyEvent key_event3(key_event, false); + key_event3.SetTranslated(true); details = dispatcher->OnEventFromSource(&key_event3); EXPECT_FALSE(key_event3.handled() || details.dispatcher_destroyed); #endif diff --git a/ash/sticky_keys/sticky_keys_controller.cc b/ash/sticky_keys/sticky_keys_controller.cc index a10bb61..53be1fc 100644 --- a/ash/sticky_keys/sticky_keys_controller.cc +++ b/ash/sticky_keys/sticky_keys_controller.cc @@ -181,10 +181,8 @@ bool StickyKeysController::HandleScrollEvent(ui::ScrollEvent* event) { void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) { // Do not consume a translated key event which is generated by an IME. - if (event->type() == ui::ET_TRANSLATED_KEY_PRESS || - event->type() == ui::ET_TRANSLATED_KEY_RELEASE) { + if (event->IsTranslated()) return; - } if (enabled_) { if (HandleKeyEvent(event)) diff --git a/ash/wm/overlay_event_filter.cc b/ash/wm/overlay_event_filter.cc index 6221e5e..cd5a487 100644 --- a/ash/wm/overlay_event_filter.cc +++ b/ash/wm/overlay_event_filter.cc @@ -28,10 +28,8 @@ void OverlayEventFilter::OnKeyEvent(ui::KeyEvent* event) { // ui::VKEY_PROCESSKEY) since the key event is generated in response to a key // press or release before showing the ovelay. This is important not to // confuse key event handling JavaScript code in a page. - if (event->type() == ui::ET_TRANSLATED_KEY_PRESS || - event->type() == ui::ET_TRANSLATED_KEY_RELEASE) { + if (event->IsTranslated()) return; - } if (delegate_ && delegate_->IsCancelingKeyEvent(event)) Cancel(); diff --git a/content/shell/browser/shell_platform_data_aura.cc b/content/shell/browser/shell_platform_data_aura.cc index 33b8073..673fa37 100644 --- a/content/shell/browser/shell_platform_data_aura.cc +++ b/content/shell/browser/shell_platform_data_aura.cc @@ -82,12 +82,9 @@ class MinimalInputEventFilter : public ui::internal::InputMethodDelegate, private: // ui::EventHandler: virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { - const ui::EventType type = event->type(); - if (type == ui::ET_TRANSLATED_KEY_PRESS || - type == ui::ET_TRANSLATED_KEY_RELEASE) { - // The |event| is already handled by this object, change the type of the - // event to ui::ET_KEY_* and pass it to the next filter. - static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent(); + // See the comment in InputMethodEventFilter::OnKeyEvent() for details. + if (event->IsTranslated()) { + event->SetTranslated(false); } else { if (input_method_->DispatchKeyEvent(*event)) event->StopPropagation(); @@ -96,7 +93,10 @@ class MinimalInputEventFilter : public ui::internal::InputMethodDelegate, // ui::internal::InputMethodDelegate: virtual bool DispatchKeyEventPostIME(const ui::KeyEvent& event) OVERRIDE { - ui::TranslatedKeyEvent aura_event(event); + // See the comment in InputMethodEventFilter::DispatchKeyEventPostIME() for + // details. + ui::KeyEvent aura_event(event); + aura_event.SetTranslated(true); ui::EventDispatchDetails details = host_->dispatcher()->OnEventFromSource(&aura_event); return aura_event.handled() || details.dispatcher_destroyed; diff --git a/mojo/examples/launcher/launcher.cc b/mojo/examples/launcher/launcher.cc index f71294b..b1fe4b8 100644 --- a/mojo/examples/launcher/launcher.cc +++ b/mojo/examples/launcher/launcher.cc @@ -82,12 +82,9 @@ class MinimalInputEventFilter : public ui::internal::InputMethodDelegate, private: // ui::EventHandler: virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { - const ui::EventType type = event->type(); - if (type == ui::ET_TRANSLATED_KEY_PRESS || - type == ui::ET_TRANSLATED_KEY_RELEASE) { - // The |event| is already handled by this object, change the type of the - // event to ui::ET_KEY_* and pass it to the next filter. - static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent(); + // See the comment in InputMethodEventFilter::OnKeyEvent() for details. + if (event->IsTranslated()) { + event->SetTranslated(false); } else { if (input_method_->DispatchKeyEvent(*event)) event->StopPropagation(); @@ -96,7 +93,10 @@ class MinimalInputEventFilter : public ui::internal::InputMethodDelegate, // ui::internal::InputMethodDelegate: virtual bool DispatchKeyEventPostIME(const ui::KeyEvent& event) OVERRIDE { - ui::TranslatedKeyEvent aura_event(event); + // See the comment in InputMethodEventFilter::DispatchKeyEventPostIME() for + // details. + ui::KeyEvent aura_event(event); + aura_event.SetTranslated(true); ui::EventDispatchDetails details = root_->GetHost()->dispatcher()->OnEventFromSource(&aura_event); return aura_event.handled() || details.dispatcher_destroyed; diff --git a/ui/events/event.cc b/ui/events/event.cc index 062dfd8..3bbae5e 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc @@ -586,35 +586,33 @@ void KeyEvent::NormalizeFlags() { set_flags(flags() & ~mask); } -//////////////////////////////////////////////////////////////////////////////// -// TranslatedKeyEvent - -TranslatedKeyEvent::TranslatedKeyEvent(const base::NativeEvent& native_event, - bool is_char) - : KeyEvent(native_event, is_char) { - SetType(type() == ET_KEY_PRESSED ? - ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE); -} - -TranslatedKeyEvent::TranslatedKeyEvent(bool is_press, - KeyboardCode key_code, - int flags) - : KeyEvent((is_press ? ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE), - key_code, - flags, - false) { -} - -TranslatedKeyEvent::TranslatedKeyEvent(const KeyEvent& key_event) - : KeyEvent(key_event) { - SetType(type() == ET_KEY_PRESSED ? - ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE); - set_is_char(false); +bool KeyEvent::IsTranslated() const { + switch (type()) { + case ET_KEY_PRESSED: + case ET_KEY_RELEASED: + return false; + case ET_TRANSLATED_KEY_PRESS: + case ET_TRANSLATED_KEY_RELEASE: + return true; + default: + NOTREACHED(); + return false; + } } -void TranslatedKeyEvent::ConvertToKeyEvent() { - SetType(type() == ET_TRANSLATED_KEY_PRESS ? - ET_KEY_PRESSED : ET_KEY_RELEASED); +void KeyEvent::SetTranslated(bool translated) { + switch (type()) { + case ET_KEY_PRESSED: + case ET_TRANSLATED_KEY_PRESS: + SetType(translated ? ET_TRANSLATED_KEY_PRESS : ET_KEY_PRESSED); + break; + case ET_KEY_RELEASED: + case ET_TRANSLATED_KEY_RELEASE: + SetType(translated ? ET_TRANSLATED_KEY_RELEASE : ET_KEY_RELEASED); + break; + default: + NOTREACHED(); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/ui/events/event.h b/ui/events/event.h index 0a5d566..d85519f 100644 --- a/ui/events/event.h +++ b/ui/events/event.h @@ -556,6 +556,12 @@ class EVENTS_EXPORT KeyEvent : public Event { // in http://crbug.com/127142#c8, the normalization is necessary. void NormalizeFlags(); + // Returns true if the key event has already been processed by an input method + // and there is no need to pass the key event to the input method again. + bool IsTranslated() const; + // Marks this key event as translated or not translated. + void SetTranslated(bool translated); + protected: // This allows a subclass TranslatedKeyEvent to be a non character event. void set_is_char(bool is_char) { is_char_ = is_char; } @@ -577,29 +583,6 @@ class EVENTS_EXPORT KeyEvent : public Event { uint16 character_; }; -// A key event which is translated by an input method (IME). -// For example, if an IME receives a KeyEvent(VKEY_SPACE), and it does not -// consume the key, the IME usually generates and dispatches a -// TranslatedKeyEvent(VKEY_SPACE) event. If the IME receives a KeyEvent and -// it does consume the event, it might dispatch a -// TranslatedKeyEvent(VKEY_PROCESSKEY) event as defined in the DOM spec. -class EVENTS_EXPORT TranslatedKeyEvent : public KeyEvent { - public: - TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char); - - // Used for synthetic events such as a VKEY_PROCESSKEY key event. - TranslatedKeyEvent(bool is_press, KeyboardCode key_code, int flags); - - explicit TranslatedKeyEvent(const KeyEvent& key_event); - - // Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so - // that RenderWidgetHostViewAura and NativeWidgetAura could handle the event. - void ConvertToKeyEvent(); - - private: - DISALLOW_COPY_AND_ASSIGN(TranslatedKeyEvent); -}; - class EVENTS_EXPORT ScrollEvent : public MouseEvent { public: explicit ScrollEvent(const base::NativeEvent& native_event); diff --git a/ui/keyboard/keyboard_util.cc b/ui/keyboard/keyboard_util.cc index 1d9409b..e28f6d0 100644 --- a/ui/keyboard/keyboard_util.cc +++ b/ui/keyboard/keyboard_util.cc @@ -28,9 +28,8 @@ const char kKeyUp[] = "keyup"; void SendProcessKeyEvent(ui::EventType type, aura::WindowTreeHost* host) { - ui::TranslatedKeyEvent event(type == ui::ET_KEY_PRESSED, - ui::VKEY_PROCESSKEY, - ui::EF_NONE); + ui::KeyEvent event(type, ui::VKEY_PROCESSKEY, ui::EF_NONE, false); + event.SetTranslated(true); ui::EventDispatchDetails details = host->event_processor()->OnEventFromSource(&event); CHECK(!details.dispatcher_destroyed); diff --git a/ui/wm/core/input_method_event_filter.cc b/ui/wm/core/input_method_event_filter.cc index 4854a1b..65bd5b5 100644 --- a/ui/wm/core/input_method_event_filter.cc +++ b/ui/wm/core/input_method_event_filter.cc @@ -37,12 +37,31 @@ void InputMethodEventFilter::SetInputMethodPropertyInRootWindow( // InputMethodEventFilter, EventFilter implementation: void InputMethodEventFilter::OnKeyEvent(ui::KeyEvent* event) { - const ui::EventType type = event->type(); - if (type == ui::ET_TRANSLATED_KEY_PRESS || - type == ui::ET_TRANSLATED_KEY_RELEASE) { - // The |event| is already handled by this object, change the type of the - // event to ui::ET_KEY_* and pass it to the next filter. - static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent(); + // We're processing key events as follows (details are simplified). + // + // At the beginning, key events have a ET_KEY_{PRESSED,RELEASED} event type, + // and they're passed from step 1 through step 3. + // 1. EventProcessor::OnEventFromSource() + // 2. InputMethodEventFilter::OnKeyEvent() + // 3. InputMethod::DispatchKeyEvent() + // where InputMethod may call DispatchKeyEventPostIME() if IME didn't consume + // the key event. Otherwise, step 4 through step 6 are skipped and we fall + // down to step 7 directly. + // 4. InputMethodEventFilter::DispatchKeyEventPostIME() + // where the key event is marked as TRANSLATED and the event type becomes + // ET_TRANSLATED_KEY_{PRESS,RELEASE}. Then, we dispatch the event again from + // the beginning. + // 5. EventProcessor::OnEventFromSource() [second time] + // 6. InputMethodEventFilter::OnKeyEvent() [second time] + // where we know that the event was already processed once by IME and + // re-dispatched, we don't pass the event to IME again. Instead we unmark the + // event as not translated (as same as the original state), and let the event + // dispatcher continue to dispatch the event to the rest event handlers. + // 7. EventHandler::OnKeyEvent() + if (event->IsTranslated()) { + // The |event| was already processed by IME, so we don't pass the event to + // IME again. Just let the event dispatcher continue to dispatch the event. + event->SetTranslated(false); } else { // If the focused window is changed, all requests to IME will be // discarded so it's safe to update the target_dispatcher_ here. @@ -62,7 +81,13 @@ bool InputMethodEventFilter::DispatchKeyEventPostIME( #if defined(OS_WIN) DCHECK(!event.HasNativeEvent() || event.native_event().message != WM_CHAR); #endif - ui::TranslatedKeyEvent aura_event(event); + // Since the underlying IME didn't consume the key event, we're going to + // dispatch the event again from the beginning of the tree of event targets. + // This time we have to skip dispatching the event to the IME, we mark the + // event as TRANSLATED so we can distinguish this event as a second time + // dispatched event. + ui::KeyEvent aura_event(event); + aura_event.SetTranslated(true); ui::EventDispatchDetails details = target_dispatcher_->OnEventFromSource(&aura_event); CHECK(!details.dispatcher_destroyed); |