summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hacohen <tom@stosb.com>2014-01-17 13:51:57 +0000
committerTom Hacohen <tom@stosb.com>2014-01-30 15:22:01 +0000
commit2f121b590c079d0da6c27266af7bf4caf28e830a (patch)
tree4e18cb7f0e63911d344634849b84e7b0e124e9fa
parentb5d86238a2e721dacd8d9f7fe1adf306713b1878 (diff)
downloadenlightenment-2f121b590c079d0da6c27266af7bf4caf28e830a.tar.gz
Tiling2: Added support for swapping windows.
-rw-r--r--src/modules/tiling2/e_mod_tiling.c65
-rw-r--r--src/modules/tiling2/window_tree.c72
-rw-r--r--src/modules/tiling2/window_tree.h2
3 files changed, 132 insertions, 7 deletions
diff --git a/src/modules/tiling2/e_mod_tiling.c b/src/modules/tiling2/e_mod_tiling.c
index f7b5870d7b..f65947b48f 100644
--- a/src/modules/tiling2/e_mod_tiling.c
+++ b/src/modules/tiling2/e_mod_tiling.c
@@ -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");
diff --git a/src/modules/tiling2/window_tree.c b/src/modules/tiling2/window_tree.c
index c76d12cc94..b20dea629c 100644
--- a/src/modules/tiling2/window_tree.c
+++ b/src/modules/tiling2/window_tree.c
@@ -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)
{
diff --git a/src/modules/tiling2/window_tree.h b/src/modules/tiling2/window_tree.h
index 424a929436..0078ee5f0a 100644
--- a/src/modules/tiling2/window_tree.h
+++ b/src/modules/tiling2/window_tree.h
@@ -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