e_focus_policy_history: fix the focus_stack and the defer_focus_stack 64/297564/1
authorSooChan Lim <sc1.lim@samsung.com>
Thu, 17 Aug 2023 03:00:47 +0000 (12:00 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 21 Aug 2023 07:58:40 +0000 (16:58 +0900)
There is many bugs to manage the focus_stack and the defer_focus_stack.
Fix some issues to follow the legacy focus stack management.

Change-Id: I665314108c21d5dfbfbb84fed03d499e31321f0d

src/bin/e_focus_policy_history.c

index de842ea..ec4cc3a 100644 (file)
@@ -23,12 +23,8 @@ struct _E_Focus_Policy_History_Impl
 static void
 _focus_policy_history_focus_stack_latest_set(E_Focus_Policy_History *history_policy, E_Client *ec)
 {
-   Eina_List *focus_stack;
-
-   focus_stack = history_policy->focus_stack;
-
-   focus_stack = eina_list_remove(focus_stack, ec);
-   focus_stack = eina_list_prepend(focus_stack, ec);
+   history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
+   history_policy->focus_stack = eina_list_prepend(history_policy->focus_stack, ec);
 }
 
 static void
@@ -36,47 +32,37 @@ _focus_policy_history_focus_stack_lower(E_Focus_Policy_History *history_policy,
 {
    Eina_List *l = NULL;
    E_Client *ec2 = NULL;
-   Eina_List *focus_stack;
-
-   focus_stack = history_policy->focus_stack;
 
-   focus_stack = eina_list_remove(focus_stack, ec);
+   history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
 
-   EINA_LIST_REVERSE_FOREACH(focus_stack, l, ec2)
+   EINA_LIST_REVERSE_FOREACH(history_policy->focus_stack, l, ec2)
      {
         if (ec2 == NULL) continue;
         if (ec2->layer < ec->layer) continue;
 
-        focus_stack = eina_list_append_relative_list(focus_stack, ec, l);
+        history_policy->focus_stack = eina_list_append_relative_list(history_policy->focus_stack, ec, l);
 
         return;
      }
 
-   focus_stack = eina_list_prepend(focus_stack, ec);
-
-   return;
+   history_policy->focus_stack = eina_list_prepend(history_policy->focus_stack, ec);
 }
 
 static void
-_focus_policy_history_focus_focus_defer_set(E_Focus_Policy_History *history_policy, E_Client *ec)
+_e_focus_policy_history_focus_focus_defer_set(E_Focus_Policy_History *history_policy, E_Client *ec)
 {
-   Eina_List *defer_focus_stack;
-
-   defer_focus_stack = history_policy->defer_focus_stack;
+   ELOGF("FOCUS", "focus defer set", ec);
 
-   defer_focus_stack = eina_list_remove(defer_focus_stack, ec);
-   defer_focus_stack = eina_list_prepend(defer_focus_stack, ec);
+   history_policy->defer_focus_stack = eina_list_remove(history_policy->defer_focus_stack, ec);
+   history_policy->defer_focus_stack = eina_list_prepend(history_policy->defer_focus_stack, ec);
 }
 
 static void
 _e_focus_policy_history_focus_defer_unset(E_Focus_Policy_History *history_policy, E_Client *ec)
 {
-   Eina_List *defer_focus_stack;
-
    ELOGF("FOCUS", "focus defer unset", ec);
 
-   defer_focus_stack = history_policy->defer_focus_stack;
-   defer_focus_stack = eina_list_remove(defer_focus_stack, ec);
+   history_policy->defer_focus_stack = eina_list_remove(history_policy->defer_focus_stack, ec);
 }
 
 static void
@@ -86,28 +72,25 @@ _e_focus_policy_history_merge_focus_stack_with_defer_focus(E_Focus_Policy_Histor
    E_Client *ec = NULL, *defer_ec = NULL;
    Eina_Bool find_rel = EINA_FALSE;
    Eina_Bool inserted = EINA_FALSE;
-   Eina_List *focus_stack, *defer_focus_stack;
    E_Client *focused_ec;
 
    focused_ec = history_policy->focused_ec;
-   focus_stack = history_policy->focus_stack;
-   defer_focus_stack = history_policy->defer_focus_stack;
 
-   if (!focus_stack)
+   if (!history_policy->focus_stack)
      {
-        focus_stack = eina_list_merge(focus_stack, defer_focus_stack);
+        history_policy->focus_stack = eina_list_merge(history_policy->focus_stack, history_policy->defer_focus_stack);
         goto end;
      }
 
    E_CLIENT_FOREACH(defer_ec)
      {
-        if (!eina_list_data_find(defer_focus_stack, defer_ec)) continue;
+        if (!eina_list_data_find(history_policy->defer_focus_stack, defer_ec)) continue;
 
         find_rel = EINA_FALSE;
         inserted = EINA_FALSE;
-        focus_stack = eina_list_remove(focus_stack, defer_ec);
+        history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, defer_ec);
 
-        EINA_LIST_FOREACH(focus_stack, l, ec)
+        EINA_LIST_FOREACH(history_policy->focus_stack, l, ec)
           {
              if (ec == NULL) continue;
 
@@ -120,19 +103,17 @@ _e_focus_policy_history_merge_focus_stack_with_defer_focus(E_Focus_Policy_Histor
 
              if (ec->layer > defer_ec->layer) continue;
 
-             focus_stack = eina_list_prepend_relative_list(focus_stack, defer_ec, l);
+             history_policy->focus_stack = eina_list_prepend_relative_list(history_policy->focus_stack, defer_ec, l);
              inserted = EINA_TRUE;
              break;
           }
 
         if (!inserted)
-          focus_stack = eina_list_append(focus_stack, defer_ec);
+          history_policy->focus_stack = eina_list_append(history_policy->focus_stack, defer_ec);
      }
 
 end:
-   defer_focus_stack = eina_list_free(defer_focus_stack);
-
-   return;
+   history_policy->defer_focus_stack = eina_list_free(history_policy->defer_focus_stack);
 }
 
 static E_Client *
@@ -144,15 +125,13 @@ _e_focus_policy_history_candidate_focus_get(E_Focus_Policy_History *history_poli
    Eina_List *l = NULL;
    Eina_Bool child_deferred;
    E_Zone *zone;
-   Eina_List *defer_focus_stack;
 
-   defer_focus_stack = history_policy->defer_focus_stack;
    zone = history_policy->zone;
    focused_ec = history_policy->focused_ec;
 
    E_CLIENT_REVERSE_FOREACH(ec)
      {
-        if (!eina_list_data_find(defer_focus_stack, ec)) continue;
+        if (!eina_list_data_find(history_policy->defer_focus_stack, ec)) continue;
 
         if (e_object_is_del(E_OBJECT(ec))) continue;
         if (e_client_util_ignored_get(ec)) continue;
@@ -183,7 +162,7 @@ _e_focus_policy_history_candidate_focus_get(E_Focus_Policy_History *history_poli
           {
              if (e_client_transient_policy_get(cec) == E_TRANSIENT_BELOW) continue;
              if (!(cec->icccm.accepts_focus || cec->icccm.take_focus)) continue;
-             if (eina_list_data_find(defer_focus_stack, cec))
+             if (eina_list_data_find(history_policy->defer_focus_stack, cec))
                {
                   child_deferred = EINA_TRUE;
                   break;
@@ -202,10 +181,6 @@ _e_focus_policy_history_candidate_focus_get(E_Focus_Policy_History *history_poli
 static Eina_Bool
 _e_focus_policy_history_focus_can_take_by_vis_obscured(E_Focus_Policy_History *history_policy, E_Client *ec)
 {
-   Eina_List *defer_focus_stack;
-
-   defer_focus_stack = history_policy->defer_focus_stack;
-
    switch (ec->visibility.obscured)
      {
        case E_VISIBILITY_UNKNOWN:
@@ -213,7 +188,7 @@ _e_focus_policy_history_focus_can_take_by_vis_obscured(E_Focus_Policy_History *h
              return EINA_FALSE;
 
            if (!evas_object_visible_get(ec->frame) &&
-               !eina_list_data_find(defer_focus_stack, ec))
+               !eina_list_data_find(history_policy->defer_focus_stack, ec))
              return EINA_FALSE;
            break;
 
@@ -279,15 +254,12 @@ _focus_policy_history_find_next_focusable_ec(E_Focus_Policy_History *history_pol
 {
    Eina_List *l = NULL;
    E_Client *temp_ec = NULL;
-   Eina_List *focus_stack;
 
    // call the intercept hook of the revert focus
    if (e_client_intercept_hook_focus_revert_call(ec))
      return NULL;
 
-   focus_stack = history_policy->focus_stack;
-
-   EINA_LIST_FOREACH(focus_stack, l, temp_ec)
+   EINA_LIST_FOREACH(history_policy->focus_stack, l, temp_ec)
      {
         if (_e_focus_policy_history_focus_can_take(history_policy, temp_ec))
           return temp_ec;
@@ -602,10 +574,9 @@ _focus_policy_history_hook_cb_client_focus_defer_set(void *data, E_Client *ec)
    history_policy = (E_Focus_Policy_History *)data;
    if (!history_policy) return;
 
-   ELOGF("FOCUS", "focus defer set", ec);
+   ELOGF("FOCUS", "focus defer set callback. e_client_focus_defer_set is called.", ec);
 
-   //ELOGF("FOCUS", "focus defer set", ec);
-   _focus_policy_history_focus_focus_defer_set(history_policy, ec);
+   _e_focus_policy_history_focus_focus_defer_set(history_policy, ec);
 }
 
 static void
@@ -617,6 +588,7 @@ _focus_policy_history_hook_cb_client_focus_latest_set(void *data, E_Client *ec)
    if (!history_policy) return;
 
    //ELOGF("FOCUS", "focus latest set", ec);
+
    _focus_policy_history_focus_stack_latest_set(history_policy, ec);
 }
 
@@ -649,7 +621,7 @@ _focus_policy_history_hook_cb_client_activate_done(void *data, E_Client *ec)
       {
          if (!e_policy_visibility_client_is_uniconic(ec))
            {
-              _focus_policy_history_focus_focus_defer_set(history_policy, ec);
+              _e_focus_policy_history_focus_focus_defer_set(history_policy, focus_ec);
               _focus_policy_history_focus_stack_latest_set(history_policy, focus_ec);
            }
          else
@@ -660,7 +632,7 @@ _focus_policy_history_hook_cb_client_activate_done(void *data, E_Client *ec)
       }
     else
       {
-         _focus_policy_history_focus_focus_defer_set(history_policy, ec);
+         _e_focus_policy_history_focus_focus_defer_set(history_policy, focus_ec);
          _focus_policy_history_focus_stack_latest_set(history_policy, focus_ec);
       }
 }
@@ -669,13 +641,11 @@ static void
 _focus_policy_history_hook_cb_client_eval_end(void *data, E_Client *ec)
 {
    E_Focus_Policy_History *history_policy;
-   Eina_List *focus_stack;
    E_Client *focused_ec;
 
    history_policy = (E_Focus_Policy_History *)data;
    if (!history_policy) return;
 
-   focus_stack = history_policy->focus_stack;
    focused_ec = history_policy->focused_ec;
 
    if ((!ec->input_only) && (!ec->iconic) &&
@@ -692,7 +662,7 @@ _focus_policy_history_hook_cb_client_eval_end(void *data, E_Client *ec)
              /* focus window by default when it is the only one on desk */
              E_Client *ec2 = NULL;
              Eina_List *l;
-             EINA_LIST_FOREACH(focus_stack, l, ec2)
+             EINA_LIST_FOREACH(history_policy->focus_stack, l, ec2)
                {
                   if (ec == ec2) continue;
                   if ((!ec2->iconic) && (ec2->visible) &&
@@ -735,20 +705,34 @@ _focus_policy_hook_history_cb_comp_object_lower(void *data, E_Client *ec)
    return EINA_TRUE;
 }
 
+static void
+_e_focus_policy_history_focus_stack_append_current_focused(E_Focus_Policy_History *history_policy, E_Client *ec)
+{
+   Eina_List *l = NULL;
+   E_Client *focused_ec, *temp_ec = NULL;
+
+   focused_ec = history_policy->focused_ec;
+   history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
+
+   EINA_LIST_FOREACH(history_policy->focus_stack, l, temp_ec)
+     {
+        if (temp_ec != focused_ec) continue;
+
+        history_policy->focus_stack = eina_list_append_relative_list(history_policy->focus_stack, ec, l);
+        return;
+     }
+
+   history_policy->focus_stack = eina_list_prepend(history_policy->focus_stack, ec);
+}
+
 static Eina_Bool
 _focus_policy_history_hook_cb_comp_object_show(void *data, E_Client *ec)
 {
    E_Focus_Policy_History *history_policy;
-   Eina_List *focus_stack;
-   E_Client *focused_ec, *temp_ec;
-   Eina_List *l;
 
    history_policy = (E_Focus_Policy_History *)data;
    if (!history_policy) return EINA_TRUE;
 
-   focused_ec = history_policy->focused_ec;
-   focus_stack = history_policy->focus_stack;
-
    if (!e_client_is_iconified_by_client(ec)||
        e_policy_visibility_client_is_uniconic(ec))
     {
@@ -757,21 +741,9 @@ _focus_policy_history_hook_cb_comp_object_show(void *data, E_Client *ec)
          {
             if (ec->exp_iconify.not_raise &&
                 e_client_check_above_focused(ec))
-              {
-                 //e_client_focus_stack_append_current_focused(ec);
-                 focus_stack = eina_list_remove(focus_stack, ec);
-                 EINA_LIST_FOREACH(focus_stack, l, temp_ec)
-                   {
-                      if (temp_ec != focused_ec) continue;
-
-                      focus_stack = eina_list_append_relative_list(focus_stack, ec, l);
-                      break;
-                   }
-                 focus_stack = eina_list_prepend(focus_stack, ec);
-              }
+              _e_focus_policy_history_focus_stack_append_current_focused(history_policy, ec);
             else
-               _e_focus_policy_history_focus_defer_unset(history_policy, ec);
-
+              _e_focus_policy_history_focus_focus_defer_set(history_policy, ec);
          }
     }
 
@@ -788,10 +760,13 @@ _focus_policy_history_hook_cb_comp_object_hide(void *data, E_Client *ec)
 
    if (history_policy->focused_ec != ec) return EINA_TRUE;
 
-   /* ensure focus-out */
-   ELOGF("FOCUS", "focus unset | comp_object_hide ", ec);
-   e_client_frame_focus_set(ec, EINA_FALSE);
-   _e_focus_policy_history_focus_defer_unset(history_policy, ec);
+   if (ec->focused)
+     {
+        /* ensure focus-out */
+        ELOGF("FOCUS", "focus unset | comp_object_hide ", ec);
+        e_client_frame_focus_set(ec, EINA_FALSE);
+        _e_focus_policy_history_focus_defer_unset(history_policy, ec);
+     }
 
    return EINA_TRUE;
 }
@@ -820,7 +795,6 @@ _focus_policy_history_hook_cb_zone_focus_reset(void *data, E_Zone *zone)
    E_Focus_Policy_History *history_policy;
    E_Client *ec;
    const Eina_List *l;
-   Eina_List *focus_stack;
 
    history_policy = (E_Focus_Policy_History *)data;
    if (!history_policy) return;
@@ -829,9 +803,7 @@ _focus_policy_history_hook_cb_zone_focus_reset(void *data, E_Zone *zone)
 
    if (e_config->focus_policy == E_FOCUS_MOUSE) return;
 
-   focus_stack = history_policy->focus_stack;
-
-   EINA_LIST_FOREACH(focus_stack, l, ec)
+   EINA_LIST_FOREACH(history_policy->focus_stack, l, ec)
      if (ec->desk && ec->desk->visible && (!ec->iconic))
        {
           g_mutex_lock(&e_comp->input_key_grabs_mutex);
@@ -906,7 +878,6 @@ _focus_policy_history_update(E_Focus_Policy_Impl *impl)
    E_Zone *zone;
    E_Client *defered_focus_ec, *reverted_focus_ec = NULL;
    E_Client *focused_ec, *old_focused_ec = NULL;
-   Eina_List *focus_stack;
 
    history_policy = (E_Focus_Policy_History *)impl;
    EINA_SAFETY_ON_NULL_RETURN_VAL(history_policy, EINA_FALSE);
@@ -920,10 +891,8 @@ _focus_policy_history_update(E_Focus_Policy_Impl *impl)
    // current focused ec
    focused_ec = history_policy->focused_ec;
 
-   focus_stack = history_policy->focus_stack;
-
    if ((!focused_ec) ||
-       (focused_ec != eina_list_data_get(focus_stack)) ||
+       (focused_ec != eina_list_data_get(history_policy->focus_stack)) ||
        (!_e_focus_policy_history_focus_can_take(history_policy, focused_ec)))
      {
         reverted_focus_ec = _focus_policy_history_focusable_get(history_policy, focused_ec);