From 6dd6bdb57d08c5068c3fac3c97f8e3807c15c7c1 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 31 Jan 2020 04:36:45 +0200 Subject: [PATCH] [wayland] Implement resize_x/resize_y constraint adjustment Summary: Since we send the initial configure event after placing xdg-popups, we can finally implement resize_x and resize_y constraint adjustments. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D27049 --- autotests/integration/transient_placement.cpp | 23 +++++++++++++++- xdgshellclient.cpp | 27 ++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/autotests/integration/transient_placement.cpp b/autotests/integration/transient_placement.cpp index a0aa9417d5..7a4e1b388d 100644 --- a/autotests/integration/transient_placement.cpp +++ b/autotests/integration/transient_placement.cpp @@ -209,6 +209,27 @@ void TransientPlacementTest::testXdgPopup_data() positioner.setGravity(Qt::TopEdge); positioner.setInitialSize(QSize(300, 200)); QTest::newRow("constraintFlipRightNoGravity") << QSize(500, 500) << QPoint(700, 80) << positioner << QRect(700 + 50 - 150, 130, 300, 200); + + // ---------------------------------------------------------------- + // resize + positioner.setConstraints(XdgPositioner::Constraint::ResizeX | XdgPositioner::Constraint::ResizeY); + positioner.setInitialSize(QSize(200, 200)); + + positioner.setAnchorEdge(Qt::TopEdge); + positioner.setGravity(Qt::TopEdge); + QTest::newRow("resizeTop") << QSize(500, 500) << QPoint(80, 80) << positioner << QRect(80 + 250 - 100, 0, 200, 130); + + positioner.setAnchorEdge(Qt::LeftEdge); + positioner.setGravity(Qt::LeftEdge); + QTest::newRow("resizeLeft") << QSize(500, 500) << QPoint(80, 80) << positioner << QRect(0, 80 + 250 - 100, 130, 200); + + positioner.setAnchorEdge(Qt::RightEdge); + positioner.setGravity(Qt::RightEdge); + QTest::newRow("resizeRight") << QSize(500, 500) << QPoint(700, 80) << positioner << QRect(700 + 50 + 400, 80 + 250 - 100, 130, 200); + + positioner.setAnchorEdge(Qt::BottomEdge); + positioner.setGravity(Qt::BottomEdge); + QTest::newRow("resizeBottom") << QSize(500, 500) << QPoint(80, 500) << positioner << QRect(80 + 250 - 100, 500 + 50 + 400, 200, 74); } void TransientPlacementTest::testXdgPopup() @@ -249,7 +270,7 @@ void TransientPlacementTest::testXdgPopup() QCOMPARE(configureRequestedSpy.first()[0].value(), expectedRelativeGeometry); popup->ackConfigure(configureRequestedSpy.first()[1].toUInt()); - auto transient = Test::renderAndWaitForShown(transientSurface, positioner.initialSize(), Qt::red); + auto transient = Test::renderAndWaitForShown(transientSurface, expectedRelativeGeometry.size(), Qt::red); QVERIFY(transient); QVERIFY(!transient->isDecorated()); diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index 1e3ca9458c..28788b3e8d 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -1712,8 +1712,18 @@ QRect XdgShellClient::transientPlacement(const QRect &bounds) const } } if (constraintAdjustments & PositionerConstraint::ResizeX) { - //TODO - //but we need to sort out when this is run as resize should only happen before first configure + QRect unconstrainedRect = popupPosition; + + if (!inBounds(unconstrainedRect, Qt::LeftEdge)) { + unconstrainedRect.setLeft(bounds.left()); + } + if (!inBounds(unconstrainedRect, Qt::RightEdge)) { + unconstrainedRect.setRight(bounds.right()); + } + + if (unconstrainedRect.isValid()) { + popupPosition = unconstrainedRect; + } } if (constraintAdjustments & PositionerConstraint::FlipY) { @@ -1744,7 +1754,18 @@ QRect XdgShellClient::transientPlacement(const QRect &bounds) const } } if (constraintAdjustments & PositionerConstraint::ResizeY) { - //TODO + QRect unconstrainedRect = popupPosition; + + if (!inBounds(unconstrainedRect, Qt::TopEdge)) { + unconstrainedRect.setTop(bounds.top()); + } + if (!inBounds(unconstrainedRect, Qt::BottomEdge)) { + unconstrainedRect.setBottom(bounds.bottom()); + } + + if (unconstrainedRect.isValid()) { + popupPosition = unconstrainedRect; + } } return popupPosition;