forked from enlightenment/enlightenment
Tiling2: Fixed bugs and improve the window tree implementation.
This commit is contained in:
parent
cfd4ea4f9f
commit
9060fa64b9
|
@ -1,3 +1,5 @@
|
|||
#include "e.h"
|
||||
|
||||
#include "window_tree.h"
|
||||
|
||||
void
|
||||
|
@ -13,43 +15,47 @@ tiling_window_tree_free(Window_Tree *root)
|
|||
}
|
||||
|
||||
Window_Tree *
|
||||
tiling_window_tree_add(Window_Tree *parent, E_Client *client)
|
||||
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->parent = parent;
|
||||
new_node->client = client;
|
||||
|
||||
if (!parent)
|
||||
{
|
||||
new_node->weight = 1.0;
|
||||
return new_node;
|
||||
}
|
||||
else if (parent->children)
|
||||
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(parent->children);
|
||||
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(parent->children, itr)
|
||||
EINA_INLIST_FOREACH(grand_parent->children, itr)
|
||||
{
|
||||
itr->weight *= weight;
|
||||
}
|
||||
|
||||
parent->children = eina_inlist_append(parent->children,
|
||||
grand_parent->children = eina_inlist_append(grand_parent->children,
|
||||
EINA_INLIST_GET(new_node));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make a new node for the parent client and split the weights in half. */
|
||||
Window_Tree *new_parent_client = calloc(1, sizeof(*new_node));
|
||||
new_node->parent = parent;
|
||||
new_parent_client->parent = parent;
|
||||
new_parent_client->client = parent->client;
|
||||
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));
|
||||
|
@ -60,22 +66,36 @@ tiling_window_tree_add(Window_Tree *parent, E_Client *client)
|
|||
return new_node;
|
||||
}
|
||||
|
||||
void
|
||||
tiling_window_tree_remove(Window_Tree *item)
|
||||
Window_Tree *
|
||||
tiling_window_tree_remove(Window_Tree *root, Window_Tree *item)
|
||||
{
|
||||
/* FIXME: Ignoring ilegal deletion of the rood node or items with children atm. */
|
||||
if (root == item)
|
||||
{
|
||||
free(item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int children_count = eina_inlist_count(item->parent->children);
|
||||
float weight = (((float) children_count) - 1.0) / children_count;
|
||||
|
||||
if (children_count == 1)
|
||||
if (children_count <= 2)
|
||||
{
|
||||
item->parent->client = item->client;
|
||||
Window_Tree *item_keep = NULL;
|
||||
/* Adjust existing children's weights */
|
||||
EINA_INLIST_FOREACH(item->parent->children, item_keep)
|
||||
{
|
||||
if (item_keep != item)
|
||||
break;
|
||||
}
|
||||
|
||||
item->parent->client = item_keep->client;
|
||||
item->parent->children = NULL;
|
||||
|
||||
free(item_keep);
|
||||
}
|
||||
else
|
||||
{
|
||||
Window_Tree *itr;
|
||||
float weight = (((float) children_count) - 1.0) / children_count;
|
||||
|
||||
item->parent->children = eina_inlist_remove(item->parent->children,
|
||||
EINA_INLIST_GET(item));
|
||||
|
@ -88,5 +108,65 @@ tiling_window_tree_remove(Window_Tree *item)
|
|||
}
|
||||
|
||||
free(item);
|
||||
return root;
|
||||
}
|
||||
|
||||
Window_Tree *
|
||||
tiling_window_tree_client_find(Window_Tree *root, E_Client *client)
|
||||
{
|
||||
Window_Tree *itr;
|
||||
|
||||
if (!root || (root->client == client))
|
||||
return root;
|
||||
|
||||
EINA_INLIST_FOREACH(root->children, itr)
|
||||
{
|
||||
Window_Tree *ret;
|
||||
ret = tiling_window_tree_client_find(itr, client);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: Deduplicate this func. */
|
||||
static void
|
||||
_e_client_move_resize(E_Client *ec,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
int h)
|
||||
{
|
||||
DBG("%p -> %dx%d+%d+%d", ec, w, h, x, y);
|
||||
evas_object_geometry_set(ec->frame, x, y, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
tiling_window_tree_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y,
|
||||
Evas_Coord w, Evas_Coord h)
|
||||
{
|
||||
Window_Tree *itr;
|
||||
|
||||
if (root->client)
|
||||
_e_client_move_resize(root->client, x, y, w, h);
|
||||
|
||||
if (root->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);
|
||||
x += itw;
|
||||
}
|
||||
}
|
||||
else if (root->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);
|
||||
y += ith;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
#define WINDOW_TREE_HO
|
||||
#include <e.h>
|
||||
|
||||
typedef enum {
|
||||
TILING_SPLIT_HORIZONTAL,
|
||||
TILING_SPLIT_VERTICAL
|
||||
} Tiling_Split_Type;
|
||||
|
||||
typedef struct _Window_Tree Window_Tree;
|
||||
|
||||
struct _Window_Tree
|
||||
|
@ -12,6 +17,17 @@ 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);
|
||||
|
||||
Window_Tree *tiling_window_tree_add(Window_Tree *parent, E_Client *client, Tiling_Split_Type split_type);
|
||||
|
||||
Window_Tree *tiling_window_tree_remove(Window_Tree *root, Window_Tree *item);
|
||||
|
||||
Window_Tree *tiling_window_tree_client_find(Window_Tree *root, E_Client *client);
|
||||
|
||||
void tiling_window_tree_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue