e_client: client which obscured by child can take focus 99/225999/3
authorJunseok, Kim <juns.kim@samsung.com>
Wed, 26 Feb 2020 05:47:40 +0000 (14:47 +0900)
committerDoyoun Kang <doyoun.kang@samsung.com>
Sun, 1 Mar 2020 23:22:22 +0000 (23:22 +0000)
Change-Id: I657aa16274c13839bd7f3e1e17861c39d56d51e7

src/bin/e_client.c

index b47d217e48da458bc036230ccf63cb210125327b..d1acd6a9e98cd092c987a6d64384831c4719064f 100644 (file)
@@ -70,6 +70,7 @@ static Eina_Bool _e_calc_visibility = EINA_FALSE;
 static Eina_Bool _e_visibility_changed = EINA_FALSE;
 
 EINTERN void e_client_focused_set(E_Client *ec);
+static void _e_client_transient_for_group_make(E_Client *ec, Eina_List **list);
 
 static Eina_Inlist *_e_client_hooks[] =
 {
@@ -832,9 +833,51 @@ _e_client_check_fully_contain_by_above(E_Client *ec, Eina_Bool check_layer)
    return above;
 }
 
+static E_Client *
+_e_client_check_obscured_by_children_group(E_Client *ec)
+{
+   E_Client *cec = NULL;
+   Eina_List *transients = NULL, *l = NULL;
+
+   _e_client_transient_for_group_make(ec, &transients);
+
+   EINA_LIST_FOREACH(transients, l, cec)
+     {
+        if (cec->transient_policy == E_TRANSIENT_BELOW)
+          continue;
+
+        if (!E_CONTAINS(cec->x, cec->y, cec->w, cec->h, ec->x, ec->y, ec->w, ec->h))
+          continue;
+
+        if (!cec->argb) goto finish;
+        else if (cec->visibility.opaque > 0) goto finish;
+     }
+
+finish:
+   if (transients)
+     eina_list_free(transients);
+
+   return cec;
+}
+
+static Eina_Bool
+_e_client_check_really_iconified(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   if (ec->iconic &&
+       !(e_policy_visibility_client_is_uniconic(ec) ||
+         e_policy_visibility_client_is_uniconify_render_running(ec)))
+     return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
 static Eina_Bool
 _e_client_focus_can_take(E_Client *ec)
 {
+   E_Client *cec = NULL;
+
    if (!ec) return EINA_FALSE;
    if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
    if (e_client_util_ignored_get(ec)) return EINA_FALSE;
@@ -842,16 +885,18 @@ _e_client_focus_can_take(E_Client *ec)
    if (ec->lock_focus_in || ec->lock_focus_out) return EINA_FALSE;
    if (!ec->visible) return EINA_FALSE;
    if (ec->bg_state) return EINA_FALSE;
-   if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED)
+   if (!(cec = _e_client_check_obscured_by_children_group(ec)) ||
+       _e_client_check_really_iconified(cec))
      {
-        if (ec->iconic &&
-            !(e_policy_visibility_client_is_uniconic(ec) ||
-              e_policy_visibility_client_is_uniconify_render_running(ec)))
-          return EINA_FALSE;
-        if (ec->visibility.obscured == E_VISIBILITY_UNKNOWN)
-          return EINA_FALSE;
+        if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED)
+          {
+             if (_e_client_check_really_iconified(ec))
+               return EINA_FALSE;
+             if (ec->visibility.obscured == E_VISIBILITY_UNKNOWN)
+               return EINA_FALSE;
+          }
+        if (_e_client_check_fully_contain_by_above(ec, EINA_FALSE)) return EINA_FALSE;
      }
-   if (_e_client_check_fully_contain_by_above(ec, EINA_FALSE)) return EINA_FALSE;
 
    return EINA_TRUE;
 }
@@ -3526,7 +3571,7 @@ static void
 _e_client_focus_calculate(E_Zone *zone)
 {
    E_Client *defered_focus_ec = NULL, *reverted_focus_ec = NULL;
-   E_Client *ec = NULL;
+   E_Client *ec = NULL, *old_focused = NULL, *cec = NULL;
 
    EINA_SAFETY_ON_NULL_RETURN(zone);
    if (zone->display_state == E_ZONE_DISPLAY_STATE_OFF) return;
@@ -3550,8 +3595,7 @@ _e_client_focus_calculate(E_Zone *zone)
         if (!reverted_focus_ec && focused)
           {
              e_client_focus_defer_unset(focused);
-             ELOGF("FOCUS", "focus unset | focus calculate", focused);
-             e_client_frame_focus_set(focused, EINA_FALSE);
+             old_focused = focused;
           }
      }
 
@@ -3570,8 +3614,13 @@ _e_client_focus_calculate(E_Zone *zone)
         if (!evas_object_visible_get(ec->frame)) continue;
         if (ec->iconic) continue;
         if (ec->bg_state) continue;
-        if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) continue;
-        if (_e_client_check_fully_contain_by_above(ec, EINA_FALSE)) continue;
+
+        if (!(cec = _e_client_check_obscured_by_children_group(ec)) ||
+            _e_client_check_really_iconified(cec))
+          {
+             if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) continue;
+             if (_e_client_check_fully_contain_by_above(ec, EINA_FALSE)) continue;
+          }
 
         if (focused && (focused->layer > ec->layer)) continue;
         else if (!focused && reverted_focus_ec && (reverted_focus_ec->layer > ec->layer)) continue;
@@ -3606,6 +3655,11 @@ _e_client_focus_calculate(E_Zone *zone)
 
         e_client_focus_defer_unset(reverted_focus_ec);
      }
+   else if (old_focused)
+     {
+        ELOGF("FOCUS", "focus unset | focus calculate", old_focused);
+        e_client_frame_focus_set(old_focused, EINA_FALSE);
+     }
 
    return;
 }