Home | History | Annotate | Download | only in core
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/wm/core/input_method_event_filter.h"
      6 
      7 #include "ui/aura/client/aura_constants.h"
      8 #include "ui/aura/window_tree_host.h"
      9 #include "ui/base/ime/input_method.h"
     10 #include "ui/base/ime/input_method_factory.h"
     11 #include "ui/base/ime/text_input_client.h"
     12 #include "ui/events/event.h"
     13 #include "ui/events/event_processor.h"
     14 
     15 namespace wm {
     16 
     17 ////////////////////////////////////////////////////////////////////////////////
     18 // InputMethodEventFilter, public:
     19 
     20 InputMethodEventFilter::InputMethodEventFilter(gfx::AcceleratedWidget widget)
     21     : input_method_(ui::CreateInputMethod(this, widget)) {
     22   // TODO(yusukes): Check if the root window is currently focused and pass the
     23   // result to Init().
     24   input_method_->Init(true);
     25 }
     26 
     27 InputMethodEventFilter::~InputMethodEventFilter() {
     28 }
     29 
     30 void InputMethodEventFilter::SetInputMethodPropertyInRootWindow(
     31     aura::Window* root_window) {
     32   root_window->SetProperty(aura::client::kRootWindowInputMethodKey,
     33                            input_method_.get());
     34 }
     35 
     36 ////////////////////////////////////////////////////////////////////////////////
     37 // InputMethodEventFilter, EventFilter implementation:
     38 
     39 void InputMethodEventFilter::OnKeyEvent(ui::KeyEvent* event) {
     40   // We're processing key events as follows (details are simplified).
     41   //
     42   // At the beginning, key events have a ET_KEY_{PRESSED,RELEASED} event type,
     43   // and they're passed from step 1 through step 3.
     44   //   1. EventProcessor::OnEventFromSource()
     45   //   2. InputMethodEventFilter::OnKeyEvent()
     46   //   3. InputMethod::DispatchKeyEvent()
     47   // where InputMethod may call DispatchKeyEventPostIME() if IME didn't consume
     48   // the key event.  Otherwise, step 4 through step 6 are skipped and we fall
     49   // down to step 7 directly.
     50   //   4. InputMethodEventFilter::DispatchKeyEventPostIME()
     51   // where the key event is marked as TRANSLATED and the event type becomes
     52   // ET_TRANSLATED_KEY_{PRESS,RELEASE}.  Then, we dispatch the event again from
     53   // the beginning.
     54   //   5. EventProcessor::OnEventFromSource()     [second time]
     55   //   6. InputMethodEventFilter::OnKeyEvent()    [second time]
     56   // where we know that the event was already processed once by IME and
     57   // re-dispatched, we don't pass the event to IME again.  Instead we unmark the
     58   // event as not translated (as same as the original state), and let the event
     59   // dispatcher continue to dispatch the event to the rest event handlers.
     60   //   7. EventHandler::OnKeyEvent()
     61   if (event->IsTranslated()) {
     62     // The |event| was already processed by IME, so we don't pass the event to
     63     // IME again.  Just let the event dispatcher continue to dispatch the event.
     64     event->SetTranslated(false);
     65   } else {
     66     if (input_method_->DispatchKeyEvent(*event))
     67       event->StopPropagation();
     68   }
     69 }
     70 
     71 ////////////////////////////////////////////////////////////////////////////////
     72 // InputMethodEventFilter, ui::InputMethodDelegate implementation:
     73 
     74 bool InputMethodEventFilter::DispatchKeyEventPostIME(
     75     const ui::KeyEvent& event) {
     76 #if defined(OS_WIN)
     77   DCHECK(!event.HasNativeEvent() || event.native_event().message != WM_CHAR);
     78 #endif
     79   // Since the underlying IME didn't consume the key event, we're going to
     80   // dispatch the event again from the beginning of the tree of event targets.
     81   // This time we have to skip dispatching the event to the IME, we mark the
     82   // event as TRANSLATED so we can distinguish this event as a second time
     83   // dispatched event.
     84   // For the target where to dispatch the event, always tries the current
     85   // focused text input client's attached window. And fallback to the target
     86   // carried by event.
     87   aura::Window* target_window = NULL;
     88   ui::TextInputClient* input = input_method_->GetTextInputClient();
     89   if (input)
     90     target_window = input->GetAttachedWindow();
     91   if (!target_window)
     92     target_window = static_cast<aura::Window*>(event.target());
     93   if (!target_window)
     94     return false;
     95   ui::EventProcessor* target_dispatcher =
     96       target_window->GetRootWindow()->GetHost()->event_processor();
     97   ui::KeyEvent aura_event(event);
     98   aura_event.SetTranslated(true);
     99   ui::EventDispatchDetails details =
    100       target_dispatcher->OnEventFromSource(&aura_event);
    101   CHECK(!details.dispatcher_destroyed);
    102   return aura_event.handled();
    103 }
    104 
    105 }  // namespace wm
    106