forked from enlightenment/enlightenment
Tiling2: Get rid of split_type, use levels instead and bug fixes.
This commit is contained in:
parent
f64763ab6e
commit
21ac77185b
|
@ -478,13 +478,14 @@ _add_client(E_Client *ec)
|
|||
|
||||
/* Window tree updating. */
|
||||
{
|
||||
E_Client *ec_focused = e_client_focused_get();
|
||||
/* If focused is NULL, it should return the root. */
|
||||
Window_Tree *parent = tiling_window_tree_client_find(_G.tinfo->tree,
|
||||
e_client_focused_get());
|
||||
ec_focused);
|
||||
Window_Tree *new_node;
|
||||
if (!parent)
|
||||
{
|
||||
if (_G.tinfo->tree)
|
||||
if (_G.tinfo->tree && ec_focused)
|
||||
{
|
||||
ERR("Couldn't find tree item for focused client %p. Using root..",
|
||||
e_client_focused_get());
|
||||
|
@ -492,7 +493,7 @@ _add_client(E_Client *ec)
|
|||
parent = _G.tinfo->tree;
|
||||
}
|
||||
|
||||
new_node = tiling_window_tree_add(parent, ec, _G.split_type);
|
||||
new_node = tiling_window_tree_add(_G.tinfo->tree, parent, ec, _G.split_type);
|
||||
if (!_G.tinfo->tree)
|
||||
_G.tinfo->tree = new_node;
|
||||
}
|
||||
|
@ -660,7 +661,7 @@ static void _move_or_resize(E_Client *ec)
|
|||
return;
|
||||
}
|
||||
|
||||
_reapply_tree();
|
||||
// _reapply_tree();
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
|
|
@ -23,38 +23,8 @@ tiling_window_tree_free(Window_Tree *root)
|
|||
tiling_window_tree_walk(root, free);
|
||||
}
|
||||
|
||||
Window_Tree *
|
||||
tiling_window_tree_add(Window_Tree *parent, E_Client *client, Tiling_Split_Type split_type)
|
||||
{
|
||||
Window_Tree *new_node = calloc(1, sizeof(*new_node));
|
||||
new_node->client = client;
|
||||
|
||||
if (!parent)
|
||||
{
|
||||
new_node->weight = 1.0;
|
||||
return new_node;
|
||||
}
|
||||
else if (parent->parent && parent->parent->children && (parent->parent->split_type == split_type))
|
||||
{
|
||||
/* Adjust existing children's weights */
|
||||
Window_Tree *grand_parent = parent->parent;
|
||||
Window_Tree *itr;
|
||||
int children_count = eina_inlist_count(grand_parent->children);
|
||||
float weight = 1.0 / (children_count + 1);
|
||||
|
||||
new_node->parent = grand_parent;
|
||||
new_node->weight = weight;
|
||||
|
||||
weight *= children_count;
|
||||
EINA_INLIST_FOREACH(grand_parent->children, itr)
|
||||
{
|
||||
itr->weight *= weight;
|
||||
}
|
||||
|
||||
grand_parent->children = eina_inlist_append(grand_parent->children,
|
||||
EINA_INLIST_GET(new_node));
|
||||
}
|
||||
else
|
||||
static void
|
||||
_tiling_window_tree_split_add(Window_Tree *parent, Window_Tree *new_node)
|
||||
{
|
||||
/* Make a new node for the parent client and split the weights in half. */
|
||||
Window_Tree *new_parent_client = calloc(1, sizeof(*new_node));
|
||||
|
@ -64,7 +34,6 @@ tiling_window_tree_add(Window_Tree *parent, E_Client *client, Tiling_Split_Type
|
|||
parent->client = NULL;
|
||||
new_parent_client->weight = 0.5;
|
||||
new_node->weight = 0.5;
|
||||
parent->split_type = split_type;
|
||||
|
||||
parent->children = eina_inlist_append(parent->children,
|
||||
EINA_INLIST_GET(new_parent_client));
|
||||
|
@ -72,6 +41,83 @@ tiling_window_tree_add(Window_Tree *parent, E_Client *client, Tiling_Split_Type
|
|||
EINA_INLIST_GET(new_node));
|
||||
}
|
||||
|
||||
static void
|
||||
_tiling_window_tree_parent_add(Window_Tree *parent, Window_Tree *new_node)
|
||||
{
|
||||
/* Adjust existing children's weights */
|
||||
Window_Tree *itr;
|
||||
int children_count = eina_inlist_count(parent->children);
|
||||
float weight = 1.0 / (children_count + 1);
|
||||
|
||||
new_node->parent = parent;
|
||||
new_node->weight = weight;
|
||||
|
||||
weight *= children_count;
|
||||
EINA_INLIST_FOREACH(parent->children, itr)
|
||||
{
|
||||
itr->weight *= weight;
|
||||
}
|
||||
|
||||
parent->children = eina_inlist_append(parent->children,
|
||||
EINA_INLIST_GET(new_node));
|
||||
}
|
||||
|
||||
static int
|
||||
_tiling_window_tree_split_type_get(Window_Tree *node)
|
||||
{
|
||||
int ret = 0;
|
||||
while (node->parent)
|
||||
{
|
||||
ret++;
|
||||
node = node->parent;
|
||||
}
|
||||
|
||||
return ret % 2;
|
||||
}
|
||||
|
||||
Window_Tree *
|
||||
tiling_window_tree_add(Window_Tree *root, Window_Tree *parent, E_Client *client, Tiling_Split_Type split_type)
|
||||
{
|
||||
Window_Tree *new_node = calloc(1, sizeof(*new_node));
|
||||
new_node->client = client;
|
||||
Tiling_Split_Type parent_split_type;
|
||||
|
||||
if (!root)
|
||||
{
|
||||
new_node->weight = 1.0;
|
||||
return new_node;
|
||||
}
|
||||
else if (!parent)
|
||||
{
|
||||
parent = root;
|
||||
}
|
||||
|
||||
parent_split_type = _tiling_window_tree_split_type_get(parent);
|
||||
|
||||
if (parent_split_type == split_type)
|
||||
{
|
||||
if (parent->children)
|
||||
{
|
||||
_tiling_window_tree_parent_add(parent, new_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiling_window_tree_split_add(parent, new_node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Window_Tree *grand_parent = parent->parent;
|
||||
if (grand_parent && grand_parent->children)
|
||||
{
|
||||
_tiling_window_tree_parent_add(grand_parent, new_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiling_window_tree_split_add(parent, new_node);
|
||||
}
|
||||
}
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
|
@ -104,7 +150,6 @@ tiling_window_tree_remove(Window_Tree *root, Window_Tree *item)
|
|||
|
||||
item->parent->client = item_keep->client;
|
||||
item->parent->children = item_keep->children;
|
||||
item->parent->split_type = item_keep->split_type;
|
||||
|
||||
/* Update the children's parent. */
|
||||
{
|
||||
|
@ -142,6 +187,9 @@ tiling_window_tree_client_find(Window_Tree *root, E_Client *client)
|
|||
{
|
||||
Window_Tree *itr;
|
||||
|
||||
if (!client)
|
||||
return NULL;
|
||||
|
||||
if (!root || (root->client == client))
|
||||
return root;
|
||||
|
||||
|
@ -169,30 +217,38 @@ _e_client_move_resize(E_Client *ec,
|
|||
}
|
||||
|
||||
void
|
||||
tiling_window_tree_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y,
|
||||
Evas_Coord w, Evas_Coord h)
|
||||
_tiling_window_tree_level_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y,
|
||||
Evas_Coord w, Evas_Coord h, int level)
|
||||
{
|
||||
Window_Tree *itr;
|
||||
Tiling_Split_Type split_type = level % 2;
|
||||
|
||||
if (root->client)
|
||||
_e_client_move_resize(root->client, x, y, w, h);
|
||||
|
||||
if (root->split_type == TILING_SPLIT_HORIZONTAL)
|
||||
if (split_type == TILING_SPLIT_HORIZONTAL)
|
||||
{
|
||||
EINA_INLIST_FOREACH(root->children, itr)
|
||||
{
|
||||
Evas_Coord itw = w * itr->weight;
|
||||
tiling_window_tree_apply(itr, x, y, itw, h);
|
||||
_tiling_window_tree_level_apply(itr, x, y, itw, h, level + 1);
|
||||
x += itw;
|
||||
}
|
||||
}
|
||||
else if (root->split_type == TILING_SPLIT_VERTICAL)
|
||||
else if (split_type == TILING_SPLIT_VERTICAL)
|
||||
{
|
||||
EINA_INLIST_FOREACH(root->children, itr)
|
||||
{
|
||||
Evas_Coord ith = h * itr->weight;
|
||||
tiling_window_tree_apply(itr, x, y, w, ith);
|
||||
_tiling_window_tree_level_apply(itr, x, y, w, ith, level + 1);
|
||||
y += ith;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tiling_window_tree_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y,
|
||||
Evas_Coord w, Evas_Coord h)
|
||||
{
|
||||
_tiling_window_tree_level_apply(root, x, y, w, h, 0);
|
||||
}
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
#define WINDOW_TREE_HO
|
||||
#include <e.h>
|
||||
|
||||
/* XXX: Gotta be 0 and 1 because it's calculated using level % 2. */
|
||||
typedef enum {
|
||||
TILING_SPLIT_HORIZONTAL,
|
||||
TILING_SPLIT_VERTICAL
|
||||
TILING_SPLIT_HORIZONTAL = 0,
|
||||
TILING_SPLIT_VERTICAL = 1
|
||||
} Tiling_Split_Type;
|
||||
|
||||
typedef struct _Window_Tree Window_Tree;
|
||||
|
||||
/* Root is level 0. Each node's split type is (level % 2). */
|
||||
struct _Window_Tree
|
||||
{
|
||||
EINA_INLIST;
|
||||
|
@ -17,13 +19,12 @@ struct _Window_Tree
|
|||
Eina_Inlist *children; /* Window_Tree * type */
|
||||
E_Client *client;
|
||||
float weight;
|
||||
Tiling_Split_Type split_type;
|
||||
};
|
||||
|
||||
void tiling_window_tree_free(Window_Tree *root);
|
||||
void tiling_window_tree_walk(Window_Tree *root, void (*func)(void *));
|
||||
|
||||
Window_Tree *tiling_window_tree_add(Window_Tree *parent, E_Client *client, Tiling_Split_Type split_type);
|
||||
Window_Tree *tiling_window_tree_add(Window_Tree *root, Window_Tree *parent, E_Client *client, Tiling_Split_Type split_type);
|
||||
|
||||
Window_Tree *tiling_window_tree_remove(Window_Tree *root, Window_Tree *item);
|
||||
|
||||
|
|
Loading…
Reference in New Issue