e_pol_vis: introduce to hook for e_pol_vis 14/114914/1
authorGwanglim Lee <gl77.lee@samsung.com>
Wed, 15 Feb 2017 13:55:13 +0000 (22:55 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Wed, 15 Feb 2017 13:55:13 +0000 (22:55 +0900)
E_POL_VIS_HOOK_TYPE_FG_SET is good point to be called after
E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER hook and given ec
has always mapped state.

Change-Id: I3752c8cc7311f38771269f2cbb026d7b777b67f5

src/bin/e_policy_visibility.c
src/bin/e_policy_visibility.h

index 8992e2011c865673e2cd44a32e34a036a541fef5..3fc66e2e038296a89c86bc98d52692bbe16833e2 100644 (file)
 # define TRACE_DS_END()
 #endif
 
+struct _E_Pol_Vis_Hook
+{
+   EINA_INLIST;
+   E_Pol_Vis_Hook_Type type;
+   E_Pol_Vis_Hook_Cb   cb;
+   void               *data;
+   Eina_Bool           delete_me;
+};
+
 static Eina_Bool _e_policy_check_transient_child_visible(E_Client *ancestor_ec, E_Client *ec);
 static Eina_Bool _e_policy_check_above_alpha_opaque(E_Client *ec);
 static void      _e_policy_client_iconify_by_visibility(E_Client *ec);
@@ -44,6 +53,53 @@ static E_Vis_Job_Group  *pol_job_group = NULL;
 /* the head of list for E_Vis_Job_Group */
 static Eina_Clist        pol_job_group_head = EINA_CLIST_INIT(pol_job_group_head);
 
+static Eina_Inlist *_e_pol_vis_hooks[] =
+{
+   [E_POL_VIS_HOOK_TYPE_FG_SET] = NULL,
+};
+
+static int _e_pol_vis_hooks_delete = 0;
+static int _e_pol_vis_hooks_walking = 0;
+
+static void
+_e_pol_vis_hooks_clean(void)
+{
+   Eina_Inlist *l;
+   E_Pol_Vis_Hook *h;
+   unsigned int x;
+
+   for (x = 0; x < E_POL_VIS_HOOK_TYPE_LAST; x++)
+     EINA_INLIST_FOREACH_SAFE(_e_pol_vis_hooks[x], l, h)
+       {
+          if (!h->delete_me) continue;
+          _e_pol_vis_hooks[x] = eina_inlist_remove(_e_pol_vis_hooks[x],
+                                                   EINA_INLIST_GET(h));
+          E_FREE(h);
+       }
+}
+
+static Eina_Bool
+_e_pol_vis_hook_call(E_Pol_Vis_Hook_Type type, E_Client *ec)
+{
+   E_Pol_Vis_Hook *h;
+
+   e_object_ref(E_OBJECT(ec));
+
+   _e_pol_vis_hooks_walking++;
+   EINA_INLIST_FOREACH(_e_pol_vis_hooks[type], h)
+     {
+        if (h->delete_me) continue;
+        h->cb(h->data, ec);
+     }
+   _e_pol_vis_hooks_walking--;
+
+   if ((_e_pol_vis_hooks_walking == 0) &&
+       (_e_pol_vis_hooks_delete > 0))
+     _e_pol_vis_hooks_clean();
+
+   return !!e_object_unref(E_OBJECT(ec));
+}
+
 static Eina_Bool
 _e_policy_check_transient_child_visible(E_Client *ancestor_ec, E_Client *ec)
 {
@@ -377,6 +433,7 @@ _e_vis_update_forground_list(void)
         DBG("VISIBILITY | \tNew : %s(%p)", fg_activity ? NAME(fg_activity) : "", fg_activity);
         pol_vis->activity = fg_activity;
         /* TODO do we need to raise event like E_EVENT_VISIBILITY_ACTIVITY_CHANGE? */
+        _e_pol_vis_hook_call(E_POL_VIS_HOOK_TYPE_FG_SET, fg_activity);
      }
 }
 
@@ -1514,6 +1571,40 @@ e_policy_visibility_client_defer_move(E_Client *ec, int x, int y)
    _e_vis_client_defer_move(vc, E_VIS_JOB_TYPE_DEFER_MOVE, x, y);
 }
 
+E_API E_Pol_Vis_Hook *
+e_policy_visibility_hook_add(E_Pol_Vis_Hook_Type type, E_Pol_Vis_Hook_Cb cb, const void *data)
+{
+   E_Pol_Vis_Hook *h;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(type >= E_POL_VIS_HOOK_TYPE_LAST, NULL);
+
+   h = E_NEW(E_Pol_Vis_Hook, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(h, NULL);
+
+   h->type = type;
+   h->cb = cb;
+   h->data = (void *)data;
+
+   _e_pol_vis_hooks[type] = eina_inlist_append(_e_pol_vis_hooks[type],
+                                               EINA_INLIST_GET(h));
+
+   return h;
+}
+
+E_API void
+e_policy_visibility_hook_del(E_Pol_Vis_Hook *h)
+{
+   h->delete_me = EINA_TRUE;
+   if (_e_pol_vis_hooks_walking == 0)
+     {
+        _e_pol_vis_hooks[h->type] = eina_inlist_remove(_e_pol_vis_hooks[h->type],
+                                                       EINA_INLIST_GET(h));
+        E_FREE(h);
+     }
+   else
+     _e_pol_vis_hooks_delete++;
+}
+
 E_API Eina_Bool
 e_policy_visibility_init(void)
 {
index f8c17ba1538ca1b945a3b34f0f465ae458b811f7..46f3059aaa733b9868b9a28eb0118be609c88d7e 100644 (file)
@@ -1,3 +1,16 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Pol_Vis_Hook E_Pol_Vis_Hook;
+
+typedef enum _E_Pol_Vis_Hook_Type
+{
+   E_POL_VIS_HOOK_TYPE_FG_SET,
+   E_POL_VIS_HOOK_TYPE_LAST,
+} E_Pol_Vis_Hook_Type;
+
+typedef Eina_Bool (*E_Pol_Vis_Hook_Cb)(void *data, E_Client *ec);
+
+#else
 #ifndef _E_POLICY_VISIBILITY_H_
 #define _E_POLICY_VISIBILITY_H_
 
@@ -16,7 +29,10 @@ E_API Eina_Bool                   e_policy_visibility_client_layer_lower(E_Clien
 E_API E_Vis_Grab                 *e_policy_visibility_client_grab_get(E_Client *ec, const char *name);
 E_API void                        e_policy_visibility_client_grab_release(E_Vis_Grab *grab);
 E_API void                        e_policy_visibility_uniconify_render_disable_set(E_Client *ec, Eina_Bool disable);
+E_API E_Pol_Vis_Hook             *e_policy_visibility_hook_add(E_Pol_Vis_Hook_Type type, E_Pol_Vis_Hook_Cb cb, const void *data);
+E_API void                        e_policy_visibility_hook_del(E_Pol_Vis_Hook *h);
 
 EINTERN void                      e_policy_visibility_client_defer_move(E_Client *ec, int x, int y);
 
 #endif
+#endif