From f6e801da1a45b2458679e20f5e6061442a434e1b Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 12 Apr 2016 14:33:18 -0700 Subject: [PATCH] PopupWindow. Don't use -1 width/height for calculations. In findDropDownPosition it's entirely possible for width/height to be -1. If this is so, and the popup is anchored to the right, we could fail to see that it is offscreen (since we think the width is -1), and so fail to do our position adjustment to move it to the left. I think this was previously covered up by window manager bugs with child windows that requested coordinates outside of their parent frame. To fix this, we ontinue to pass the same value to the window manager, but use the width/height we expect to receive for local layout calculations. Bug: 28085451 Change-Id: Ia04ca3fcd17ad8819615b5ff42f7923462ce4b42 --- core/java/android/widget/PopupWindow.java | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 0d8d8ed17b654..a57dad58ba348 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -1514,6 +1514,24 @@ public class PopupWindow { outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; + // Let the window manager know to align the top to y. + outParams.gravity = Gravity.LEFT | Gravity.TOP; + outParams.width = width; + outParams.height = height; + + // If width or height is unspecified. We can leave it to the window manager to match + // to the parent size, but for our local purposes of calculating positioning, we need + // to fill in real width and height values. + final Rect displayFrame = new Rect(); + anchor.getWindowVisibleDisplayFrame(displayFrame); + if (width < 0) { + width = displayFrame.right - displayFrame.left; + } + if (height < 0) { + height = displayFrame.bottom - displayFrame.top; + } + + // If we need to adjust for gravity RIGHT, align to the bottom-right // corner of the anchor (still accounting for offsets). final int hgrav = Gravity.getAbsoluteGravity(gravity, anchor.getLayoutDirection()) @@ -1522,17 +1540,9 @@ public class PopupWindow { outParams.x -= width - anchorWidth; } - // Let the window manager know to align the top to y. - outParams.gravity = Gravity.LEFT | Gravity.TOP; - outParams.width = width; - outParams.height = height; - final int[] screenLocation = mTmpScreenLocation; anchor.getLocationOnScreen(screenLocation); - final Rect displayFrame = new Rect(); - anchor.getWindowVisibleDisplayFrame(displayFrame); - // First, attempt to fit the popup vertically without resizing. final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, @@ -2116,10 +2126,10 @@ public class PopupWindow { // If an explicit width/height has not specified, use the most recent // explicitly specified value (either from setWidth/Height or update). - if (width == -1) { + if (width < 0) { width = mWidth; } - if (height == -1) { + if (height < 0) { height = mHeight; }