Tiling2: Added resizing support.

There are still some bugs.
This commit is contained in:
Tom Hacohen 2014-01-14 17:25:32 +00:00
parent 3aa597c4af
commit 6b606cde41
3 changed files with 155 additions and 4 deletions

View File

@ -333,10 +333,18 @@ tiling_e_client_move_resize_extra(E_Client *ec,
int w,
int h)
{
Client_Extra *extra = _get_or_create_client_extra(ec);
if (!extra) {
Client_Extra *extra = eina_hash_find(_G.client_extras, &ec);
if (!extra) {
ERR("No extra for %p", ec);
}
return;
}
extra->expected = (geom_t) {
.x = x,
.y = y,
.w = w,
.h = h,
};
_e_client_move_resize(ec, x, y, w, h);
}
@ -597,6 +605,12 @@ static void _move_or_resize(E_Client *ec)
if (!ec) {
return;
}
if (is_floating_window(ec)) {
return;
}
if (!is_tilable(ec)) {
return;
}
if (!desk_should_tile_check(ec->desk))
return;
@ -618,6 +632,47 @@ static void _move_or_resize(E_Client *ec)
return;
}
if ((ec->x == extra->expected.x) && (ec->y == extra->expected.y) &&
(ec->w == extra->expected.w) && (ec->h == extra->expected.h))
{
return;
}
Window_Tree *item = tiling_window_tree_client_find(_G.tinfo->tree, ec);
if (!item)
{
ERR("Couldn't find tree item for resized client %p!", ec);
return;
}
{
int w_dir = 1, h_dir = 1;
double w_diff = 1.0, h_diff = 1.0;
if (abs(extra->expected.w - ec->w) >= MAX(ec->icccm.step_w, 1))
{
w_diff = ((double) ec->w) / extra->expected.w;
printf("w %d %d %f\n", extra->expected.w, ec->w, w_diff);
}
if (abs(extra->expected.h - ec->h) >= MAX(ec->icccm.step_h, 1))
{
h_diff = ((double) ec->h) / extra->expected.h;
printf("h %d %d %f\n", extra->expected.h, ec->h, h_diff);
}
if (extra->expected.x != ec->x)
{
w_dir = -1;
}
if (extra->expected.y != ec->y)
{
h_dir = -1;
}
if ((w_diff != 1.0) || (h_diff != 1.0))
{
tiling_window_tree_node_resize(item, w_dir, w_diff, h_dir, h_diff);
}
}
_reapply_tree();
}

View File

@ -281,6 +281,100 @@ tiling_window_tree_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y,
_tiling_window_tree_level_apply(root, x, y, w, h, 0);
}
static Window_Tree *
_inlist_next(Window_Tree *it)
{
return (Window_Tree *) EINA_INLIST_GET(it)->next;
}
static Window_Tree *
_inlist_prev(Window_Tree *it)
{
return (Window_Tree *) EINA_INLIST_GET(it)->prev;
}
static void
_tiling_window_tree_node_resize_direction(Window_Tree *node, Window_Tree *parent,
double dir_diff, int dir)
{
double weight = 0.0;
double weight_diff;
Window_Tree *children_start;
Window_Tree *itr;
Window_Tree *(*itr_func)(Window_Tree *);
if (dir > 0)
{
itr_func = _inlist_prev;
children_start = (Window_Tree *) parent->children->last;
}
else
{
itr_func = _inlist_next;
children_start = (Window_Tree *) parent->children;
}
itr = (Window_Tree *) children_start;
while (itr != node)
{
weight += itr->weight;
itr = itr_func(itr);
}
if (weight == 0.0)
return;
weight_diff = itr->weight;
itr->weight *= dir_diff;
weight_diff -= itr->weight;
weight_diff /= weight;
for (itr = children_start ; itr != node ; itr = itr_func(itr))
{
itr->weight += itr->weight * weight_diff;
}
}
void
tiling_window_tree_node_resize(Window_Tree *node, int w_dir, double w_diff, int h_dir, double h_diff)
{
Window_Tree *parent = node->parent;
Window_Tree *w_parent, *h_parent;
/* If we have no parent, means we need to be full screen anyway. */
if (!parent)
return;
Window_Tree *grand_parent = parent->parent;
Tiling_Split_Type parent_split_type = _tiling_window_tree_split_type_get(parent);
/* w_diff related changes. */
if (parent_split_type == TILING_SPLIT_HORIZONTAL)
{
w_parent = parent;
h_parent = grand_parent;
}
else
{
w_parent = grand_parent;
h_parent = parent;
}
if ((h_diff != 1.0) && h_parent)
{
Window_Tree *tmp_node = (h_parent == parent) ? node : parent;
_tiling_window_tree_node_resize_direction(tmp_node, h_parent, h_diff, h_dir);
}
if ((w_diff != 1.0) && w_parent)
{
Window_Tree *tmp_node = (w_parent == parent) ? node : parent;
_tiling_window_tree_node_resize_direction(tmp_node, w_parent, w_diff, w_dir);
}
}
void
tiling_window_tree_dump(Window_Tree *root, int level)
{

View File

@ -18,7 +18,7 @@ struct _Window_Tree
/* FIXME: client is falid iff children is null. Sholud enforce it. */
Eina_Inlist *children; /* Window_Tree * type */
E_Client *client;
float weight;
double weight;
};
void tiling_window_tree_free(Window_Tree *root);
@ -32,4 +32,6 @@ 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);
void tiling_window_tree_node_resize(Window_Tree *node, int w_dir, double w_diff, int h_dir, double h_diff);
#endif