forked from enlightenment/enlightenment
tiling: fix insertion in the tree
the problem here was that in the initial case the function got the previous state of the tree wrong, so the insertion of a second client ended up in a unpossible state of the tree, this should not happen anymore now. The insertion is now also way more stable, since in a errorcase the client is not just not placed in the tree but associated with a window tree, its just not placing the client in the window tree at all.
This commit is contained in:
parent
f1fb4a0c83
commit
de21e6ddb8
|
@ -703,7 +703,7 @@ _insert_client_prefered(E_Client *ec)
|
|||
}
|
||||
else
|
||||
{
|
||||
_G.tinfo->tree = tiling_window_tree_insert(_G.tinfo->tree, _G.tinfo->tree, ec, _current_tiled_state(EINA_FALSE), EINA_FALSE);
|
||||
_G.tinfo->tree = tiling_window_tree_insert(_G.tinfo->tree, NULL, ec, _current_tiled_state(EINA_FALSE), EINA_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,13 +95,6 @@ _tiling_window_tree_split_type_get(Window_Tree *node)
|
|||
|
||||
#define VERIFY_TYPE(t) if (t > TILING_SPLIT_VERTICAL || t < 0) { ERR("Invalid insert type"); return root; }
|
||||
|
||||
#define ROOT_CHECK() \
|
||||
if (!root) \
|
||||
{ \
|
||||
new_node->weight = 1.0; \
|
||||
return new_node; \
|
||||
}
|
||||
|
||||
Window_Tree *
|
||||
tiling_window_tree_insert(Window_Tree *root, Window_Tree *buddy,
|
||||
E_Client *client, Tiling_Split_Type split_type, Eina_Bool before)
|
||||
|
@ -115,28 +108,42 @@ tiling_window_tree_insert(Window_Tree *root, Window_Tree *buddy,
|
|||
new_node = calloc(1, sizeof(*new_node));
|
||||
new_node->client = client;
|
||||
|
||||
ROOT_CHECK()
|
||||
|
||||
parent = buddy->parent;
|
||||
|
||||
if (!parent)
|
||||
if (!root)
|
||||
{
|
||||
//this means buddy is the root so just set buddy to NULL and parent to buddy
|
||||
parent = buddy;
|
||||
buddy = NULL;
|
||||
}
|
||||
root = calloc(1, sizeof(*root));
|
||||
root->weight = 1.0;
|
||||
|
||||
parent_split_type = _tiling_window_tree_split_type_get(parent);
|
||||
|
||||
if (parent_split_type == split_type)
|
||||
{
|
||||
_tiling_window_tree_parent_add(parent, new_node, buddy, !before);
|
||||
_tiling_window_tree_parent_add(root, new_node, NULL, !before);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if there is no buddy we are going to take the last child of the root
|
||||
if (!buddy)
|
||||
buddy = root;
|
||||
_tiling_window_tree_split_add(buddy, new_node, !before);
|
||||
{
|
||||
buddy = root;
|
||||
do
|
||||
{
|
||||
buddy = EINA_INLIST_CONTAINER_GET(eina_inlist_last(buddy->children), Window_Tree);
|
||||
}
|
||||
while (!buddy->client);
|
||||
}
|
||||
else
|
||||
{
|
||||
//make sure this buddy has a client,
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(!buddy->client, root);
|
||||
}
|
||||
|
||||
parent = buddy->parent;
|
||||
parent_split_type = _tiling_window_tree_split_type_get(parent);
|
||||
|
||||
if (parent_split_type == split_type)
|
||||
{
|
||||
_tiling_window_tree_parent_add(parent, new_node, buddy, !before);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiling_window_tree_split_add(buddy, new_node, !before);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
|
|
|
@ -34,6 +34,16 @@ int tiling_window_tree_edges_get(Window_Tree *node);
|
|||
void tiling_window_tree_free(Window_Tree *root);
|
||||
void tiling_window_tree_walk(Window_Tree *root, void (*func)(void *));
|
||||
|
||||
/**
|
||||
* Insert a new client into the tree
|
||||
*
|
||||
* @param root the root node where to insert in some subtree
|
||||
* @param buddy the buddy where you want to place client to, buddy MUST be a node with a associated client OR NULL
|
||||
* @param split_type the split type you want to insert the client
|
||||
* @param before true to insert the client before the buddy false to insert it after the buddy
|
||||
*
|
||||
* @return the new root node
|
||||
*/
|
||||
Window_Tree *tiling_window_tree_insert(Window_Tree *root, Window_Tree *buddy,
|
||||
E_Client *client, Tiling_Split_Type split_type, Eina_Bool before);
|
||||
|
||||
|
|
Loading…
Reference in New Issue