From 24f5773a76eb104b7c495a12442417c234873935 Mon Sep 17 00:00:00 2001 From: DashieTM Date: Sat, 15 Jun 2024 22:13:02 +0200 Subject: [PATCH 1/4] xdg-shell: Continue transform of popup until size fits --- src/protocols/XDGShell.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 49b7b417269..08461fa6a3e 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -534,30 +534,26 @@ 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; - CBox test = predictedBox; - success = true; - if (flipX && test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}).expand(-1).inside(constraint)) + if (flipX && flipY) + test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}); + else if (flipX) 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)) + else if (flipY) 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; @@ -570,10 +566,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) @@ -595,10 +591,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) { From 71d1d62b9c08e39165cda62898f4b2c1a9ab7955 Mon Sep 17 00:00:00 2001 From: DashieTM Date: Sat, 15 Jun 2024 22:32:20 +0200 Subject: [PATCH 2/4] xdg-shell: Check for edge out of constraint in flip --- src/protocols/XDGShell.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 08461fa6a3e..212a83b0a81 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -541,11 +541,14 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa const bool flipX = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X; const bool flipY = state.constraintAdjustment & XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y; - if (flipX && flipY) + const bool horizontalEdgeOut = test.x < constraint.x || test.x + test.w > constraint.x + constraint.w; + const bool verticalEdgeOut = test.y < constraint.y || test.y + test.h > constraint.y + constraint.h; + + if (flipX && horizontalEdgeOut && flipY && verticalEdgeOut) test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}); - else if (flipX) + else if (flipX && horizontalEdgeOut) test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}); - else if (flipY) + else if (flipY && verticalEdgeOut) test.translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}); success = test.copy().expand(-1).inside(constraint); From 9be8b372aeb74ca5fec0922650fc6fc87c9e93dc Mon Sep 17 00:00:00 2001 From: DashieTM Date: Sun, 16 Jun 2024 14:59:14 +0200 Subject: [PATCH 3/4] xdg-shell: Compare edgecount before flipping --- src/protocols/XDGShell.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 212a83b0a81..7cf3cc82468 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -538,17 +538,24 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa 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 horizontalEdgeOut = test.x < constraint.x || test.x + test.w > constraint.x + constraint.w; - const bool verticalEdgeOut = test.y < constraint.y || test.y + test.h > constraint.y + constraint.h; - - if (flipX && horizontalEdgeOut && flipY && verticalEdgeOut) + 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); + + // -1 as we want 2 edges to be resolved with the flip, otherwise move on to only x or only y + if (flipX && flipY && edgeCount - 1 > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}))) test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}); - else if (flipX && horizontalEdgeOut) + else 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 && verticalEdgeOut) + else if (flipY && edgeCount > countEdges(test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}))) test.translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}); success = test.copy().expand(-1).inside(constraint); From dbb4ab93bde9d9fca558d33a57989d0e1a820b60 Mon Sep 17 00:00:00 2001 From: DashieTM Date: Sun, 16 Jun 2024 18:32:32 +0200 Subject: [PATCH 4/4] xdg-shell: Remove superflous flipX && flipY --- src/protocols/XDGShell.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/protocols/XDGShell.cpp b/src/protocols/XDGShell.cpp index 7cf3cc82468..eaa22035739 100644 --- a/src/protocols/XDGShell.cpp +++ b/src/protocols/XDGShell.cpp @@ -550,12 +550,9 @@ CBox CXDGPositionerRules::getPosition(const CBox& constraint, const Vector2D& pa }; int edgeCount = countEdges(test); - // -1 as we want 2 edges to be resolved with the flip, otherwise move on to only x or only y - if (flipX && flipY && edgeCount - 1 > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}))) - test.translate(Vector2D{-predictedBox.w - state.anchorRect.w, -predictedBox.h - state.anchorRect.h}); - else if (flipX && edgeCount > countEdges(test.copy().translate(Vector2D{-predictedBox.w - state.anchorRect.w, 0}))) + 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 && edgeCount > countEdges(test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}))) + if (flipY && edgeCount > countEdges(test.copy().translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}))) test.translate(Vector2D{0, -predictedBox.h - state.anchorRect.h}); success = test.copy().expand(-1).inside(constraint);