diff options
-rw-r--r-- | ui/base/ime/input_method_ibus.cc | 136 | ||||
-rw-r--r-- | ui/base/ime/input_method_ibus.h | 14 |
2 files changed, 37 insertions, 113 deletions
diff --git a/ui/base/ime/input_method_ibus.cc b/ui/base/ime/input_method_ibus.cc index 1113f51..3183d99 100644 --- a/ui/base/ime/input_method_ibus.cc +++ b/ui/base/ime/input_method_ibus.cc @@ -76,77 +76,6 @@ chromeos::IBusInputContextClient* GetInputContextClient() { namespace ui { -// A class to hold all data related to a key event being processed by the input -// method but still has no result back yet. -class InputMethodIBus::PendingKeyEvent { - public: - PendingKeyEvent(InputMethodIBus* input_method, - const base::NativeEvent& native_event, - uint32 ibus_keyval); - virtual ~PendingKeyEvent(); - - // Process this pending key event after we receive its result from the input - // method. It just call through InputMethodIBus::ProcessKeyEventPostIME(). - void ProcessPostIME(bool handled); - - // Abandon this pending key event. Its result will just be discarded. - void Abandon() { input_method_ = NULL; } - - InputMethodIBus* input_method() const { return input_method_; } - - private: - InputMethodIBus* input_method_; - - // TODO(yusukes): To support a fabricated key event (which is typically from - // a virtual keyboard), we might have to copy event type, event flags, key - // code, 'character_', and 'unmodified_character_'. See views::InputMethodIBus - // for details. - - // corresponding XEvent data of a key event. It's a plain struct so we can do - // bitwise copy. - // Since |x_event_| might be treated as XEvent whose size is bigger than - // XKeyEvent e.g. in CopyNativeEvent() in ui/base/events/event.cc, allocating - // |x_event_| as XKeyEvent and casting it to XEvent is unsafe. - // crbug.com/151884 - XEvent x_event_; - - const uint32 ibus_keyval_; - - DISALLOW_COPY_AND_ASSIGN(PendingKeyEvent); -}; - -InputMethodIBus::PendingKeyEvent::PendingKeyEvent( - InputMethodIBus* input_method, - const base::NativeEvent& native_event, - uint32 ibus_keyval) - : input_method_(input_method), - ibus_keyval_(ibus_keyval) { - DCHECK(input_method_); - - // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). - DCHECK(native_event); - x_event_ = *native_event; -} - -InputMethodIBus::PendingKeyEvent::~PendingKeyEvent() { - if (input_method_) - input_method_->FinishPendingKeyEvent(this); -} - -void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) { - if (!input_method_) - return; - - if (x_event_.type == KeyPress || x_event_.type == KeyRelease) { - input_method_->ProcessKeyEventPostIME(&x_event_, ibus_keyval_, handled); - return; - } - - // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). - // See views::InputMethodIBus for details. Never forget to set 'character_' - // and 'unmodified_character_' to support i18n VKs like a French VK! -} - // InputMethodIBus implementation ----------------------------------------- InputMethodIBus::InputMethodIBus( internal::InputMethodDelegate* delegate) @@ -157,6 +86,7 @@ InputMethodIBus::InputMethodIBus( composing_text_(false), composition_changed_(false), suppress_next_result_(false), + current_keyevent_id_(0), weak_ptr_factory_(this) { SetDelegate(delegate); } @@ -199,19 +129,19 @@ void InputMethodIBus::Init(bool focused) { InputMethodBase::Init(focused); } -// static -void InputMethodIBus::ProcessKeyEventDone( - PendingKeyEvent* pending_key_event, bool is_handled) { - DCHECK(pending_key_event); - pending_key_event->ProcessPostIME(is_handled); - delete pending_key_event; -} +void InputMethodIBus::ProcessKeyEventDone(uint32 id, + XEvent* event, + uint32 keyval, + bool is_handled) { + DCHECK(event); + std::set<uint32>::iterator it = pending_key_events_.find(id); -// static -void InputMethodIBus::ProcessKeyEventFail(PendingKeyEvent* pending_key_event) { - DCHECK(pending_key_event); - pending_key_event->ProcessPostIME(false); - delete pending_key_event; + if (it == pending_key_events_.end()) + return; // Abandoned key event. + if (event->type == KeyPress || event->type == KeyRelease) + ProcessKeyEventPostIME(event, keyval, is_handled); + + pending_key_events_.erase(it); } void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { @@ -241,18 +171,26 @@ void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { return; } - PendingKeyEvent* pending_key = - new PendingKeyEvent(this, native_event, ibus_keyval); - pending_key_events_.insert(pending_key); + pending_key_events_.insert(current_keyevent_id_); - GetInputContextClient()->ProcessKeyEvent( - ibus_keyval, - ibus_keycode, - ibus_state, + // Since |native_event| might be treated as XEvent whose size is bigger than + // XKeyEvent e.g. in CopyNativeEvent() in ui/base/events/event.cc, allocating + // |event| as XKeyEvent and casting it to XEvent is unsafe. crbug.com/151884 + XEvent* event = new XEvent; + *event = *native_event; + const chromeos::IBusInputContextClient::ProcessKeyEventCallback callback = base::Bind(&InputMethodIBus::ProcessKeyEventDone, - base::Unretained(pending_key)), - base::Bind(&InputMethodIBus::ProcessKeyEventFail, - base::Unretained(pending_key))); + weak_ptr_factory_.GetWeakPtr(), + current_keyevent_id_, + base::Owned(event), // Pass the ownership of |event|. + ibus_keyval); + + GetInputContextClient()->ProcessKeyEvent(ibus_keyval, + ibus_keycode, + ibus_state, + callback, + base::Bind(callback, false)); + ++current_keyevent_id_; // We don't want to suppress the result generated by this key event, but it // may cause problem. See comment in ResetContext() method. @@ -710,19 +648,7 @@ void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const { 0); } -void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEvent* pending_key) { - DCHECK(pending_key_events_.count(pending_key)); - - // |pending_key| will be deleted in ProcessKeyEventDone(). - pending_key_events_.erase(pending_key); -} - void InputMethodIBus::AbandonAllPendingKeyEvents() { - std::set<PendingKeyEvent*>::iterator i; - for (i = pending_key_events_.begin(); i != pending_key_events_.end(); ++i) { - // The object will be deleted in ProcessKeyEventDone(). - (*i)->Abandon(); - } pending_key_events_.clear(); } diff --git a/ui/base/ime/input_method_ibus.h b/ui/base/ime/input_method_ibus.h index e02659a..730a1cc 100644 --- a/ui/base/ime/input_method_ibus.h +++ b/ui/base/ime/input_method_ibus.h @@ -148,10 +148,6 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { // the focused View. void SendFakeProcessKeyEvent(bool pressed) const; - // Called when a pending key event has finished. The event will be removed - // from |pending_key_events_|. - void FinishPendingKeyEvent(PendingKeyEvent* pending_key); - // Abandons all pending key events. It usually happends when we lose keyboard // focus, the text input type is changed or we are destroyed. void AbandonAllPendingKeyEvents(); @@ -177,16 +173,15 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { void CreateInputContextDone(const dbus::ObjectPath& object_path); void CreateInputContextFail(); - static void ProcessKeyEventDone(PendingKeyEvent* pending_key_event, - bool is_handled); - static void ProcessKeyEventFail(PendingKeyEvent* pending_key_event); + void ProcessKeyEventDone(uint32 id, XEvent* xevent, uint32 keyval, + bool is_handled); scoped_ptr<internal::IBusClient> ibus_client_; // All pending key events. Note: we do not own these object, we just save // pointers to these object so that we can abandon them when necessary. // They will be deleted in ProcessKeyEventDone(). - std::set<PendingKeyEvent*> pending_key_events_; + std::set<uint32> pending_key_events_; // Represents input context's state. InputContextState input_context_state_; @@ -219,6 +214,9 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { // event will be discarded. bool suppress_next_result_; + // The latest id of key event. + uint32 current_keyevent_id_; + // An object to compose a character from a sequence of key presses // including dead key etc. CharacterComposer character_composer_; |