Tiling2: Fixed adjacent node swapping.

Really swap adjacent nodes, not just nodes having a border on the
same line, but never touching.
Also, it's now weighted, so the best matching node will be chosen, not
the first matching.
This commit is contained in:
Tom Hacohen 2014-01-20 12:08:12 +00:00
parent e3fcc03152
commit 1e3f71af71
2 changed files with 42 additions and 16 deletions

View File

@ -93,4 +93,7 @@ void tiling_e_client_move_resize_extra(E_Client *ec,
#define EINA_LIST_REMOVE(_list, _el) \ #define EINA_LIST_REMOVE(_list, _el) \
_list = eina_list_remove(_list, _el) _list = eina_list_remove(_list, _el)
#define _TILE_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define _TILE_MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif #endif

View File

@ -459,8 +459,34 @@ static struct _Node_Move_Context {
Window_Tree *node; Window_Tree *node;
Window_Tree *ret; Window_Tree *ret;
int cross_edge; int cross_edge;
int best_match;
} _node_move_ctx; } _node_move_ctx;
#define CNODE (_node_move_ctx.node)
#define IF_MATCH_SET_LR(node) _tiling_window_tree_node_move_if_match_set(node, \
CNODE->client->y, CNODE->client->h, node->client->y, node->client->h)
#define IF_MATCH_SET_TB(node) _tiling_window_tree_node_move_if_match_set(node, \
CNODE->client->x, CNODE->client->w, node->client->x, node->client->w)
static void
_tiling_window_tree_node_move_if_match_set(Window_Tree *node, Evas_Coord cx,
Evas_Coord cw, Evas_Coord ox, Evas_Coord ow)
{
Evas_Coord leftx, rightx;
int match;
leftx = _TILE_MAX(cx, ox);
rightx = _TILE_MIN(cx + cw, ox + ow);
match = rightx - leftx;
if (match > _node_move_ctx.best_match)
{
_node_move_ctx.best_match = match;
_node_move_ctx.ret = node;
}
}
static void static void
_tiling_window_tree_node_move_walker(void *_node) _tiling_window_tree_node_move_walker(void *_node)
{ {
@ -470,37 +496,33 @@ _tiling_window_tree_node_move_walker(void *_node)
if (!node->client) if (!node->client)
return; return;
/* Quit if we've already found something. */
if (_node_move_ctx.ret)
return;
switch (_node_move_ctx.cross_edge) switch (_node_move_ctx.cross_edge)
{ {
case TILING_WINDOW_TREE_EDGE_LEFT: case TILING_WINDOW_TREE_EDGE_LEFT:
if ((node->client->x + node->client->w) == if ((node->client->x + node->client->w) == CNODE->client->x)
_node_move_ctx.node->client->x) IF_MATCH_SET_LR(node);
_node_move_ctx.ret = node;
break; break;
case TILING_WINDOW_TREE_EDGE_RIGHT: case TILING_WINDOW_TREE_EDGE_RIGHT:
if (node->client->x == if (node->client->x == (CNODE->client->x + CNODE->client->w))
(_node_move_ctx.node->client->x + _node_move_ctx.node->client->w)) IF_MATCH_SET_LR(node);
_node_move_ctx.ret = node;
break; break;
case TILING_WINDOW_TREE_EDGE_TOP: case TILING_WINDOW_TREE_EDGE_TOP:
if ((node->client->y + node->client->h) == if ((node->client->y + node->client->h) == CNODE->client->y)
_node_move_ctx.node->client->y) IF_MATCH_SET_TB(node);
_node_move_ctx.ret = node;
break; break;
case TILING_WINDOW_TREE_EDGE_BOTTOM: case TILING_WINDOW_TREE_EDGE_BOTTOM:
if (node->client->y == if (node->client->y == (CNODE->client->y + CNODE->client->h))
(_node_move_ctx.node->client->y + _node_move_ctx.node->client->h)) IF_MATCH_SET_TB(node);
_node_move_ctx.ret = node;
break; break;
default: default:
break; break;
} }
} }
#undef CNODE
#undef IF_MATCH_SET_LR
#undef IF_MATCH_SET_TB
void void
tiling_window_tree_node_move(Window_Tree *node, int cross_edge) tiling_window_tree_node_move(Window_Tree *node, int cross_edge)
{ {
@ -514,6 +536,7 @@ tiling_window_tree_node_move(Window_Tree *node, int cross_edge)
_node_move_ctx.node = node; _node_move_ctx.node = node;
_node_move_ctx.cross_edge = cross_edge; _node_move_ctx.cross_edge = cross_edge;
_node_move_ctx.ret = NULL; _node_move_ctx.ret = NULL;
_node_move_ctx.best_match = 0;
tiling_window_tree_walk(root, _tiling_window_tree_node_move_walker); tiling_window_tree_walk(root, _tiling_window_tree_node_move_walker);