From a17835e7f877c16f69627fb3a661a314d1b5b153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cosmin=20B=C4=83ie=C8=99?= Date: Mon, 22 May 2023 16:45:28 +0200 Subject: [PATCH] Update nav bar insets when in extractView Before, when the IME was shown in the extractView (fullscreen), with gesture navigation enabled, and in landscape, the first time the IME would show, the IME collapse and switcher buttons would not appear in the navigation bar. This was because we were receiving 0 insets initially, but the updated values would not be propragated later on. Test: open an app where the IME shows in full screen when in landscape (e.g. WhatsApp) directly in landscape with gesture navigation enabled, show the IME (e.g. tap on search icon), observe whether the navigation bar buttons show correctly Bug: 260053129 Change-Id: I4df22b47a417e3045eee0662bfe73459b266c6a1 --- .../NavigationBarController.java | 100 +++++++++--------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java index 69105016e0ea1..78388efe98c7a 100644 --- a/core/java/android/inputmethodservice/NavigationBarController.java +++ b/core/java/android/inputmethodservice/NavigationBarController.java @@ -246,8 +246,7 @@ final class NavigationBarController { @Override public void updateTouchableInsets(@NonNull InputMethodService.Insets originalInsets, @NonNull ViewTreeObserver.InternalInsetsInfo dest) { - if (!mImeDrawsImeNavBar || mNavigationBarFrame == null - || mService.isExtractViewShown()) { + if (!mImeDrawsImeNavBar || mNavigationBarFrame == null) { return; } @@ -255,53 +254,58 @@ final class NavigationBarController { if (systemInsets != null) { final Window window = mService.mWindow.getWindow(); final View decor = window.getDecorView(); - Region touchableRegion = null; - final View inputFrame = mService.mInputFrame; - switch (originalInsets.touchableInsets) { - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: - if (inputFrame.getVisibility() == View.VISIBLE) { - inputFrame.getLocationInWindow(mTempPos); - mTempRect.set(mTempPos[0], mTempPos[1], - mTempPos[0] + inputFrame.getWidth(), - mTempPos[1] + inputFrame.getHeight()); - touchableRegion = new Region(mTempRect); - } - break; - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: - if (inputFrame.getVisibility() == View.VISIBLE) { - inputFrame.getLocationInWindow(mTempPos); - mTempRect.set(mTempPos[0], originalInsets.contentTopInsets, - mTempPos[0] + inputFrame.getWidth() , - mTempPos[1] + inputFrame.getHeight()); - touchableRegion = new Region(mTempRect); - } - break; - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: - if (inputFrame.getVisibility() == View.VISIBLE) { - inputFrame.getLocationInWindow(mTempPos); - mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets, - mTempPos[0] + inputFrame.getWidth(), - mTempPos[1] + inputFrame.getHeight()); - touchableRegion = new Region(mTempRect); - } - break; - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: - touchableRegion = new Region(); - 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) { - touchableRegion = new Region(mTempRect); - } else { - touchableRegion.union(mTempRect); - } - dest.touchableRegion.set(touchableRegion); - dest.setTouchableInsets( - ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + // If the extract view is shown, everything is touchable, so no need to update + // touchable insets, but we still update normal insets below. + if (!mService.isExtractViewShown()) { + Region touchableRegion = null; + final View inputFrame = mService.mInputFrame; + switch (originalInsets.touchableInsets) { + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: + if (inputFrame.getVisibility() == View.VISIBLE) { + inputFrame.getLocationInWindow(mTempPos); + mTempRect.set(mTempPos[0], mTempPos[1], + mTempPos[0] + inputFrame.getWidth(), + mTempPos[1] + inputFrame.getHeight()); + touchableRegion = new Region(mTempRect); + } + break; + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: + if (inputFrame.getVisibility() == View.VISIBLE) { + inputFrame.getLocationInWindow(mTempPos); + mTempRect.set(mTempPos[0], originalInsets.contentTopInsets, + mTempPos[0] + inputFrame.getWidth(), + mTempPos[1] + inputFrame.getHeight()); + touchableRegion = new Region(mTempRect); + } + break; + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: + if (inputFrame.getVisibility() == View.VISIBLE) { + inputFrame.getLocationInWindow(mTempPos); + mTempRect.set(mTempPos[0], originalInsets.visibleTopInsets, + mTempPos[0] + inputFrame.getWidth(), + mTempPos[1] + inputFrame.getHeight()); + touchableRegion = new Region(mTempRect); + } + break; + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: + touchableRegion = new Region(); + 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) { + touchableRegion = new Region(mTempRect); + } else { + touchableRegion.union(mTempRect); + } + + dest.touchableRegion.set(touchableRegion); + dest.setTouchableInsets( + ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + } // TODO(b/215443343): See if we can use View#OnLayoutChangeListener(). // TODO(b/215443343): See if we can replace DecorView#mNavigationColorViewState.view