Fixed the bug that Input Method couldn't receive the input_panel_show/hide event. 15/69815/6
authorWonkeun Oh <wonkeun.oh@samsung.com>
Mon, 16 May 2016 04:39:54 +0000 (13:39 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Wed, 18 May 2016 04:56:19 +0000 (13:56 +0900)
If input_method->context doesn't exist, create context struct to send input_panel_show/hide event to Input Method(IME) correctly.
Because input_panel_show event can be called before/after focus_in/out(activate/deactivate) by application.
And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is shown/hidden.

Change-Id: I6740a6c6c087ea7d9ee21ad05bae923cbf14f310

src/e_mod_main.c

index f4c7eb5..080ec19 100644 (file)
@@ -799,6 +799,44 @@ _e_text_input_cb_deactivate(struct wl_client *client EINA_UNUSED, struct wl_reso
    _e_text_input_deactivate(text_input, input_method);
 }
 
+static Eina_Bool
+_e_text_input_method_create_context(struct wl_client *client EINA_UNUSED, E_Input_Method *input_method, E_Text_Input *text_input)
+{
+   E_Input_Method_Context *context = NULL;
+
+   g_text_input = text_input;
+   input_method->model = text_input;
+   text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
+
+   if (input_method && input_method->resource)
+     {
+        if (!(context = E_NEW(E_Input_Method_Context, 1)))
+          {
+             wl_client_post_no_memory(client);
+             ERR("Could not allocate space for Input_Method_Context");
+             return EINA_FALSE;
+          }
+
+        context->resource =
+           wl_resource_create(wl_resource_get_client(input_method->resource),
+                              &wl_input_method_context_interface, 1, 0);
+
+        wl_resource_set_implementation(context->resource,
+                                       &_e_text_input_method_context_implementation,
+                                       context, _e_text_input_method_context_cb_resource_destroy);
+
+        context->model = text_input;
+        context->input_method = input_method;
+        input_method->context = context;
+
+        wl_input_method_send_activate(input_method->resource, context->resource, text_input->id);
+
+        return EINA_TRUE;
+     }
+   else
+     return EINA_FALSE;
+}
+
 static void
 _e_text_input_cb_input_panel_show(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
 {
@@ -819,6 +857,14 @@ _e_text_input_cb_input_panel_show(struct wl_client *client EINA_UNUSED, struct w
    if (g_input_method && g_input_method->resource)
      input_method = wl_resource_get_user_data(g_input_method->resource);
 
+    /*
+      If input_method->context doesn't exist, create context struct to send input_panel_show event to Input Method(IME) correctly.
+      Because input_panel_show event can be called before focus_in(activate) by application.
+      And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is shown.
+    */
+   if (input_method && (!input_method->context || !input_method->context->resource))
+     _e_text_input_method_create_context(client, input_method, text_input);
+
    if (input_method && input_method->resource && input_method->context && input_method->context->resource)
      wl_input_method_send_show_input_panel(input_method->resource, input_method->context->resource);
 
@@ -836,6 +882,7 @@ _e_text_input_cb_input_panel_hide(struct wl_client *client EINA_UNUSED, struct w
 {
    E_Text_Input *text_input = wl_resource_get_user_data(resource);
    E_Input_Method *input_method = NULL;
+   Eina_Bool _context_created = EINA_FALSE;
 
    if (!text_input)
      {
@@ -856,8 +903,19 @@ _e_text_input_cb_input_panel_hide(struct wl_client *client EINA_UNUSED, struct w
    if (g_input_method && g_input_method->resource)
      input_method = wl_resource_get_user_data(g_input_method->resource);
 
+    /*
+      If input_method->context is already deleted, create context struct again to send input_panel_hide event to Input Method(IME) correctly.
+      Because input_panel_hide event can be called after focus_out(deactivate) by application.
+      And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is hidden.
+    */
+   if (input_method && (!input_method->context || !input_method->context->resource))
+     _context_created = _e_text_input_method_create_context(client, input_method, text_input);
+
    if (input_method && input_method->resource && input_method->context && input_method->context->resource)
      wl_input_method_send_hide_input_panel(input_method->resource, input_method->context->resource);
+
+   if (_context_created)
+     _e_text_input_deactivate(text_input, input_method);
 }
 
 static void