From 0d97035d030c3e769f43266caa15c00af6251d0e Mon Sep 17 00:00:00 2001 From: Shubham Chakraborty Date: Tue, 10 Mar 2026 13:50:08 +0530 Subject: [PATCH] Fix: Migrate to WindowInsets API for API 30+ - Replace deprecated FLAG_FULLSCREEN with WindowInsetsController - Update KeyboardUtils to use WindowInsets API instead of deprecated flags - Resolves TODO in KeyboardUtils.java:108 regarding API 30 deprecation - Maintains backward compatibility for older API levels" Signed-off-by: Shubham Chakraborty --- .../java/com/termux/app/TermuxActivity.java | 4 +++- .../app/terminal/TermuxActivityRootView.java | 15 +++++++++++- .../app/terminal/io/FullScreenWorkAround.java | 23 ++++++++++++++++++- .../com/termux/shared/view/KeyboardUtils.java | 17 ++++++++++---- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index 0c9f74125b..1eb41445fc 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -62,6 +62,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.WindowInsetsCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.viewpager.widget.ViewPager; @@ -233,7 +234,8 @@ public void onCreate(Bundle savedInstanceState) { View content = findViewById(android.R.id.content); content.setOnApplyWindowInsetsListener((v, insets) -> { - mNavBarHeight = insets.getSystemWindowInsetBottom(); + WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets); + mNavBarHeight = insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom; return insets; }); diff --git a/app/src/main/java/com/termux/app/terminal/TermuxActivityRootView.java b/app/src/main/java/com/termux/app/terminal/TermuxActivityRootView.java index 7e8b0e9d38..68d684f829 100644 --- a/app/src/main/java/com/termux/app/terminal/TermuxActivityRootView.java +++ b/app/src/main/java/com/termux/app/terminal/TermuxActivityRootView.java @@ -3,6 +3,7 @@ import android.content.Context; import android.graphics.Rect; import android.inputmethodservice.InputMethodService; +import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; @@ -275,7 +276,19 @@ public void onGlobalLayout() { public static class WindowInsetsListener implements View.OnApplyWindowInsetsListener { @Override public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { - mStatusBarHeight = WindowInsetsCompat.toWindowInsetsCompat(insets).getInsets(WindowInsetsCompat.Type.statusBars()).top; + WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets); + mStatusBarHeight = insetsCompat.getInsets(WindowInsetsCompat.Type.statusBars()).top; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // If decorFitsSystemWindows is false, we should apply padding to avoid overlapping with system bars and IME. + androidx.core.graphics.Insets systemBarInsets = insetsCompat.getInsets(WindowInsetsCompat.Type.systemBars()); + androidx.core.graphics.Insets imeInsets = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()); + + // Use the maximum of system bar bottom and IME bottom to avoid overlapping + int bottomPadding = Math.max(systemBarInsets.bottom, imeInsets.bottom); + v.setPadding(systemBarInsets.left, systemBarInsets.top, systemBarInsets.right, bottomPadding); + } + // Let view window handle insets however it wants return v.onApplyWindowInsets(insets); } diff --git a/app/src/main/java/com/termux/app/terminal/io/FullScreenWorkAround.java b/app/src/main/java/com/termux/app/terminal/io/FullScreenWorkAround.java index c01f8994d8..876cdc271d 100644 --- a/app/src/main/java/com/termux/app/terminal/io/FullScreenWorkAround.java +++ b/app/src/main/java/com/termux/app/terminal/io/FullScreenWorkAround.java @@ -1,8 +1,12 @@ package com.termux.app.terminal.io; import android.graphics.Rect; +import android.os.Build; import android.view.View; import android.view.ViewGroup; +import android.view.WindowInsets; + +import androidx.core.view.WindowInsetsCompat; import com.termux.app.TermuxActivity; @@ -31,7 +35,24 @@ private FullScreenWorkAround(TermuxActivity activity) { mChildOfContent = content.getChildAt(0); mViewGroupLayoutParams = mChildOfContent.getLayoutParams(); mNavBarHeight = activity.getNavBarHeight(); - mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(this::possiblyResizeChildOfContent); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + mChildOfContent.setOnApplyWindowInsetsListener((v, insets) -> { + WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets); + int imeHeight = insetsCompat.getInsets(WindowInsetsCompat.Type.ime()).bottom; + int navBarHeight = insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom; + + if (imeHeight > 0) { + mViewGroupLayoutParams.height = v.getRootView().getHeight() - imeHeight + navBarHeight; + } else { + mViewGroupLayoutParams.height = v.getRootView().getHeight(); + } + v.setLayoutParams(mViewGroupLayoutParams); + return insets; + }); + } else { + mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(this::possiblyResizeChildOfContent); + } } private void possiblyResizeChildOfContent() { diff --git a/termux-shared/src/main/java/com/termux/shared/view/KeyboardUtils.java b/termux-shared/src/main/java/com/termux/shared/view/KeyboardUtils.java index 5df35d2b09..339789efca 100644 --- a/termux-shared/src/main/java/com/termux/shared/view/KeyboardUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/view/KeyboardUtils.java @@ -105,12 +105,19 @@ public static void setSoftKeyboardAlwaysHiddenFlags(final Activity activity) { } public static void setSoftInputModeAdjustResize(final Activity activity) { - // TODO: The flag is deprecated for API 30 and WindowInset API should be used - // https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE - // https://medium.com/androiddevelopers/animating-your-keyboard-fb776a8fb66d - // https://stackoverflow.com/a/65194077/14686958 - if (activity != null && activity.getWindow() != null) + if (activity == null || activity.getWindow() == null) return; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // SOFT_INPUT_ADJUST_RESIZE is deprecated in API 30. + // The modern way to handle this is to set decorFitsSystemWindows to false + // and then handle WindowInsets manually using View.OnApplyWindowInsetsListener. + // https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE + // https://medium.com/androiddevelopers/animating-your-keyboard-fb776a8fb66d + // https://stackoverflow.com/a/65194077/14686958 + activity.getWindow().setDecorFitsSystemWindows(false); + } else { activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + } } /**