discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=1c36bb833397f4a15a852e54fbc144729d6d98f1

commit 1c36bb833397f4a15a852e54fbc144729d6d98f1
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Fri Sep 25 18:31:30 2015 -0400

    fix handling of x11 ICCCM WithdrawnState
    
    according to ICCCM 4.1.4:
    Only the client can effect a transition into or out of the Withdrawn state
    
    withdrawn windows cannot be shown under any circumstances. the best that can
    be done is to try mapping the window and hope it decides to appear.
    
    to prevent any inadvertent showing of the window before it leaves the
    withdrawn state, we play games with the E_Client->ignored flag in order
    to skip client evals until we get notified that maybe we want to stop
    skipping those evals
    
    ref T2745
---
 src/bin/e_comp_object.c |  7 ++-----
 src/bin/e_comp_x.c      | 47 ++++++++++++++++++++++++++++-------------------
 src/bin/e_hints.c       | 20 ++++++++++++--------
 3 files changed, 42 insertions(+), 32 deletions(-)

diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c
index f17ccc6..173cbe1 100644
--- a/src/bin/e_comp_object.c
+++ b/src/bin/e_comp_object.c
@@ -1437,11 +1437,8 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj)
    if (!cw->defer_hide)
      {
         if ((!cw->ec->iconic) && (!cw->ec->override))
-          {
-             /* unset delete requested so the client doesn't break */
-             cw->ec->delete_requested = 0;
-             e_hints_window_hidden_set(cw->ec);
-          }
+          /* unset delete requested so the client doesn't break */
+          cw->ec->delete_requested = 0;
         if ((!cw->animating) || cw->showing || cw->ec->iconic)
           {
              if (cw->ec->iconic)
diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index fb8a77b..551d431 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -327,8 +327,6 @@ _e_comp_x_client_new_helper(E_Client *ec)
                ec->icccm.fetch.client_leader = 1;
              else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
                ec->icccm.fetch.window_role = 1;
-             else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
-               ec->icccm.fetch.state = 1;
           }
         /* netwm, loop again, netwm will ignore some icccm, so we
          * have to be sure that netwm is checked after */
@@ -1283,7 +1281,7 @@ _e_comp_x_show_helper(E_Client *ec)
              evas_object_hide(ec->frame);
              e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
           }
-        else
+        else if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
           evas_object_show(ec->frame);
         _e_comp_x_client_data_get(ec)->first_map = 1;
         if (ec->internal_elm_win)
@@ -1392,6 +1390,7 @@ _e_comp_x_hide(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_Windo
      {
         hid = EINA_TRUE;
         evas_object_hide(ec->frame);
+        e_hints_window_hidden_set(ec);
         if (!ec->internal)
           {
              if (ec->exe_inst && ec->exe_inst->exe)
@@ -1774,6 +1773,8 @@ _e_comp_x_property(void *data EINA_UNUSED, int type 
EINA_UNUSED, Ecore_X_Event_W
      {
         ec->icccm.fetch.hints = 1;
         EC_CHANGED(ec);
+        if (ec->icccm.state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+          ec->ignored = 0;
      }
    else if (ev->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
      {
@@ -3037,11 +3038,9 @@ _e_comp_x_hook_client_pre_frame_assign(void *d 
EINA_UNUSED, E_Client *ec)
              cd->set_win_type = 0;
           }
      }
-   if (ec->re_manage || ec->visible)
-     {
-        ecore_x_window_show(win);
-        ecore_x_window_show(pwin);
-     }
+   ecore_x_window_show(win);
+   if (!ec->iconic)
+     ecore_x_window_show(pwin);
 
    _e_comp_x_focus_init(ec);
    e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, win);
@@ -3049,7 +3048,8 @@ _e_comp_x_hook_client_pre_frame_assign(void *d 
EINA_UNUSED, E_Client *ec)
    _e_comp_x_client_evas_init(ec);
    if (ec->netwm.ping && (!ec->ping_poller))
      e_client_ping(ec);
-   if (ec->visible) evas_object_show(ec->frame);
+   if (ec->visible && (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN))
+     evas_object_show(ec->frame);
    cd->need_reparent = 0;
    ec->redirected = 1;
    if (cd->change_icon)
@@ -3188,12 +3188,6 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, 
E_Client *ec)
         eina_stringshare_del(pclass);
         ec->icccm.fetch.name_class = 0;
      }
-   if (ec->changes.prop || ec->icccm.fetch.state)
-     {
-        ec->icccm.state = ecore_x_icccm_state_get(win);
-        ec->icccm.fetch.state = 0;
-        rem_change = 1;
-     }
    if (ec->changes.prop || ec->e.fetch.state)
      {
         e_hints_window_e_state_get(ec);
@@ -3362,19 +3356,33 @@ _e_comp_x_hook_client_fetch(void *d EINA_UNUSED, 
E_Client *ec)
    if (ec->changes.prop || ec->icccm.fetch.hints)
      {
         Eina_Bool accepts_focus, is_urgent;
+        Ecore_X_Window_State_Hint state = ec->icccm.state;
 
         accepts_focus = EINA_TRUE;
         is_urgent = EINA_FALSE;
-        ec->icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+        ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
         if (ecore_x_icccm_hints_get(win,
                                     &accepts_focus,
-                                    &ec->icccm.initial_state,
+                                    &ec->icccm.state,
                                     &ec->icccm.icon_pixmap,
                                     &ec->icccm.icon_mask,
                                     (Ecore_X_Window*)&ec->icccm.icon_window,
                                     (Ecore_X_Window*)&ec->icccm.window_group,
                                     &is_urgent))
           {
+             if (ec->new_client)
+               ec->icccm.initial_state = ec->icccm.state;
+             if (state != ec->icccm.state)
+               {
+                  ecore_x_icccm_state_set(win, ec->icccm.state);
+                  if (ec->icccm.state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+                    ec->ignored = 1, ec->visible = 0;
+                  else
+                    {
+                       ec->ignored = ec->changes.visible = ec->visible = 1;
+                       e_client_unignore(ec);
+                    }
+               }
              ec->icccm.accepts_focus = accepts_focus;
              ec->icccm.urgent = is_urgent;
              e_client_urgent_set(ec, is_urgent);
@@ -4358,7 +4366,7 @@ _e_comp_x_hook_client_new(void *d EINA_UNUSED, E_Client 
*ec)
    ec->changes.shape_input = 1;
 
    ec->netwm.type = E_WINDOW_TYPE_UNKNOWN;
-   ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NONE;
+   ec->icccm.state =ec->icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NONE;
 
    if (!_e_comp_x_client_new_helper(ec)) return;
    ec->ignored |= e_comp->comp_type == E_PIXMAP_TYPE_WL;
@@ -4977,7 +4985,8 @@ _e_comp_x_manage_windows(void)
                   evas_object_geometry_set(ec->frame, ec->client.x, 
ec->client.y, ec->client.w, ec->client.h);
                }
              ec->ignore_first_unmap = 1;
-             evas_object_show(ec->frame);
+             if (ec->override || (!ec->icccm.fetch.hints))
+               evas_object_show(ec->frame);
              _e_comp_x_client_stack(ec);
           }
      }
diff --git a/src/bin/e_hints.c b/src/bin/e_hints.c
index f95fed2..101f975 100644
--- a/src/bin/e_hints.c
+++ b/src/bin/e_hints.c
@@ -411,7 +411,7 @@ e_hints_window_init(E_Client *ec)
    if (ec->remember)
      rem = ec->remember;
 
-   if (ec->icccm.state == ECORE_X_WINDOW_STATE_HINT_NONE)
+   if (ec->icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_NONE)
      {
         if (ec->netwm.state.hidden)
           ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
@@ -560,7 +560,7 @@ e_hints_window_init(E_Client *ec)
    else if (ec->desk == e_desk_current_get(ec->zone))
      {
         /* ...but only if it's supposed to be shown */
-        if (ec->re_manage)
+        if (ec->re_manage && (ec->icccm.state != 
ECORE_X_WINDOW_STATE_HINT_WITHDRAWN))
           {
              ec->changes.visible = 1;
              ec->visible = 1;
@@ -1239,9 +1239,11 @@ e_hints_window_visible_set(E_Client *ec)
    (void)ec;
 #else
    if (!e_client_has_xwindow(ec)) return;
-   if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
-     ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
-   ecore_x_icccm_state_set(e_client_util_win_get(ec), 
ECORE_X_WINDOW_STATE_HINT_NORMAL);
+   if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+     {
+        ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
+        ecore_x_icccm_state_set(e_client_util_win_get(ec), 
ECORE_X_WINDOW_STATE_HINT_NORMAL);
+     }
    if (ec->netwm.state.hidden)
      {
         ec->netwm.update.state = 1;
@@ -1259,9 +1261,11 @@ e_hints_window_iconic_set(E_Client *ec)
    (void)ec;
 #else
    if (!e_client_has_xwindow(ec)) return;
-   if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_ICONIC)
-     ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
-   ecore_x_icccm_state_set(e_client_util_win_get(ec), 
ECORE_X_WINDOW_STATE_HINT_ICONIC);
+   if (ec->icccm.state != ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
+     {
+        ec->icccm.state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
+        ecore_x_icccm_state_set(e_client_util_win_get(ec), 
ECORE_X_WINDOW_STATE_HINT_ICONIC);
+     }
    if (!ec->netwm.state.hidden)
      {
         ec->netwm.update.state = 1;

-- 


Reply via email to