Tiling2: Added support for swapping windows.

This commit is contained in:
Tom Hacohen 2014-01-17 13:51:57 +00:00
parent 6fb54d58ac
commit 6795380282
3 changed files with 132 additions and 7 deletions

View File

@ -65,7 +65,10 @@ static struct tiling_mod_main_g
Eina_Hash *overlays;
E_Action *act_togglefloat,
*act_swap,
*act_move_up,
*act_move_down,
*act_move_left,
*act_move_right,
*act_toggle_split_mode;
int warp_x,
@ -530,11 +533,10 @@ _e_mod_menu_border_cb(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED
}
/* }}} */
/* {{{ Swap */
/* {{{ Move windows */
static void
_e_mod_action_swap_cb(E_Object *obj __UNUSED__,
const char *params __UNUSED__)
_action_swap(int cross_edge)
{
E_Desk *desk;
E_Client *focused_ec;
@ -550,6 +552,42 @@ _e_mod_action_swap_cb(E_Object *obj __UNUSED__,
if (!desk_should_tile_check(desk))
return;
Window_Tree *item = tiling_window_tree_client_find(_G.tinfo->tree, focused_ec);
if (item)
{
tiling_window_tree_node_move(item, cross_edge);
_reapply_tree();
}
}
static void
_e_mod_action_move_left_cb(E_Object *obj __UNUSED__,
const char *params __UNUSED__)
{
_action_swap(TILING_WINDOW_TREE_EDGE_LEFT);
}
static void
_e_mod_action_move_right_cb(E_Object *obj __UNUSED__,
const char *params __UNUSED__)
{
_action_swap(TILING_WINDOW_TREE_EDGE_RIGHT);
}
static void
_e_mod_action_move_up_cb(E_Object *obj __UNUSED__,
const char *params __UNUSED__)
{
_action_swap(TILING_WINDOW_TREE_EDGE_TOP);
}
static void
_e_mod_action_move_down_cb(E_Object *obj __UNUSED__,
const char *params __UNUSED__)
{
_action_swap(TILING_WINDOW_TREE_EDGE_BOTTOM);
}
/* }}} */
@ -1137,8 +1175,18 @@ e_modapi_init(E_Module *m)
ACTION_ADD(_G.act_togglefloat, _e_mod_action_toggle_floating_cb,
N_("Toggle floating"), "toggle_floating",
NULL, NULL, 0);
ACTION_ADD(_G.act_swap, _e_mod_action_swap_cb,
N_("Swap a window with an other"), "swap",
ACTION_ADD(_G.act_move_up, _e_mod_action_move_up_cb,
N_("Move the focused window up"), "move_up",
NULL, NULL, 0);
ACTION_ADD(_G.act_move_down, _e_mod_action_move_down_cb,
N_("Move the focused window down"), "move_down",
NULL, NULL, 0);
ACTION_ADD(_G.act_move_left, _e_mod_action_move_left_cb,
N_("Move the focused window left"), "move_left",
NULL, NULL, 0);
ACTION_ADD(_G.act_move_right, _e_mod_action_move_right_cb,
N_("Move the focused window right"), "move_right",
NULL, NULL, 0);
ACTION_ADD(_G.act_toggle_split_mode, _e_mod_action_toggle_split_mode,
@ -1275,7 +1323,10 @@ e_modapi_shutdown(E_Module *m __UNUSED__)
act = NULL; \
}
ACTION_DEL(_G.act_togglefloat, "Toggle floating", "toggle_floating");
ACTION_DEL(_G.act_swap, "Swap a window with an other", "swap");
ACTION_DEL(_G.act_move_up, "Move the focused window up", "move_up");
ACTION_DEL(_G.act_move_down, "Move the focused window down", "move_down");
ACTION_DEL(_G.act_move_left, "Move the focused window left", "move_left");
ACTION_DEL(_G.act_move_right, "Move the focused window right", "move_right");
ACTION_DEL(_G.act_toggle_split_mode, "Toggle split mode",
"toggle_split_mode");

View File

@ -445,6 +445,78 @@ tiling_window_tree_edges_get(Window_Tree *node)
EINA_FALSE);
}
/* Node move */
static struct _Node_Move_Context {
Window_Tree *node;
Window_Tree *ret;
int cross_edge;
} _node_move_ctx;
static void
_tiling_window_tree_node_move_walker(void *_node)
{
Window_Tree *node = _node;
/* We are only interested in nodes with clients. */
if (!node->client)
return;
/* Quit if we've already found something. */
if (_node_move_ctx.ret)
return;
switch (_node_move_ctx.cross_edge)
{
case TILING_WINDOW_TREE_EDGE_LEFT:
if ((node->client->x + node->client->w) ==
_node_move_ctx.node->client->x)
_node_move_ctx.ret = node;
break;
case TILING_WINDOW_TREE_EDGE_RIGHT:
if (node->client->x ==
(_node_move_ctx.node->client->x + _node_move_ctx.node->client->w))
_node_move_ctx.ret = node;
break;
case TILING_WINDOW_TREE_EDGE_TOP:
if ((node->client->y + node->client->h) ==
_node_move_ctx.node->client->y)
_node_move_ctx.ret = node;
break;
case TILING_WINDOW_TREE_EDGE_BOTTOM:
if (node->client->y ==
(_node_move_ctx.node->client->y + _node_move_ctx.node->client->h))
_node_move_ctx.ret = node;
break;
default:
break;
}
}
void
tiling_window_tree_node_move(Window_Tree *node, int cross_edge)
{
Window_Tree *root = node;
/* FIXME: This is very slow and possibly buggy. Can be done much better,
* but is very easy to implement. */
while (root->parent)
root = root->parent;
_node_move_ctx.node = node;
_node_move_ctx.cross_edge = cross_edge;
_node_move_ctx.ret = NULL;
tiling_window_tree_walk(root, _tiling_window_tree_node_move_walker);
if (_node_move_ctx.ret)
{
E_Client *ec = node->client;
node->client = _node_move_ctx.ret->client;
_node_move_ctx.ret->client = ec;
}
}
/* End Node move. */
void
tiling_window_tree_dump(Window_Tree *root, int level)
{

View File

@ -41,4 +41,6 @@ void tiling_window_tree_apply(Window_Tree *root, Evas_Coord x, Evas_Coord y, Eva
Eina_Bool tiling_window_tree_node_resize(Window_Tree *node, int w_dir, double w_diff, int h_dir, double h_diff);
void tiling_window_tree_node_move(Window_Tree *node, int cross_edge);
#endif