i3 - improved tiling WM


Use a saner sanity check for floating_reposition.

Patch status: merged

Patch by Yuxuan Shui

Long description:

The function contained_by_output checks whether any output contains any
parts of a give rect. Rather than relying on the central point of the rect.

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

b/include/randr.h

17
@@ -87,6 +87,16 @@ Output *get_output_by_name(const char *name);
18
  */
19
 Output *get_output_containing(int x, int y);
20
 
21
+/*
22
+ * In contained_by_output, we check if any active output contains part of the container.
23
+ * We do this by checking if the output rect is intersected by the Rect.
24
+ * This is the 2-dimensional counterpart of get_output_containing.
25
+ * Since we don't actually need the outputs intersected by the given Rect (There could
26
+ * be many), we just return true or false for convenience.
27
+ *
28
+ */
29
+bool contained_by_output(Rect rect);
30
+
31
 /**
32
  * Gets the output which is the next one in the given direction.
33
  *

b/src/floating.c

38
@@ -659,11 +659,7 @@ void drag_pointer(Con *con, const xcb_button_press_event_t *event, xcb_window_t
39
 void floating_reposition(Con *con, Rect newrect) {
40
     /* Sanity check: Are the new coordinates on any output? If not, we
41
      * ignore that request. */
42
-    Output *output = get_output_containing(
43
-        newrect.x + (newrect.width / 2),
44
-        newrect.y + (newrect.height / 2));
45
-
46
-    if (!output) {
47
+    if (!contained_by_output(newrect)) {
48
         ELOG("No output found at destination coordinates. Not repositioning.\n");
49
         return;
50
     }

b/src/randr.c

55
@@ -93,6 +93,31 @@ Output *get_output_containing(int x, int y) {
56
 }
57
 
58
 /*
59
+ * In contained_by_output, we check if any active output contains part of the container.
60
+ * We do this by checking if the output rect is intersected by the Rect.
61
+ * This is the 2-dimensional counterpart of get_output_containing.
62
+ * Since we don't actually need the outputs intersected by the given Rect (There could
63
+ * be many), we just return true or false for convenience.
64
+ *
65
+ */
66
+bool contained_by_output(Rect rect){
67
+    Output *output;
68
+    int lx = rect.x, uy = rect.y;
69
+    int rx = rect.x + rect.width, by = rect.y + rect.height;
70
+    TAILQ_FOREACH(output, &outputs, outputs) {
71
+        if (!output->active)
72
+            continue;
73
+        DLOG("comparing x=%d y=%d with x=%d and y=%d width %d height %d\n",
74
+                        rect.x, rect.y, output->rect.x, output->rect.y, output->rect.width, output->rect.height);
75
+        if (rx >= (int)output->rect.x && lx <= (int)(output->rect.x + output->rect.width) &&
76
+            by >= (int)output->rect.y && uy <= (int)(output->rect.y + output->rect.height))
77
+            return true;
78
+    }
79
+    return false;
80
+
81
+}
82
+
83
+/*
84
  * Like get_output_next with close_far == CLOSEST_OUTPUT, but wraps.
85
  *
86
  * For example if get_output_next(D_DOWN, x, FARTHEST_OUTPUT) = NULL, then