#include "e.h"
-typedef struct _E_Policy_Stack E_Policy_Stack;
-
-struct _E_Policy_Stack
-{
- E_Client *ec;
-
- struct
- {
- Ecore_Window win;
- Eina_Bool fetched;
- } transient;
-};
-
-static Eina_Hash *hash_pol_stack = NULL;
-
-static void
-_e_policy_stack_cb_data_free(void *data)
-{
- E_FREE(data);
-}
-
-E_Policy_Stack*
-_e_policy_stack_data_add(E_Client *ec)
-{
- E_Policy_Stack *ps;
-
- if ((ps = eina_hash_find(hash_pol_stack, &ec)))
- return ps;
-
- ps = E_NEW(E_Policy_Stack, 1);
- if (!ps) return NULL;
-
- ps->ec = ec;
- eina_hash_add(hash_pol_stack, &ec, ps);
-
- return ps;
-}
-
-void
-_e_policy_stack_data_del(E_Client *ec)
-{
- E_Policy_Stack *ps;
-
- if ((ps = eina_hash_find(hash_pol_stack, &ec)))
- {
- eina_hash_del_by_key(hash_pol_stack, &ec);
- }
-}
-
Eina_Bool
_e_policy_stack_transient_for_check_descendant(E_Client *ec, E_Client *ancestor)
{
_e_policy_stack_fetch_transient(E_Client *ec)
{
E_Client *new_focus = NULL;
- E_Policy_Stack *ps;
- ps = eina_hash_find(hash_pol_stack, &ec);
-
- if (ps)
- {
- if (ps->transient.fetched)
- {
- if (ps->transient.win)
- {
- if (ec->icccm.transient_for == ps->transient.win)
- _e_policy_stack_transient_for_apply(ec);
- else
- ps->transient.win = ec->icccm.transient_for;
+ E_Client *parent = NULL;
- if (ec->parent)
- {
- if (ec->parent == e_client_focused_get())
- {
- new_focus = e_client_transient_child_top_get(ec->parent, EINA_TRUE);
- if (new_focus)
- {
- if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
- {
- ELOGF("FOCUS", "focus set | tranient_for fetch", new_focus);
- e_client_frame_focus_set(new_focus, EINA_TRUE);
- }
- }
- }
- }
- }
- else
- {
- _e_policy_stack_transient_for_apply(ec);
- }
- ps->transient.fetched = 0;
- }
- }
-}
+ if (!ec->icccm.fetch.transient_for) return;
-void
-e_policy_stack_hook_pre_post_fetch(E_Client *ec)
-{
- _e_policy_stack_fetch_transient(ec);
-}
+ parent = e_pixmap_find_client(E_PIXMAP_TYPE_WL, ec->icccm.transient_for);
-static void
-_e_policy_stack_fetch_icccm_transient_for(E_Client *ec)
-{
- if (ec->icccm.fetch.transient_for)
+ if (parent != ec->parent)
{
- E_Policy_Stack *ps;
- Ecore_Window transient_for_win = 0;
- E_Client *parent = NULL;
- Eina_Bool transient_each_other = EINA_FALSE;
-
- ps = _e_policy_stack_data_add(ec);
- EINA_SAFETY_ON_NULL_RETURN(ps);
+ ELOGF("POL", "CRITICAL. parent(win:%x, ec:%p), ec->parent(win:%x, ec:%p)...", ec,
+ e_client_util_win_get(parent), parent, e_client_util_win_get(ec->parent), ec->parent);
+ }
- parent = e_pixmap_find_client(E_PIXMAP_TYPE_WL, ec->icccm.transient_for);
+ if (ec->icccm.transient_for != e_client_util_win_get(ec->parent))
+ {
+ ELOGF("POL", "CRITICAL. icccm.transient_for(%x), ec->parent win(%x)...", ec,
+ ec->icccm.transient_for, e_client_util_win_get(ec->parent));
+ }
- if (parent)
+ if (parent)
+ {
+ if (ec->desk_group.desk_group && parent->desk_group.desk_group)
{
- ps->transient.win = e_client_util_win_get(parent);
- ps->transient.fetched = 1;
-
- /* clients transient for each other */
- transient_each_other = _e_policy_stack_transient_for_tree_check(ec, parent);
- if (transient_each_other)
+ if (ec->desk_group.desk_group != parent->desk_group.desk_group)
{
- ec->icccm.transient_for = transient_for_win;
- ps->transient.fetched = 0;
- parent = NULL;
+ e_client_desk_group_set(ec, parent->desk_group.desk_group);
}
}
- else
- {
- ps->transient.win = 0;
- ps->transient.fetched = 1;
- }
+ }
+
+ _e_policy_stack_transient_for_apply(ec);
- if (parent)
+ if (ec->parent)
+ {
+ if (ec->parent == e_client_focused_get())
{
- if (ec->desk_group.desk_group && parent->desk_group.desk_group)
+ new_focus = e_client_transient_child_top_get(ec->parent, EINA_TRUE);
+ if (new_focus)
{
- if (ec->desk_group.desk_group != parent->desk_group.desk_group)
+ if (e_config->focus_policy_ext != E_FOCUS_EXT_TOP_STACK)
{
- e_client_desk_group_set(ec, parent->desk_group.desk_group);
+ ELOGF("FOCUS", "focus set | tranient_for fetch", new_focus);
+ e_client_frame_focus_set(new_focus, EINA_TRUE);
}
}
}
-
- ec->icccm.fetch.transient_for = 0;
}
+
+ ec->icccm.fetch.transient_for = EINA_FALSE;
}
void
-e_policy_stack_hook_pre_fetch(E_Client *ec)
+e_policy_stack_transient_for_apply(E_Client *ec)
{
- _e_policy_stack_fetch_icccm_transient_for(ec);
+ if (!ec) return;
+ _e_policy_stack_fetch_transient(ec);
}
void
-e_policy_stack_transient_for_set(E_Client *ec, E_Client *parent)
+_e_policy_stack_transient_for_set(E_Client *ec, E_Client *parent, Eina_Bool transient)
{
E_Client *child = NULL;
- E_Policy_Stack *ps;
Ecore_Window pwin = 0;
Eina_List *dup_transients = NULL;
+ Eina_Bool transient_each_other = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN(ec);
-
if (!parent)
{
- ec->icccm.fetch.transient_for = EINA_TRUE;
ec->icccm.transient_for = 0;
if (ec->parent)
{
eina_list_remove(ec->parent->transients, ec);
if (ec->parent->modal == ec) ec->parent->modal = NULL;
ec->parent = NULL;
+
+ ec->icccm.fetch.transient_for = EINA_TRUE;
+ EC_CHANGED(ec);
}
return;
}
- ps = _e_policy_stack_data_add(ec);
- EINA_SAFETY_ON_NULL_RETURN(ps);
+ /* check whether clients transient for each other */
+ transient_each_other = _e_policy_stack_transient_for_tree_check(ec, parent);
+ if (transient_each_other)
+ {
+ ELOGF("POL", "CRITICAL! TRANSIENT_FOR each other. parent(ec:%p, win:%x)",
+ ec, parent, e_client_util_win_get(parent));
+ return;
+ }
pwin = e_client_util_win_get(parent);
+ if (!transient)
+ e_pixmap_parent_window_set(ec->pixmap, pwin);
+
/* If we already have a parent, remove it */
if (ec->parent)
{
ec->icccm.fetch.transient_for = EINA_TRUE;
ec->icccm.transient_for = pwin;
-
- if (!ps->transient.win)
- ec->saved.layer = ec->layer;
-
EC_CHANGED(ec);
}
void
-e_policy_stack_transient_for_apply(E_Client *ec)
+e_policy_stack_transient_for_set(E_Client *ec, E_Client *parent)
{
- if (!ec) return;
-
- _e_policy_stack_fetch_icccm_transient_for(ec);
- _e_policy_stack_fetch_transient(ec);
+ _e_policy_stack_transient_for_set(ec, parent, EINA_TRUE);
}
void e_policy_stack_transient_child_raise(E_Client *ec)
if (e_object_is_del(E_OBJECT(child))) continue;
// for restore child's original layer
child->icccm.fetch.transient_for = EINA_TRUE;
+ child->icccm.transient_for = 0;
EC_CHANGED(child);
}
-
- _e_policy_stack_data_del(ec);
}
void
e_policy_stack_shutdown(void)
{
- eina_hash_free(hash_pol_stack);
- hash_pol_stack = NULL;
}
void
e_policy_stack_init(void)
{
- hash_pol_stack = eina_hash_pointer_new(_e_policy_stack_cb_data_free);
}
void