discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=3047ce85b8e8dd18a7600aa0701c7377edefeb6f

commit 3047ce85b8e8dd18a7600aa0701c7377edefeb6f
Author: discomfitor <[email protected]>
Date:   Wed Oct 16 16:19:34 2013 +0100

    not sure if keep... add retries for failure x clients
    
    if a client's X attributes fail to be fetched on the first attempt, it's 
possible that we might succeed on a second attempt, which would prevent us from 
losing a client
---
 src/bin/e_comp_x.c | 110 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 86 insertions(+), 24 deletions(-)

diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index 39458de..0b473ae 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -24,6 +24,8 @@ struct _Frame_Extents
 
 struct _E_Comp_Data
 {
+   Eina_List *retry_clients;
+   Ecore_Timer *retry_timer;
    Eina_Bool restack : 1;
 };
 
@@ -967,7 +969,20 @@ _e_comp_x_destroy(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_Wi
    //INF("X DESTROY: %u", ev->win);
    e_comp_ignore_win_del(E_PIXMAP_TYPE_X, ev->win);
    ec = _e_comp_x_client_find_by_window(ev->win);
-   if (!ec) return ECORE_CALLBACK_RENEW;
+   if (!ec)
+     {
+        const Eina_List *l;
+        E_Comp *c;
+
+        EINA_LIST_FOREACH(e_comp_list(), l, c)
+          {
+             if (!c->comp_data->retry_clients) continue;
+             c->comp_data->retry_clients = 
eina_list_remove(c->comp_data->retry_clients, (uintptr_t*)(unsigned 
long)ev->win);
+             if (!c->comp_data->retry_clients)
+               E_FREE_FUNC(c->comp_data->retry_timer, ecore_timer_del);
+          }
+        return ECORE_CALLBACK_PASS_ON;
+     }
    if (ec->comp_data)
      {
         if (ec->comp_data->reparented)
@@ -1081,28 +1096,9 @@ _e_comp_x_show_request(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Eve
    return ECORE_CALLBACK_RENEW;
 }
 
-static Eina_Bool
-_e_comp_x_show(void *data EINA_UNUSED, int type EINA_UNUSED, 
Ecore_X_Event_Window_Show *ev)
+static void
+_e_comp_x_show_helper(E_Client *ec)
 {
-   E_Client *ec;
-   E_Comp *c;
-
-   //INF("X SHOW: %u", ev->win);
-   ec = _e_comp_x_client_find_by_window(ev->win);
-   if (!ec)
-     {
-        if (e_comp_ignore_win_find(ev->win)) return ECORE_CALLBACK_RENEW;
-        c = e_comp_find_by_window(ev->event_win);
-        if (!c) return ECORE_CALLBACK_RENEW;
-        if (ev->event_win != c->man->root) return ECORE_CALLBACK_RENEW;
-        if ((c->win == ev->win) || (c->ee_win == ev->win) ||
-            (c->man->root == ev->win) || (c->cm_selection == ev->win)) return 
ECORE_CALLBACK_RENEW;
-        /* some window which we haven't made a client for yet but need to */
-        ec = _e_comp_x_client_new(c, ev->win, 0);
-        if (!ec) return ECORE_CALLBACK_RENEW;
-     }
-   else if (e_object_is_del(E_OBJECT(ec)) || ec->already_unparented)
-     return ECORE_CALLBACK_RENEW;
    if ((!ec->override) && (!ec->re_manage) && (!ec->comp_data->first_map) &&
        (!ec->comp_data->reparented) && (!ec->comp_data->need_reparent))
      {
@@ -1141,9 +1137,60 @@ _e_comp_x_show(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_Windo
              ec->comp->comp_data->restack = 1;
           }
      }
+}
+
+static Eina_Bool
+_e_comp_x_show_retry(void *data)
+{
+   E_Comp *c = data;
+   uintptr_t *win;
+
+   EINA_LIST_FREE(c->comp_data->retry_clients, win)
+     {
+        E_Client *ec;
+
+        ec = _e_comp_x_client_new(c, (Ecore_X_Window)(uintptr_t)win, 0);
+        if (ec) _e_comp_x_show_helper(ec);
+     }
+
+   c->comp_data->retry_timer = NULL;
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_e_comp_x_show(void *data EINA_UNUSED, int type EINA_UNUSED, 
Ecore_X_Event_Window_Show *ev)
+{
+   E_Client *ec;
+   E_Comp *c;
+
+   //INF("X SHOW: %u", ev->win);
+   ec = _e_comp_x_client_find_by_window(ev->win);
+   if (!ec)
+     {
+        if (e_comp_ignore_win_find(ev->win)) return ECORE_CALLBACK_RENEW;
+        c = e_comp_find_by_window(ev->event_win);
+        if (!c) return ECORE_CALLBACK_RENEW;
+        if (ev->event_win != c->man->root) return ECORE_CALLBACK_RENEW;
+        if ((c->win == ev->win) || (c->ee_win == ev->win) ||
+            (c->man->root == ev->win) || (c->cm_selection == ev->win)) return 
ECORE_CALLBACK_RENEW;
+        /* some window which we haven't made a client for yet but need to */
+        ec = _e_comp_x_client_new(c, ev->win, 0);
+        if (!ec)
+          {
+             if (c->comp_data->retry_timer)
+               ecore_timer_reset(c->comp_data->retry_timer);
+             else
+               c->comp_data->retry_timer = ecore_timer_add(0.02, 
_e_comp_x_show_retry, c);
+             c->comp_data->retry_clients = 
eina_list_append(c->comp_data->retry_clients, (uintptr_t*)(unsigned 
long)ev->win);
+             return ECORE_CALLBACK_RENEW;
+          }
+     }
+   else if (e_object_is_del(E_OBJECT(ec)) || ec->already_unparented)
+     return ECORE_CALLBACK_RENEW;
+   _e_comp_x_show_helper(ec);
    if (ec->internal || (!ec->override))
      _e_comp_x_client_stack(ec);
-   return ECORE_CALLBACK_PASS_ON;
+   return ECORE_CALLBACK_RENEW;
 }
 
 static Eina_Bool
@@ -1154,7 +1201,20 @@ _e_comp_x_hide(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_Windo
 
    //INF("X HIDE: %u", ev->win);
    ec = _e_comp_x_client_find_by_window(ev->win);
-   if (!ec) return ECORE_CALLBACK_PASS_ON;
+   if (!ec)
+     {
+        const Eina_List *l;
+        E_Comp *c;
+
+        EINA_LIST_FOREACH(e_comp_list(), l, c)
+          {
+             if (!c->comp_data->retry_clients) continue;
+             c->comp_data->retry_clients = 
eina_list_remove(c->comp_data->retry_clients, (uintptr_t*)(unsigned 
long)ev->win);
+             if (!c->comp_data->retry_clients)
+               E_FREE_FUNC(c->comp_data->retry_timer, ecore_timer_del);
+          }
+        return ECORE_CALLBACK_PASS_ON;
+     }
    if (!ec->visible)
      {
         //INF("IGNORED");
@@ -4387,6 +4447,8 @@ _e_comp_x_del(E_Comp *c)
    ecore_x_window_free(c->cm_selection);
    ecore_x_screen_is_composited_set(c->man->num, 0);
 
+   eina_list_free(c->comp_data->retry_clients);
+   ecore_timer_del(c->comp_data->retry_timer);
    free(c->comp_data);
 }
 

-- 


Reply via email to