i3 - improved tiling WM


wrap when moving things to outputs with direction

Patch status: rejected

Patch by Francesco Mazzoli

To apply this patch, use:
curl http://cr.i3wm.org/patch/3/raw.patch | git am

b/include/randr.h

15
@@ -103,4 +103,10 @@ Output *get_output_most(direction_t direction, Output *current);
16
  */
17
 Output *get_output_next(direction_t direction, Output *current, output_close_far_t close_far);
18
 
19
+/**
20
+ * Like get_output_next with close_far == CLOSEST_OUTPUT, but wraps.
21
+ *
22
+ */
23
+Output *get_output_next_wrap(direction_t direction, Output *current);
24
+
25
 #endif

b/src/commands.c

30
@@ -55,23 +55,15 @@ static bool definitelyGreaterThan(float a, float b, float epsilon) {
31
 static Output *get_output_from_string(Output *current_output, const char *output_str) {
32
     Output *output;
33
 
34
-    if (strcasecmp(output_str, "left") == 0) {
35
-        output = get_output_next(D_LEFT, current_output, CLOSEST_OUTPUT);
36
-        if (!output)
37
-            output = get_output_most(D_RIGHT, current_output);
38
-    } else if (strcasecmp(output_str, "right") == 0) {
39
-        output = get_output_next(D_RIGHT, current_output, CLOSEST_OUTPUT);
40
-        if (!output)
41
-            output = get_output_most(D_LEFT, current_output);
42
-    } else if (strcasecmp(output_str, "up") == 0) {
43
-        output = get_output_next(D_UP, current_output, CLOSEST_OUTPUT);
44
-        if (!output)
45
-            output = get_output_most(D_DOWN, current_output);
46
-    } else if (strcasecmp(output_str, "down") == 0) {
47
-        output = get_output_next(D_DOWN, current_output, CLOSEST_OUTPUT);
48
-        if (!output)
49
-            output = get_output_most(D_UP, current_output);
50
-    } else output = get_output_by_name(output_str);
51
+    if (strcasecmp(output_str, "left") == 0)
52
+        output = get_output_next_wrap(D_LEFT, current_output);
53
+    else if (strcasecmp(output_str, "right") == 0)
54
+        output = get_output_next_wrap(D_RIGHT, current_output);
55
+    else if (strcasecmp(output_str, "up") == 0)
56
+        output = get_output_next_wrap(D_UP, current_output);
57
+    else if (strcasecmp(output_str, "down") == 0)
58
+        output = get_output_next_wrap(D_DOWN, current_output);
59
+    else output = get_output_by_name(output_str);
60
 
61
     return output;
62
 }
63
@@ -1052,13 +1044,13 @@ void cmd_move_con_to_output(I3_CMD, char *name) {
64
 
65
     // TODO: clean this up with commands.spec as soon as we switched away from the lex/yacc command parser
66
     if (strcasecmp(name, "up") == 0)
67
-        output = get_output_next(D_UP, current_output, CLOSEST_OUTPUT);
68
+        output = get_output_next_wrap(D_UP, current_output);
69
     else if (strcasecmp(name, "down") == 0)
70
-        output = get_output_next(D_DOWN, current_output, CLOSEST_OUTPUT);
71
+        output = get_output_next_wrap(D_DOWN, current_output);
72
     else if (strcasecmp(name, "left") == 0)
73
-        output = get_output_next(D_LEFT, current_output, CLOSEST_OUTPUT);
74
+        output = get_output_next_wrap(D_LEFT, current_output);
75
     else if (strcasecmp(name, "right") == 0)
76
-        output = get_output_next(D_RIGHT, current_output, CLOSEST_OUTPUT);
77
+        output = get_output_next_wrap(D_RIGHT, current_output);
78
     else
79
         output = get_output_by_name(name);
80
 

b/src/randr.c

85
@@ -93,15 +93,26 @@ Output *get_output_containing(int x, int y) {
86
 }
87
 
88
 /*
89
- * Gets the output which is the last one in the given direction, for example
90
- * the output on the most bottom when direction == D_DOWN, the output most
91
- * right when direction == D_RIGHT and so on.
92
+ * Like get_output_next with close_far == CLOSEST_OUTPUT, but wraps.
93
  *
94
  * This function always returns a output.
95
  *
96
  */
97
-Output *get_output_most(direction_t direction, Output *current) {
98
-    Output *best = get_output_next(direction, current, FARTHEST_OUTPUT);
99
+Output *get_output_next_wrap(direction_t direction, Output *current) {
100
+    Output *best = get_output_next(direction, current, CLOSEST_OUTPUT);
101
+    /* If no output can be found, wrap */
102
+    if (!best) {
103
+        direction_t opposite;
104
+        if (direction == D_RIGHT)
105
+            opposite = D_LEFT;
106
+        else if (direction == D_LEFT)
107
+            opposite = D_RIGHT;
108
+        else if (direction == D_DOWN)
109
+            opposite = D_UP;
110
+        else
111
+            opposite = D_DOWN;
112
+        best = get_output_next(opposite, current, FARTHEST_OUTPUT);
113
+    }
114
     if (!best)
115
         best = current;
116
     DLOG("current = %s, best = %s\n", current->name, best->name);