* 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
*
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);
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, int *x, int *y, int *w, int *h);
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);
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);
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) \
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);
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();
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);
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);
}
}
(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
}
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)
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);
if (bd->new_client)
{
- _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
- return;
+ /* FIXME: hack for resizing vkbd like window.
+ * IT SHOULD BE REMOVED after move the code which set the geometry of vkbd like window
+ * to illume's layout hook handler.
+ * the job of pending move/resize wouldn't be processed,
+ * in case this function is called from "_e_border_rotation_check" via "e_hints_window_init".
+ * thus we have to move/resize directry without pending in case geometry hint is existed. */
+ if (!_e_border_rotation_geom_get(bd, bd->zone, bd->client.e.state.rot.curr,
+ NULL, NULL, NULL, NULL, NULL))
+ {
+ _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
+ return;
+ }
}
if (bd->maximized)
_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
{
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
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);
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);
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);
void *ev)
{
E_Border *bd;
+ E_Container *con;
Ecore_X_Event_Window_Show_Request *e;
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return ECORE_CALLBACK_PASS_ON;
+
+ if ((e_config->wm_win_rotation) &&
+ (rot.vkbd_ctrl_win) && (rot.vkbd) &&
+ (bd == rot.vkbd) &&
+ (rot.vkbd_hide_prepare_timer))
+ {
+ con = bd->zone->container;
+ bd = e_border_new(con, e->win, 0, 0);
+ }
+
if (bd->iconic)
{
if (!bd->lock_client_iconify)
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;
}
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)
{
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));
}
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;
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);
}
}
#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;
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
{
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);
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);
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)
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();
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;
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.
*/
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];
_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;
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)",
hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
if (hint)
- _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
+ {
+ _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
+ ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
+ bd->client.icccm.name, x, y, w, h);
+ }
/* need to check previous rotation angle, this may be because
* the window was unmapped with non-0 rotation degree.
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)) &&
{
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;
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,
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;
}
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;
+ int x=0, y=0, w=0, h=0;
+
+ 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->win_resize = _e_border_rotation_pre_resize(bd, &x, &y, &w, &h);
+ info->x = x; info->y = y;
+ info->w = w; info->h = h;
+ 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_list_add(E_Zone *zone, Eina_Bool without_vkbd)
+_e_border_rotation_pre_resize(E_Border *bd, int *x, int *y, int *w, int *h)
+{
+ 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 (x) *x = bd->x;
+ if (y) *y = bd->y;
+ if (w) *w = bd->w;
+ if (h) *h = bd->h;
+
+ if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
+
+ ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
+ ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
+ bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
+
+ 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;
+ ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
+ bd->client.icccm.name, _x, _y, _w, _h);
+ }
+ 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);
+ ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
+ bd->client.icccm.name, _x, _y, _w, _h);
+
+ }
+ }
+ }
+
+ if (resize)
+ {
+ if (x) *x = _x;
+ if (y) *y = _y;
+ if (w) *w = _w;
+ if (h) *h = _h;
+ }
+
+ return resize;
+}
+
+static Eina_Bool
+_e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd)
{
Eina_Bool wait = EINA_FALSE;
E_Border_List *l = NULL;
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)) &&
(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;
/* 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
{
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;
}
{
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);
}
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;
}
{
/* 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)
{
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)
{
(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;
}
#endif
#ifdef _F_ZONE_WINDOW_ROTATION_
if ((e_config->wm_win_rotation) &&
- (need_rotation_set))
+ (need_rotation_set) &&
+ /* since this parts of code is processed before illume's layout hook handler is processed,
+ * this border could be non-fullsize window at this time.
+ * in this case, if we send rotation like message to window,
+ * that window could have abnormal geometry.
+ * so, we skip it in case new_client for now.*/
+ (!bd->new_client))
{
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
#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