From a4f32a5a468ab57eef83b29a7d9b3ca5f432b064 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 30 Oct 2025 16:36:45 +0100 Subject: [PATCH] android: Fix edge-to-edge layout issues with settings and app selection Using FrameLayout for the settings instead of the recommended FragmentContainerView because the latter makes handling insets more complicated (fitsSystemWindows doesn't work as the fragment is responsible for handling insets but how that should work with PreferenceFragmentCompat is unclear). Fixes: 2404b2bee632 ("android: Apply UI changes for edge-to-edge views in Android 15+") --- .../ui/SelectedApplicationsActivity.java | 7 ++++-- .../ui/SelectedApplicationsListFragment.java | 4 ++++ .../android/ui/SettingsActivity.java | 14 ++++++++---- .../ui/TrustedCertificateImportActivity.java | 1 - .../ui/TrustedCertificatesActivity.java | 1 - .../layout/selected_applications_activity.xml | 21 ++++++++++++++++++ .../src/main/res/layout/settings_activity.xml | 22 +++++++++++++++++++ 7 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 src/frontends/android/app/src/main/res/layout/selected_applications_activity.xml create mode 100644 src/frontends/android/app/src/main/res/layout/settings_activity.xml diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsActivity.java index b3c23ffc8..d7a606d7f 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsActivity.java @@ -20,7 +20,9 @@ import android.content.Intent; import android.os.Bundle; import android.view.MenuItem; +import org.strongswan.android.R; import org.strongswan.android.data.VpnProfileDataSource; +import org.strongswan.android.utils.Utils; import androidx.activity.OnBackPressedCallback; import androidx.annotation.Nullable; @@ -38,8 +40,9 @@ public class SelectedApplicationsActivity extends AppCompatActivity protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.selected_applications_activity); WindowCompat.enableEdgeToEdge(getWindow()); - WindowCompat.setDecorFitsSystemWindows(getWindow(), true); + Utils.applyWindowInsetsAsMarginsForLists(findViewById(R.id.fragment_container)); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); @@ -59,7 +62,7 @@ public class SelectedApplicationsActivity extends AppCompatActivity if (mApps == null) { mApps = new SelectedApplicationsListFragment(); - fm.beginTransaction().add(android.R.id.content, mApps, LIST_TAG).commit(); + fm.beginTransaction().add(R.id.fragment_container, mApps, LIST_TAG).commit(); } } diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsListFragment.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsListFragment.java index 89b581530..013a7adc5 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsListFragment.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SelectedApplicationsListFragment.java @@ -34,6 +34,7 @@ import org.strongswan.android.R; import org.strongswan.android.data.VpnProfileDataSource; import org.strongswan.android.ui.adapter.SelectedApplicationEntry; import org.strongswan.android.ui.adapter.SelectedApplicationsAdapter; +import org.strongswan.android.utils.Utils; import java.util.ArrayList; import java.util.Collections; @@ -61,6 +62,9 @@ public class SelectedApplicationsListFragment extends ListFragment implements Me super.onViewCreated(view, savedInstanceState); requireActivity().addMenuProvider(this, getViewLifecycleOwner()); + getListView().setClipToPadding(false); + Utils.applyWindowInsetsAsPaddingForLists(getListView()); + final boolean readOnly = getActivity().getIntent().getBooleanExtra(VpnProfileDataSource.KEY_READ_ONLY, false); getListView().setChoiceMode(readOnly ? ListView.CHOICE_MODE_NONE : ListView.CHOICE_MODE_MULTIPLE); diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java index eec782fb7..d3cd8a8d5 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java @@ -19,6 +19,8 @@ package org.strongswan.android.ui; import android.os.Bundle; import android.view.MenuItem; +import org.strongswan.android.R; + import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; @@ -29,14 +31,18 @@ public class SettingsActivity extends AppCompatActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.settings_activity); WindowCompat.enableEdgeToEdge(getWindow()); - WindowCompat.setDecorFitsSystemWindows(getWindow(), true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportFragmentManager().beginTransaction() - .replace(android.R.id.content, new SettingsFragment()) - .commit(); + if (savedInstanceState == null) + { + getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .add(R.id.fragment_container, SettingsFragment.class, null) + .commit(); + } } @Override diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java index a794e93ba..322e21e2c 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java @@ -41,7 +41,6 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDialogFragment; -import androidx.core.view.WindowCompat; import androidx.fragment.app.FragmentTransaction; public class TrustedCertificateImportActivity extends AppCompatActivity diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java index c9e242881..a6fd0bc09 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java @@ -33,7 +33,6 @@ import org.strongswan.android.logic.TrustedCertificateManager; import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource; import org.strongswan.android.security.TrustedCertificateEntry; import org.strongswan.android.ui.CertificateDeleteConfirmationDialog.OnCertificateDeleteListener; -import org.strongswan.android.utils.Utils; import java.security.KeyStore; diff --git a/src/frontends/android/app/src/main/res/layout/selected_applications_activity.xml b/src/frontends/android/app/src/main/res/layout/selected_applications_activity.xml new file mode 100644 index 000000000..f2bed6f56 --- /dev/null +++ b/src/frontends/android/app/src/main/res/layout/selected_applications_activity.xml @@ -0,0 +1,21 @@ + + + diff --git a/src/frontends/android/app/src/main/res/layout/settings_activity.xml b/src/frontends/android/app/src/main/res/layout/settings_activity.xml new file mode 100644 index 000000000..d8eccc48c --- /dev/null +++ b/src/frontends/android/app/src/main/res/layout/settings_activity.xml @@ -0,0 +1,22 @@ + + +