xdg-shell: Continue transform of popup until size fits (#6521)

This commit is contained in:
Dashie 2024-06-16 20:01:08 +02:00 committed by GitHub
parent 069a21a34e
commit 738530e62e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 25 additions and 22 deletions

View File

@ -539,30 +539,33 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa
if (success)
return predictedBox.translate(-parentCoord - constraint.pos());
CBox test = predictedBox;
if (state.constraintAdjustment & (XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y)) {
// attempt to flip
const bool flipX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X;
const bool flipY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y;
const bool flipX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X;
const bool flipY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y;
auto countEdges = [constraint](const CBox& test) -> int {
int edgeCount = 0;
edgeCount += test.x < constraint.x ? 1 : 0;
edgeCount += test.x + test.w > constraint.x + constraint.w ? 1 : 0;
edgeCount += test.y < constraint.y ? 1 : 0;
edgeCount += test.y + test.h > constraint.y + constraint.h ? 1 : 0;
return edgeCount;
};
int edgeCount = countEdges(test);
CBox test = predictedBox;
success = true;
if (flipX && test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}).expand(-1).inside(constraint))
if (flipX && edgeCount > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0})))
test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0});
else if (flipY && test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}).expand(-1).inside(constraint))
if (flipY && edgeCount > countEdges(test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h})))
test.translate(Vector2D{0, -predictedBox.h - state.anchorRect.h});
else if (flipX && flipY && test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}).expand(-1).inside(constraint))
test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h});
else
success = false;
success = test.copy().expand(-1).inside(constraint);
if (success)
return test.translate(-parentCoord - constraint.pos());
}
// if flips fail, we will slide and remember.
// if the positioner is allowed to resize, then resize the slid thing.
CBox test = predictedBox;
// for slide and resize, defines the padding around the edge for the positioned
// surface.
constexpr int EDGE_PADDING = 4;
@ -575,10 +578,10 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa
//const bool gravityLeft = state.gravity == XDG_POSITIONER_GRAVITY_NONE || state.gravity == XDG_POSITIONER_GRAVITY_LEFT || state.gravity == XDG_POSITIONER_GRAVITY_TOP_LEFT || state.gravity == XDG_POSITIONER_GRAVITY_BOTTOM_LEFT;
//const bool gravityTop = state.gravity == XDG_POSITIONER_GRAVITY_NONE || state.gravity == XDG_POSITIONER_GRAVITY_TOP || state.gravity == XDG_POSITIONER_GRAVITY_TOP_LEFT || state.gravity == XDG_POSITIONER_GRAVITY_TOP_RIGHT;
const bool leftEdgeOut = predictedBox.x < constraint.x;
const bool topEdgeOut = predictedBox.y < constraint.y;
const bool rightEdgeOut = predictedBox.x + predictedBox.w > constraint.x + constraint.w;
const bool bottomEdgeOut = predictedBox.y + predictedBox.h > constraint.y + constraint.h;
const bool leftEdgeOut = test.x < constraint.x;
const bool topEdgeOut = test.y < constraint.y;
const bool rightEdgeOut = test.x + test.w > constraint.x + constraint.w;
const bool bottomEdgeOut = test.y + test.h > constraint.y + constraint.h;
// TODO: this isn't truly conformant.
if (leftEdgeOut && slideX)
@ -600,10 +603,10 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa
const bool resizeX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X;
const bool resizeY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y;
const bool leftEdgeOut = predictedBox.x < constraint.x;
const bool topEdgeOut = predictedBox.y < constraint.y;
const bool rightEdgeOut = predictedBox.x + predictedBox.w > constraint.x + constraint.w;
const bool bottomEdgeOut = predictedBox.y + predictedBox.h > constraint.y + constraint.h;
const bool leftEdgeOut = test.x < constraint.x;
const bool topEdgeOut = test.y < constraint.y;
const bool rightEdgeOut = test.x + test.w > constraint.x + constraint.w;
const bool bottomEdgeOut = test.y + test.h > constraint.y + constraint.h;
// TODO: this isn't truly conformant.
if (leftEdgeOut && resizeX) {