Fix touchable region calculation in NavigationBarController

This is a follow up CL to my previous CL [1], which aimed to
automatically adjust InputMethodService.Insets so that the tap events
on the navigation bar region can be sent to the IME.

What I forgot was that View#get{Left,Top,Right,Bottom}() returns
values in the window local coordinates, not in the screen coordinates.
As a result, in some cases the keyboard area could become untouchable
unless the IME specified

  ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION

to

  InputMethodService.Insets#touchableInsets.

With this CL, touchable region should be correctly calculated.

 [1]: I3e7e1f83554444131e2765dc159617bb9e2337c7
      ff7b453ca8

Fix: 226566506
Test: manually verified with the IME mentioned in the bug.
Change-Id: I0fe54efac80dd0d55f4ba37cfa7d7188b642abb0
This commit is contained in:
Yohei Yukawa
2022-04-06 11:26:18 -07:00
parent 7bf91fbc25
commit 487b4db166

View File

@@ -259,23 +259,22 @@ final class NavigationBarController {
switch (originalInsets.touchableInsets) {
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
if (inputFrame.getVisibility() == View.VISIBLE) {
touchableRegion = new Region(inputFrame.getLeft(),
inputFrame.getTop(), inputFrame.getRight(),
inputFrame.getBottom());
inputFrame.getBoundsOnScreen(mTempRect);
touchableRegion = new Region(mTempRect);
}
break;
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
if (inputFrame.getVisibility() == View.VISIBLE) {
touchableRegion = new Region(inputFrame.getLeft(),
originalInsets.contentTopInsets, inputFrame.getRight(),
inputFrame.getBottom());
inputFrame.getBoundsOnScreen(mTempRect);
mTempRect.top = originalInsets.contentTopInsets;
touchableRegion = new Region(mTempRect);
}
break;
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
if (inputFrame.getVisibility() == View.VISIBLE) {
touchableRegion = new Region(inputFrame.getLeft(),
originalInsets.visibleTopInsets, inputFrame.getRight(),
inputFrame.getBottom());
inputFrame.getBoundsOnScreen(mTempRect);
mTempRect.top = originalInsets.visibleTopInsets;
touchableRegion = new Region(mTempRect);
}
break;
case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION:
@@ -283,6 +282,7 @@ final class NavigationBarController {
touchableRegion.set(originalInsets.touchableRegion);
break;
}
// Hereafter "mTempRect" means a navigation bar rect.
mTempRect.set(decor.getLeft(), decor.getBottom() - systemInsets.bottom,
decor.getRight(), decor.getBottom());
if (touchableRegion == null) {