[Tizen][M34-Merge] Fix IME Event Handling
authorYoungsoo Choi <kenshin.choi@samsung.com>
Thu, 16 Oct 2014 20:34:26 +0000 (13:34 -0700)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Tue, 10 Jul 2018 06:57:09 +0000 (06:57 +0000)
IME virtual keyboard does not properly work on TV.
Even though following two lines are applied, non-numeric character input,
including Korean and alphabet, does not work on TV.

>> if (pressed && modifiers & blink::WebInputEvent::AltKey)
>>   webKitEvent.isSystemKey = true;

There are OnCommit and OnPreeditChanged Ecore callbacks for key events.
The OnCommit is called by numeric character input,
and the OnPreeditChanged is called by non-numeric character input.
The problem is that OnPreeditChanged is not called when
there is a non-numeric character input.
Another one is that IPC message has been commented out on impl side
and removed on renderer side, so browser process couldn't
receive result of processed input event from renderer process.

The following two patches resolve above issues.

>> Simplify and fix current IME context handling logic
>> Fix IME events handling

[Merged Patches]
==========================================================
- Support for multiple commit events.
Original author: Marcin Krakowiak <m.krakowiak@samsung.com>
Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=6123

- Composed text disappear after return key.
Origianl author: Karol Furmaniak <k.furmaniak@samsung.com>
Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=6215

- Simplify and fix current IME context handling logic
Origianl author: Piotr Tworek <p.tworek@samsung.com>
Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=5835

- fixup! Wrong korean keycodes in IME.
Original author: Karol Furmaniak <k.furmaniak@samsung.com>
Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=5411

- Fixed handling of input panel state change
Original author: Kamil Klimek <k.klimek@partner.samsung.com>

- Fix IME events handling.
Original author: Karol Furmaniak <k.furmaniak@samsung.com>
Issue: CBBROWSER-248, CBBROWSER-249
==========================================================

Bug: http://107.108.218.239/bugzilla/show_bug.cgi?id=6715
Reviewed by: SeungSeop Park, Viatcheslav Ostapenko, Youngbok Yoon

Change-Id: I876a3c6da9f19dfb6dea08e2d53b59ccd3bd3c8b
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
tizen_src/impl/browser/renderer_host/im_context_efl.cc
tizen_src/impl/browser/renderer_host/im_context_efl.h
tizen_src/impl/browser/renderer_host/render_widget_host_view_efl.cc [changed mode: 0644->0755]
tizen_src/impl/browser/renderer_host/render_widget_host_view_efl.h [changed mode: 0644->0755]

index dd16737a0fe976ae19936874ac0aba1000e531cd..66127330efa52e80599d5425d1773605976d5198 100644 (file)
@@ -65,12 +65,14 @@ IMContextEfl* IMContextEfl::Create(RenderWidgetHostViewEfl* view) {
 IMContextEfl::IMContextEfl(RenderWidgetHostViewEfl* view, Ecore_IMF_Context* context)
     : view_(view),
       context_(context),
-      focused_(false),
-      enabled_(false),
-      panel_was_ever_shown_(false),
+      is_focused_(false),
+      is_ime_panel_visible_(false),
       is_in_form_tag_(false),
+      current_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
+      current_type_(ui::TEXT_INPUT_TYPE_NONE),
+      can_compose_inline_(false),
       is_handling_keydown_(false),
-      input_type_(ui::TEXT_INPUT_TYPE_NONE) {
+      is_ime_ctx_reset_(false) {
   IM_CTX_LOG;
   InitializeIMFContext(context_);
 }
@@ -90,24 +92,10 @@ void IMContextEfl::InitializeIMFContext(Ecore_IMF_Context* context) {
   ecore_imf_context_retrieve_surrounding_callback_set(context, &IMFRetrieveSurroundingCallback, this);
 }
 
-void IMContextEfl::ResetIMFContext() {
-  ecore_imf_context_focus_out(context_);
-  ecore_imf_context_input_panel_hide(context_);
-  ecore_imf_context_del(context_);
-  context_ = CreateIMFContext(view_->evas());
-  InitializeIMFContext(context_);
-}
-
 IMContextEfl::~IMContextEfl() {
   ecore_imf_context_del(context_);
 }
 
-void IMContextEfl::Reset() {
-  ClearQueues();
-  view_->ClearQueues();
-  ecore_imf_context_reset(context_);
-}
-
 void IMContextEfl::HandleKeyDownEvent(const Evas_Event_Key_Down* event, bool* wasFiltered) {
 #if USE_IM_COMPOSITING
   Ecore_IMF_Event im_event;
@@ -126,61 +114,15 @@ void IMContextEfl::HandleKeyUpEvent(const Evas_Event_Key_Up* event, bool* wasFil
 #endif
 }
 
-void IMContextEfl::UpdateInputMethodState(ui::TextInputType input_type,
-                                          bool can_compose_inline,
-                                          ui::TextInputMode input_mode,
-                                          bool is_user_action) {
-  IM_CTX_LOG << "textinputtype=" << input_type;
-
-  input_type_ = input_type;
-  bool enabled = input_type != ui::TEXT_INPUT_TYPE_NONE;
-
-  enabled_ = enabled;
-  ClearQueues();
-  view_->ClearQueues();
-  ecore_imf_context_reset(context_);
-
-  // This can only be called when having focus since we disable IME messages in OnFocusOut.
-  DCHECK(focused_);
-
-  if (enabled)
-    ShowPanel(input_type, input_mode, is_user_action);
-  else
-    HidePanel();
-
-  // FIXME: viewport should be adjusted
-
-  if (enabled) {
-    // If the focused element supports inline rendering of composition text,
-    // we receive and send related events to it. Otherwise, the events related
-    // to the updates of composition text are directed to the candidate window.
-    ecore_imf_context_use_preedit_set(context_, can_compose_inline);
-  }
-}
-
-void IMContextEfl::UpdateInputMethodState(ui::TextInputType input_type) {
-  IM_CTX_LOG << "textinputtype=" << input_type;
-
-  input_type_ = input_type;
-  bool enabled = input_type != ui::TEXT_INPUT_TYPE_NONE;
-  enabled_ = enabled;
-  ClearQueues();
-  view_->ClearQueues();
-
-  bool is_showing = ecore_imf_context_input_panel_state_get(context_) ==
-                    ECORE_IMF_INPUT_PANEL_STATE_SHOW;
-  if (enabled_) {
-    if (!is_showing) {
-      ecore_imf_context_focus_in(context_);
-      ecore_imf_context_input_panel_show(context_);
-    }
-  } else
-    HidePanel();
-}
+void IMContextEfl::UpdateInputMethodType(ui::TextInputType type,
+                                         ui::TextInputMode mode,
+                                         bool can_compose_inline) {
+  IM_CTX_LOG;
 
-void IMContextEfl::ShowPanel(ui::TextInputType input_type, ui::TextInputMode input_mode, bool is_user_action) {
-  if (!is_user_action && !view_->eweb_view()->GetSettings()->useKeyPadWithoutUserAction())
+  if (current_type_ == type && current_mode_ == mode &&
+      can_compose_inline_ == can_compose_inline) {
     return;
+  }
 
   Ecore_IMF_Input_Panel_Layout layout;
   Ecore_IMF_Input_Panel_Return_Key_Type return_key_type = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
@@ -190,7 +132,7 @@ void IMContextEfl::ShowPanel(ui::TextInputType input_type, ui::TextInputMode inp
   if (is_in_form_tag_)
     return_key_type = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO;
 
-  switch (input_type) {
+  switch (type) {
     case ui::TEXT_INPUT_TYPE_TEXT:
       layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
       if (!is_in_form_tag_)
@@ -242,36 +184,61 @@ void IMContextEfl::ShowPanel(ui::TextInputType input_type, ui::TextInputMode inp
       return;
   }
 
-  Ecore_IMF_Input_Mode mode;
-  switch (input_mode) {
+  Ecore_IMF_Input_Mode imf_mode;
+  switch (mode) {
     case ui::TEXT_INPUT_MODE_NUMERIC:
-      mode = ECORE_IMF_INPUT_MODE_NUMERIC;
+      imf_mode = ECORE_IMF_INPUT_MODE_NUMERIC;
     default:
-      mode = ECORE_IMF_INPUT_MODE_ALPHA;
+      imf_mode = ECORE_IMF_INPUT_MODE_ALPHA;
   }
 
-  if (panel_was_ever_shown_)
-    ResetIMFContext();
-
-  panel_was_ever_shown_ = true;
-
   ecore_imf_context_input_panel_layout_set(context_, layout);
-  ecore_imf_context_input_mode_set(context_, mode);
+  ecore_imf_context_input_mode_set(context_, imf_mode);
   ecore_imf_context_input_panel_return_key_type_set(context_, return_key_type);
   ecore_imf_context_autocapital_type_set(context_, cap_type);
   ecore_imf_context_prediction_allow_set(context_, allow_prediction);
 
+  // If the focused element supports inline rendering of composition text,
+  // we receive and send related events to it. Otherwise, the events related
+  // to the updates of composition text are directed to the candidate window.
+  ecore_imf_context_use_preedit_set(context_, can_compose_inline);
+
+  current_type_ = type;
+  current_mode_ = mode;
+  can_compose_inline_ = can_compose_inline;
+}
+
+void IMContextEfl::UpdateInputMethodState(ui::TextInputType type,
+                                          bool can_compose_inline,
+                                          bool show_if_needed) {
+  if (current_type_ != type || can_compose_inline_ != can_compose_inline) {
+    UpdateInputMethodType(type, ui::TEXT_INPUT_MODE_DEFAULT, can_compose_inline);
+  }
+
+  IM_CTX_LOG;
+
+  bool show = type != ui::TEXT_INPUT_TYPE_NONE;
+  if (show && !is_ime_panel_visible_ && show_if_needed) {
+    ShowPanel();
+  } else if (!show && is_ime_panel_visible_) {
+    HidePanel();
+  }
+}
+
+void IMContextEfl::ShowPanel() {
+  IM_CTX_LOG;
   ecore_imf_context_focus_in(context_);
   ecore_imf_context_input_panel_show(context_);
 }
 
 void IMContextEfl::HidePanel() {
+  IM_CTX_LOG;
   ecore_imf_context_focus_out(context_);
   ecore_imf_context_input_panel_hide(context_);
 }
 
 void IMContextEfl::UpdateCaretBounds(const gfx::Rect& caret_bounds) {
-  if (enabled_) {
+  if (is_ime_panel_visible_) {
     int x = caret_bounds.x();
     int y = caret_bounds.y();
     int w = caret_bounds.width();
@@ -283,50 +250,55 @@ void IMContextEfl::UpdateCaretBounds(const gfx::Rect& caret_bounds) {
 void IMContextEfl::OnFocusIn() {
   CancelComposition();
 
-  if (focused_)
+  if (is_focused_)
     return;
 
   IM_CTX_LOG;
-  focused_ = true;
+  is_focused_ = true;
 
-  if (enabled_) {
-    ecore_imf_context_focus_in(context_);
-    ecore_imf_context_input_panel_show(context_);
-  }
+  ecore_imf_context_focus_in(context_);
 
   // Enables RenderWidget's IME related events, so that we can be notified
   // when WebKit wants to enable or disable IME.
-  if (view_->GetRenderWidgetHost())
-    RenderWidgetHostImpl::From(view_->GetRenderWidgetHost())->SetInputMethodActive(true);
+  RenderWidgetHostImpl *rwhi = GetRenderWidgetHostImpl();
+  if (rwhi)
+    rwhi->SetInputMethodActive(true);
 }
 
 void IMContextEfl::OnFocusOut() {
-  if (!focused_)
+  if (!is_focused_)
     return;
 
   IM_CTX_LOG;
-  focused_ = false;
-
-  // XXX Gtk calls ConfirmComposition here.
-  // Consider whether we need it to avoid data loss.
+  is_focused_ = false;
 
-  ClearQueues();
-  view_->ClearQueues();
+  CancelComposition();
 
-  ecore_imf_context_reset(context_);
   ecore_imf_context_focus_out(context_);
-  ecore_imf_context_input_panel_hide(context_);
 
   // Disable RenderWidget's IME related events to save bandwidth.
-  if (view_->GetRenderWidgetHost())
-    RenderWidgetHostImpl::From(view_->GetRenderWidgetHost())->SetInputMethodActive(false);
+  RenderWidgetHostImpl *rwhi = GetRenderWidgetHostImpl();
+  if (rwhi)
+    rwhi->SetInputMethodActive(false);
+}
+
+void IMContextEfl::ResetIMFContext() {
+  is_ime_ctx_reset_ = true;
+  ecore_imf_context_reset(context_);
+  is_ime_ctx_reset_ = false;
 }
 
 void IMContextEfl::CancelComposition() {
   IM_CTX_LOG;
   ClearQueues();
   view_->ClearQueues();
-  ecore_imf_context_reset(context_);
+
+  ResetIMFContext();
+  if (composition_.text.length() > 0) {
+    base::string16 empty;
+    view_->ConfirmComposition(empty);
+    composition_.Clear();
+  }
 }
 
 void IMContextEfl::ConfirmComposition() {
@@ -336,11 +308,7 @@ void IMContextEfl::ConfirmComposition() {
 
 void IMContextEfl::SetIsInFormTag(bool is_in_form_tag) {
   is_in_form_tag_ = is_in_form_tag;
-  if (!context_)
-    return;
-
-  if (ecore_imf_context_input_panel_state_get(context_) ==
-      ECORE_IMF_INPUT_PANEL_STATE_HIDE)
+  if (!context_ || !is_ime_panel_visible_)
     return;
 
   if (ecore_imf_context_input_panel_return_key_type_get(context_) ==
@@ -349,10 +317,10 @@ void IMContextEfl::SetIsInFormTag(bool is_in_form_tag) {
 
   if (is_in_form_tag_)
     ecore_imf_context_input_panel_return_key_type_set(context_,
-      ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO);
+    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO);
   else {
-    if (input_type_ == ui::TEXT_INPUT_TYPE_TEXT ||
-        input_type_ == ui::TEXT_INPUT_TYPE_NUMBER)
+    if (current_type_ == ui::TEXT_INPUT_TYPE_TEXT ||
+        current_type_ == ui::TEXT_INPUT_TYPE_NUMBER)
       ecore_imf_context_input_panel_return_key_type_set(context_,
       ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE);
     else
@@ -362,42 +330,35 @@ void IMContextEfl::SetIsInFormTag(bool is_in_form_tag) {
 }
 
 void IMContextEfl::OnCommit(void* event_info) {
+  if (is_ime_ctx_reset_) {
+    return;
+  }
+
 #if USE_IM_COMPOSITING
   IM_CTX_LOG;
   composition_.Clear();
 
   char* text = static_cast<char*>(event_info);
-  base::string16 text16;
-  base::UTF8ToUTF16(text, strlen(text), &text16);
 
+  base::string16 text16 = base::UTF8ToUTF16(text);
   // Only add commit to queue, till we dont know if key event
   // should be handled. It can be default prevented for exactly.
   commit_queue_.push(text16);
 
   // sending fake key event if hardware key is not handled as it is
   // in Webkit.
-  SendFakeCompositionKeyEvent(text);
+  SendFakeCompositionKeyEvent(text16);
 #endif
 }
 
-void IMContextEfl::SendFakeCompositionKeyEvent(char * buf) {
+void IMContextEfl::SendFakeCompositionKeyEvent(const base::string16& buf) {
   if (is_handling_keydown_)
     return;
 
-  if (!buf)
+  if (!buf.length())
     return;
 
-  UChar32 ch = 0;
-  if (strlen(buf)) {
-    ch = buf[strlen(buf) - 1];
-  }
-
-  std::string str;
-
-  if (u_isspace(ch))
-    str = "space";
-  else
-    str.append(1, ch);
+  std::string str = base::UTF16ToUTF8(buf.substr(buf.length() -1));
 
   Evas_Event_Key_Down downEvent;
   memset(&downEvent, 0, sizeof(Evas_Event_Key_Down));
@@ -417,6 +378,9 @@ void IMContextEfl::SendFakeCompositionKeyEvent(char * buf) {
 }
 
 void IMContextEfl::OnPreeditChanged(void* data, Ecore_IMF_Context* context, void* event_info) {
+  if (is_ime_ctx_reset_)
+    return;
+
 #if USE_IM_COMPOSITING
   composition_.Clear();
 
@@ -426,16 +390,26 @@ void IMContextEfl::OnPreeditChanged(void* data, Ecore_IMF_Context* context, void
   if (!buffer)
       return;
 
-  SendFakeCompositionKeyEvent(buffer);
+  // Add empty commit to stop processing commits.
+  commit_queue_.push(base::string16());
+
+  base::string16 text16 = base::UTF8ToUTF16(buffer);
+  if (!text16.empty())
+    SendFakeCompositionKeyEvent(text16);
   composition_.Clear();
-  composition_.text = base::UTF8ToUTF16(buffer);
+  composition_.text = text16;
 
   composition_.underlines.push_back(ui::CompositionUnderline(0, composition_.text.length(), SK_ColorBLACK, false));
   composition_.selection = gfx::Range(composition_.text.length());
 
   // Only add preedit to queue, till we dont know if key event
   // should be handled. It can be default prevented for exactly.
-  preedit_queue_.push(composition_);
+  if (!text16.empty())
+    preedit_queue_.push(composition_);
+  else {
+    view_->SetComposition(composition_);
+    ResetIMFContext();
+  }
 
   free(buffer);
 
@@ -446,10 +420,17 @@ void IMContextEfl::OnPreeditChanged(void* data, Ecore_IMF_Context* context, void
 // Tizen-WebKit-efl using all of them.
 
 void IMContextEfl::OnInputPanelStateChanged(int state) {
-  if (state == ECORE_IMF_INPUT_PANEL_STATE_SHOW)
+  if (state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
+    IM_CTX_LOG << ": show";
+    is_ime_panel_visible_ = true;
     view_->eweb_view()->SmartCallback<EWebViewCallbacks::IMEInputPanelShow>().call();
-  else
+  } else if (state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
+    IM_CTX_LOG << ": hide";
+    is_ime_panel_visible_ = false;
     view_->eweb_view()->SmartCallback<EWebViewCallbacks::IMEInputPanelHide>().call();
+  }
+
+  // ignore ECORE_IMF_INPUT_PANEL_WILL_SHOW value
 }
 
 void IMContextEfl::OnInputPanelGeometryChanged() {
@@ -477,16 +458,17 @@ bool IMContextEfl::OnRetrieveSurrounding(char** text, int* offset) {
 void IMContextEfl::OnDeleteSurrounding(void* event_info) {
 }
 
-void IMContextEfl::OnCandidateInputPanelLanguageChanged(Ecore_IMF_Context* /*context*/, int /*value*/) {
-  if (!view_->GetRenderWidgetHost() || composition_.text.length() == 0)
+void IMContextEfl::OnCandidateInputPanelLanguageChanged(Ecore_IMF_Context*, int) {
+  RenderWidgetHostImpl *rwhi = GetRenderWidgetHostImpl();
+
+  if (!rwhi || composition_.text.length() == 0)
     return;
-  Reset();
-  RenderWidgetHostImpl::From(view_->GetRenderWidgetHost())->ImeConfirmComposition(composition_.text, gfx::Range::InvalidRange(), false);
-  composition_.Clear();
+
+  CancelComposition();
 }
 
 bool IMContextEfl::IsShow() {
-  return (context_ && focused_ && ecore_imf_context_input_panel_state_get(context_) != ECORE_IMF_INPUT_PANEL_STATE_HIDE);
+  return context_ && is_focused_ && is_ime_panel_visible_;
 }
 
 void IMContextEfl::ClearQueues() {
@@ -499,4 +481,58 @@ void IMContextEfl::ClearQueues() {
   }
 }
 
+void IMContextEfl::IMFCommitCallback(
+    void* data, Ecore_IMF_Context*, void* event_info) {
+  static_cast<IMContextEfl*>(data)->OnCommit(event_info);
+}
+
+void IMContextEfl::IMFPreeditChangedCallback(
+    void* data, Ecore_IMF_Context* context, void* event_info) {
+  static_cast<IMContextEfl*>(data)->
+      OnPreeditChanged(data, context, event_info);
+}
+
+void IMContextEfl::IMFInputPanelStateChangedCallback(
+    void* data, Ecore_IMF_Context*, int state) {
+  static_cast<IMContextEfl*>(data)->OnInputPanelStateChanged(state);
+}
+
+void IMContextEfl::IMFInputPanelGeometryChangedCallback(
+    void* data, Ecore_IMF_Context*, int state) {
+  static_cast<IMContextEfl*>(data)->OnInputPanelGeometryChanged();
+}
+
+void IMContextEfl::IMFCandidatePanelStateChangedCallback(
+    void* data, Ecore_IMF_Context*, int state) {
+  static_cast<IMContextEfl*>(data)->OnCandidateInputPanelStateChanged(state);
+}
+
+void IMContextEfl::IMFCandidatePanelGeometryChangedCallback(
+    void* data, Ecore_IMF_Context*, int state) {
+  static_cast<IMContextEfl*>(data)->OnCandidateInputPanelGeometryChanged();
+}
+
+Eina_Bool IMContextEfl::IMFRetrieveSurroundingCallback(
+    void* data, Ecore_IMF_Context*, char** text, int* offset) {
+  return static_cast<IMContextEfl*>(data)->OnRetrieveSurrounding(text, offset);
+}
+
+void IMContextEfl::IMFDeleteSurroundingCallback(
+    void* data, Ecore_IMF_Context*, void* event_info) {
+  static_cast<IMContextEfl*>(data)->OnDeleteSurrounding(event_info);
+}
+
+void IMContextEfl::IMFCandidatePanelLanguageChangedCallback(
+    void* data, Ecore_IMF_Context* context, int value) {
+  static_cast<IMContextEfl*>(data)->
+      OnCandidateInputPanelLanguageChanged(context, value);
+}
+
+RenderWidgetHostImpl* IMContextEfl::GetRenderWidgetHostImpl() const {
+  RenderWidgetHost *rwh = view_->GetRenderWidgetHost();
+  if (!rwh)
+    return NULL;
+  return RenderWidgetHostImpl::From(rwh);
+}
+
 } // namespace content
index 8ffe54d99764f6b08966c01de86410206679063f..bfaaa8a6958c9894b97a2c6c89633163a0d0970d 100644 (file)
 
 #include <Evas.h>
 
-namespace gfx {
-class Rect;
-}
-
 typedef std::queue<base::string16> CommitQueue;
 typedef std::queue<ui::CompositionText> PreeditQueue;
 
@@ -34,55 +30,52 @@ class IMContextEfl {
 
   ~IMContextEfl();
 
-  void Reset();
   void HandleKeyDownEvent(const Evas_Event_Key_Down* event, bool* wasFiltered);
   void HandleKeyUpEvent(const Evas_Event_Key_Up* event, bool* wasFiltered);
 
-  void UpdateInputMethodState(ui::TextInputType type, bool can_compose_inline, ui::TextInputMode input_mode,
-                              bool is_user_action = false);
-  void UpdateInputMethodState(ui::TextInputType type);
+  void UpdateInputMethodType(ui::TextInputType, ui::TextInputMode,
+                             bool can_compose_inline);
+  void UpdateInputMethodState(ui::TextInputType, bool can_compose_inline,
+                              bool show_if_needed);
   void UpdateCaretBounds(const gfx::Rect& caret_bounds);
 
   void OnFocusIn();
   void OnFocusOut();
 
+  void ShowPanel();
+  void HidePanel();
+
+  void ResetIMFContext();
   void CancelComposition();
   void ConfirmComposition();
   void SetIsInFormTag(bool is_in_form_tag);
   bool IsShow();
   gfx::Rect GetIMERect() const { return ime_rect_; }
+  void SetIMERect(const gfx::Rect& rect) { ime_rect_ = rect; }
   CommitQueue GetCommitQueue() { return commit_queue_; }
   PreeditQueue GetPreeditQueue() { return preedit_queue_; }
   void CommitQueuePop() { commit_queue_.pop(); }
   void PreeditQueuePop() { preedit_queue_.pop(); }
   void ClearQueues();
 
-  void SendFakeCompositionKeyEvent(char * buf);
+  void SendFakeCompositionKeyEvent(const base::string16& buf);
 
  private:
   IMContextEfl(RenderWidgetHostViewEfl*, Ecore_IMF_Context*);
 
   void InitializeIMFContext(Ecore_IMF_Context*);
-  void ResetIMFContext();
-
-  void ShowPanel(ui::TextInputType, ui::TextInputMode, bool is_user_action = false);
-  void HidePanel();
-
-  void SetIMERect(const gfx::Rect& rect) { ime_rect_ = rect; }
 
   // callbacks
-  static void IMFCommitCallback(void* data, Ecore_IMF_Context*, void* event_info) { reinterpret_cast<IMContextEfl*>(data)->OnCommit(event_info); }
-  static void IMFPreeditChangedCallback(void* data, Ecore_IMF_Context* context, void* event_info) { reinterpret_cast<IMContextEfl*>(data)->OnPreeditChanged(data, context, event_info); }
-
-  static void IMFInputPanelStateChangedCallback(void* data, Ecore_IMF_Context*, int state) { reinterpret_cast<IMContextEfl*>(data)->OnInputPanelStateChanged(state); }
-  static void IMFInputPanelGeometryChangedCallback(void* data, Ecore_IMF_Context*, int state) { reinterpret_cast<IMContextEfl*>(data)->OnInputPanelGeometryChanged(); }
-
-  static void IMFCandidatePanelStateChangedCallback(void* data, Ecore_IMF_Context*, int state) { reinterpret_cast<IMContextEfl*>(data)->OnCandidateInputPanelStateChanged(state); }
-  static void IMFCandidatePanelGeometryChangedCallback(void* data, Ecore_IMF_Context*, int state) { reinterpret_cast<IMContextEfl*>(data)->OnCandidateInputPanelGeometryChanged(); }
+  static void IMFCommitCallback(void* data, Ecore_IMF_Context*, void* event_info);
+  static void IMFPreeditChangedCallback(void* data, Ecore_IMF_Context* context, void* event_info);
+  static void IMFInputPanelStateChangedCallback(void* data, Ecore_IMF_Context*, int state);
+  static void IMFInputPanelGeometryChangedCallback(void* data, Ecore_IMF_Context*, int state);
+  static void IMFCandidatePanelStateChangedCallback(void* data, Ecore_IMF_Context*, int state);
+  static void IMFCandidatePanelGeometryChangedCallback(void* data, Ecore_IMF_Context*, int state);
+  static Eina_Bool IMFRetrieveSurroundingCallback(void* data, Ecore_IMF_Context*, char** text, int* offset);
+  static void IMFDeleteSurroundingCallback(void* data, Ecore_IMF_Context*, void* event_info);
+  static void IMFCandidatePanelLanguageChangedCallback(void* data, Ecore_IMF_Context* context, int value);
 
-  static Eina_Bool IMFRetrieveSurroundingCallback(void* data, Ecore_IMF_Context*, char** text, int* offset) { return reinterpret_cast<IMContextEfl*>(data)->OnRetrieveSurrounding(text, offset); }
-  static void IMFDeleteSurroundingCallback(void* data, Ecore_IMF_Context*, void* event_info) { reinterpret_cast<IMContextEfl*>(data)->OnDeleteSurrounding(event_info); }
-  static void IMFCandidatePanelLanguageChangedCallback(void* data, Ecore_IMF_Context* context, int value) { reinterpret_cast<IMContextEfl*>(data)->OnCandidateInputPanelLanguageChanged(context, value); }
   // callback handlers
   void OnCommit(void* event_info);
   void OnPreeditChanged(void* data, Ecore_IMF_Context* context, void* event_info);
@@ -97,25 +90,26 @@ class IMContextEfl {
   void OnDeleteSurrounding(void* event_info);
   void OnCandidateInputPanelLanguageChanged(Ecore_IMF_Context* context, int value);
 
+  RenderWidgetHostImpl* GetRenderWidgetHostImpl() const;
+
   RenderWidgetHostViewEfl* view_;
 
   Ecore_IMF_Context* context_;
 
-  // Whether or not the accociated widget is focused.
-  bool focused_;
-
-  // Whether or not the IME is enabled.
-  bool enabled_;
+  // Whether or not the associated widget is focused.
+  bool is_focused_;
 
-  // Whether ShowPanel was ever called.
-  // At the first time when we show the input panel we can use the initial context which we create
-  // in order to check that input method is supported on the platform. Later on we need to reset context
-  // before showing the panel to be able to switch between different layouts.
-  bool panel_was_ever_shown_;
+  // Is software keyboard currently visible
+  bool is_ime_panel_visible_;
 
   // Whether or not is in form tag.
   bool is_in_form_tag_;
 
+  // The current soft keyboard mode and layout
+  ui::TextInputMode current_mode_;
+  ui::TextInputType current_type_;
+  bool can_compose_inline_;
+
   ui::CompositionText composition_;
 
   gfx::Rect ime_rect_;
@@ -124,7 +118,7 @@ class IMContextEfl {
   PreeditQueue preedit_queue_;
 
   bool is_handling_keydown_;
-  ui::TextInputType input_type_;
+  bool is_ime_ctx_reset_;
 };
 
 } // namespace content
old mode 100644 (file)
new mode 100755 (executable)
index 6de7cfe..7e53c57
@@ -393,13 +393,9 @@ bool RenderWidgetHostViewEfl::OnMessageReceived(const IPC::Message& message) {
     IPC_MESSAGE_HANDLER(EwkHostMsg_DidChangePageScaleFactor, OnDidChangePageScaleFactor)
     IPC_MESSAGE_HANDLER(EwkHostMsg_DidChangePageScaleRange, OnDidChangePageScaleRange)
     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, OnTextInputStateChanged)
-#if !defined(EWK_BRINGUP)
     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputInFormStateChanged, OnTextInputInFormStateChanged)
-#endif
 #if defined(OS_TIZEN)
-#if !defined(EWK_BRINGUP)
-    IPC_MESSAGE_HANDLER(InputHostMsg_DidInputEventHandled, OnDidInputEventHandled)
-#endif
+    IPC_MESSAGE_HANDLER(InputHostMsg_DidHandleKeyEvent, OnDidHandleKeyEvent)
 #endif
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
@@ -617,7 +613,8 @@ void RenderWidgetHostViewEfl::OnTextInputStateChanged(
     return;
 
   if (im_context_) {
-    im_context_->UpdateInputMethodState(params.type);
+    im_context_->UpdateInputMethodState(params.type, params.can_compose_inline,
+                                        params.show_ime_if_needed);
     web_view_->QuerySelectionStyle();
 
     // Obsolete TextInputTypeChanged was doing it in similar code block
@@ -1058,9 +1055,6 @@ void RenderWidgetHostViewEfl::HandleEvasEvent(const Evas_Event_Mouse_Down* event
 }
 
 void RenderWidgetHostViewEfl::HandleEvasEvent(const Evas_Event_Mouse_Up* event) {
-  if (im_context_)
-    im_context_->Reset();
-
   host_->ForwardMouseEvent(WebEventFactoryEfl::toWebMouseEvent(web_view_->GetEvas(), web_view_->evas_object(), event, device_scale_factor_));
 }
 
@@ -1103,6 +1097,9 @@ void RenderWidgetHostViewEfl::HandleEvasEvent(const Evas_Event_Key_Down* event)
   }
 
   if (im_context_) {
+    if (!strcmp(event->key, "Return")) {
+      im_context_->CancelComposition();
+    }
     im_context_->HandleKeyDownEvent(event, &wasFiltered);
     NativeWebKeyboardEvent n_event = WebEventFactoryEfl::toWebKeyboardEvent(evas_, event);
 
@@ -1140,7 +1137,7 @@ void RenderWidgetHostViewEfl::HandleEvasEvent(const Evas_Event_Key_Up* event) {
     im_context_->HandleKeyUpEvent(event, &wasFiltered);
 
   if (!im_context_)
-      host_->ForwardKeyboardEvent(WebEventFactoryEfl::toWebKeyboardEvent(evas_, event));
+    host_->ForwardKeyboardEvent(WebEventFactoryEfl::toWebKeyboardEvent(evas_, event));
 }
 
 #ifdef OS_TIZEN
@@ -1165,36 +1162,31 @@ void RenderWidgetHostViewEfl::makePinchZoom(void* eventInfo) {
 #endif
 }
 
-void RenderWidgetHostViewEfl::OnDidInputEventHandled(const blink::WebInputEvent* input_event, bool processed) {
-#if !defined(EWK_BRINGUP)
+void RenderWidgetHostViewEfl::OnDidHandleKeyEvent(const blink::WebInputEvent* input_event, bool processed) {
   if (!im_context_)
     return;
 
-  if (blink::WebInputEvent::isKeyboardEventType(input_event->type)) {
-    if (input_event->type == blink::WebInputEvent::KeyDown) {
-
-      // Handling KeyDown event of modifier key(Shift for example)
-      if (input_event->modifiers && !is_modifier_key_) {
-        is_modifier_key_ = true;
-        return;
-      }
-      // Handling KeyDown event of key+modifier (Shift+a=A for example)
-      if (is_modifier_key_) {
-        HandleCommitQueue(processed);
-        HandlePreeditQueue(processed);
-        HandleKeyUpQueue();
-        HandleKeyDownQueue();
-        is_modifier_key_ = false;
-      }
+  if (input_event->type == blink::WebInputEvent::KeyDown) {
+    // Handling KeyDown event of modifier key(Shift for example)
+    if (input_event->modifiers && !is_modifier_key_) {
+      is_modifier_key_ = true;
+      return;
+    }
 
+    // Handling KeyDown event of key+modifier (Shift+a=A for example)
+    if (is_modifier_key_) {
       HandleCommitQueue(processed);
       HandlePreeditQueue(processed);
-
       HandleKeyUpQueue();
       HandleKeyDownQueue();
+      is_modifier_key_ = false;
     }
+
+    HandleCommitQueue(processed);
+    HandlePreeditQueue(processed);
+    HandleKeyUpQueue();
+    HandleKeyDownQueue();
   }
-#endif
 }
 #endif
 
@@ -1424,6 +1416,16 @@ SelectionControllerEfl* RenderWidgetHostViewEfl::GetSelectionController() {
   return web_view_->GetSelectionController();
 }
 
+void RenderWidgetHostViewEfl::SetComposition(const ui::CompositionText& composition_text) {
+  const std::vector<blink::WebCompositionUnderline>& underlines =
+      reinterpret_cast<const std::vector<blink::WebCompositionUnderline>&>(
+      composition_text.underlines);
+
+  host_->ImeSetComposition(
+      composition_text.text, underlines, composition_text.selection.start(),
+      composition_text.selection.end());
+}
+
 void RenderWidgetHostViewEfl::ClearQueues() {
   while (!keyupev_queue_.empty()) {
     keyupev_queue_.pop();
@@ -1435,19 +1437,24 @@ void RenderWidgetHostViewEfl::ClearQueues() {
   }
 }
 
+void RenderWidgetHostViewEfl::ConfirmComposition(base::string16& text) {
+  host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
+}
+
 void RenderWidgetHostViewEfl::HandleCommitQueue(bool processed) {
   if (!im_context_)
     return;
 
-  if (!processed) {
-    if (!im_context_->GetCommitQueue().empty()) {
-      base::string16 text16 = im_context_->GetCommitQueue().front();
-      host_->ImeConfirmComposition(text16, gfx::Range::InvalidRange(), false);
-      im_context_->CommitQueuePop();
-    }
-  } else {
-    if (!im_context_->GetCommitQueue().empty())
-      im_context_->CommitQueuePop();
+  while (!im_context_->GetCommitQueue().empty()) {
+    const bool isEmpty = im_context_->GetCommitQueue().front().empty();
+
+    if (!processed && !isEmpty)
+      ConfirmComposition(im_context_->GetCommitQueue().front());
+
+    im_context_->CommitQueuePop();
+
+    if (isEmpty)
+      break;
   }
 }
 
@@ -1455,22 +1462,11 @@ void RenderWidgetHostViewEfl::HandlePreeditQueue(bool processed) {
   if (!im_context_)
     return;
 
-  if (!processed) {
-    if (!im_context_->GetPreeditQueue().empty()) {
-      ui::CompositionText composition_ = im_context_->GetPreeditQueue().front();
+  if (!im_context_->GetPreeditQueue().empty()) {
+    if (!processed)
+      SetComposition(im_context_->GetPreeditQueue().front());
 
-      const std::vector<blink::WebCompositionUnderline>& underlines =
-      reinterpret_cast<const std::vector<blink::WebCompositionUnderline>&>(
-      composition_.underlines);
-
-      host_->ImeSetComposition(
-      composition_.text, underlines, composition_.selection.start(),
-      composition_.selection.end());
-      im_context_->PreeditQueuePop();
-    }
-  } else {
-    if (!im_context_->GetPreeditQueue().empty())
-      im_context_->PreeditQueuePop();
+    im_context_->PreeditQueuePop();
   }
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index d4ad3e7..5aea29a
@@ -22,6 +22,7 @@
 #include "content/browser/compositor/image_transport_factory.h"
 #include "content/browser/compositor/owned_mailbox.h"
 #include "gpu/command_buffer/common/mailbox.h"
+#include "ui/base/ime/composition_text.h"
 #include "ui/base/ime/text_input_client.h"
 #include "eweb_view.h"
 #include "browser/renderer_host/im_context_efl.h"
@@ -172,7 +173,7 @@ class RenderWidgetHostViewEfl
 #ifdef OS_TIZEN
   void FilterInputMotion(const blink::WebGestureEvent& gesture_event);
   void makePinchZoom(void* eventInfo);
-  void OnDidInputEventHandled(const blink::WebInputEvent* input_event, bool processed);
+  void OnDidHandleKeyEvent(const blink::WebInputEvent* input_event, bool processed);
   void GetSnapshotForRect(gfx::Rect& rect);
   void SetRectSnapshot(const SkBitmap& bitmap);
 #endif
@@ -227,6 +228,9 @@ class RenderWidgetHostViewEfl
   // This function sets CSS "view-mode" media feature value.
   void SetViewMode(tizen_webview::View_Mode view_mode);
 
+  void SetComposition(const ui::CompositionText& composition_text);
+  void ConfirmComposition(base::string16& text);
+
  protected:
   friend class RenderWidgetHostView;