add code to sync resizing window by rotation geometry set 71/216171/1
authorDoyoun Kang <doyoun.kang@samsung.com>
Mon, 21 Oct 2019 01:47:21 +0000 (10:47 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Tue, 22 Oct 2019 01:42:13 +0000 (10:42 +0900)
Change-Id: I9552d01ec8feb8954d555d971d47277b16a0d19f

src/e_mod_input_panel.c

index 30aedb86383ab5ca552f794fe12691b8c3c2fc25..45d5860a08cef653f09b525475fc57f05be9db19 100644 (file)
@@ -4,6 +4,7 @@
 #include <input-method-server-protocol.h>
 
 #define WTI_WARNING(resource, code, msg)     (_e_input_panel_log_show((resource), (code), (msg), __func__))
+#define WAIT_UPDATE_TIMER_INTERVAL 2.0f
 
 typedef struct _E_Input_Panel E_Input_Panel;
 typedef struct _E_Input_Panel_Surface E_Input_Panel_Surface;
@@ -38,11 +39,15 @@ struct _E_Input_Panel_Surface
    {
       Ecore_Event_Handler *rot_change_end;
       Ecore_Event_Handler *buf_change;
+      Ecore_Event_Handler *rot_geometry_set;
    } eh;
 
    Eina_Bool panel;
    Eina_Bool showing;
    Eina_Bool need_show;
+
+   Eina_Bool resizing;
+   Ecore_Timer *resize_timer;
 };
 
 struct _E_Input_Panel_Floating_Info
@@ -68,6 +73,78 @@ E_Input_Panel_Floating_Info *g_floating_info = NULL;
 Eina_List *handlers = NULL;
 static Eina_Bool panel_show_need_rerun = EINA_FALSE;
 
+static E_Input_Panel_Surface *
+_e_input_panel_surface_get(E_Client *ec)
+{
+   E_Input_Panel_Surface *ips;
+   Eina_List *l;
+   Eina_List *l_next;
+
+   if (!g_input_panel) return NULL;
+
+   EINA_LIST_FOREACH_SAFE(g_input_panel->surfaces, l, l_next, ips)
+     {
+        if (!ips->ec) continue;
+        if (ips->ec == ec)
+          {
+             return ips;
+          }
+     }
+
+   return NULL;
+}
+
+static void
+_e_input_panel_start_drawing(E_Input_Panel_Surface *ips)
+{
+   if (!ips) return;
+   if (!ips->resizing) return;
+
+   if (ips->resize_timer)
+     {
+        ecore_timer_del(ips->resize_timer);
+        ips->resize_timer = NULL;
+     }
+
+   LOGD("Norender pop by resizing keyboard");
+   e_comp_canvas_norender_pop();
+   ips->resizing = EINA_FALSE;
+}
+
+static Eina_Bool
+_resize_timeout_cb(void *data)
+{
+   E_Input_Panel_Surface *ips = NULL;
+
+   LOGE("TIMED OUT while waiting for resizing keyboard");
+
+   ips = data;
+   if (!ips) return ECORE_CALLBACK_CANCEL;
+
+   LOGD("Norender pop by resizing keyboard timeout");
+   e_comp_canvas_norender_pop();
+   ips->resizing = EINA_FALSE;
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
+static void
+_e_input_panel_stop_drawing(E_Input_Panel_Surface *ips)
+{
+   if (!ips) return;
+   if (ips->resizing) return;
+
+   LOGD("Norender push by resizing keyboard");
+   e_comp_canvas_norender_push();
+   ips->resizing = EINA_TRUE;
+
+   if (!ips->resize_timer)
+     {
+        ips->resize_timer = ecore_timer_add(WAIT_UPDATE_TIMER_INTERVAL,
+                                            _resize_timeout_cb, ips);
+     }
+}
+
 static void
 _e_input_panel_log_show(struct wl_resource *resource, uint32_t code, const char *msg, const char *warning_msg)
 {
@@ -279,8 +356,15 @@ _e_input_panel_surface_resource_destroy(struct wl_resource *resource)
           }
      }
 
+   if (ips->resizing)
+     {
+        LOGD("Destroyed Waiting Resize Input Surface. Starting Drawing Again");
+        _e_input_panel_start_drawing(ips);
+     }
+
    LOGD("Removing ips %p from input panel %p", ips, input_panel);
    input_panel->surfaces = eina_list_remove(input_panel->surfaces, ips);
+   E_FREE_FUNC(ips->eh.rot_geometry_set, 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);
@@ -654,11 +738,58 @@ end:
    return ECORE_CALLBACK_PASS_ON;
 }
 
+static Eina_Bool
+_e_input_panel_client_cb_rotation_geometry_set(void *data, int type, void *event)
+{
+   E_Client *ec;
+   E_Input_Panel_Surface *ips = data;
+   E_Event_Client_Rotation_Geometry_Set *ev = event;
+   int i;
+   int w, h;
+
+   ec = ev->ec;
+   if (ec != ips->ec)
+     goto end;
+
+   if (!ips->showing)
+     goto end;
+
+   if (ips->resizing)
+     goto end;
+
+   if (ev->angle != ec->e.state.rot.ang.curr)
+     goto end;
+
+   evas_object_geometry_get(ec->frame, NULL, NULL, &w, &h);
+
+   switch (ev->angle)
+     {
+      case 0:   i = 0; break;
+      case 90:  i = 1; break;
+      case 180: i = 2; break;
+      case 270: i = 3; break;
+      default:  i = 0; break;
+     }
+
+   if ((w != ec->e.state.rot.geom[i].w) ||
+       (h != ec->e.state.rot.geom[i].h))
+     {
+        LOGD("Resizing by Rotation Geometry. Pending Drawing");
+        _e_input_panel_stop_drawing(ips);
+     }
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
 static void
 _e_ips_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
+   E_Input_Panel_Surface *ips = NULL;
    E_Client *ec;
    int w, h;
+   int angle;
+   int i;
 
    ec = data;
    if (e_object_is_del(E_OBJECT(ec)))
@@ -667,6 +798,27 @@ _e_ips_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *e
    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
 
    _e_input_panel_position_set(ec, w, h);
+
+   ips = _e_input_panel_surface_get(ec);
+   if (!ips) return;
+   if (!ips->resizing) return;
+
+   angle = ec->e.state.rot.ang.curr;
+   switch (angle)
+     {
+      case 0:   i = 0; break;
+      case 90:  i = 1; break;
+      case 180: i = 2; break;
+      case 270: i = 3; break;
+      default:  i = 0; break;
+     }
+
+   if ((w == ec->e.state.rot.geom[i].w) ||
+       (h == ec->e.state.rot.geom[i].h))
+     {
+        LOGD("Resize Done to Rotation Geometry. Starting Drawing Again");
+        _e_input_panel_start_drawing(ips);
+     }
 }
 
 static void
@@ -846,6 +998,10 @@ _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *reso
    ips->eh.rot_change_end =
       ecore_event_handler_add(E_EVENT_CLIENT_ROTATION_CHANGE_END,
                               _e_input_panel_client_cb_rotation_change_end, ips);
+
+   ips->eh.rot_geometry_set =
+      ecore_event_handler_add(E_EVENT_CLIENT_ROTATION_GEOMETRY_SET,
+                              _e_input_panel_client_cb_rotation_geometry_set, ips);
 }