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:
Marcel Hollerbach 2017-08-12 22:26:32 +02:00
parent f1fb4a0c83
commit de21e6ddb8
3 changed files with 41 additions and 24 deletions

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);