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 |