diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 206ad33499..78e5b24bba 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -16,6 +16,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; @@ -25,6 +26,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.PopupMenu; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -342,6 +346,8 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP ActivityEmulationBinding binding = ActivityEmulationBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + setInsets(binding.frameMenu); + // Find or create the EmulationFragment mEmulationFragment = (EmulationFragment) getSupportFragmentManager() .findFragmentById(R.id.frame_emulation_fragment); @@ -538,6 +544,28 @@ public final class EmulationActivity extends AppCompatActivity implements ThemeP } } + private void setInsets(View view) + { + ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> + { + Insets cutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()); + ViewGroup.MarginLayoutParams mlpMenu = + (ViewGroup.MarginLayoutParams) v.getLayoutParams(); + int menuWidth = getResources().getDimensionPixelSize(R.dimen.menu_width); + if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR) + { + mlpMenu.width = cutInsets.left + menuWidth; + } + else + { + mlpMenu.width = cutInsets.right + menuWidth; + } + NativeLibrary.SetObscuredPixelsTop(cutInsets.top); + NativeLibrary.SetObscuredPixelsLeft(cutInsets.left); + return windowInsets; + }); + } + public void showOverlayControlsMenu(@NonNull View anchor) { PopupMenu popup = new PopupMenu(this, anchor); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index dfed5871c0..fdd67507f1 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -3,7 +3,6 @@ package org.dolphinemu.dolphinemu.fragments; import android.content.pm.PackageManager; -import android.graphics.Rect; import android.os.Bundle; import android.util.SparseIntArray; import android.view.LayoutInflater; @@ -14,6 +13,9 @@ import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.Fragment; import org.dolphinemu.dolphinemu.NativeLibrary; @@ -21,6 +23,7 @@ import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; import org.dolphinemu.dolphinemu.databinding.FragmentIngameMenuBinding; import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; +import org.dolphinemu.dolphinemu.utils.InsetsHelper; public final class MenuFragment extends Fragment implements View.OnClickListener { @@ -28,6 +31,8 @@ public final class MenuFragment extends Fragment implements View.OnClickListener private static final String KEY_WII = "wii"; private static SparseIntArray buttonsActionsMap = new SparseIntArray(); + private int mCutInset = 0; + static { buttonsActionsMap @@ -68,14 +73,6 @@ public final class MenuFragment extends Fragment implements View.OnClickListener return fragment; } - // This is primarily intended to account for any navigation bar at the bottom of the screen - private int getBottomPaddingRequired() - { - Rect visibleFrame = new Rect(); - requireActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame); - return visibleFrame.bottom - visibleFrame.top - getResources().getDisplayMetrics().heightPixels; - } - @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, @@ -88,6 +85,7 @@ public final class MenuFragment extends Fragment implements View.OnClickListener @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + setInsets(); updatePauseUnpauseVisibility(); if (!requireActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) @@ -100,21 +98,6 @@ public final class MenuFragment extends Fragment implements View.OnClickListener mBinding.menuRefreshWiimotes.setVisibility(View.GONE); } - int bottomPaddingRequired = getBottomPaddingRequired(); - - // Provide a safe zone between the navigation bar and Exit Emulation to avoid accidental touches - float density = getResources().getDisplayMetrics().density; - if (bottomPaddingRequired >= 32 * density) - { - bottomPaddingRequired += 32 * density; - } - - if (bottomPaddingRequired > view.getPaddingBottom()) - { - view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), - view.getPaddingRight(), bottomPaddingRequired); - } - LinearLayout options = mBinding.layoutOptions; for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++) { @@ -130,11 +113,41 @@ public final class MenuFragment extends Fragment implements View.OnClickListener { mBinding.textGameTitle.setText(title); } + } - if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) + private void setInsets() + { + ViewCompat.setOnApplyWindowInsetsListener(mBinding.getRoot(), (v, windowInsets) -> { - view.post(() -> NativeLibrary.SetObscuredPixelsLeft(view.getWidth())); - } + Insets cutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()); + mCutInset = cutInsets.left; + + int left = 0; + int right = 0; + if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR) + { + left = cutInsets.left; + } + else + { + right = cutInsets.right; + } + + v.post(() -> NativeLibrary.SetObscuredPixelsLeft(v.getWidth())); + + // Don't use padding if the navigation bar isn't in the way + if (InsetsHelper.getBottomPaddingRequired(requireActivity()) > 0) + { + v.setPadding(left, cutInsets.top, right, + cutInsets.bottom + InsetsHelper.getNavigationBarHeight(requireContext())); + } + else + { + v.setPadding(left, cutInsets.top, right, + cutInsets.bottom + getResources().getDimensionPixelSize(R.dimen.spacing_large)); + } + return windowInsets; + }); } @Override @@ -155,7 +168,7 @@ public final class MenuFragment extends Fragment implements View.OnClickListener { super.onDestroyView(); - NativeLibrary.SetObscuredPixelsLeft(0); + NativeLibrary.SetObscuredPixelsLeft(mCutInset); mBinding = null; } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/InsetsHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/InsetsHelper.java index 7b98528667..ca62669f97 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/InsetsHelper.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/InsetsHelper.java @@ -1,7 +1,9 @@ package org.dolphinemu.dolphinemu.utils; +import android.app.Activity; import android.content.Context; import android.content.res.Resources; +import android.graphics.Rect; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; @@ -222,4 +224,24 @@ public class InsetsHelper } return 0; } + + public static int getNavigationBarHeight(Context context) + { + Resources resources = context.getResources(); + int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + if (resourceId > 0) + { + return resources.getDimensionPixelSize(resourceId); + } + return 0; + } + + // This is primarily intended to account for any navigation bar at the bottom of the screen + public static int getBottomPaddingRequired(Activity activity) + { + Rect visibleFrame = new Rect(); + activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame); + return visibleFrame.bottom - visibleFrame.top - + activity.getResources().getDisplayMetrics().heightPixels; + } } diff --git a/Source/Android/app/src/main/res/layout/activity_emulation.xml b/Source/Android/app/src/main/res/layout/activity_emulation.xml index c3be452d67..8ae93d2604 100644 --- a/Source/Android/app/src/main/res/layout/activity_emulation.xml +++ b/Source/Android/app/src/main/res/layout/activity_emulation.xml @@ -22,7 +22,7 @@ diff --git a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml index 5e674fc5a5..69ed1ddd35 100644 --- a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml +++ b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml @@ -1,20 +1,19 @@ - + + +