rotation: support for zombie ec 10/114910/3
authorGwanglim Lee <gl77.lee@samsung.com>
Wed, 15 Feb 2017 13:34:49 +0000 (22:34 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Wed, 15 Feb 2017 14:11:16 +0000 (23:11 +0900)
Occasionally, some client destroys only the xdg_surface and
keeps the wl_surface. In this case, E20 has the zombie ec for
maintaining of this kind of client. If the zombie ec is going
to be alive again (it means that client tries to show window),
then the zombie ec has the unmap state on the
E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER handler. So fg_ec of
rotation module can not be changed to activated ec even if it
is shown on the screen.

Thus, we need to use a new hook for changing to right fg_ec of
rotation module in this case. 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: I6369d55e8198df567225fda2c25aa0de28e2f7f5

src/rotation/e_mod_rotation_wl.c

index c0d4b5f..57b7b71 100644 (file)
@@ -83,6 +83,7 @@ static Eina_List *rot_cbs = NULL;
 static Eina_List *rot_ec_hooks = NULL;
 static Eina_List *rot_obj_hooks = NULL;
 static Eina_List *wl_hooks = NULL;
+static Eina_List *pol_vis_hooks = NULL;
 static Ecore_Idle_Enterer *rot_idle_enterer = NULL;
 static E_Client *fg_ec = NULL;
 
@@ -2097,6 +2098,71 @@ end_fetch_rot:
      ec->e.fetch.rot.need_rotation = EINA_FALSE;
 }
 
+/* Occasionally, some client destroys only the xdg_surface and keeps the wl_surface.
+ * In this case, E20 has the zombie ec for maintaining of this kind of client.
+ * If the zombie ec is going to be alive again (it means that client tries to show window),
+ * then the zombie ec has the unmap state on the E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER handler.
+ * So fg_ec of rotation module can not be changed to activated ec even if it is shown on the screen.
+ *
+ * Thus, we need to use a new hook for changing to right fg_ec of rotation module in this case.
+ * 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.
+ */
+static Eina_Bool
+_rot_hook_fg_set(void *d EINA_UNUSED, E_Client *ec)
+{
+   Policy_Ext_Rotation *rot;
+
+   rot = eina_hash_find(rot_hash, &ec);
+   if (!rot)
+     return EINA_TRUE;
+
+   if (e_pixmap_type_get(ec->pixmap) == E_PIXMAP_TYPE_EXT_OBJECT)
+     return EINA_TRUE;
+
+   if (!rot->hint_fetch)
+     {
+        /* need to fetch rotation hint. */
+        ec->e.state.rot.pending_show = 1;
+        EC_CHANGED(ec);
+        return EINA_FALSE;
+     }
+
+   if (ec->e.state.rot.pending_show)
+     return EINA_FALSE;
+
+   if (e_policy_visibility_client_is_activity(ec))
+     {
+        EDBG(ec, "Check ec %x to set fg_ec", e_client_util_win_get(ec));
+        if (_no_active_lockscreen_check(ec))
+          {
+             /* don't need to check visibility of given foreground ec
+              * it will have E_VISIBILITY_UNOBSCURED soon
+              */
+             EDBG(ec, "Set the fg_ec to %x", e_client_util_win_get(ec));
+             fg_ec = ec;
+
+             if (_camera_check(ec))
+               _unlock_rot_for_fg_app(ec->zone);
+             else
+               _try_lock_rot_for_fg_app(ec->zone);
+          }
+     }
+
+   _e_client_rotation_zone_set(ec->zone, ec, NULL);
+   if (ec->changes.rotation)
+     {
+        EDBG(ec, "Postpone show: ang %d", ec->e.state.rot.ang.next);
+        e_pixmap_image_clear(ec->pixmap, 1);
+        ec->e.state.rot.pending_show = 1;
+        /* to be invoked 'eval_end' */
+        EC_CHANGED(ec);
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
 static Eina_Bool
 _rot_intercept_hook_show_helper(void *d EINA_UNUSED, E_Client *ec)
 {
@@ -2296,6 +2362,9 @@ e_mod_rot_wl_init(void)
    E_COMP_OBJECT_INTERCEPT_HOOK_APPEND(rot_obj_hooks, E_COMP_OBJECT_INTERCEPT_HOOK_HIDE,        _rot_intercept_hook_hide,        NULL);
    E_COMP_WL_HOOK_APPEND(wl_hooks,                    E_COMP_WL_HOOK_BUFFER_CHANGE,             _rot_cb_wl_buffer_change,        NULL);
 
+   E_Pol_Vis_Hook *h = e_policy_visibility_hook_add(E_POL_VIS_HOOK_TYPE_FG_SET, _rot_hook_fg_set, NULL);
+   pol_vis_hooks = eina_list_append(pol_vis_hooks, h);
+
    rot_idle_enterer = ecore_idle_enterer_add(_rot_cb_idle_enterer, NULL);
 
    return EINA_TRUE;
@@ -2307,6 +2376,7 @@ e_mod_rot_wl_shutdown(void)
    E_FREE_FUNC(rot_hash, eina_hash_free);
    E_FREE_FUNC(rot.force_update_list, eina_list_free);
 
+   E_FREE_LIST(pol_vis_hooks, e_policy_visibility_hook_del);
    E_FREE_LIST(wl_hooks, e_comp_wl_hook_del);
    E_FREE_LIST(rot_ec_hooks, e_client_hook_del);
    E_FREE_LIST(rot_cbs, ecore_event_handler_del);