From 50520aa9a537306227b1ad22139a70ed5fd79934 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 20 Oct 2016 16:59:01 +0900 Subject: [PATCH] rotation: fix the problem that black frame is displayed for a moment if activity client window is destroyed on landscape mode. Now, rotation will be worked with deiconify rendering. Change-Id: Ic29f459476df423992ed0b5a5a3d911982917524 --- src/rotation/e_mod_rotation_wl.c | 143 ++++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 23 deletions(-) diff --git a/src/rotation/e_mod_rotation_wl.c b/src/rotation/e_mod_rotation_wl.c index 3e3fb78..95fd048 100644 --- a/src/rotation/e_mod_rotation_wl.c +++ b/src/rotation/e_mod_rotation_wl.c @@ -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); -- 2.7.4