Modified to show input panel after receiving set_ready request 23/75523/4
authorJi-hoon Lee <dalton.lee@samsung.com>
Fri, 17 Jun 2016 06:55:04 +0000 (15:55 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Thu, 23 Jun 2016 01:16:16 +0000 (10:16 +0900)
Change-Id: Iba15f283c1114cc4afae7448d19dc00d22dee7ac

src/e_mod_input_panel.c
src/e_mod_main.c
src/e_mod_main.h
src/wti_log.h

index b39ef0f..81313a2 100644 (file)
@@ -11,6 +11,10 @@ struct _E_Input_Panel
    struct wl_global *global;
    struct wl_resource *resource;
    Eina_List *surfaces;
+
+   Ecore_Event_Handler *buf_change_handler;
+
+   Eina_Bool wait_update; /* wait update state for global input panel object */
 };
 
 struct _E_Input_Panel_Surface
@@ -20,10 +24,15 @@ struct _E_Input_Panel_Surface
    E_Input_Panel *input_panel;
    E_Client *ec;
 
-   Ecore_Event_Handler *rot_handler;
+   struct
+   {
+      Ecore_Event_Handler *rot_change_end;
+      Ecore_Event_Handler *buf_change;
+   } eh;
 
    Eina_Bool panel;
    Eina_Bool showing;
+   Eina_Bool wait_update; /* wait update state for individual input panel surface */
 };
 
 E_Input_Panel *g_input_panel = NULL;
@@ -69,9 +78,33 @@ _e_input_panel_surface_cb_overlay_panel_set(struct wl_client *client EINA_UNUSED
    ips->panel = EINA_TRUE;
 }
 
+static void
+_e_input_panel_surface_cb_ready_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t state EINA_UNUSED)
+{
+   E_Input_Panel_Surface *ips = wl_resource_get_user_data(resource);
+
+   if (!g_input_panel) return;
+
+   if (!ips)
+     {
+        wl_resource_post_error(resource,
+            WL_DISPLAY_ERROR_INVALID_OBJECT,
+            "No Input Panel Surface For Surface");
+        return;
+     }
+
+   if (g_input_panel->wait_update)
+     {
+        WTI_LOG("IPS::SHOW::READY");
+        e_input_panel_visibility_change(EINA_TRUE);
+        e_input_panel_wait_update_set(EINA_FALSE);
+     }
+}
+
 static const struct wl_input_panel_surface_interface _e_input_panel_surface_implementation = {
      _e_input_panel_surface_cb_toplevel_set,
-     _e_input_panel_surface_cb_overlay_panel_set
+     _e_input_panel_surface_cb_overlay_panel_set,
+     _e_input_panel_surface_cb_ready_set
 };
 
 static void
@@ -114,7 +147,8 @@ _e_input_panel_surface_resource_destroy(struct wl_resource *resource)
      }
 
    input_panel->surfaces = eina_list_remove(input_panel->surfaces, ips);
-   E_FREE_FUNC(ips->rot_handler, ecore_event_handler_del);
+   E_FREE_FUNC(ips->eh.rot_change_end, ecore_event_handler_del);
+   E_FREE_FUNC(ips->eh.buf_change, ecore_event_handler_del);
    free(ips);
 }
 
@@ -154,9 +188,54 @@ _e_input_panel_position_set(E_Client *ec, int w, int h)
 }
 
 static void
+_ips_show(E_Client *ec)
+{
+   if (ec->visible)
+     return;
+
+   WTI_LOG("IPS::SHOW");
+
+   _e_input_panel_position_set(ec, ec->client.w, ec->client.h);
+
+   ec->visible = EINA_TRUE;
+   evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
+   evas_object_show(ec->frame);
+   e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
+}
+
+static Eina_Bool
+_ips_cb_buffer_change(void *data, int type, void *event)
+{
+   E_Event_Client *ev = event;
+   E_Input_Panel_Surface *ips = data;
+
+   if (!ips || !ev)
+     goto end;
+
+   if (ips->ec != ev->ec)
+     goto end;
+
+   if (!ips->wait_update)
+     goto clean;
+
+   WTI_LOG("IPS::BUFFER::CHANGED::DEFER_SHOW");
+
+   _ips_show(ips->ec);
+
+   ips->wait_update = EINA_FALSE;
+
+clean:
+   E_FREE_FUNC(ips->eh.buf_change, ecore_event_handler_del);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
 _e_input_panel_surface_visible_update(E_Input_Panel_Surface *ips)
 {
    E_Client *ec;
+   E_Comp_Wl_Client_Data *cdata;
 
    if (!ips) return;
 
@@ -166,15 +245,22 @@ _e_input_panel_surface_visible_update(E_Input_Panel_Surface *ips)
 
    if ((ips->showing) && (e_pixmap_usable_get(ec->pixmap)))
      {
-        _e_input_panel_position_set(ec, ec->client.w, ec->client.h);
+        if (ec->visible)
+          return;
 
-        ec->visible = EINA_TRUE;
-        evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h);
-        evas_object_show(ec->frame);
-        e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
+        WTI_LOG("IPS::DEFER_SHOW::ADD");
+        ips->wait_update = EINA_TRUE;
+        if (!ips->eh.buf_change)
+          {
+             ips->eh.buf_change =
+                ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
+                                        _ips_cb_buffer_change, ips);
+          }
      }
    else
      {
+        WTI_LOG("IPS::DEFER_SHOW::HIDE");
+        ips->wait_update = EINA_FALSE;
         ec->visible = EINA_FALSE;
         evas_object_hide(ec->frame);
      }
@@ -367,6 +453,8 @@ _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *reso
    ec->border_size = 0;
    ec->vkbd.vkbd = 1;
    ec->icccm.window_role = eina_stringshare_add("input_panel_surface");
+   /* skip iconify */
+   ec->exp_iconify.skip_iconify = 1;
    evas_object_layer_set(ec->frame, E_LAYER_CLIENT_ABOVE);
    evas_object_raise(ec->frame);
 
@@ -392,7 +480,7 @@ _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *reso
                                   &_e_input_panel_surface_implementation,
                                   ips, _e_input_panel_surface_resource_destroy);
 
-   ips->rot_handler =
+   ips->eh.rot_change_end =
       ecore_event_handler_add(E_EVENT_CLIENT_ROTATION_CHANGE_END,
                               _e_input_panel_client_cb_rotation_change_end, ips);
 }
@@ -539,3 +627,71 @@ e_input_panel_shutdown(void)
            }
       }
 }
+
+static void
+_ips_client_frame_flush(E_Input_Panel_Surface  *ips)
+{
+   if (!ips->ec)
+     return;
+
+   if (e_object_is_del(E_OBJECT(ips->ec)))
+     return;
+
+   WTI_LOG("IPS::FRAME::FLUSH ec %p", ips->ec);
+   e_pixmap_image_clear(ips->ec->pixmap, EINA_TRUE);
+}
+
+static Eina_Bool
+_ip_cb_e_buf_change(void *data EINA_UNUSED, int ev_type EINA_UNUSED, void *event)
+{
+   E_Event_Client *ev;
+   E_Input_Panel_Surface *ips;
+   Eina_List *l;
+
+   ev = event;
+   if (EINA_UNLIKELY(!ev))
+     goto end;
+
+   if (EINA_UNLIKELY(!g_input_panel))
+     goto end;
+
+   EINA_LIST_FOREACH(g_input_panel->surfaces, l, ips)
+     {
+        if (ips->ec != ev->ec) continue;
+        _ips_client_frame_flush(ips);
+     }
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+EINTERN void
+e_input_panel_wait_update_set(Eina_Bool wait_update)
+{
+   E_Input_Panel_Surface *ips;
+   Eina_List *l;
+
+   if (!g_input_panel)
+     return;
+
+   g_input_panel->wait_update = wait_update;
+
+   /* If we are in wait_update mode, the input panel surfaces have to be updated forcibly */
+   if (wait_update)
+     {
+        EINA_LIST_FOREACH(g_input_panel->surfaces, l, ips)
+          {
+             if (!ips->ec) continue;
+             _ips_client_frame_flush(ips);
+          }
+
+        if (!g_input_panel->buf_change_handler)
+          {
+             WTI_LOG("IPS::WAIT::UPDATE::SET (add buf change handler)");
+             g_input_panel->buf_change_handler = ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
+                                                                         _ip_cb_e_buf_change, NULL);
+          }
+     }
+   else
+     E_FREE_FUNC(g_input_panel->buf_change_handler, ecore_event_handler_del);
+}
index b4d0289..5dc850b 100644 (file)
@@ -134,6 +134,8 @@ _input_panel_hide(struct wl_client *client, struct wl_resource *resource)
 
    if (_context_created)
      _e_text_input_deactivate(text_input, input_method);
+
+   e_input_panel_wait_update_set(EINA_FALSE);
 }
 
 static void
@@ -1049,11 +1051,21 @@ _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_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);
+     {
+        /* DO NOT show input panel surface until we get message "show complete" from input method,
+         * in order to give a change to update UI */
+        WTI_LOG("IM::SHOW::WAIT_FOR_READY");
 
-   text_input->input_panel_visibile = EINA_TRUE;
+        wl_input_method_send_show_input_panel(input_method->resource, input_method->context->resource);
 
-   e_input_panel_visibility_change(EINA_TRUE);
+        /* we need to force update in order to release buffer
+         * if we do not, client can't update
+         * because they may in manual render state by frame callback mechanism,
+         * and also don't have released buffer */
+        e_input_panel_wait_update_set(EINA_TRUE);
+     }
+
+   text_input->input_panel_visibile = EINA_TRUE;
 
    if (text_input->resource)
      wl_text_input_send_input_panel_state(text_input->resource,
index a1396df..59cb6b3 100644 (file)
@@ -7,5 +7,7 @@ Eina_Bool   e_input_panel_init(void);
 void        e_input_panel_shutdown(void);
 void        e_input_panel_visibility_change(Eina_Bool visible);
 Eina_Bool   e_input_panel_client_find(E_Client *ec);
+EINTERN void   e_input_panel_wait_update_set(Eina_Bool wait_update);
+
 
 #endif
index 566d4f9..4c11f89 100644 (file)
 #undef CRI
 #endif
 
+#ifndef WTI_LOG
+#define WTI_LOG(...) printf(__VA_ARGS__)
+#endif
+
 extern EINTERN int _wti_log_domain;
 #define DBG(...)     EINA_LOG_DOM_DBG(_wti_log_domain, __VA_ARGS__)
 #define INF(...)     EINA_LOG_DOM_INFO(_wti_log_domain, __VA_ARGS__)