X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fbin%2Fe_border.c;h=965456950fba65085a6ff33d6d98b5d1a41de994;hb=refs%2Fchanges%2F12%2F9712%2F1;hp=b77269c2a2bf6ffad7daa46ecf519e9c1327d0cc;hpb=d0a184b17aacdba2e80c899ac8cbe91b4f902a58;p=platform%2Fcore%2Fuifw%2Fe17.git diff --git a/src/bin/e_border.c b/src/bin/e_border.c index b77269c..9654569 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -2,7 +2,7 @@ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved. * * This file is a modified version of BSD licensed file and - * licensed under the Flora License, Version 1.0 (the License); + * licensed under the Flora License, Version 1.1 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -149,9 +149,9 @@ static Eina_Bool _e_border_cb_desk_window_profile_change(void *data, void *ev); #endif #ifdef _F_ZONE_WINDOW_ROTATION_ -static Eina_Bool _e_border_cb_zone_rotation_change(void *data, - int ev_type, - void *ev); +static Eina_Bool _e_border_cb_zone_rotation_change_begin(void *data, + int ev_type, + void *ev); static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data); static void _e_border_rotation_change_request(E_Zone *zone); static Eina_Bool _e_border_rotation_change_done_timeout(void *data); @@ -164,8 +164,9 @@ static Eina_Bool _e_border_rotation_geom_get(E_Border *bd, int *w, int *h, Eina_Bool *move); -static Eina_Bool _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd); +static Eina_Bool _e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd); static void _e_border_rotation_list_remove(E_Border *bd); +static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd); static Eina_Bool _e_border_rotation_check(E_Border *bd); static Eina_Bool _e_border_rotation_zone_check(E_Zone *zone); static Eina_Bool _e_border_rotation_border_check(E_Border *bd, int ang); @@ -239,8 +240,13 @@ static void _e_border_event_border_fullscreen_free(void *data, static void _e_border_event_border_unfullscreen_free(void *data, void *ev); #ifdef _F_ZONE_WINDOW_ROTATION_ -static void _e_border_event_border_rotation_free(void *data, - void *ev); +static void _e_border_event_border_rotation_change_begin_free(void *data, + void *ev); +static void _e_border_event_border_rotation_change_cancel_free(void *data, + void *ev); +static void _e_border_event_border_rotation_change_end_free(void *data, + void *ev); +static void _e_border_event_border_rotation_change_begin_send(E_Border *bd); #endif static void _e_border_zone_update(E_Border *bd); @@ -391,7 +397,10 @@ EAPI int E_EVENT_BORDER_PROPERTY = 0; EAPI int E_EVENT_BORDER_FULLSCREEN = 0; EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0; #ifdef _F_ZONE_WINDOW_ROTATION_ -EAPI int E_EVENT_BORDER_ROTATION = 0; +EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */ +EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0; +EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0; +EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0; #endif #define GRAV_SET(bd, grav) \ @@ -469,7 +478,7 @@ e_border_init(void) handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL)); #endif #ifdef _F_ZONE_WINDOW_ROTATION_ - handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE, _e_border_cb_zone_rotation_change, NULL)); + handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL)); #endif if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL); @@ -495,7 +504,10 @@ e_border_init(void) E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new(); E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new(); #ifdef _F_ZONE_WINDOW_ROTATION_ - E_EVENT_BORDER_ROTATION = ecore_event_type_new(); + E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */ + E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new(); + E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new(); + E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new(); #endif // e_init_undone(); @@ -868,6 +880,7 @@ e_border_new(E_Container *con, bd->changed = 1; #ifdef _F_ZONE_WINDOW_ROTATION_ bd->client.e.state.rot.preferred_rot = -1; + bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL; #endif // bd->zone = e_zone_current_get(con); @@ -1315,7 +1328,13 @@ _e_border_vkbd_hide(E_Border *bd) rot.vkbd_hide_timer = NULL; if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE))) { + ELB(ELBT_BD, "HIDE VKBD", bd->client.win); e_border_hide(bd, 0); + if (!e_object_is_del(E_OBJECT(bd))) + { + ELB(ELBT_BD, "DEL VKBD", bd->client.win); + e_object_del(E_OBJECT(bd)); + } rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd); } } @@ -1398,7 +1417,21 @@ e_border_show(E_Border *bd) (bd->client.e.state.rot.app_set))) { ELB(ELBT_ROT, "CHECK", bd->client.win); - _e_border_rotation_check(bd); + Eina_Bool _rot = _e_border_rotation_check(bd); + /* check whether rotation is available for sub borders such as prediction and magnifier */ + if (_rot) + { + Eina_List *ll; + E_Border *_child; + Eina_List *_list = _e_border_sub_borders_new(bd); + EINA_LIST_FOREACH(_list, ll, _child) + { + if ((_child->client.e.state.rot.support) || + (_child->client.e.state.rot.app_set)) + _e_border_rotation_check(_child); + } + eina_list_free(_list); + } } #endif } @@ -1498,7 +1531,8 @@ e_border_hide(E_Border *bd, if (!bd->need_reparent) { - if (bd->focused) + if ((bd->focused) || + (e_grabinput_last_focus_win_get() == bd->client.win)) { e_border_focus_set(bd, 0, 1); if (manage != 2) @@ -1562,6 +1596,10 @@ e_border_hide(E_Border *bd, send_event: if (!stopping) { +#ifdef _F_ZONE_WINDOW_ROTATION_ + _e_border_rotation_list_remove(bd); +#endif + E_Event_Border_Hide *ev; ev = E_NEW(E_Event_Border_Hide, 1); @@ -3676,17 +3714,108 @@ static Eina_Bool _e_border_uniconify_timeout(void *data) { E_Border *bd; + E_Border *child_bd; + bd = data; if (!e_object_is_del(E_OBJECT(bd))) { + ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win); bd->client.e.state.deiconify_approve.render_done = 1; - e_border_uniconify(bd); + if (bd->client.e.state.deiconify_approve.req_list) + { + EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd) + { + child_bd->client.e.state.deiconify_approve.render_done = 1; + child_bd->client.e.state.deiconify_approve.ancestor = NULL; + } + } + bd->client.e.state.deiconify_approve.req_list = NULL; bd->client.e.state.deiconify_approve.wait_timer = NULL; + e_border_uniconify(bd); } return ECORE_CALLBACK_CANCEL; } + +static void +_e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor) +{ + if (!bd || !bd_ancestor) return; + + if (e_config->deiconify_approve) + { + if (e_config->transient.iconify) + { + Eina_List *l; + E_Border *child; + Eina_List *list = _e_border_sub_borders_new(bd); + EINA_LIST_FOREACH(list, l, child) + { +#ifdef _F_ZONE_WINDOW_ROTATION_ + if ((e_config->wm_win_rotation) && + ((child->client.e.state.rot.support) || + (child->client.e.state.rot.app_set))) + { + ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win); + _e_border_rotation_check(child); + } +#endif + _e_border_deiconify_approve_send(child, bd_ancestor); + if (child->client.e.state.deiconify_approve.support) + { + ELBF(ELBT_BD, 0, child->client.win, + "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win); + + ecore_x_client_message32_send(child->client.win, + ECORE_X_ATOM_E_DEICONIFY_APPROVE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + child->client.win, 0, 0, 0, 0); + child->client.e.state.deiconify_approve.ancestor = bd_ancestor; + bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child); + } + } + eina_list_free(list); + } + } +} + +static void +_e_border_deiconify_approve_send_all_transient(E_Border *bd) +{ + E_Border *bd_ancestor; + bd_ancestor = bd; + + if (e_config->deiconify_approve) + { +#ifdef _F_ZONE_WINDOW_ROTATION_ + if ((e_config->wm_win_rotation) && + ((bd->client.e.state.rot.support) || + (bd->client.e.state.rot.app_set))) + { + ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win); + _e_border_rotation_check(bd); + } +#endif + + if (e_config->transient.iconify) + { + _e_border_deiconify_approve_send(bd, bd_ancestor); + } + + if (bd->client.e.state.deiconify_approve.support) + { + ELBF(ELBT_BD, 0, bd->client.win, + "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win); + + ecore_x_client_message32_send(bd->client.win, + ECORE_X_ATOM_E_DEICONIFY_APPROVE, + ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, + bd->client.win, 0, 0, 0, 0); + bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd); + } + } +} #endif EAPI void @@ -3704,18 +3833,18 @@ e_border_uniconify(E_Border *bd) { if (bd->client.e.state.deiconify_approve.support) { - if (bd->client.e.state.deiconify_approve.wait_timer) return; + if (bd->client.e.state.deiconify_approve.wait_timer) + { + ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win); + return; + } if (bd->client.e.state.deiconify_approve.render_done == 0) { - ecore_x_client_message32_send(bd->client.win, - ECORE_X_ATOM_E_DEICONIFY_APPROVE, - ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, - bd->client.win, 0, 0, 0, 0); - bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd); + ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win); + _e_border_deiconify_approve_send_all_transient(bd); return; } } - bd->client.e.state.deiconify_approve.render_done = 0; } #endif @@ -4184,9 +4313,7 @@ e_border_idler_before(void) if (m) zone = e_util_zone_current_get(m); if ((zone) && (rot.wait_prepare_done)) { - if (_e_border_rotation_list_add(zone, EINA_FALSE)) - _e_border_rotation_change_request(zone); - else + if (!_e_border_rotation_start(zone, EINA_FALSE)) { if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer); @@ -5639,14 +5766,6 @@ _e_border_del(E_Border *bd) ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL); } -#ifdef _F_DEICONIFY_APPROVE_ - if (bd->client.e.state.deiconify_approve.wait_timer) - { - ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer); - bd->client.e.state.deiconify_approve.wait_timer = NULL; - } -#endif - if (bd->parent) { bd->parent->transients = eina_list_remove(bd->parent->transients, bd); @@ -5665,6 +5784,45 @@ _e_border_del(E_Border *bd) child->parent = NULL; } +#ifdef _F_DEICONIFY_APPROVE_ + bd->client.e.state.deiconify_approve.render_done = 0; + + E_Border *ancestor_bd; + ancestor_bd = bd->client.e.state.deiconify_approve.ancestor; + if ((ancestor_bd) && + (!e_object_is_del(E_OBJECT(ancestor_bd)))) + { + ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd); + bd->client.e.state.deiconify_approve.ancestor = NULL; + + if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) && + (ancestor_bd->client.e.state.deiconify_approve.render_done)) + { + if (ancestor_bd->client.e.state.deiconify_approve.wait_timer) + { + ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer); + ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL; + e_border_uniconify(ancestor_bd); + } + } + } + + if (bd->client.e.state.deiconify_approve.wait_timer) + { + ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer); + bd->client.e.state.deiconify_approve.wait_timer = NULL; + } + + if (bd->client.e.state.deiconify_approve.req_list) + { + EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child) + { + child->client.e.state.deiconify_approve.render_done = 0; + child->client.e.state.deiconify_approve.ancestor = NULL; + } + } +#endif + if (bd->leader) { bd->leader->group = eina_list_remove(bd->leader->group, bd); @@ -5733,6 +5891,27 @@ _e_border_cb_window_destroy(void *data __UNUSED__, e = ev; bd = e_border_find_by_client_window(e->win); if (!bd) return ECORE_CALLBACK_PASS_ON; + ELB(ELBT_BD, "X_WIN_DEL", bd->client.win); +#ifdef _F_ZONE_WINDOW_ROTATION_ + if (e_config->wm_win_rotation) + { + if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD) + { + ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win); + if (!rot.vkbd_hide_prepare_timer) + { + ELB(ELBT_BD, "HIDE VKBD", bd->client.win); + e_border_hide(bd, 0); + if (!rot.vkbd_hide_prepare_timer) + { + ELB(ELBT_BD, "DEL VKBD", bd->client.win); + e_object_del(E_OBJECT(bd)); + } + } + return ECORE_CALLBACK_PASS_ON; + } + } +#endif e_border_hide(bd, 0); e_object_del(E_OBJECT(bd)); return ECORE_CALLBACK_PASS_ON; @@ -5763,7 +5942,16 @@ _e_border_cb_window_hide(void *data __UNUSED__, } if (!bd) bd = e_border_find_by_client_window(e->win); // printf(" bd = %p\n", bd); - if (!bd) return ECORE_CALLBACK_PASS_ON; + if (!bd) + { + if (ecore_x_window_visible_get(e->win)) + { + ELB(ELBT_BD, "FORCE UNMAP client window", e->win); + ecore_x_window_hide(e->win); + } + return ECORE_CALLBACK_PASS_ON; + } + // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap); if (bd->ignore_first_unmap > 0) { @@ -5801,6 +5989,27 @@ _e_border_cb_window_hide(void *data __UNUSED__, bd->visible = 1; } #endif + +#ifdef _F_ZONE_WINDOW_ROTATION_ + if (e_config->wm_win_rotation) + { + if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD) + { + ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win); + if (!rot.vkbd_hide_prepare_timer) + { + ELB(ELBT_BD, "HIDE VKBD", bd->client.win); + e_border_hide(bd, 0); + if (!rot.vkbd_hide_prepare_timer) + { + ELB(ELBT_BD, "DEL VKBD", bd->client.win); + e_object_del(E_OBJECT(bd)); + } + } + return ECORE_CALLBACK_PASS_ON; + } + } +#endif e_border_hide(bd, 0); e_object_del(E_OBJECT(bd)); } @@ -6721,13 +6930,38 @@ _e_border_cb_client_message(void *data __UNUSED__, if (bd->client.e.state.deiconify_approve.support) { if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON; - if (bd->client.e.state.deiconify_approve.wait_timer) + bd->client.e.state.deiconify_approve.render_done = 1; + + E_Border *ancestor_bd; + ancestor_bd = bd->client.e.state.deiconify_approve.ancestor; + if (ancestor_bd) { - ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer); - bd->client.e.state.deiconify_approve.wait_timer = NULL; + ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd); + bd->client.e.state.deiconify_approve.ancestor = NULL; + } + else + { + ancestor_bd = bd; + } + + ELBF(ELBT_BD, 0, bd->client.win, + "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win); + + if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) && + (ancestor_bd->client.e.state.deiconify_approve.render_done)) + { + if (ancestor_bd->client.e.state.deiconify_approve.wait_timer) + { + ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer); + ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL; + e_border_uniconify(ancestor_bd); + } + else + { + ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win); + ancestor_bd->client.e.state.deiconify_approve.render_done = 0; + } } - bd->client.e.state.deiconify_approve.render_done = 1; - e_border_uniconify(bd); } } return ECORE_CALLBACK_PASS_ON; @@ -6774,7 +7008,7 @@ _e_border_cb_client_message(void *data __UNUSED__, if (e_config->wm_win_rotation) { - if ((int)e->data.l[1] == bd->zone->rot.curr) + if ((int)e->data.l[1] == bd->client.e.state.rot.curr) _e_border_rotation_list_remove(bd); } } @@ -7653,11 +7887,11 @@ _e_border_cb_desk_window_profile_change(void *data __UNUSED__, #ifdef _F_ZONE_WINDOW_ROTATION_ static Eina_Bool -_e_border_cb_zone_rotation_change(void *data __UNUSED__, - int ev_type __UNUSED__, - void *ev) +_e_border_cb_zone_rotation_change_begin(void *data __UNUSED__, + int ev_type __UNUSED__, + void *ev) { - E_Event_Zone_Rotation_Change *e = ev; + E_Event_Zone_Rotation_Change_Begin *e = ev; Eina_Bool res = EINA_FALSE; if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON; @@ -7697,10 +7931,7 @@ _e_border_cb_zone_rotation_change(void *data __UNUSED__, rot.wait_prepare_done = EINA_TRUE; } else - { - _e_border_rotation_list_add(e->zone, EINA_TRUE); - _e_border_rotation_change_request(e->zone); - } + _e_border_rotation_start(e->zone, EINA_TRUE); } else { @@ -7718,13 +7949,9 @@ _e_border_rotation_change_prepare_timeout(void *data) ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0); - if ((rot.wait_prepare_done) && - (zone) && - (_e_border_rotation_list_add(zone, EINA_FALSE))) - { - _e_border_rotation_change_request(zone); - } - else + if ((!rot.wait_prepare_done) || + (!zone) || + (!_e_border_rotation_start(zone, EINA_FALSE))) { if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer); @@ -7747,6 +7974,12 @@ _e_border_rotation_change_request(E_Zone *zone __UNUSED__) EINA_LIST_FOREACH(rot.list, l, info) { + if (!info->bd) continue; + if ((zone->rot.block_count) && + (info->bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT)) continue; + + _e_border_event_border_rotation_change_begin_send(info->bd); + ELBF(ELBT_ROT, 1, info->bd->client.win, "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d", info->ang, info->win_resize, info->w, info->h); @@ -7770,11 +8003,27 @@ _e_border_rotation_change_request(E_Zone *zone __UNUSED__) NULL); } +EAPI void +e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request) +{ + Eina_List *l = NULL; + E_Border_Rotation_Info *info = NULL; + + if (send_request) _e_border_rotation_change_request(zone); + else + { + EINA_LIST_FREE(rot.list, info) + E_FREE(info); + rot.list = NULL; + } +} + static void _e_border_rotation_list_remove(E_Border *bd) { Eina_List *l = NULL; E_Border_Rotation_Info *info = NULL; + E_Event_Border_Rotation_Change_End *ev = NULL; if (!e_config->wm_win_rotation) return; EINA_LIST_FOREACH(rot.list, l, info) @@ -7789,6 +8038,23 @@ _e_border_rotation_list_remove(E_Border *bd) if (bd->client.e.state.rot.wait_for_done) { bd->client.e.state.rot.wait_for_done = 0; + + /* if we make the border event in the _e_border_free function, + * then we may meet a crash problem, only work this at least e_border_hide. + */ + if (!e_object_is_del(E_OBJECT(bd))) + { + ev = E_NEW(E_Event_Border_Rotation_Change_End, 1); + if (ev) + { + ev->border = bd; + e_object_ref(E_OBJECT(bd)); + ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END, + ev, + _e_border_event_border_rotation_change_end_free, + NULL); + } + } if (eina_list_count(rot.list) == 0) { _e_border_rotation_change_done(); @@ -7862,8 +8128,10 @@ _e_border_rotation_get(E_Border *bd, int base_ang) { int ang = -1; + int current_ang = bd->client.e.state.rot.curr; unsigned int i; Eina_Bool found = EINA_FALSE; + Eina_Bool found_curr_ang = EINA_FALSE; if (!e_config->wm_win_rotation) return ang; if (!bd->client.e.state.rot.app_set) return ang; @@ -7884,6 +8152,8 @@ _e_border_rotation_get(E_Border *bd, found = EINA_TRUE; break; } + if (bd->client.e.state.rot.available_rots[i] == current_ang) + found_curr_ang = EINA_TRUE; } /* do nothing. this window wants to maintain current state. @@ -7893,7 +8163,7 @@ _e_border_rotation_get(E_Border *bd, */ if (!found) { - if (bd->client.e.state.rot.curr != -1) + if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang)) ang = bd->client.e.state.rot.curr; else ang = bd->client.e.state.rot.available_rots[0]; @@ -7921,8 +8191,9 @@ static Eina_Bool _e_border_rotation_check(E_Border *bd) { E_Zone *zone = bd->zone; + Eina_List *nl = NULL; int x, y, w, h, ang = 0; - int diff = 0, _ang = 0; + int _ang = 0; Eina_Bool resize = EINA_TRUE; Eina_Bool hint = EINA_FALSE; Eina_Bool move = EINA_TRUE; @@ -7933,8 +8204,7 @@ _e_border_rotation_check(E_Border *bd) ang = zone->rot.curr; - if (((rot.vkbd) && (rot.vkbd == bd)) || - ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd))) + if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE) { ELBF(ELBT_ROT, 1, bd->client.win, "%s->parent:0x%08x (support:%d app_set:%d ang:%d)", @@ -8033,8 +8303,6 @@ _e_border_rotation_check(E_Border *bd) if (bd->client.e.state.rot.curr != ang) { - Eina_Bool is_screen_locked = EINA_FALSE; - if ((rot.vkbd != bd) && (rot.vkbd_prediction != bd) && /* check whether virtual keyboard is visible on the zone */ (_e_border_rotation_zone_vkbd_check(bd->zone)) && @@ -8047,7 +8315,6 @@ _e_border_rotation_check(E_Border *bd) { ELB(ELBT_ROT, "DO VKBD ROT", bd->client.win); e_manager_comp_screen_lock(e_manager_current_get()); - is_screen_locked = EINA_TRUE; if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer); rot.prepare_timer = NULL; @@ -8057,7 +8324,7 @@ _e_border_rotation_check(E_Border *bd) ELB(ELBT_ROT, "send rot_change_prepare", rot.vkbd_ctrl_win); ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win, - bd->zone->rot.curr, + ang, EINA_FALSE, 1, 1); rot.prepare_timer = ecore_timer_add(4.0f, _e_border_rotation_change_prepare_timeout, @@ -8068,72 +8335,9 @@ _e_border_rotation_check(E_Border *bd) bd->client.e.state.rot.prev = bd->client.e.state.rot.curr; bd->client.e.state.rot.curr = ang; bd->client.e.state.rot.wait_for_done = 1; + nl = eina_list_append(nl, bd); - diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev; - if ((diff == 180) || (diff == -180)) - resize = EINA_FALSE; - - /* Check if it has size hint, full size or not, and needs to resize. - * Under the below condition, replace width value with height. - */ - if ((!hint) && (!REGION_EQUAL_TO_ZONE(bd, bd->zone)) && (resize)) - { - x = bd->x; y = bd->y; - w = bd->w; h = bd->h; - - if (w == h) - resize = EINA_FALSE; - else - { - w = bd->h; - h = bd->w; - - _e_border_move_resize_internal(bd, x, y, w, h, - EINA_TRUE, EINA_FALSE); - } - } - - /* hack ... */ - if (bd->client.e.state.rot.app_set) resize = EINA_FALSE; - - E_Border_Rotation_Info *info = NULL; - info = E_NEW(E_Border_Rotation_Info, 1); - if (info) - { - if (!is_screen_locked) - e_manager_comp_screen_lock(e_manager_current_get()); - - info->bd = bd; - info->ang = ang; - info->x = x; info->y = y; - info->w = w; info->h = h; - info->win_resize = resize; - rot.list = eina_list_append(rot.list, info); - - if (info->win_resize) - bd->client.e.state.rot.pending_change_request = 1; - - ELBF(ELBT_ROT, 1, info->bd->client.win, - "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d", - info->ang, info->win_resize, info->w, info->h); - - ecore_x_e_window_rotation_change_prepare_send - (info->bd->client.win, info->ang, - info->win_resize, info->w, info->h); - - if (!info->bd->client.e.state.rot.pending_change_request) - { - ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST"); - ecore_x_e_window_rotation_change_request_send(info->bd->client.win, - info->ang); - } - - if (rot.done_timer) - ecore_timer_del(rot.done_timer); - rot.done_timer = ecore_timer_add(4.0f, - _e_border_rotation_change_done_timeout, - NULL); - } + e_border_rotation_list_add_change_req(zone, nl); } return EINA_TRUE; } @@ -8294,8 +8498,96 @@ _e_border_rotation_transient_for_check(E_Border *bd, int ang) return ret; } +EAPI Eina_Bool +e_border_rotation_list_add_change_req(E_Zone *zone, Eina_List *list) +{ + Eina_List *l; + E_Border *bd; + Eina_Bool ret = EINA_FALSE; + + if (e_border_rotation_list_add(list)) + { + EINA_LIST_FOREACH(list, l, bd) + _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, bd); + _e_border_rotation_change_request(zone); + ret = EINA_TRUE; + } + + return ret; +} + +EAPI Eina_Bool +e_border_rotation_list_add(Eina_List *list) +{ + Eina_List *l; + E_Border *bd = NULL; + E_Border_Rotation_Info *info = NULL; + + if (!list) return EINA_FALSE; + EINA_LIST_FOREACH(list, l, bd) + { + info = E_NEW(E_Border_Rotation_Info, 1); + if (!info) continue; + + info->bd = bd; + info->ang = bd->client.e.state.rot.curr; + info->x = bd->x; info->y = bd->y; + info->w = bd->w; info->h = bd->h; + info->win_resize = _e_border_rotation_pre_resize(bd); + if (info->win_resize) bd->client.e.state.rot.pending_change_request = 1; + rot.list = eina_list_append(rot.list, info); + } + + return EINA_TRUE; +} + +#define SIZE_EQUAL_TO_ZONE(a, z) \ + ((((a)->w) == ((z)->w)) && \ + (((a)->h) == ((z)->h))) +static Eina_Bool +_e_border_rotation_pre_resize(E_Border *bd) +{ + E_Zone *zone = bd->zone; + int ang = bd->client.e.state.rot.curr; + int diff = ang - bd->client.e.state.rot.prev; + int x, y, w, h; + Eina_Bool move = EINA_FALSE; + Eina_Bool hint = EINA_FALSE; + Eina_Bool resize = EINA_FALSE; + + if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize; + + hint = _e_border_rotation_geom_get(bd, bd->zone, ang, + &x, &y, &w, &h, &move); + if (hint) + { + _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move); + resize = EINA_TRUE; + } + else + { + x = bd->x; y = bd->y; + w = bd->w; h = bd->h; + + if ((diff != 180) && (diff != -180)) + { + if (w != h) + { + w = bd->h; + h = bd->w; + resize = EINA_TRUE; + + _e_border_move_resize_internal(bd, x, y, w, h, + EINA_TRUE, EINA_TRUE); + } + } + } + + return resize; +} + static Eina_Bool -_e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd) +_e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd) { Eina_Bool wait = EINA_FALSE; E_Border_List *l = NULL; @@ -8312,8 +8604,10 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd) if ((!bd) || (e_object_is_del(E_OBJECT(bd)))) continue; if ((without_vkbd) && - (((rot.vkbd) && (rot.vkbd == bd)) || - ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))) continue; + (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)) + { + continue; + } if ((bd->visible) && ((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) && @@ -8321,6 +8615,8 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd) (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h, bd->x, bd->y, bd->w, bd->h))) { + if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue; + // check if this window is available to be rotate. if ((bd->client.e.state.rot.app_set) && (bd->client.e.state.rot.preferred_rot != -1)) continue; @@ -8336,8 +8632,20 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd) /* skip same angle */ if (bd->client.e.state.rot.curr == ang) { - ELBF(ELBT_ROT, 0, bd->client.win, "SKIP ang:%d", ang); - continue; + /* FIXME: hack for rotating vkbd: + * even if angle of zone is not changed, + * if preferred_rot of parent is set with specific angle, vkbd has to rotate, too. + * all of other transient window like this case. + */ + if ((bd->parent) && + (bd->parent->client.e.state.rot.preferred_rot != -1)) + ang = bd->parent->client.e.state.rot.preferred_rot; + if (bd->client.e.state.rot.curr == ang) + { + ELBF(ELBT_ROT, 0, bd->client.win, "SKIP ang:%d", ang); + continue; + } + ELBF(ELBT_ROT, 0, bd->client.win, "rotate by parent ang:%d", ang); } else { @@ -8348,81 +8656,28 @@ _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd) bd->client.e.state.rot.prev = bd->client.e.state.rot.curr; bd->client.e.state.rot.curr = ang; bd->client.e.state.rot.wait_for_done = 1; + nl = eina_list_append(nl, bd); - info = E_NEW(E_Border_Rotation_Info, 1); - if (info) + /* check whether rotation is available for sub borders such as prediction and magnifier */ + Eina_List *ll; + E_Border *_child; + Eina_List *_list = _e_border_sub_borders_new(bd); + EINA_LIST_FOREACH(_list, ll, _child) { - info->bd = bd; - info->ang = ang; - info->x = bd->x; info->y = bd->y; - info->w = bd->w; info->h = bd->h; - info->win_resize = EINA_FALSE; - nl = eina_list_append(nl, info); + if ((_child->client.e.state.rot.support) || + (_child->client.e.state.rot.app_set)) + _e_border_rotation_check(_child); } + eina_list_free(_list); - if (REGION_EQUAL_TO_ZONE(bd, zone)) - { - wait = EINA_TRUE; // for the maximized window - } - else - { - int diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev; - int x, y, w, h; - Eina_Bool resize = EINA_TRUE; - if ((diff == 180) || (diff == -180)) - resize = EINA_FALSE; - - Eina_Bool move = EINA_TRUE; - Eina_Bool hint = EINA_FALSE; - hint = _e_border_rotation_geom_get(bd, zone, zone->rot.curr, &x, &y, &w, &h, &move); - if (hint) - _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move); - else - { - x = bd->x; y = bd->y; - w = bd->w; h = bd->h; - if (resize) - { - if (w == h) - resize = EINA_FALSE; - else - { - // swap width and height and resize border - w = bd->h; - h = bd->w; - - _e_border_move_resize_internal(bd, x, y, w, h, - EINA_TRUE, EINA_TRUE); - } - } - } - - if (info) - { - info->x = x; info->y = y; - info->w = w; info->h = h; - info->win_resize = resize; - } - - if (resize) - bd->client.e.state.rot.pending_change_request = 1; - - wait = EINA_TRUE; - } + wait = EINA_TRUE; } } if (l) e_container_border_list_free(l); - if (nl) - { - // clear previous list - EINA_LIST_FREE(rot.list, info) - { - E_FREE(info); - } - rot.list = nl; - } + wait = e_border_rotation_list_add_change_req(zone, nl); + eina_list_free(nl); return wait; } @@ -8827,7 +9082,7 @@ _e_border_eval0(E_Border *bd) { const char **profiles = NULL; const char *str; - int num, i; + int num = 0, i; if (bd->client.e.state.profile) eina_stringshare_del(bd->client.e.state.profile); @@ -8865,7 +9120,11 @@ _e_border_eval0(E_Border *bd) } if (profiles) - free(profiles); + { + for (i = 0; i < num; i++) + if (profiles[i]) free(profiles[i]); + free(profiles); + } bd->client.e.fetch.profile_list = 0; } @@ -9195,6 +9454,9 @@ _e_border_eval0(E_Border *bd) { /* TODO: What do to if the transient for isn't mapped yet? */ E_Border *bd_parent = NULL; +#ifdef _F_DEICONIFY_APPROVE_ + Eina_Bool change_parent = EINA_FALSE; +#endif bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win); if (bd->client.icccm.transient_for) @@ -9216,6 +9478,9 @@ _e_border_eval0(E_Border *bd) { bd_parent->transients = eina_list_append(bd_parent->transients, bd); bd->parent = bd_parent; +#ifdef _F_DEICONIFY_APPROVE_ + change_parent = EINA_TRUE; +#endif } if (bd->parent) { @@ -9235,6 +9500,33 @@ _e_border_eval0(E_Border *bd) (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED))) bd->take_focus = 1; } + +#ifdef _F_DEICONIFY_APPROVE_ + if (change_parent) + { + bd->client.e.state.deiconify_approve.render_done = 0; + + E_Border *ancestor_bd; + ancestor_bd = bd->client.e.state.deiconify_approve.ancestor; + if ((ancestor_bd) && + (!e_object_is_del(E_OBJECT(ancestor_bd)))) + { + ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd); + bd->client.e.state.deiconify_approve.ancestor = NULL; + + if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) && + (ancestor_bd->client.e.state.deiconify_approve.render_done)) + { + if (ancestor_bd->client.e.state.deiconify_approve.wait_timer) + { + ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer); + ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL; + e_border_uniconify(ancestor_bd); + } + } + } + } +#endif bd->client.icccm.fetch.transient_for = 0; rem_change = 1; } @@ -9770,7 +10062,21 @@ _e_border_eval0(E_Border *bd) (need_rotation_set)) { ELB(ELBT_ROT, "NEED ROT", bd->client.win); - _e_border_rotation_check(bd); + Eina_Bool _rot = _e_border_rotation_check(bd); + /* check whether rotation is available for sub borders such as prediction and magnifier */ + if (_rot) + { + Eina_List *ll; + E_Border *_child; + Eina_List *_list = _e_border_sub_borders_new(bd); + EINA_LIST_FOREACH(_list, ll, _child) + { + if ((_child->client.e.state.rot.support) || + (_child->client.e.state.rot.app_set)) + _e_border_rotation_check(_child); + } + eina_list_free(_list); + } } #endif @@ -11528,15 +11834,50 @@ _e_border_event_border_unfullscreen_free(void *data __UNUSED__, #ifdef _F_ZONE_WINDOW_ROTATION_ static void -_e_border_event_border_rotation_free(void *data __UNUSED__, - void *ev) +_e_border_event_border_rotation_change_begin_free(void *data __UNUSED__, + void *ev) { - E_Event_Border_Rotation *e; + E_Event_Border_Rotation_Change_Begin *e; + e = ev; + e_object_unref(E_OBJECT(e->border)); + E_FREE(e); +} + +static void +_e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__, + void *ev) +{ + E_Event_Border_Rotation_Change_Cancel *e; + e = ev; + e_object_unref(E_OBJECT(e->border)); + E_FREE(e); +} +static void +_e_border_event_border_rotation_change_end_free(void *data __UNUSED__, + void *ev) +{ + E_Event_Border_Rotation_Change_End *e; e = ev; e_object_unref(E_OBJECT(e->border)); E_FREE(e); } + +static void +_e_border_event_border_rotation_change_begin_send(E_Border *bd) +{ + E_Event_Border_Rotation_Change_Begin *ev = NULL; + ev = E_NEW(E_Event_Border_Rotation_Change_End, 1); + if (ev) + { + ev->border = bd; + e_object_ref(E_OBJECT(bd)); + ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN, + ev, + _e_border_event_border_rotation_change_begin_free, + NULL); + } +} #endif static void