GestureNav: Fix broken exclusion rect calculation for modal windows am: b106379310 am: eb6ad762fc
am: 60ed8ce91e
Change-Id: I483fd8d92423abfb6a5585a9e64ea75ed906dbfb
This commit is contained in:
@@ -5162,7 +5162,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
final int[] remainingLeftRight =
|
||||
{mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};
|
||||
|
||||
// Traverse all windows bottom up to assemble the gesture exclusion rects.
|
||||
// Traverse all windows top down to assemble the gesture exclusion rects.
|
||||
// For each window, we only take the rects that fall within its touchable region.
|
||||
forAllWindows(w -> {
|
||||
if (w.cantReceiveTouchInput() || !w.isVisible()
|
||||
@@ -5170,12 +5170,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
|| unhandled.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final boolean modal =
|
||||
(w.mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
|
||||
|
||||
// Get the touchable region of the window, and intersect with where the screen is still
|
||||
// touchable, i.e. touchable regions on top are not covering it yet.
|
||||
w.getTouchableRegion(touchableRegion);
|
||||
w.getEffectiveTouchableRegion(touchableRegion);
|
||||
touchableRegion.op(unhandled, Op.INTERSECT);
|
||||
|
||||
if (w.isImplicitlyExcludingAllSystemGestures()) {
|
||||
|
||||
@@ -3030,6 +3030,25 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
subtractTouchExcludeRegionIfNeeded(outRegion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective touchable region in global coordinates.
|
||||
*
|
||||
* In contrast to {@link #getTouchableRegion}, this takes into account
|
||||
* {@link WindowManager.LayoutParams#FLAG_NOT_TOUCH_MODAL touch modality.}
|
||||
*/
|
||||
void getEffectiveTouchableRegion(Region outRegion) {
|
||||
final boolean modal = (mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
|
||||
final DisplayContent dc = getDisplayContent();
|
||||
|
||||
if (modal && dc != null) {
|
||||
outRegion.set(dc.getBounds());
|
||||
cropRegionToStackBoundsIfNeeded(outRegion);
|
||||
subtractTouchExcludeRegionIfNeeded(outRegion);
|
||||
} else {
|
||||
getTouchableRegion(outRegion);
|
||||
}
|
||||
}
|
||||
|
||||
private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
|
||||
final Task task = getTask();
|
||||
if (task == null || !task.cropWindowsToStackBounds()) {
|
||||
|
||||
@@ -793,6 +793,30 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
assertEquals(expected, dc.calculateSystemGestureExclusion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateSystemGestureExclusion_modal() throws Exception {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "base");
|
||||
win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
|
||||
win.setSystemGestureExclusion(Collections.singletonList(new Rect(0, 0, 1000, 1000)));
|
||||
|
||||
final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "modal");
|
||||
win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
|
||||
win2.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
|
||||
win2.getAttrs().width = 10;
|
||||
win2.getAttrs().height = 10;
|
||||
win2.setSystemGestureExclusion(Collections.emptyList());
|
||||
|
||||
dc.setLayoutNeeded();
|
||||
dc.performLayout(true /* initial */, false /* updateImeWindows */);
|
||||
|
||||
win.setHasSurface(true);
|
||||
win2.setHasSurface(true);
|
||||
|
||||
final Region expected = Region.obtain();
|
||||
assertEquals(expected, dc.calculateSystemGestureExclusion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
|
||||
synchronized (mWm.mGlobalLock) {
|
||||
|
||||
Reference in New Issue
Block a user