]> git.sur5r.net Git - i3/i3/commitdiff
Make command `move [direction]` work with criteria
authorTony Crisci <tony@dubstepdish.com>
Thu, 19 Jun 2014 12:09:31 +0000 (08:09 -0400)
committerMichael Stapelberg <michael@stapelberg.de>
Mon, 23 Jun 2014 19:17:27 +0000 (21:17 +0200)
A container selected with criteria should be moved with the `move
[direction]` command, instead of this command always acting on the
focused container.

include/move.h
src/commands.c
src/move.c
testcases/t/232-cmd-move-criteria.t [new file with mode: 0644]

index 5c8a7d20f2ad7ce2d0d55271548af987a945b909..939665ec41f09b73cb2be7cce20dc598a5dfb5fe 100644 (file)
@@ -10,8 +10,8 @@
 #pragma once
 
 /**
- * Moves the current container in the given direction (TOK_LEFT, TOK_RIGHT,
+ * Moves the given container in the given direction (TOK_LEFT, TOK_RIGHT,
  * TOK_UP, TOK_DOWN from cmdparse.l)
  *
  */
-void tree_move(int direction);
+void tree_move(Con *con, int direction);
index a60dde629939fdd0747e2a2dfd63c6830b643044..baf19893b02c7d69fd70c5f4f12f1dbe8bb850f7 100644 (file)
@@ -1545,26 +1545,36 @@ void cmd_move_direction(I3_CMD, char *direction, char *move_px) {
     // TODO: We could either handle this in the parser itself as a separate token (and make the stack typed) or we need a better way to convert a string to a number with error checking
     int px = atoi(move_px);
 
-    /* TODO: make 'move' work with criteria. */
-    DLOG("moving in direction %s, px %s\n", direction, move_px);
-    if (con_is_floating(focused)) {
-        DLOG("floating move with %d pixels\n", px);
-        Rect newrect = focused->parent->rect;
-        if (strcmp(direction, "left") == 0) {
-            newrect.x -= px;
-        } else if (strcmp(direction, "right") == 0) {
-            newrect.x += px;
-        } else if (strcmp(direction, "up") == 0) {
-            newrect.y -= px;
-        } else if (strcmp(direction, "down") == 0) {
-            newrect.y += px;
+    owindow *current;
+    HANDLE_EMPTY_MATCH;
+
+    Con *initially_focused = focused;
+
+    TAILQ_FOREACH (current, &owindows, owindows) {
+        DLOG("moving in direction %s, px %s\n", direction, move_px);
+        if (con_is_floating(current->con)) {
+            DLOG("floating move with %d pixels\n", px);
+            Rect newrect = current->con->parent->rect;
+            if (strcmp(direction, "left") == 0) {
+                newrect.x -= px;
+            } else if (strcmp(direction, "right") == 0) {
+                newrect.x += px;
+            } else if (strcmp(direction, "up") == 0) {
+                newrect.y -= px;
+            } else if (strcmp(direction, "down") == 0) {
+                newrect.y += px;
+            }
+            floating_reposition(current->con->parent, newrect);
+        } else {
+            tree_move(current->con, (strcmp(direction, "right") == 0 ? D_RIGHT : (strcmp(direction, "left") == 0 ? D_LEFT : (strcmp(direction, "up") == 0 ? D_UP : D_DOWN))));
+            cmd_output->needs_tree_render = true;
         }
-        floating_reposition(focused->parent, newrect);
-    } else {
-        tree_move((strcmp(direction, "right") == 0 ? D_RIGHT : (strcmp(direction, "left") == 0 ? D_LEFT : (strcmp(direction, "up") == 0 ? D_UP : D_DOWN))));
-        cmd_output->needs_tree_render = true;
     }
 
+    /* the move command should not disturb focus */
+    if (focused != initially_focused)
+        con_focus(initially_focused);
+
     // XXX: default reply for now, make this a better reply
     ysuccess(true);
 }
index 44045f25f96c1d833168375dad88a260a1441542..9c0f310f769f641fc2dfb58e92446f269f78650e 100644 (file)
@@ -132,18 +132,17 @@ static void move_to_output_directed(Con *con, direction_t direction) {
 }
 
 /*
- * Moves the current container in the given direction (D_LEFT, D_RIGHT,
+ * Moves the given container in the given direction (D_LEFT, D_RIGHT,
  * D_UP, D_DOWN).
  *
  */
-void tree_move(int direction) {
+void tree_move(Con *con, int direction) {
     position_t position;
     Con *target;
 
     DLOG("Moving in direction %d\n", direction);
 
     /* 1: get the first parent with the same orientation */
-    Con *con = focused;
 
     if (con->type == CT_WORKSPACE) {
         DLOG("Not moving workspace\n");
diff --git a/testcases/t/232-cmd-move-criteria.t b/testcases/t/232-cmd-move-criteria.t
new file mode 100644 (file)
index 0000000..22a2eb4
--- /dev/null
@@ -0,0 +1,37 @@
+#!perl
+# vim:ts=4:sw=4:expandtab
+#
+# Please read the following documents before working on tests:
+# • http://build.i3wm.org/docs/testsuite.html
+#   (or docs/testsuite)
+#
+# • http://build.i3wm.org/docs/lib-i3test.html
+#   (alternatively: perldoc ./testcases/lib/i3test.pm)
+#
+# • http://build.i3wm.org/docs/ipc.html
+#   (or docs/ipc)
+#
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
+#   (unless you are already familiar with Perl)
+#
+# Test that the `move [direction]` command works with criteria
+# Bug still in: 4.8-16-g6888a1f
+use i3test;
+
+my $ws = fresh_workspace;
+
+my $win1 = open_window;
+my $win2 = open_window;
+my $win3 = open_window;
+
+# move win1 from the left to the right
+cmd '[id="' . $win1->{id} . '"] move right';
+
+# now they should be switched, with win2 still being focused
+my $ws_con = get_ws($ws);
+
+# win2 should be on the left
+is($ws_con->{nodes}[0]->{window}, $win2->{id}, 'the `move [direction]` command should work with criteria');
+is($x->input_focus, $win3->{id}, 'it should not disturb focus');
+
+done_testing;