diff --git a/src/placement.c b/src/placement.c index 01f2590..a46b7a0 100644 --- a/src/placement.c +++ b/src/placement.c @@ -552,8 +552,6 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) frame_width = frameWidth (c); frame_left = frameLeft(c); frame_top = frameTop (c); - test_x = 0; - test_y = 0; best_overlaps = 0.0; first = TRUE; @@ -562,14 +560,28 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) best_x = full_x + frameLeft (c); best_y = full_y + frameTop (c); + TRACE ("analyzing %i clients", screen_info->client_count); + test_y = full_y + frameTop (c); do { + gint next_test_y = G_MAXINT; + gboolean first_test_x = TRUE; + + TRACE ("testing y position %d", test_y); + test_x = full_x + frameLeft (c); do { gfloat count_overlaps = 0.0; - TRACE ("analyzing %i clients", screen_info->client_count); + gint next_test_x = G_MAXINT; + gint c2_next_test_x; + gint c2_next_test_y; + gint c2_frame_height; + gint c2_frame_width; + + TRACE ("testing x position %d", test_x); + for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++) { if ((c2 != c) && (c2->type != WINDOW_DESKTOP) @@ -577,7 +589,22 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)) { c2_x = frameX (c2); + c2_frame_width = frameWidth (c2); + if (c2_x > xmax + || c2_x + c2_frame_width < full_x) + { + /* skip clients on right-of or left-of monitor */ + continue; + } + c2_y = frameY (c2); + c2_frame_height = frameHeight (c2); + if (c2_y > ymax + || c2_y + c2_frame_height < full_y) + { + /* skip clients on above-of or below-of monitor */ + continue; + } count_overlaps += overlap (test_x - frame_left, test_y - frame_top, @@ -585,8 +612,43 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) test_y - frame_top + frame_height, c2_x, c2_y, - c2_x + frameWidth (c2), - c2_y + frameHeight (c2)); + c2_x + c2_frame_width, + c2_y + c2_frame_height); + + /* find the next x boundy change */ + if (test_x > c2_x) + { + /* test location is beyond the x of the window, + * take the window right corner as next target */ + c2_x += c2_frame_width; + } + c2_next_test_x = MIN (c2_x, xmax); + if (c2_next_test_x < next_test_x + && c2_next_test_x > test_x) + { + /* set new optimal next x step poistion */ + next_test_x = c2_next_test_x; + } + + if (first_test_x) + { + /* find the next y boundy change */ + if (test_y > c2_y) + { + /* test location is beyond the y of the window, + * take the window bottom corner as next target */ + c2_y += c2_frame_height; + } + c2_next_test_y = MIN (c2_y, ymax); + if (c2_next_test_y < next_test_y + && c2_next_test_y > test_y) + { + /* set new optimal next y step poistion */ + next_test_y = c2_next_test_y; + } + + first_test_x = FALSE; + } } } if (count_overlaps < 0.1) @@ -603,14 +665,38 @@ smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h) best_y = test_y; best_overlaps = count_overlaps; } - if (first) + + first = FALSE; + + if (next_test_x != G_MAXINT) { - first = FALSE; + test_x = next_test_x + frameLeft (c); + if (test_x > xmax) + { + /* always clamp on the monitor */ + test_x = xmax; + } + } + else + { + test_x++; } - test_x += 8; } while (test_x <= xmax); - test_y += 8; + + if (next_test_y != G_MAXINT) + { + test_y = next_test_y + frameTop (c); + if (test_y > ymax) + { + /* always clamp on the monitor */ + test_y = ymax; + } + } + else + { + test_y++; + } } while (test_y <= ymax);