Support key input in case of no focus 35/116735/2
authorJihoon Kim <jihoon48.kim@samsung.com>
Tue, 28 Feb 2017 04:34:58 +0000 (13:34 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Tue, 28 Feb 2017 10:13:40 +0000 (19:13 +0900)
Change-Id: I04712aa764449d896daa3d1fcd6fecda03ca227f

src/e_mod_main.c

index d2b490aa086afc68b92415ebd809e3e79914711d..089118b3303aa55a3677bf1f8f3cc3127f046665 100644 (file)
@@ -92,6 +92,7 @@ enum _E_Input_Panel_State
 static E_Input_Method *g_input_method = NULL;
 static E_Text_Input *g_text_input = NULL;
 static struct wl_client *g_client = NULL;
+static struct wl_client *g_focused_client = NULL;
 static Eina_List *shutdown_list = NULL;
 static Eina_Bool g_disable_show_panel = EINA_FALSE;
 static Eeze_Udev_Watch *eeze_udev_watch_hander = NULL;
@@ -240,7 +241,7 @@ _input_panel_hide(struct wl_client *client, struct wl_resource *resource, Eina_B
       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 && 
+   if (input_method &&
        ((!input_method->context) || (!input_method->context->resource)))
      _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
 
@@ -636,9 +637,32 @@ _e_text_input_method_context_cb_keysym(struct wl_client *client EINA_UNUSED, str
         return;
      }
 
+   struct wl_resource *text_input_resource = NULL;
+   Eina_Bool resource_created = EINA_FALSE;
+
    if ((context->input) && (context->input->resource))
-     wl_text_input_send_keysym(context->input->resource,
-                               serial, time, sym, state, modifiers);
+     text_input_resource = context->input->resource;
+
+   if (!text_input_resource)
+     {
+        LOGD("Create text input resource...\n");
+        if (g_focused_client)
+          {
+            text_input_resource = wl_resource_create(g_focused_client, &wl_text_input_interface, 1, 0);
+
+            if (text_input_resource)
+              resource_created = EINA_TRUE;
+          }
+     }
+
+   if (text_input_resource)
+     {
+        wl_text_input_send_keysym(text_input_resource,
+                                  serial, time, sym, state, modifiers);
+
+        if (resource_created)
+          wl_resource_destroy(text_input_resource);
+     }
 }
 
 #if ENABLE_GRAB_KEYBOARD
@@ -1031,6 +1055,8 @@ _e_mod_ecore_key_down_cb(void *data, int type, void *event)
 static void
 _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in)
 {
+   LOGD("text_input : %p, input_method : %p\n", text_input, input_method);
+
    if (text_input == g_text_input)
      {
         g_text_input = NULL;
@@ -1057,12 +1083,6 @@ _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method,
              ecore_key_down_handler = NULL;
           }
 
-        input_method->input = NULL;
-        if (input_method->context) input_method->context->input = NULL;
-        input_method->context = NULL;
-
-        text_input->input_methods = eina_list_remove(text_input->input_methods, input_method);
-
         if (text_input->resource)
           wl_text_input_send_leave(text_input->resource);
 
@@ -1078,7 +1098,6 @@ _e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource
    E_Text_Input *text_input = NULL;
    E_Input_Method *input_method = NULL;
    E_Text_Input *old = NULL;
-   E_Input_Method_Context *context = NULL;
 
    EINA_SAFETY_ON_NULL_GOTO(resource, err);
    EINA_SAFETY_ON_NULL_GOTO(seat, err);
@@ -1091,14 +1110,14 @@ _e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource
    EINA_SAFETY_ON_TRUE_GOTO(e_object_is_del(E_OBJECT(ec)), err);
    client_surface_ec = ec;
 
-   text_input = wl_resource_get_user_data(resource);
-   g_text_input = text_input;
-   g_client = client;
-
    /* FIXME: should get input_method object from seat. */
    input_method = wl_resource_get_user_data(g_input_method->resource);
+   LOGD("resource : %p, inputmethod : %p\n", g_input_method->resource, input_method);
    EINA_SAFETY_ON_NULL_GOTO(input_method, err);
 
+   text_input = wl_resource_get_user_data(resource);
+   LOGD("client : %p, text_input : %p, input_method : %p\n", client, text_input, input_method);
+
    old = input_method->input;
    if (old == text_input)
      return;
@@ -1106,41 +1125,15 @@ _e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource
    if (old)
      _e_text_input_deactivate(old, input_method, EINA_TRUE);
 
-   input_method->input = text_input;
-   text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
-
-   if (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;
-          }
-
-        if (!ecore_key_down_handler)
-          ecore_key_down_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
-                                                           _e_mod_ecore_key_down_cb,
-                                                           NULL);
-
-        context->resource =
-           wl_resource_create(wl_resource_get_client(input_method->resource),
-                              &wl_input_method_context_interface, 1, 0);
-
-
-        if (context->resource)
-          wl_resource_set_implementation(context->resource,
-                                         &_e_text_input_method_context_implementation,
-                                         context, _e_text_input_method_context_cb_resource_destroy);
-
-        context->input = text_input;
-        context->input_method = input_method;
-        input_method->context = context;
+   if (!_e_text_input_method_create_context(client, input_method, text_input, EINA_TRUE))
+     return;
 
-        if (context->resource)
-          wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, EINA_TRUE);
-     }
+   g_focused_client = client;
 
+   if (!ecore_key_down_handler)
+     ecore_key_down_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
+                                                      _e_mod_ecore_key_down_cb,
+                                                      NULL);
 #ifdef _TV
    set_soft_keyboard_mode();
 #endif
@@ -1209,7 +1202,9 @@ _e_text_input_method_create_context(struct wl_client *client, E_Input_Method *in
    g_text_input = text_input;
    g_client = client;
    input_method->input = text_input;
-   text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
+
+   if (!text_input->input_methods)
+     text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
 
    if (!(context = E_NEW(E_Input_Method_Context, 1)))
      {
@@ -1714,6 +1709,8 @@ _e_text_input_cb_resource_destroy(struct wl_resource *resource)
    E_Text_Input *text_input = wl_resource_get_user_data(resource);
    E_Input_Method *input_method = NULL;
 
+   LOGD("text input : %p\n", text_input);
+
    if (!text_input)
      {
         WTI_WARNING(resource,
@@ -1744,7 +1741,16 @@ _e_text_input_cb_resource_destroy(struct wl_resource *resource)
 
    EINA_LIST_FREE(text_input->input_methods, input_method)
      {
+        LOGD("destroy input method : %p\n", input_method);
         _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
+
+        if (input_method->input == text_input)
+          {
+              input_method->input = NULL;
+              if (input_method->context) input_method->context->input = NULL;
+              input_method->context = NULL;
+              text_input->input_methods = eina_list_remove(text_input->input_methods, input_method);
+          }
      }
 
    free(text_input);
@@ -1753,6 +1759,12 @@ _e_text_input_cb_resource_destroy(struct wl_resource *resource)
 static void
 _e_text_input_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
 {
+    E_Text_Input *text_input = wl_resource_get_user_data(resource);
+    LOGD("client : %p, text input : %p\n", client, text_input);
+
+    if (g_focused_client == client)
+      g_focused_client = NULL;
+
     wl_resource_destroy(resource);
 }