rotation: fix the problem that black frame is displayed for a moment if activity... 10/93110/1
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 20 Oct 2016 07:59:01 +0000 (16:59 +0900)
committerSeunghun Lee <shiin.lee@samsung.com>
Thu, 20 Oct 2016 08:13:14 +0000 (17:13 +0900)
Now, rotation will be worked with deiconify rendering.

Change-Id: Ic29f459476df423992ed0b5a5a3d911982917524

src/rotation/e_mod_rotation_wl.c

index 3e3fb78..95fd048 100644 (file)
@@ -37,6 +37,7 @@ typedef struct _E_Client_Rotation E_Client_Rotation;
 struct _Policy_Ext_Rotation
 {
    E_Client *ec;
+   E_Vis_Grab *show_grab;
    uint32_t available_angles, preferred_angle;
    enum tizen_rotation_angle cur_angle, prev_angle;
    Eina_List *rotation_list;
@@ -81,6 +82,7 @@ static Eina_List *rot_handlers = NULL;
 static Eina_List *rot_hooks = NULL;
 static Eina_List *rot_intercept_hooks = NULL;
 static Ecore_Idle_Enterer *rot_idle_enterer = NULL;
+static E_Client *fg_ec = NULL;
 
 /* local subsystem functions */
 static Policy_Ext_Rotation* _policy_ext_rotation_get(E_Client *ec);
@@ -149,6 +151,47 @@ static Eina_Bool _rot_intercept_hook_show_helper(void *d EINA_UNUSED, E_Client *
 static Eina_Bool _rot_intercept_hook_hide(void *d EINA_UNUSED, E_Client *ec);
 static Eina_Bool _rot_cb_idle_enterer(void *data EINA_UNUSED);
 
+static void
+_rot_client_cb_vis_prepare_foreground(void *data, Evas_Object *obj, void *event_info)
+{
+   Policy_Ext_Rotation *rot;
+   E_Client *ec;
+
+   rot = data;
+   ec = rot->ec;
+
+   EDBG(ec, "Update Foreground Client '%s'(%p)", ec->icccm.name, ec);
+   fg_ec = ec;
+   _e_client_rotation_zone_set(ec->zone, ec, NULL);
+   if (ec->changes.rotation)
+     {
+        EDBG(ec, "Postpone foreground: ang %d", ec->e.state.rot.ang.next);
+        e_pixmap_image_clear(ec->pixmap, 1);
+        rot->show_grab = e_policy_visibility_client_grab_get(ec, __func__);
+        /* to be invoked 'eval_end' */
+        EC_CHANGED(ec);
+     }
+}
+
+static void
+_policy_ext_rotation_free(void *data)
+{
+   Policy_Ext_Rotation *rot;
+   E_Client *ec;
+
+   rot = data;
+   ec = rot->ec;
+
+   if (ec->frame)
+     {
+        evas_object_smart_callback_del(ec->frame,
+                                       "e,visibility,prepare,foreground",
+                                       _rot_client_cb_vis_prepare_foreground);
+     }
+
+   free(rot);
+}
+
 /* local subsystem functions */
 static Policy_Ext_Rotation*
 _policy_ext_rotation_get(E_Client *ec)
@@ -166,6 +209,10 @@ _policy_ext_rotation_get(E_Client *ec)
         rot->ec = ec;
         rot->angle_change_done = EINA_TRUE;
         eina_hash_add(hash_policy_ext_rotation, &ec, rot);
+        evas_object_smart_callback_add(ec->frame,
+                                       "e,visibility,prepare,foreground",
+                                       _rot_client_cb_vis_prepare_foreground,
+                                       rot);
      }
 
    return rot;
@@ -540,38 +587,77 @@ _e_client_rotation_zone_set(E_Zone *zone, E_Client *include_ec, E_Client *exclud
              continue;
           }
 
-        if ((!bg_ec) ||
-            ((include_ec == ec) &&
-             (evas_object_layer_get(ec->frame) >= evas_object_layer_get(bg_ec->frame))))
+        if (!fg_ec)
           {
-             EDBG(ec, "Append to rotation target list");
-             target_list = eina_list_append(target_list, ec);
-          }
-        else
-          {
-             e_client_rotation_set(ec, zone->rot.curr);
-             continue;
-          }
-
-        if ((ec->x == zone->x) && (ec->y == zone->y) &&
-            (ec->w == zone->w) && (ec->h == zone->h) &&
-            (ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_NORMAL))
-          {
-             if (!ec->argb)
+             if ((!bg_ec) ||
+                 ((include_ec == ec) &&
+                  (evas_object_layer_get(ec->frame) >= evas_object_layer_get(bg_ec->frame))))
                {
-                  EDBG(ec, "Found Topmost Fullscreen Window");
-                  bg_ec = ec;
+                  EDBG(ec, "Append to rotation target list");
+                  target_list = eina_list_append(target_list, ec);
                }
              else
                {
-                  if ((ec->visibility.opaque > 0) &&
-                      (!ec->parent))
+                  e_client_rotation_set(ec, zone->rot.curr);
+                  continue;
+               }
+
+             if ((ec->x == zone->x) && (ec->y == zone->y) &&
+                 (ec->w == zone->w) && (ec->h == zone->h) &&
+                 (ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_NORMAL))
+               {
+                  if (!ec->argb)
                     {
                        EDBG(ec, "Found Topmost Fullscreen Window");
                        bg_ec = ec;
                     }
+                  else
+                    {
+                       if ((ec->visibility.opaque > 0) &&
+                           (!ec->parent))
+                         {
+                            EDBG(ec, "Found Topmost Fullscreen Window");
+                            bg_ec = ec;
+                         }
+                    }
                }
           }
+        else
+          {
+             /* if already found background client,
+              * that means this client is placed under background client */
+             if (bg_ec)
+               {
+                  /* if this client don't have parent, rotate */
+                  if (!ec->parent)
+                    e_client_rotation_set(ec, zone->rot.curr);
+                  continue;
+               }
+             /*
+              * activity clients placed above background client should not be
+              * rotated. that's because this is deactivated sometime later by
+              * visibility's deiconify rendering logic.
+              */
+             else if ((fg_ec != ec) &&
+                 (ec->x == zone->x) && (ec->y == zone->y) &&
+                 (ec->w == zone->w) && (ec->h == zone->h) &&
+                 (ec->e.state.rot.type == E_CLIENT_ROTATION_TYPE_NORMAL))
+               {
+                  if (!ec->argb)
+                    continue;
+                  else
+                    {
+                       if ((ec->visibility.opaque > 0) &&
+                           (!ec->parent))
+                         continue;
+                    }
+               }
+
+             EDBG(ec, "Append Rotation List '%s'(%p)", ec->icccm.name, ec);
+             target_list = eina_list_append(target_list, ec);
+             if (ec == fg_ec)
+               bg_ec = ec;
+          }
      }
 
    angle = zone->rot.curr;
@@ -668,6 +754,7 @@ end:
 static void
 _e_client_rotation_change_done(void)
 {
+   Policy_Ext_Rotation *er;
    E_Client *ec;
 
    if (rot.done_timer)
@@ -685,6 +772,9 @@ _e_client_rotation_change_done(void)
              evas_object_show(ec->frame); // e_client_show(ec);
              e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
           }
+        er = eina_hash_find(hash_policy_ext_rotation, &ec);
+        if ((er) && (er->show_grab))
+          E_FREE_FUNC(er->show_grab, e_policy_visibility_client_grab_release);
         ec->e.state.rot.ang.next = -1;
         ec->e.state.rot.wait_for_done = 0;
      }
@@ -1290,6 +1380,10 @@ _rot_cb_buffer_change(void *data EINA_UNUSED, int ev_type EINA_UNUSED, E_Event_C
              evas_object_show(ev->ec->frame);
              e_comp_object_damage(ev->ec->frame, 0, 0, ev->ec->w, ev->ec->h);
           }
+
+        if (rot->show_grab)
+          E_FREE_FUNC(rot->show_grab, e_policy_visibility_client_grab_release);
+
         rot->wait_update = EINA_FALSE;
      }
 
@@ -1579,6 +1673,9 @@ _rot_intercept_hook_show_helper(void *d EINA_UNUSED, E_Client *ec)
    if (ec->e.state.rot.pending_show)
      return EINA_FALSE;
 
+   if (e_policy_visibility_client_is_activity(ec))
+     fg_ec = ec;
+
    _e_client_rotation_zone_set(ec->zone, ec, NULL);
    if (ec->changes.rotation)
      {
@@ -1601,7 +1698,7 @@ _rot_intercept_hook_hide(void *d EINA_UNUSED, E_Client *ec)
    ec->e.state.rot.pending_show = 0;
 
    // for rotating ec in the force_update_list
-   _e_client_rotation_zone_set(ec->zone, NULL, ec);
+   _e_client_rotation_zone_set(ec->zone, fg_ec, ec);
 
    return EINA_TRUE;
 }
@@ -1694,7 +1791,7 @@ e_mod_rot_wl_init(void)
         return EINA_FALSE;
      }
 
-   hash_policy_ext_rotation = eina_hash_pointer_new(free);
+   hash_policy_ext_rotation = eina_hash_pointer_new(_policy_ext_rotation_free);
 
    E_LIST_HANDLER_APPEND(rot_handlers, E_EVENT_ZONE_ROTATION_CHANGE_BEGIN,
                          _rot_cb_zone_rotation_change_begin, NULL);