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 |