In the case of sending rotation like message before illume's layout hook handler...
[platform/core/uifw/e17.git] / src / bin / e_border.c
index 89bceb4..843e418 100644 (file)
@@ -164,8 +164,9 @@ static Eina_Bool _e_border_rotation_geom_get(E_Border  *bd,
                                              int       *w,
                                              int       *h,
                                              Eina_Bool *move);
-static Eina_Bool _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd);
+static Eina_Bool _e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd);
 static void      _e_border_rotation_list_remove(E_Border *bd);
+static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd, int *x, int *y, int *w, int *h);
 static Eina_Bool _e_border_rotation_check(E_Border *bd);
 static Eina_Bool _e_border_rotation_zone_check(E_Zone *zone);
 static Eina_Bool _e_border_rotation_border_check(E_Border *bd, int ang);
@@ -879,6 +880,7 @@ e_border_new(E_Container   *con,
    bd->changed = 1;
 #ifdef _F_ZONE_WINDOW_ROTATION_
    bd->client.e.state.rot.preferred_rot = -1;
+   bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
 #endif
 
 //   bd->zone = e_zone_current_get(con);
@@ -2022,8 +2024,18 @@ _e_border_move_resize_internal(E_Border *bd,
 
    if (bd->new_client)
      {
-        _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
-        return;
+        /* FIXME: hack for resizing vkbd like window.
+         * IT SHOULD BE REMOVED after move the code which set the geometry of vkbd like window
+         * to illume's layout hook handler.
+         * the job of pending move/resize wouldn't be processed,
+         * in case this function is called from "_e_border_rotation_check" via "e_hints_window_init".
+         * thus we have to move/resize directry without pending in case geometry hint is existed. */
+        if (!_e_border_rotation_geom_get(bd, bd->zone, bd->client.e.state.rot.curr,
+                                         NULL, NULL, NULL, NULL, NULL))
+          {
+             _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
+             return;
+          }
      }
 
    if (bd->maximized)
@@ -4311,9 +4323,7 @@ e_border_idler_before(void)
                        if (m) zone = e_util_zone_current_get(m);
                        if ((zone) && (rot.wait_prepare_done))
                          {
-                            if (_e_border_rotation_list_add(zone, EINA_FALSE))
-                              _e_border_rotation_change_request(zone);
-                            else
+                            if (!_e_border_rotation_start(zone, EINA_FALSE))
                               {
                                  if (rot.prepare_timer)
                                    ecore_timer_del(rot.prepare_timer);
@@ -5860,11 +5870,22 @@ _e_border_cb_window_show_request(void *data  __UNUSED__,
                                  void       *ev)
 {
    E_Border *bd;
+   E_Container *con;
    Ecore_X_Event_Window_Show_Request *e;
 
    e = ev;
    bd = e_border_find_by_client_window(e->win);
    if (!bd) return ECORE_CALLBACK_PASS_ON;
+
+   if ((e_config->wm_win_rotation) &&
+       (rot.vkbd_ctrl_win) && (rot.vkbd) &&
+       (bd == rot.vkbd) &&
+       (rot.vkbd_hide_prepare_timer))
+     {
+        con = bd->zone->container;
+        bd = e_border_new(con, e->win, 0, 0);
+     }
+
    if (bd->iconic)
      {
         if (!bd->lock_client_iconify)
@@ -7931,10 +7952,7 @@ _e_border_cb_zone_rotation_change_begin(void *data  __UNUSED__,
              rot.wait_prepare_done = EINA_TRUE;
           }
         else
-          {
-             _e_border_rotation_list_add(e->zone, EINA_TRUE);
-             _e_border_rotation_change_request(e->zone);
-          }
+          _e_border_rotation_start(e->zone, EINA_TRUE);
      }
    else
      {
@@ -7952,13 +7970,9 @@ _e_border_rotation_change_prepare_timeout(void *data)
 
    ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
 
-   if ((rot.wait_prepare_done) &&
-       (zone) &&
-       (_e_border_rotation_list_add(zone, EINA_FALSE)))
-     {
-        _e_border_rotation_change_request(zone);
-     }
-   else
+   if ((!rot.wait_prepare_done) ||
+       (!zone) ||
+       (!_e_border_rotation_start(zone, EINA_FALSE)))
      {
         if (rot.prepare_timer)
           ecore_timer_del(rot.prepare_timer);
@@ -7981,6 +7995,10 @@ _e_border_rotation_change_request(E_Zone *zone __UNUSED__)
 
    EINA_LIST_FOREACH(rot.list, l, info)
      {
+        if (!info->bd) continue;
+        if ((zone->rot.block_count) &&
+            (info->bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT)) continue;
+
         _e_border_event_border_rotation_change_begin_send(info->bd);
 
         ELBF(ELBT_ROT, 1, info->bd->client.win,
@@ -8006,6 +8024,21 @@ _e_border_rotation_change_request(E_Zone *zone __UNUSED__)
                                     NULL);
 }
 
+EAPI void
+e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
+{
+   Eina_List *l = NULL;
+   E_Border_Rotation_Info *info = NULL;
+
+   if (send_request) _e_border_rotation_change_request(zone);
+   else
+     {
+        EINA_LIST_FREE(rot.list, info)
+           E_FREE(info);
+        rot.list = NULL;
+     }
+}
+
 static void
 _e_border_rotation_list_remove(E_Border *bd)
 {
@@ -8179,8 +8212,9 @@ static Eina_Bool
 _e_border_rotation_check(E_Border *bd)
 {
    E_Zone *zone = bd->zone;
+   Eina_List *nl = NULL;
    int x, y, w, h, ang = 0;
-   int diff = 0, _ang = 0;
+   int _ang = 0;
    Eina_Bool resize = EINA_TRUE;
    Eina_Bool hint = EINA_FALSE;
    Eina_Bool move = EINA_TRUE;
@@ -8273,7 +8307,11 @@ _e_border_rotation_check(E_Border *bd)
 
    hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
    if (hint)
-     _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
+     {
+        _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
+        ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
+             bd->client.icccm.name, x, y, w, h);
+     }
 
    /* need to check previous rotation angle, this may be because
     * the window was unmapped with non-0 rotation degree.
@@ -8322,71 +8360,9 @@ _e_border_rotation_check(E_Border *bd)
         bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
         bd->client.e.state.rot.curr = ang;
         bd->client.e.state.rot.wait_for_done = 1;
+        nl = eina_list_append(nl, bd);
 
-        diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
-        if ((diff == 180) || (diff == -180))
-          resize = EINA_FALSE;
-
-        /* Check if it has size hint, full size or not, and needs to resize.
-         * Under the below condition, replace width value with height.
-         */
-        if ((!hint) && (!REGION_EQUAL_TO_ZONE(bd, bd->zone)) && (resize))
-          {
-             x = bd->x;  y = bd->y;
-             w = bd->w;  h = bd->h;
-
-             if (w == h)
-               resize = EINA_FALSE;
-             else
-               {
-                  w = bd->h;
-                  h = bd->w;
-
-                  _e_border_move_resize_internal(bd, x, y, w, h,
-                                                 EINA_TRUE, EINA_FALSE);
-               }
-          }
-
-        /* hack ... */
-        if (bd->client.e.state.rot.app_set) resize = EINA_FALSE;
-
-        E_Border_Rotation_Info *info = NULL;
-        info = E_NEW(E_Border_Rotation_Info, 1);
-        if (info)
-          {
-             info->bd = bd;
-             info->ang = ang;
-             info->x = x; info->y = y;
-             info->w = w; info->h = h;
-             info->win_resize = resize;
-             rot.list = eina_list_append(rot.list, info);
-
-             if (info->win_resize)
-               bd->client.e.state.rot.pending_change_request = 1;
-
-             _e_border_event_border_rotation_change_begin_send(bd);
-
-             ELBF(ELBT_ROT, 1, info->bd->client.win,
-                  "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
-                  info->ang, info->win_resize, info->w, info->h);
-
-             ecore_x_e_window_rotation_change_prepare_send
-                (info->bd->client.win, info->ang,
-                 info->win_resize, info->w, info->h);
-
-             if (!info->bd->client.e.state.rot.pending_change_request)
-               {
-                  ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
-                  ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
-                                                                info->ang);
-               }
-
-             if (rot.done_timer)
-               ecore_timer_del(rot.done_timer);
-             rot.done_timer = ecore_timer_add(4.0f,
-                                              _e_border_rotation_change_done_timeout,
-                                              NULL);
-          }
+        e_border_rotation_list_add_change_req(zone, nl);
      }
    return EINA_TRUE;
 }
@@ -8547,8 +8523,119 @@ _e_border_rotation_transient_for_check(E_Border *bd, int ang)
    return ret;
 }
 
+EAPI Eina_Bool
+e_border_rotation_list_add_change_req(E_Zone *zone, Eina_List *list)
+{
+   Eina_List *l;
+   E_Border *bd;
+   Eina_Bool ret = EINA_FALSE;
+
+   if (e_border_rotation_list_add(list))
+     {
+        EINA_LIST_FOREACH(list, l, bd)
+           _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, bd);
+        _e_border_rotation_change_request(zone);
+        ret = EINA_TRUE;
+     }
+
+   return ret;
+}
+
+EAPI Eina_Bool
+e_border_rotation_list_add(Eina_List *list)
+{
+   Eina_List *l;
+   E_Border *bd = NULL;
+   E_Border_Rotation_Info *info = NULL;
+   int x=0, y=0, w=0, h=0;
+
+   if (!list) return EINA_FALSE;
+   EINA_LIST_FOREACH(list, l, bd)
+     {
+        info = E_NEW(E_Border_Rotation_Info, 1);
+        if (!info) continue;
+
+        info->bd = bd;
+        info->ang = bd->client.e.state.rot.curr;
+        info->win_resize = _e_border_rotation_pre_resize(bd, &x, &y, &w, &h);
+        info->x = x; info->y = y;
+        info->w = w; info->h = h;
+        if (info->win_resize) bd->client.e.state.rot.pending_change_request = 1;
+        rot.list = eina_list_append(rot.list, info);
+     }
+
+   return EINA_TRUE;
+}
+
+#define SIZE_EQUAL_TO_ZONE(a, z) \
+   ((((a)->w) == ((z)->w)) &&    \
+    (((a)->h) == ((z)->h)))
+static Eina_Bool
+_e_border_rotation_pre_resize(E_Border *bd, int *x, int *y, int *w, int *h)
+{
+   E_Zone *zone = bd->zone;
+   int ang = bd->client.e.state.rot.curr;
+   int diff = ang - bd->client.e.state.rot.prev;
+   int _x, _y, _w, _h;
+   Eina_Bool move = EINA_FALSE;
+   Eina_Bool hint = EINA_FALSE;
+   Eina_Bool resize = EINA_FALSE;
+
+   if (x) *x = bd->x;
+   if (y) *y = bd->y;
+   if (w) *w = bd->w;
+   if (h) *h = bd->h;
+
+   if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
+
+   ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
+   ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
+        bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
+
+   hint = _e_border_rotation_geom_get(bd, bd->zone, ang,
+                                      &_x, &_y, &_w, &_h, &move);
+   if (hint)
+     {
+        _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
+        resize = EINA_TRUE;
+        ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
+             bd->client.icccm.name, _x, _y, _w, _h);
+     }
+   else
+     {
+        _x = bd->x; _y = bd->y;
+        _w = bd->w; _h = bd->h;
+
+        if ((diff != 180) && (diff != -180))
+          {
+             if (w != h)
+               {
+                  _w = bd->h;
+                  _h = bd->w;
+                  resize = EINA_TRUE;
+
+                  _e_border_move_resize_internal(bd, _x, _y, _w, _h,
+                                                 EINA_TRUE, EINA_TRUE);
+                  ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
+                       bd->client.icccm.name, _x, _y, _w, _h);
+
+               }
+          }
+     }
+
+   if (resize)
+     {
+        if (x) *x = _x;
+        if (y) *y = _y;
+        if (w) *w = _w;
+        if (h) *h = _h;
+     }
+
+   return resize;
+}
+
 static Eina_Bool
-_e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
+_e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd)
 {
    Eina_Bool wait = EINA_FALSE;
    E_Border_List *l = NULL;
@@ -8576,6 +8663,8 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
             (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
                           bd->x, bd->y, bd->w, bd->h)))
           {
+             if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
+
              // check if this window is available to be rotate.
              if ((bd->client.e.state.rot.app_set) &&
                  (bd->client.e.state.rot.preferred_rot != -1)) continue;
@@ -8615,68 +8704,7 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
              bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
              bd->client.e.state.rot.curr = ang;
              bd->client.e.state.rot.wait_for_done = 1;
-
-             info = E_NEW(E_Border_Rotation_Info, 1);
-             if (info)
-               {
-                  info->bd = bd;
-                  info->ang = ang;
-                  info->x = bd->x; info->y = bd->y;
-                  info->w = bd->w; info->h = bd->h;
-                  info->win_resize = EINA_FALSE;
-                  nl = eina_list_append(nl, info);
-               }
-
-             if (REGION_EQUAL_TO_ZONE(bd, zone))
-               {
-                  wait = EINA_TRUE; // for the maximized window
-               }
-             else
-               {
-                  int diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
-                  int x, y, w, h;
-                  Eina_Bool resize = EINA_TRUE;
-                  if ((diff == 180) || (diff == -180))
-                    resize = EINA_FALSE;
-
-                  Eina_Bool move = EINA_TRUE;
-                  Eina_Bool hint = EINA_FALSE;
-                  hint = _e_border_rotation_geom_get(bd, zone, ang,
-                                                     &x, &y, &w, &h, &move);
-                  if (hint)
-                    _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
-                  else
-                    {
-                       x = bd->x; y = bd->y;
-                       w = bd->w; h = bd->h;
-                       if (resize)
-                         {
-                            if (w == h)
-                              resize = EINA_FALSE;
-                            else
-                              {
-                                 // swap width and height and resize border
-                                 w = bd->h;
-                                 h = bd->w;
-
-                                 _e_border_move_resize_internal(bd, x, y, w, h,
-                                                                EINA_TRUE, EINA_TRUE);
-                              }
-                         }
-                    }
-
-                  if (info)
-                    {
-                       info->x = x; info->y = y;
-                       info->w = w; info->h = h;
-                       info->win_resize = resize;
-                    }
-
-                  if (resize)
-                    bd->client.e.state.rot.pending_change_request = 1;
-
-                  wait = EINA_TRUE;
-               }
+             nl = eina_list_append(nl, bd);
 
              /* check whether rotation is available for sub borders such as prediction and magnifier */
              Eina_List *ll;
@@ -8689,20 +8717,15 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
                     _e_border_rotation_check(_child);
                }
              eina_list_free(_list);
+
+             wait = EINA_TRUE;
           }
      }
 
    if (l) e_container_border_list_free(l);
 
-   if (nl)
-     {
-        // clear previous list
-        EINA_LIST_FREE(rot.list, info)
-          {
-             E_FREE(info);
-          }
-        rot.list = nl;
-     }
+   wait = e_border_rotation_list_add_change_req(zone, nl);
+   eina_list_free(nl);
 
    return wait;
 }
@@ -10084,7 +10107,13 @@ _e_border_eval0(E_Border *bd)
 #endif
 #ifdef _F_ZONE_WINDOW_ROTATION_
    if ((e_config->wm_win_rotation) &&
-       (need_rotation_set))
+       (need_rotation_set) &&
+       /* since this parts of code is processed before illume's layout hook handler is processed,
+        * this border could be non-fullsize window at this time.
+        * in this case, if we send rotation like message to window,
+        * that window could have abnormal geometry.
+        * so, we skip it in case new_client for now.*/
+       (!bd->new_client))
      {
         ELB(ELBT_ROT, "NEED ROT", bd->client.win);
         Eina_Bool _rot = _e_border_rotation_check(bd);