Support input panel to display candidates in H/W keyboard mode 35/138735/2
authorJi-hoon Lee <dalton.lee@samsung.com>
Thu, 13 Jul 2017 06:59:55 +0000 (15:59 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Fri, 28 Jul 2017 02:32:39 +0000 (02:32 +0000)
Change-Id: I8a70ac9a043e91f4b3475bbe05e87e7479575a56

src/e_mod_main.c

index 76155e5..d171fd6 100644 (file)
@@ -123,6 +123,7 @@ struct _E_Input_Method_Keymap_Info
    const char *layout;
 };
 
+/* This represents the overall input panel's state including the candidate area */
 enum _E_Input_Panel_State
 {
     E_INPUT_PANEL_STATE_DID_HIDE,
@@ -148,6 +149,9 @@ static E_Client *client_surface_ec = NULL;
 static E_Text_Input *g_show_text_input = NULL;
 static struct wl_client *g_show_client = NULL;
 
+/* The candidate's show state that was requested by the application or IME */
+static Eina_Bool g_show_state_candidate = EINA_FALSE;
+
 static Eina_List *hooks_ec = NULL;
 
 const int WILL_HIDE_TIMER_INTERVAL = 1.0f;
@@ -168,6 +172,7 @@ static struct _E_Input_Method_Keymap_Info g_keymap_info[] = {
    {"ru_RU", "evdev", "pc105", "ru"},
 };
 
+static void _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource);
 static void _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in);
 static Eina_Bool _e_text_input_method_create_context(struct wl_client *client, E_Input_Method *input_method, E_Text_Input *text_input, Eina_Bool need_focus_out);
 
@@ -302,6 +307,9 @@ _input_panel_hide(struct wl_client *client, struct wl_resource *resource, Eina_B
      _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
 
    e_input_panel_wait_update_set(EINA_FALSE);
+
+   /* When the input panel suface is hidden, the candidate will hide too */
+   g_show_state_candidate = EINA_FALSE;
 }
 
 static void
@@ -312,11 +320,15 @@ _keyboard_mode_changed_cb(keynode_t *key, void* data)
      {
         if (val == 0)
           {
+             /* Switching to S/W keyboard mode, hide input panel since it could be displaying candidate only */
+             if (g_disable_show_panel && g_text_input && g_text_input->resource && g_client)
+               _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
              g_disable_show_panel = EINA_FALSE;
           }
         else
           {
-             if (g_text_input && g_text_input->resource && g_client)
+             /* Switching to H/W keyboard mode, hide input panel only if there is no candidate */
+             if (!g_show_state_candidate && g_text_input && g_text_input->resource && g_client)
                _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
              g_disable_show_panel = EINA_TRUE;
           }
@@ -963,6 +975,39 @@ _e_text_input_method_context_cb_input_panel_event(struct wl_client *client EINA_
 }
 
 static void
+_e_text_input_method_context_cb_update_candidate_state(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t state)
+{
+    E_Input_Method_Context *context = wl_resource_get_user_data(resource);
+
+    if (!context)
+      {
+         WTI_WARNING(resource,
+                     WL_DISPLAY_ERROR_INVALID_OBJECT,
+                     "No Input Method Context For Resource");
+         return;
+      }
+
+    LOGD("Candidate State : %d", state);
+    Eina_Bool prev_show_state = g_show_state_candidate;
+    g_show_state_candidate = state;
+    if (g_input_panel_state == E_INPUT_PANEL_STATE_DID_HIDE)
+      prev_show_state = EINA_FALSE;
+
+    if (!state)
+      {
+         /* If the candidate state has been changed to OFF when panel is not in show state, */
+         if (!g_show_state_candidate && prev_show_state && g_disable_show_panel && g_client && g_text_input)
+            _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
+      }
+    else
+      {
+         /* If the candidate state has been changed to ON when panel is not in show state */
+         if (g_show_state_candidate && !prev_show_state && g_disable_show_panel && g_client && g_text_input)
+            _e_text_input_cb_input_panel_show(g_client, g_text_input->resource);
+      }
+}
+
+static void
 _e_text_input_method_context_cb_input_panel_data_update(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *data, uint32_t length)
 {
    E_Input_Method_Context *context = wl_resource_get_user_data(resource);
@@ -1109,7 +1154,8 @@ static const struct wl_input_method_context_interface _e_text_input_method_conte
      _e_text_input_method_context_cb_update_ise_geometry,
      _e_text_input_method_context_cb_recapture_string,
      _e_text_input_method_context_cb_input_panel_event,
-     _e_text_input_method_context_cb_commit_content
+     _e_text_input_method_context_cb_commit_content,
+     _e_text_input_method_context_cb_update_candidate_state,
 };
 
 static void
@@ -1415,9 +1461,6 @@ _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *
         return;
      }
 
-   if (g_disable_show_panel == EINA_TRUE)
-     return;
-
    if (g_input_method && g_input_method->resource)
      input_method = wl_resource_get_user_data(g_input_method->resource);
 
@@ -1427,6 +1470,18 @@ _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *
    if (input_method && (!input_method->context || !input_method->context->resource))
      _e_text_input_method_create_context(client, input_method, text_input, EINA_TRUE);
 
+   if (g_disable_show_panel == EINA_TRUE)
+     {
+        if (g_show_state_candidate == EINA_TRUE)
+          {
+             g_input_panel_state = E_INPUT_PANEL_STATE_DID_SHOW;
+             g_show_client = client;
+             e_input_panel_visibility_change(EINA_TRUE);
+             e_input_panel_transient_for_set(client_surface_ec);
+          }
+       return;
+     }
+
    if (input_method && input_method->resource && input_method->context && input_method->context->resource)
      {
         /* DO NOT show input panel surface until we get message "show complete" from input method,