diff --git a/autotests/integration/placement_test.cpp b/autotests/integration/placement_test.cpp index 0746bf6b14..3dec510e8a 100644 --- a/autotests/integration/placement_test.cpp +++ b/autotests/integration/placement_test.cpp @@ -136,23 +136,33 @@ std::pair> TestPla void TestPlacement::testPlaceSmart() { + const auto outputs = workspace()->outputs(); + const QList desiredGeometries{ + QRect(0, 0, 600, 500), + QRect(600, 0, 600, 500), + QRect(0, 500, 600, 500), + QRect(600, 500, 600, 500), + QRect(680, 524, 600, 500), + QRect(680, 0, 600, 500), + QRect(0, 524, 600, 500), + QRect(0, 0, 600, 500), + }; + setPlacementPolicy(PlacementSmart); std::vector> surfaces; - QRegion usedArea; - for (int i = 0; i < 4; i++) { + for (const QRect &desiredGeometry : desiredGeometries) { auto [windowPlacement, surface] = createAndPlaceWindow(QSize(600, 500)); + surfaces.push_back(std::move(surface)); + // smart placement shouldn't define a size on windows QCOMPARE(windowPlacement.initiallyConfiguredSize, QSize(0, 0)); QCOMPARE(windowPlacement.finalGeometry.size(), QSize(600, 500)); - // exact placement isn't a defined concept that should be tested - // but the goal of smart placement is to make sure windows don't overlap until they need to - // 4 windows of 600, 500 should fit without overlap - QVERIFY(!usedArea.intersects(windowPlacement.finalGeometry.toRect())); - usedArea += windowPlacement.finalGeometry.toRect(); - surfaces.push_back(std::move(surface)); + QVERIFY(outputs[0]->geometry().contains(windowPlacement.finalGeometry.toRect())); + + QCOMPARE(windowPlacement.finalGeometry.toRect(), desiredGeometry); } } diff --git a/src/placement.cpp b/src/placement.cpp index d63096f420..17cb558de0 100644 --- a/src/placement.cpp +++ b/src/placement.cpp @@ -190,17 +190,17 @@ void Placement::placeSmart(Window *window, const QRectF &area, PlacementPolicy / y_optimal = y; // client gabarit - int ch = window->height() - 1; - int cw = window->width() - 1; + int ch = window->height(); + int cw = window->width(); bool first_pass = true; // CT lame flag. Don't like it. What else would do? // loop over possible positions do { // test if enough room in x and y directions - if (y + ch > area.bottom() && ch < area.height()) { + if (y + ch > area.y() + area.height() && ch < area.height()) { overlap = h_wrong; // this throws the algorithm to an exit - } else if (x + cw > area.right()) { + } else if (x + cw > area.x() + area.width()) { overlap = w_wrong; } else { overlap = none; // initialize @@ -257,7 +257,7 @@ void Placement::placeSmart(Window *window, const QRectF &area, PlacementPolicy / // really need to loop? test if there's any overlap if (overlap > none) { - possible = area.right(); + possible = area.x() + area.width(); if (possible - cw > x) { possible -= cw; } @@ -294,7 +294,7 @@ void Placement::placeSmart(Window *window, const QRectF &area, PlacementPolicy / // ... else ==> not enough x dimension (overlap was wrong on horizontal) else if (overlap == w_wrong) { x = area.left(); - possible = area.bottom(); + possible = area.y() + area.height(); if (possible - ch > y) { possible -= ch; @@ -325,7 +325,7 @@ void Placement::placeSmart(Window *window, const QRectF &area, PlacementPolicy / } y = possible; } - } while ((overlap != none) && (overlap != h_wrong) && (y < area.bottom())); + } while ((overlap != none) && (overlap != h_wrong) && (y < area.y() + area.height())); if (ch >= area.height()) { y_optimal = area.top();