e_focus_policy_history: Use wl_listener instead of Hooks 70/300370/2
authorSooChan Lim <sc1.lim@samsung.com>
Wed, 4 Oct 2023 08:43:11 +0000 (17:43 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 23 Oct 2023 06:22:21 +0000 (06:22 +0000)
Change-Id: Ic05c869e67fe221d235dfd7f0b1366a3479d498a

src/bin/e_client.c
src/bin/e_client.h
src/bin/e_focus_policy_history.c
src/bin/e_policy_stack.c

index 784fe36..b2a6756 100644 (file)
@@ -9091,6 +9091,14 @@ e_client_uniconify_event_send(E_Client *ec)
 #endif
 
 EINTERN void
+e_client_stack_transient_for_done_notify(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   wl_signal_emit_mutable(&PRI(ec)->events.stack_transient_for_done, NULL);
+}
+
+EINTERN void
 e_client_eval_pre_fetch_listener_add(E_Client *ec, struct wl_listener *listener)
 {
    API_ENTRY;
index 74a2107..2411672 100644 (file)
@@ -1396,6 +1396,8 @@ EINTERN void e_client_frame_update(E_Client *ec);
 EINTERN Eina_Bool e_client_is_parent_iconify_by_client(E_Client *ec);
 //#endif
 
+EINTERN void e_client_stack_transient_for_done_notify(E_Client *ec);
+
 /**
  * Move window to coordinates that do not account client decorations yet.
  *
index d1c0ac5..4b5e814 100644 (file)
@@ -1,8 +1,12 @@
 #include "e.h"
+#include "e_zone_intern.h"
+#include "e_client_intern.h"
+#include "e_comp_object_intern.h"
 
 #ifdef REFACTOR_FOCUS_POLICY
 
 typedef struct _E_Focus_Policy_History_Impl E_Focus_Policy_History;
+typedef struct _E_Focus_Policy_History_Client E_Focus_Policy_History_Client;
 
 struct _E_Focus_Policy_History_Impl
 {
@@ -14,10 +18,34 @@ struct _E_Focus_Policy_History_Impl
    Eina_List *focus_stack;
    Eina_List *defer_focus_stack;
 
-   Eina_List *ec_hooks;
-   Eina_List *co_hooks;
-   Eina_List *zone_hooks;
-   Eina_List *policy_hooks;
+   struct wl_listener zone_client_add;
+   struct wl_listener zone_client_remove;
+   struct wl_listener zone_focus_clear;
+   struct wl_listener zone_focus_reset;
+};
+
+struct _E_Focus_Policy_History_Client
+{
+   E_Client *ec;
+   E_Focus_Policy_History *history_policy;
+
+   struct wl_listener client_destroy;
+   struct wl_listener client_mouse_in;
+   struct wl_listener client_mouse_out;
+   struct wl_listener client_mouse_down;
+   struct wl_listener client_focus_set;
+   struct wl_listener client_focus_unset;
+   struct wl_listener client_lower;
+   struct wl_listener client_move;
+   struct wl_listener client_focus_defer_set;
+   struct wl_listener client_focus_latest_set;
+   struct wl_listener client_activate_done;
+   struct wl_listener client_eval_end;
+   struct wl_listener stack_transient_for_done;
+
+   struct wl_listener comp_object_lower;
+   struct wl_listener comp_object_show;
+   struct wl_listener comp_object_hide;
 };
 
 // Trace the focus history
@@ -37,8 +65,6 @@ struct _E_Focus_Policy_History_Impl
 #define E_FOCUS_HISTORY_TRACE(history_policy, ec)
 #endif
 
-
-
 static void
 _focus_policy_history_focus_stack_latest_set(E_Focus_Policy_History *history_policy, E_Client *ec)
 {
@@ -351,43 +377,57 @@ _focus_policy_history_next_focus_set(E_Focus_Policy_History *history_policy, E_C
 }
 
 static void
-_focus_policy_history_hook_cb_client_del(void *data, E_Client *ec)
+_focus_policy_history_cb_client_destroy(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_destroy);
 
-   E_FOCUS_HISTORY_TRACE(history_policy, ec);
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
 
-   // remove ec from focus stack and defer_focus_stack
-   history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
-   _e_focus_policy_history_focus_defer_unset(history_policy, ec);
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
-   // find the next focus and set it when ec is focused.
-   if (ec->focused)
-     {
-        _focus_policy_history_next_focus_set(history_policy, ec);
+   E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
-        // check the critical case
-        if (history_policy->focused_ec == ec)
-          {
-             ELOGF("FOCUS_HISTORY", "CRITICAL. focused is deleted ec.", ec);
-             ELOGF("FOCUS_HISTORY", "CLIENT FOCUS_SET", NULL);
-             g_mutex_lock(&history_policy->focused_ec_mutex);
-             history_policy->focused_ec = NULL;
-             g_mutex_unlock(&history_policy->focused_ec_mutex);
-         }
-     }
+   wl_list_remove(&history_client->comp_object_hide.link);
+   wl_list_remove(&history_client->comp_object_show.link);
+   wl_list_remove(&history_client->comp_object_lower.link);
+
+   wl_list_remove(&history_client->stack_transient_for_done.link);
+   wl_list_remove(&history_client->client_eval_end.link);
+   wl_list_remove(&history_client->client_activate_done.link);
+   wl_list_remove(&history_client->client_focus_latest_set.link);
+   wl_list_remove(&history_client->client_focus_defer_set.link);
+   wl_list_remove(&history_client->client_lower.link);
+   wl_list_remove(&history_client->client_move.link);
+   wl_list_remove(&history_client->client_focus_unset.link);
+   wl_list_remove(&history_client->client_focus_set.link);
+   wl_list_remove(&history_client->client_mouse_down.link);
+   wl_list_remove(&history_client->client_mouse_out.link);
+   wl_list_remove(&history_client->client_mouse_in.link);
+   wl_list_remove(&history_client->client_destroy.link);
+
+   E_FREE(history_client);
 }
 
 static void
-_focus_policy_history_hook_cb_client_mouse_in(void *data, E_Client *ec)
+_focus_policy_history_cb_client_mouse_in(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_mouse_in);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -409,12 +449,19 @@ _focus_policy_history_hook_cb_client_mouse_in(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_mouse_out(void *data, E_Client *ec)
+_focus_policy_history_cb_client_mouse_out(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_mouse_out);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -435,13 +482,20 @@ _focus_policy_history_hook_cb_client_mouse_out(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_mouse_down(void *data, E_Client *ec)
+_focus_policy_history_cb_client_mouse_down(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
    E_Client *focused_ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_mouse_down);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -476,15 +530,21 @@ _focus_policy_history_hook_cb_client_mouse_down(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_focus_set(void *data, E_Client *ec)
+_focus_policy_history_cb_client_focus_set(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
-   E_Client *focused_ec, *ec2;
+   E_Client *focused_ec, *ec, *ec2;
    E_Zone *zone;
    Eina_List *l, *ll;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_focus_set);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -527,16 +587,20 @@ _focus_policy_history_hook_cb_client_focus_set(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_focus_unset(void *data, E_Client *ec)
+_focus_policy_history_cb_client_focus_unset(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec, *ec2;
    E_Zone *zone;
-   E_Client *ec2;
    Eina_List *l;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_focus_unset);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
 
+   ec = history_client->ec;
    EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
@@ -583,12 +647,19 @@ _focus_policy_history_hook_cb_client_focus_unset(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_lower(void *data, E_Client *ec)
+_focus_policy_history_cb_client_lower(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_lower);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -603,13 +674,20 @@ _focus_policy_history_hook_cb_client_lower(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_move(void *data, E_Client *ec)
+_focus_policy_history_cb_client_move(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
    E_Zone *zone;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_move);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -629,12 +707,19 @@ _focus_policy_history_hook_cb_client_move(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_focus_defer_set(void *data, E_Client *ec)
+_focus_policy_history_cb_client_focus_defer_set(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_focus_defer_set);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -644,12 +729,19 @@ _focus_policy_history_hook_cb_client_focus_defer_set(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_focus_latest_set(void *data, E_Client *ec)
+_focus_policy_history_cb_client_focus_latest_set(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_focus_latest_set);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -659,14 +751,21 @@ _focus_policy_history_hook_cb_client_focus_latest_set(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_activate_done(void *data, E_Client *ec)
+_focus_policy_history_cb_client_activate_done(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
    E_Client *focus_ec = NULL;
    E_Client *obscured_above = NULL;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_activate_done);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -706,14 +805,20 @@ _focus_policy_history_hook_cb_client_activate_done(void *data, E_Client *ec)
 }
 
 static void
-_focus_policy_history_hook_cb_client_eval_end(void *data, E_Client *ec)
+_focus_policy_history_cb_client_eval_end(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *focused_ec, *ec;
    E_Zone *zone;
-   E_Client *focused_ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_client = wl_container_of(listener, history_client, client_eval_end);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -761,22 +866,55 @@ _focus_policy_history_hook_cb_client_eval_end(void *data, E_Client *ec)
      ec->take_focus = ec->want_focus = 0;
 }
 
-static Eina_Bool
-_focus_policy_history_hook_cb_comp_object_lower(void *data, E_Client *ec)
+static void
+_focus_policy_history_cb_stack_transient_for_done(struct wl_listener *listener, void *data)
+{
+   E_Focus_Policy_History_Client *history_client;
+   E_Focus_Policy_History *history_policy;
+   E_Client *new_focus, *ec;
+
+   history_client = wl_container_of(listener, history_client, stack_transient_for_done);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   E_FOCUS_HISTORY_TRACE(history_policy, ec);
+
+   if (!ec->parent) return;
+   if (ec->parent != history_policy->focused_ec) return;
+
+   new_focus = e_client_transient_child_top_get(ec->parent, EINA_TRUE);
+   if (!new_focus) return;
+
+   ELOGF("FOCUS_HISTORY", "focus set   | tranient_for fetch", new_focus);
+
+   e_client_frame_focus_set(new_focus, EINA_TRUE);
+}
+
+static void
+_focus_policy_history_cb_comp_object_lower(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
+
+   history_client = wl_container_of(listener, history_client, comp_object_lower);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return EINA_TRUE;
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
    // return if post_lower of ec is set
-   if (ec->post_lower) return EINA_TRUE;
+   if (ec->post_lower) return;
 
    _focus_policy_history_focus_stack_lower(history_policy, ec);
-
-   return EINA_TRUE;
 }
 
 static void
@@ -799,13 +937,20 @@ _e_focus_policy_history_focus_stack_append_current_focused(E_Focus_Policy_Histor
    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)
+static void
+_focus_policy_history_cb_comp_object_show(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return EINA_TRUE;
+   history_client = wl_container_of(listener, history_client, comp_object_show);
+
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -822,17 +967,22 @@ _focus_policy_history_hook_cb_comp_object_show(void *data, E_Client *ec)
               _e_focus_policy_history_focus_focus_defer_set(history_policy, ec);
          }
     }
-
-   return EINA_TRUE;
 }
 
-static Eina_Bool
-_focus_policy_history_hook_cb_comp_object_hide(void *data, E_Client *ec)
+static void
+_focus_policy_history_cb_comp_object_hide(struct wl_listener *listener, void *data)
 {
+   E_Focus_Policy_History_Client *history_client;
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
+
+   history_client = wl_container_of(listener, history_client, comp_object_hide);
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return EINA_TRUE;
+   history_policy = history_client->history_policy;
+   EINA_SAFETY_ON_NULL_RETURN(history_policy);
+
+   ec = history_client->ec;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
 
    E_FOCUS_HISTORY_TRACE(history_policy, ec);
 
@@ -843,21 +993,119 @@ _focus_policy_history_hook_cb_comp_object_hide(void *data, E_Client *ec)
         e_client_frame_focus_set(ec, EINA_FALSE);
         _e_focus_policy_history_focus_defer_unset(history_policy, ec);
      }
+}
 
-   return EINA_TRUE;
+static void
+_focus_policy_history_cb_zone_client_add(struct wl_listener *listener, void *data)
+{
+   E_Focus_Policy_History *history_policy;
+   E_Focus_Policy_History_Client *history_client;
+   E_Client *ec;
+   Evas_Object *obj;
+
+   history_policy = wl_container_of(listener, history_policy, zone_client_add);
+
+   ec = (E_Client *)data;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   E_FOCUS_HISTORY_TRACE(history_policy, ec);
+
+   obj = ec->frame;
+   EINA_SAFETY_ON_NULL_RETURN(obj);
+
+   history_client = E_NEW(E_Focus_Policy_History_Client, 1);
+   EINA_SAFETY_ON_NULL_RETURN(history_client);
+
+   history_client->ec = ec;
+   history_client->history_policy = history_policy;
+
+   // e_client listeners
+   history_client->client_destroy.notify = _focus_policy_history_cb_client_destroy;
+   e_client_destroy_listener_add(ec, &history_client->client_destroy);
+   history_client->client_mouse_in.notify = _focus_policy_history_cb_client_mouse_in;
+   e_client_mouse_in_listener_add(ec, &history_client->client_mouse_in);
+   history_client->client_mouse_out.notify = _focus_policy_history_cb_client_mouse_out;
+   e_client_mouse_out_listener_add(ec, &history_client->client_mouse_out);
+   history_client->client_mouse_down.notify = _focus_policy_history_cb_client_mouse_down;
+   e_client_mouse_down_listener_add(ec, &history_client->client_mouse_down);
+   history_client->client_focus_set.notify = _focus_policy_history_cb_client_focus_set;
+   e_client_focus_set_listener_add(ec, &history_client->client_focus_set);
+   history_client->client_focus_unset.notify = _focus_policy_history_cb_client_focus_unset;
+   e_client_focus_unset_listener_add(ec, &history_client->client_focus_unset);
+   history_client->client_lower.notify = _focus_policy_history_cb_client_lower;
+   e_client_lower_listener_add(ec, &history_client->client_lower);
+   history_client->client_move.notify = _focus_policy_history_cb_client_move;
+   e_client_move_listener_add(ec, &history_client->client_move);
+   history_client->client_focus_defer_set.notify = _focus_policy_history_cb_client_focus_defer_set;
+   e_client_focus_defer_set_listener_add(ec, &history_client->client_focus_defer_set);
+   history_client->client_focus_latest_set.notify = _focus_policy_history_cb_client_focus_latest_set;
+   e_client_focus_latest_set_listener_add(ec, &history_client->client_focus_latest_set);
+   history_client->client_activate_done.notify = _focus_policy_history_cb_client_activate_done;
+   e_client_activate_done_listener_add(ec, &history_client->client_activate_done);
+   history_client->client_eval_end.notify = _focus_policy_history_cb_client_eval_end;
+   e_client_eval_end_listener_add(ec, &history_client->client_eval_end);
+   history_client->stack_transient_for_done.notify = _focus_policy_history_cb_stack_transient_for_done;
+   e_client_stack_transient_for_done_listener_add(ec, &history_client->stack_transient_for_done);
+
+   // e_comp_object listeners
+   history_client->comp_object_lower.notify = _focus_policy_history_cb_comp_object_lower;
+   e_comp_object_lower_listener_add(obj, &history_client->comp_object_lower);
+   history_client->comp_object_show.notify = _focus_policy_history_cb_comp_object_show;
+   e_comp_object_show_listener_add(obj, &history_client->comp_object_show);
+   history_client->comp_object_hide.notify = _focus_policy_history_cb_comp_object_hide;
+   e_comp_object_hide_listener_add(obj, &history_client->comp_object_hide);
+
+   ELOGF("FOCUS_HISTORY", "zone_client_add | ", ec);
 }
 
 static void
-_focus_policy_history_hook_cb_zone_focus_clear(void *data, E_Zone *zone)
+_focus_policy_history_cb_zone_client_remove(struct wl_listener *listener, void *data)
 {
    E_Focus_Policy_History *history_policy;
+   E_Client *ec;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_policy = wl_container_of(listener, history_policy, zone_client_remove);
+
+   ec = (E_Client *)data;
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   E_FOCUS_HISTORY_TRACE(history_policy, ec);
+
+   ELOGF("FOCUS_HISTORY", "zone_client_remove | ", ec);
+
+   // remove ec from focus stack and defer_focus_stack
+   history_policy->focus_stack = eina_list_remove(history_policy->focus_stack, ec);
+   _e_focus_policy_history_focus_defer_unset(history_policy, ec);
+
+   // find the next focus and set it when ec is focused.
+   if (ec->focused)
+     {
+        _focus_policy_history_next_focus_set(history_policy, ec);
+
+        // check the critical case
+        if (history_policy->focused_ec == ec)
+          {
+             ELOGF("FOCUS_HISTORY", "CRITICAL. focused is deleted ec.", ec);
+             ELOGF("FOCUS_HISTORY", "CLIENT FOCUS_SET", NULL);
+             g_mutex_lock(&history_policy->focused_ec_mutex);
+             history_policy->focused_ec = NULL;
+             g_mutex_unlock(&history_policy->focused_ec_mutex);
+         }
+     }
+}
+
+static void
+_focus_policy_history_cb_zone_focus_clear(struct wl_listener *listener, void *data)
+{
+   E_Focus_Policy_History *history_policy;
+   E_Zone *zone;
+
+   history_policy = wl_container_of(listener, history_policy, zone_focus_clear);
 
    E_FOCUS_HISTORY_TRACE(history_policy, NULL);
 
-   if (history_policy->zone != zone) return;
+   zone = history_policy->zone;
+   EINA_SAFETY_ON_NULL_RETURN(zone);
 
    // make focused_ec be NULL
    g_mutex_lock(&history_policy->focused_ec_mutex);
@@ -868,21 +1116,22 @@ _focus_policy_history_hook_cb_zone_focus_clear(void *data, E_Zone *zone)
 }
 
 static void
-_focus_policy_history_hook_cb_zone_focus_reset(void *data, E_Zone *zone)
+_focus_policy_history_cb_zone_focus_reset(struct wl_listener *listener, void *data)
 {
    E_Focus_Policy_History *history_policy;
-   E_Client *ec;
+   E_Zone *zone;
    E_Desk *desk;
+   E_Client *ec;
    const Eina_List *l;
 
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
+   history_policy = wl_container_of(listener, history_policy, zone_focus_reset);
 
    E_FOCUS_HISTORY_TRACE(history_policy, NULL);
 
-   if (history_policy->zone != zone) return;
+   zone = history_policy->zone;
+   EINA_SAFETY_ON_NULL_RETURN(zone);
 
-   if (e_config->focus_policy == E_FOCUS_MOUSE) return;
+  if (e_config->focus_policy == E_FOCUS_MOUSE) return;
 
    EINA_LIST_FOREACH(history_policy->focus_stack, l, ec)
      {
@@ -906,27 +1155,6 @@ _focus_policy_history_hook_cb_zone_focus_reset(void *data, E_Zone *zone)
 }
 
 static void
-_focus_policy_history_hook_cb_policy_client_stack_transient_for_done(void *data, E_Client *ec)
-{
-   E_Focus_Policy_History *history_policy;
-   E_Client *new_focus;
-
-   history_policy = (E_Focus_Policy_History *)data;
-   if (!history_policy) return;
-
-   E_FOCUS_HISTORY_TRACE(history_policy, ec);
-
-   if (!ec->parent) return;
-   if (ec->parent != history_policy->focused_ec) return;
-
-   new_focus = e_client_transient_child_top_get(ec->parent, EINA_TRUE);
-   if (!new_focus) return;
-
-   ELOGF("FOCUS_HISTORY", "focus set   | tranient_for fetch", new_focus);
-   e_client_frame_focus_set(new_focus, EINA_TRUE);
-}
-
-static void
 _focus_policy_history_del(E_Focus_Policy_Impl *impl)
 {
    E_Focus_Policy_History *history_policy = (E_Focus_Policy_History *)impl;
@@ -940,9 +1168,10 @@ _focus_policy_history_del(E_Focus_Policy_Impl *impl)
    if (history_policy->defer_focus_stack)
      history_policy->defer_focus_stack = eina_list_free(history_policy->defer_focus_stack);
 
-   E_FREE_LIST(history_policy->zone_hooks, e_zone_hook_del);
-   E_FREE_LIST(history_policy->co_hooks, e_comp_object_hook_del);
-   E_FREE_LIST(history_policy->ec_hooks, e_client_hook_del);
+   wl_list_remove(&history_policy->zone_focus_reset.link);
+   wl_list_remove(&history_policy->zone_focus_clear.link);
+   wl_list_remove(&history_policy->zone_client_remove.link);
+   wl_list_remove(&history_policy->zone_client_add.link);
 
    g_mutex_clear(&history_policy->focused_ec_mutex);
 
@@ -1041,8 +1270,6 @@ e_focus_policy_iface_history_new(E_Zone* zone)
 {
    E_Focus_Policy_Iface *policy_iface;
    E_Focus_Policy_History *history_policy;
-   E_Zone_Hook *zone_hook;
-   E_Policy_Hook *policy_hook;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(zone, NULL);
 
@@ -1062,34 +1289,15 @@ e_focus_policy_iface_history_new(E_Zone* zone)
    policy_iface->focused_ec_get = _focus_policy_history_focused_ec_get;
    policy_iface->update = _focus_policy_history_update;
 
-   // e_client hooks
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_DEL, _focus_policy_history_hook_cb_client_del, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_MOUSE_IN, _focus_policy_history_hook_cb_client_mouse_in, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_MOUSE_OUT, _focus_policy_history_hook_cb_client_mouse_out, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_MOUSE_DOWN, _focus_policy_history_hook_cb_client_mouse_down, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_FOCUS_SET, _focus_policy_history_hook_cb_client_focus_set, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_FOCUS_UNSET, _focus_policy_history_hook_cb_client_focus_unset, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_LOWER, _focus_policy_history_hook_cb_client_lower, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_MOVE, _focus_policy_history_hook_cb_client_move, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_FOCUS_DEFER_SET, _focus_policy_history_hook_cb_client_focus_defer_set, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_FOCUS_LATEST_SET, _focus_policy_history_hook_cb_client_focus_latest_set, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_ACTIVATE_DONE, _focus_policy_history_hook_cb_client_activate_done, history_policy);
-   E_LIST_HOOK_APPEND(history_policy->ec_hooks, E_CLIENT_HOOK_EVAL_END, _focus_policy_history_hook_cb_client_eval_end, history_policy);
-
-   // e_comp_object hooks
-   E_COMP_COMP_HOOK_APPEND(history_policy->co_hooks, E_COMP_OBJECT_HOOK_LOWER, _focus_policy_history_hook_cb_comp_object_lower, history_policy);
-   E_COMP_COMP_HOOK_APPEND(history_policy->co_hooks, E_COMP_OBJECT_HOOK_SHOW,  _focus_policy_history_hook_cb_comp_object_show, history_policy);
-   E_COMP_COMP_HOOK_APPEND(history_policy->co_hooks, E_COMP_OBJECT_HOOK_HIDE,  _focus_policy_history_hook_cb_comp_object_hide, history_policy);
-
-   // e_zone hooks
-   zone_hook = e_zone_hook_add(E_ZONE_HOOK_FOCUS_CLEAR, _focus_policy_history_hook_cb_zone_focus_clear, history_policy);
-   if (zone_hook) history_policy->zone_hooks = eina_list_append(history_policy->zone_hooks, zone_hook);
-   zone_hook = e_zone_hook_add(E_ZONE_HOOK_FOCUS_RESET, _focus_policy_history_hook_cb_zone_focus_reset, history_policy);
-   if (zone_hook) history_policy->zone_hooks = eina_list_append(history_policy->zone_hooks, zone_hook);
-
-   // e_policy hooks
-   policy_hook = e_policy_hook_add(E_POLICY_HOOK_CLIENT_STACK_TRANSIENT_FOR_DONE, _focus_policy_history_hook_cb_policy_client_stack_transient_for_done, history_policy);
-   if (policy_hook) history_policy->policy_hooks = eina_list_append(history_policy->policy_hooks, policy_hook);
+   // zone listeners
+   history_policy->zone_client_add.notify = _focus_policy_history_cb_zone_client_add;
+   e_zone_client_add_listener_add(zone, &history_policy->zone_client_add);
+   history_policy->zone_client_remove.notify = _focus_policy_history_cb_zone_client_remove;
+   e_zone_client_remove_listener_add(zone, &history_policy->zone_client_remove);
+   history_policy->zone_focus_clear.notify = _focus_policy_history_cb_zone_focus_clear;
+   e_zone_focus_clear_listener_add(zone, &history_policy->zone_focus_clear);
+   history_policy->zone_focus_reset.notify = _focus_policy_history_cb_zone_focus_reset;
+   e_zone_focus_reset_listener_add(zone, &history_policy->zone_focus_reset);
 
    return policy_iface;
 
index 5d23b2d..4e27250 100644 (file)
@@ -231,7 +231,7 @@ _e_policy_stack_transient_for_apply(E_Client *ec)
      }
 
 #ifdef REFACTOR_FOCUS_POLICY
-   e_policy_hook_call(E_POLICY_HOOK_CLIENT_STACK_TRANSIENT_FOR_DONE, ec);
+   e_client_stack_transient_for_done_notify(ec);
 #endif
 }