[E_BORDER] Add missing code to delete timer when the window gets DEICONIFY_APPROVE...
[platform/core/uifw/e17.git] / src / bin / e_border.c
index bff9e83..b1f5316 100644 (file)
@@ -180,6 +180,7 @@ static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
 static void      _e_border_vkbd_show(E_Border *bd);
 static void      _e_border_vkbd_hide(E_Border *bd);
+static Eina_Bool _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending);
 #endif
 static void      _e_border_move_resize_internal(E_Border *bd,
                                                 int       x,
@@ -1388,11 +1389,11 @@ e_border_show(E_Border *bd)
 #ifdef _F_ZONE_WINDOW_ROTATION_
    // newly created window that has to be rotated will be show after rotation done.
    // so, skip at this time. it will be called again after GETTING ROT_DONE.
-#if 0
    if ((bd->new_client) &&
        (bd->client.e.state.rot.changes != -1))
      {
-        // if this window is in withdrawn state, show this window right now.
+        ELB(ELBT_BD, "PENDING SHOW UNTIL GETTING ROT_DONE", bd->client.win);
+        // if this window is in withdrawn state, set the normal state
         // that's because the window in withdrawn state can't render its canvas.
         // eventually, this window will not send the message of rotation done,
         // even if e17 request to rotation this window.
@@ -1402,7 +1403,6 @@ e_border_show(E_Border *bd)
         bd->client.e.state.rot.pending_show = 1;
         return;
      }
-#endif
    if ((e_config->wm_win_rotation) &&
        (rot.vkbd_ctrl_win) && (rot.vkbd) &&
        (bd == rot.vkbd) &&
@@ -2227,6 +2227,14 @@ e_border_resize(E_Border *bd,
    _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
 }
 
+#ifdef _F_ZONE_WINDOW_ROTATION_
+EAPI Eina_Bool
+e_border_rotation_set(E_Border *bd, int rotation)
+{
+   return _e_border_rotation_set_internal(bd, rotation, NULL);
+}
+#endif
+
 /**
  * Resize window to values that do not account border decorations yet.
  *
@@ -3753,7 +3761,39 @@ _e_border_uniconify_timeout(void *data)
 }
 
 static void
-_e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
+_e_border_deiconify_approve_send_pending_end(void *data)
+{
+   E_Border *bd = (E_Border *)data;
+   E_Border *bd_ancestor;
+
+   if (e_config->deiconify_approve)
+     {
+        if (!e_object_is_del(E_OBJECT(bd)))
+          {
+             bd->client.e.state.deiconify_approve.pending_job = NULL;
+
+             ELBF(ELBT_BD, 0, bd->client.win,
+                  "SEND DEICONIFY_APPROVE. (PENDING_END) ancestor:%x",
+                  bd->client.win);
+
+             ecore_x_client_message32_send(bd->client.win,
+                                           ECORE_X_ATOM_E_DEICONIFY_APPROVE,
+                                           ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+                                           bd->client.win, 0, 0, 0, 0);
+             bd_ancestor = bd->client.e.state.deiconify_approve.ancestor;
+             if (bd_ancestor)
+               {
+                  bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, bd);
+               }
+
+             if (!bd->client.e.state.deiconify_approve.wait_timer)
+               bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
+          }
+     }
+}
+
+static void
+_e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor, Eina_Bool pending_ancestor)
 {
    if (!bd || !bd_ancestor) return;
 
@@ -3766,6 +3806,9 @@ _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
              Eina_List *list = _e_border_sub_borders_new(bd);
              EINA_LIST_FOREACH(list, l, child)
                {
+                  Eina_Bool pending = EINA_FALSE;
+                  Eina_Bool p = EINA_FALSE;
+
 #ifdef _F_ZONE_WINDOW_ROTATION_
                   if ((e_config->wm_win_rotation) &&
                       ((child->client.e.state.rot.support) ||
@@ -3773,21 +3816,37 @@ _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
                     {
                        ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
                        int rotation = _e_border_rotation_angle_get(bd);
-                       if (rotation != -1) e_border_rotation_set(bd, rotation);
+                       if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
                     }
 #endif
-                  _e_border_deiconify_approve_send(child, bd_ancestor);
+                  if ((pending_ancestor) || (pending)) p = EINA_TRUE;
+
+                  _e_border_deiconify_approve_send(child, bd_ancestor, p);
                   if (child->client.e.state.deiconify_approve.support)
                     {
-                       ELBF(ELBT_BD, 0, child->client.win,
-                            "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win);
-
-                       ecore_x_client_message32_send(child->client.win,
-                                                     ECORE_X_ATOM_E_DEICONIFY_APPROVE,
-                                                     ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
-                                                     child->client.win, 0, 0, 0, 0);
-                       child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
-                       bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
+                       if (!p)
+                         {
+                            ELBF(ELBT_BD, 0, child->client.win,
+                                 "SEND DEICONIFY_APPROVE. ancestor:%x pending(%d,%d)",
+                                 bd_ancestor->client.win,
+                                 pending_ancestor, pending);
+
+                            ecore_x_client_message32_send(child->client.win,
+                                                          ECORE_X_ATOM_E_DEICONIFY_APPROVE,
+                                                          ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+                                                          child->client.win, 0, 0, 0, 0);
+                            child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
+                            bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
+                         }
+                       else
+                         {
+                            /* queue a deiconify send job to give the chance to other jobs */
+                            ELBF(ELBT_BD, 0, child->client.win,
+                                 "SEND DEICONIFY_APPROVE. (PENDING) ancestor:%x",
+                                 bd_ancestor->client.win);
+                            child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
+                            child->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, child);
+                         }
                     }
                }
              eina_list_free(list);
@@ -3798,8 +3857,7 @@ _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
 static void
 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
 {
-   E_Border *bd_ancestor;
-   bd_ancestor = bd;
+   Eina_Bool pending = EINA_FALSE;
 
    if (e_config->deiconify_approve)
      {
@@ -3810,25 +3868,32 @@ _e_border_deiconify_approve_send_all_transient(E_Border *bd)
           {
              ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
              int rotation = _e_border_rotation_angle_get(bd);
-             if (rotation != -1) e_border_rotation_set(bd, rotation);
+             if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
           }
 #endif
 
         if (e_config->transient.iconify)
           {
-             _e_border_deiconify_approve_send(bd, bd_ancestor);
+             _e_border_deiconify_approve_send(bd, bd, pending);
           }
 
         if (bd->client.e.state.deiconify_approve.support)
           {
-             ELBF(ELBT_BD, 0, bd->client.win,
-                  "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win);
-
-             ecore_x_client_message32_send(bd->client.win,
-                                           ECORE_X_ATOM_E_DEICONIFY_APPROVE,
-                                           ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
-                                           bd->client.win, 0, 0, 0, 0);
-             bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
+             if (!pending)
+               {
+                  ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE.");
+                  ecore_x_client_message32_send(bd->client.win,
+                                                ECORE_X_ATOM_E_DEICONIFY_APPROVE,
+                                                ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
+                                                bd->client.win, 0, 0, 0, 0);
+                  bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
+               }
+             else
+               {
+                  /* queue a deiconify send job to give the chance to other jobs */
+                  ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE. (PENDING)");
+                  bd->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, bd);
+               }
           }
      }
 }
@@ -3854,6 +3919,13 @@ e_border_uniconify(E_Border *bd)
                   ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
                   return;
                }
+
+             if (bd->client.e.state.deiconify_approve.pending_job)
+               {
+                  ELB(ELBT_BD, "DEICONIFY_APPROVE PENDING_JOB is already running", bd->client.win);
+                  return;
+               }
+
              if (bd->client.e.state.deiconify_approve.render_done == 0)
                {
                   ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
@@ -4330,14 +4402,16 @@ e_border_idler_before(void)
                        if ((zone) && (rot.wait_prepare_done))
                          {
                             if (rot.list)
+                              _e_border_rotation_change_request(zone);
+                            else if (rot.async_list)
                               {
-                                 _e_border_rotation_change_request(zone);
-                                 if (rot.prepare_timer)
-                                   ecore_timer_del(rot.prepare_timer);
-                                 rot.prepare_timer = NULL;
-                                 rot.wait_prepare_done = EINA_FALSE;
-
+                                 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
+                                 rot.async_list = NULL;
                               }
+                            if (rot.prepare_timer)
+                              ecore_timer_del(rot.prepare_timer);
+                            rot.prepare_timer = NULL;
+                            rot.wait_prepare_done = EINA_FALSE;
                          }
                     }
                }
@@ -5668,6 +5742,13 @@ _e_border_free(E_Border *bd)
           rot.vkbd_prediction = NULL;
      }
 #endif
+#ifdef _F_DEICONIFY_APPROVE_
+   if (bd->client.e.state.deiconify_approve.pending_job)
+     {
+        ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
+        bd->client.e.state.deiconify_approve.pending_job = NULL;
+     }
+#endif
    evas_object_del(bd->bg_object);
    e_canvas_del(bd->bg_ecore_evas);
    ecore_evas_free(bd->bg_ecore_evas);
@@ -5831,6 +5912,12 @@ _e_border_del(E_Border *bd)
         bd->client.e.state.deiconify_approve.wait_timer = NULL;
      }
 
+   if (bd->client.e.state.deiconify_approve.pending_job)
+     {
+        ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
+        bd->client.e.state.deiconify_approve.pending_job = NULL;
+     }
+
    if (bd->client.e.state.deiconify_approve.req_list)
      {
         EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
@@ -6999,6 +7086,13 @@ _e_border_cb_client_message(void *data  __UNUSED__,
                          {
                             ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
                             ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
+
+                            if (bd->client.e.state.deiconify_approve.wait_timer)
+                              {
+                                 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
+                                 bd->client.e.state.deiconify_approve.wait_timer = NULL;
+                              }
+
                             e_border_uniconify(ancestor_bd);
                          }
                        else
@@ -7007,6 +7101,15 @@ _e_border_cb_client_message(void *data  __UNUSED__,
                             ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
                          }
                     }
+
+                  if (bd != ancestor_bd)
+                    {
+                       if (bd->client.e.state.deiconify_approve.wait_timer)
+                         {
+                            ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
+                            bd->client.e.state.deiconify_approve.wait_timer = NULL;
+                         }
+                    }
                }
           }
         return ECORE_CALLBACK_PASS_ON;
@@ -7056,14 +7159,16 @@ _e_border_cb_client_message(void *data  __UNUSED__,
              if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
                {
                   _e_border_rotation_list_remove(bd);
-#if 0
                   if (bd->client.e.state.rot.pending_show)
                     {
                        ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
                        e_border_show(bd);
+#ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
+                       if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
+                         _e_border_check_stack(bd);
+#endif
                        bd->client.e.state.rot.pending_show = 0;
                     }
-#endif
                }
           }
      }
@@ -7996,8 +8101,11 @@ _e_border_cb_rotation_async_job(void *data)
 
    ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
 
-   _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
-   rot.async_list = NULL;
+   if (!rot.wait_prepare_done)
+     {
+        _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
+        rot.async_list = NULL;
+     }
 
 end:
    // clear async job
@@ -8197,6 +8305,10 @@ _e_border_rotation_change_done(void)
                {
                   ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
                   e_border_show(info->bd);
+#ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
+                  if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
+                    _e_border_check_stack(info->bd);
+#endif
                   info->bd->client.e.state.rot.pending_show = 0;
                }
              info->bd->client.e.state.rot.wait_for_done = 0;
@@ -8443,8 +8555,8 @@ _e_border_rotation_zone_set(E_Zone *zone)
    return ret;
 }
 
-EAPI Eina_Bool
-e_border_rotation_set(E_Border *bd, int rotation)
+static Eina_Bool
+_e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending)
 {
    E_Zone *zone = bd->zone;
    E_Border_Rotation_Info *info = NULL;
@@ -8452,6 +8564,7 @@ e_border_rotation_set(E_Border *bd, int rotation)
    E_Border *child;
 
    if (rotation < 0) return EINA_FALSE;
+   if (pending) *pending = EINA_FALSE;
 
    /* step 1. check if rotation */
    if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
@@ -8504,6 +8617,8 @@ e_border_rotation_set(E_Border *bd, int rotation)
           e_manager_comp_screen_lock(e_manager_current_get());
      }
 
+   if (pending) *pending = EINA_TRUE;
+
    /* step 3. search rotatable window in this window's child */
    list = _e_border_sub_borders_new(bd);
    EINA_LIST_FOREACH(list, l, child)
@@ -8606,7 +8721,6 @@ _e_border_is_vkbd(E_Border *bd)
    if ((rot.vkbd_ctrl_win) &&
        (rot.vkbd == bd) &&
        (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
-       (rot.vkbd->visible) &&
        (rot.vkbd->zone == bd->zone) &&
        (E_INTERSECTS(bd->zone->x, bd->zone->y,
                      bd->zone->w, bd->zone->h,
@@ -8810,7 +8924,7 @@ _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w
         if (rot_dif < 0) rot_dif = -rot_dif;
         if (rot_dif != 180)
           {
-             if (w != h)
+             if (_w != _h)
                {
                   _w = bd->h;
                   _h = bd->w;
@@ -10245,7 +10359,8 @@ _e_border_eval0(E_Border *bd)
 #ifdef _F_ZONE_WINDOW_ROTATION_
    if (e_config->wm_win_rotation)
      {
-        if (need_rotation_set)
+        if ((need_rotation_set) &&
+            (bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_NORMAL))
           {
              Eina_Bool hint = EINA_FALSE;
              int ang = 0;
@@ -10254,20 +10369,19 @@ _e_border_eval0(E_Border *bd)
              ELB(ELBT_ROT, "NEED ROT", bd->client.win);
              bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
 
-             if (bd->client.e.state.rot.changes != -1)
+             if (bd->client.e.state.rot.changes == -1)
                {
-                  ang = bd->client.e.state.rot.changes;
-                  bd->changed = 1;
-               }
-             else ang = bd->client.e.state.rot.curr;
+                  ang = bd->client.e.state.rot.curr;
 
-             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);
-                  ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
-                       bd->client.icccm.name, x, y, w, 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);
+                       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 bd->changed = 1;
           }
      }
 #endif