From 12690c699c83554e48bd9c901ff80bc4add84225 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:56:34 +0530 Subject: [PATCH 1/6] recreate the activity when turning on or off material colors instead of restarting the entire application --- .../main/java/org/stratoemu/strato/StratoApplication.kt | 6 ++++++ .../stratoemu/strato/settings/GlobalSettingsFragment.kt | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt index c993a57d7..8c9dce98b 100644 --- a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt +++ b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt @@ -29,6 +29,12 @@ class StratoApplication : Application() { private set val context : Context get() = instance.applicationContext + + fun setTheme(newValue: Boolean) { + val dynamicColorsOptions = DynamicColorsOptions.Builder().setPrecondition { _, _ -> newValue }.build() + DynamicColors.applyToActivitiesIfAvailable(instance, dynamicColorsOptions) + if (newValue == false) { instance.setTheme(R.style.AppTheme) } + } } override fun onCreate() { diff --git a/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt b/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt index a2454d1cf..5a9f93bc6 100644 --- a/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt +++ b/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt @@ -20,6 +20,7 @@ import org.stratoemu.strato.MainActivity import org.stratoemu.strato.R import org.stratoemu.strato.utils.GpuDriverHelper import org.stratoemu.strato.utils.WindowInsetsHelper +import org.stratoemu.strato.StratoApplication import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -45,9 +46,10 @@ class GlobalSettingsFragment : PreferenceFragmentCompat() { addPreferencesFromResource(R.xml.credits_preferences) // Re-launch the app if Material You is toggled - findPreference("use_material_you")?.setOnPreferenceChangeListener { _, _ -> - requireActivity().finishAffinity() - startActivity(Intent(requireContext(), MainActivity::class.java)) + findPreference("use_material_you")?.setOnPreferenceChangeListener { _, newValue -> + val isMaterialYouEnabled = newValue as Boolean + StratoApplication.setTheme(isMaterialYouEnabled) + requireActivity().recreate() true } From 0e741634f761ae9213b134cd9ed1be18e36df597 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:29:45 +0530 Subject: [PATCH 2/6] fx --- .../java/org/stratoemu/strato/MainActivity.kt | 13 ++++ .../org/stratoemu/strato/StratoApplication.kt | 19 +++--- .../strato/settings/SettingsActivity.kt | 14 +++++ app/src/main/res/values-night-v31/themes.xml | 63 +++++++++++++++++++ app/src/main/res/values-v31/themes.xml | 63 +++++++++++++++++++ 5 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 app/src/main/res/values-night-v31/themes.xml create mode 100644 app/src/main/res/values-v31/themes.xml diff --git a/app/src/main/java/org/stratoemu/strato/MainActivity.kt b/app/src/main/java/org/stratoemu/strato/MainActivity.kt index 9e2978e5c..fd5f82124 100644 --- a/app/src/main/java/org/stratoemu/strato/MainActivity.kt +++ b/app/src/main/java/org/stratoemu/strato/MainActivity.kt @@ -25,6 +25,9 @@ import androidx.documentfile.provider.DocumentFile import androidx.preference.PreferenceManager import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import org.stratoemu.strato.adapter.* @@ -42,6 +45,7 @@ import org.stratoemu.strato.utils.WindowInsetsHelper import javax.inject.Inject import kotlin.math.ceil import com.google.android.material.R as MaterialR +import kotlinx.coroutines.launch @AndroidEntryPoint class MainActivity : AppCompatActivity() { @@ -152,6 +156,15 @@ class MainActivity : AppCompatActivity() { window.decorView.findViewById(android.R.id.content).viewTreeObserver.addOnTouchModeChangeListener { isInTouchMode -> refreshIconVisible = !isInTouchMode } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.CREATED) { + StratoApplication.themeChangeFlow.collect { themeId -> + setTheme(themeId) + recreate() + } + } + } } private fun setAppListDecoration() { diff --git a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt index 8c9dce98b..41c5d8624 100644 --- a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt +++ b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt @@ -7,11 +7,11 @@ package org.stratoemu.strato import android.app.Application import android.content.Context -import com.google.android.material.color.DynamicColors -import com.google.android.material.color.DynamicColorsOptions import dagger.hilt.android.HiltAndroidApp import org.stratoemu.strato.di.getSettings import java.io.File +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.asSharedFlow /** * @return The optimal directory for putting public files inside, this may return a private directory if a public directory cannot be retrieved @@ -30,10 +30,15 @@ class StratoApplication : Application() { val context : Context get() = instance.applicationContext + private val _themeChangeFlow = MutableSharedFlow(replay = 1) + val themeChangeFlow = _themeChangeFlow.asSharedFlow() + fun setTheme(newValue: Boolean) { - val dynamicColorsOptions = DynamicColorsOptions.Builder().setPrecondition { _, _ -> newValue }.build() - DynamicColors.applyToActivitiesIfAvailable(instance, dynamicColorsOptions) - if (newValue == false) { instance.setTheme(R.style.AppTheme) } + if (newValue) { + _themeChangeFlow.tryEmit(R.style.AppTheme_MaterialYou) + } else { + _themeChangeFlow.tryEmit(R.style.AppTheme) + } } } @@ -41,8 +46,6 @@ class StratoApplication : Application() { super.onCreate() instance = this System.loadLibrary("skyline") - - val dynamicColorsOptions = DynamicColorsOptions.Builder().setPrecondition { _, _ -> getSettings().useMaterialYou }.build() - DynamicColors.applyToActivitiesIfAvailable(this, dynamicColorsOptions) + setTheme(getSettings().useMaterialYou) } } diff --git a/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt b/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt index a8d12990a..83594024d 100644 --- a/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt +++ b/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt @@ -22,6 +22,9 @@ import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat import androidx.preference.forEach +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle import com.google.android.material.appbar.AppBarLayout import com.google.android.material.internal.ToolbarUtils import org.stratoemu.strato.BuildConfig @@ -33,6 +36,8 @@ import org.stratoemu.strato.preference.dialog.EditTextPreferenceMaterialDialogFr import org.stratoemu.strato.preference.dialog.IntegerListPreferenceMaterialDialogFragmentCompat import org.stratoemu.strato.preference.dialog.ListPreferenceMaterialDialogFragmentCompat import org.stratoemu.strato.utils.WindowInsetsHelper +import org.stratoemu.strato.StratoApplication +import kotlinx.coroutines.launch private const val PREFERENCE_DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG" @@ -123,6 +128,15 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere .replace(R.id.settings, preferenceFragment) .commit() } + + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.CREATED) { + StratoApplication.themeChangeFlow.collect { themeId -> + setTheme(themeId) + recreate() + } + } + } } override fun onCreateOptionsMenu(menu : Menu?) : Boolean { diff --git a/app/src/main/res/values-night-v31/themes.xml b/app/src/main/res/values-night-v31/themes.xml new file mode 100644 index 000000000..db7625ae9 --- /dev/null +++ b/app/src/main/res/values-night-v31/themes.xml @@ -0,0 +1,63 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v31/themes.xml b/app/src/main/res/values-v31/themes.xml new file mode 100644 index 000000000..10dda7d59 --- /dev/null +++ b/app/src/main/res/values-v31/themes.xml @@ -0,0 +1,63 @@ + + + + \ No newline at end of file From e75b54a5bdea068b844375e5964025424bb3aad3 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:31:58 +0530 Subject: [PATCH 3/6] Typo --- .../java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt b/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt index 5a9f93bc6..18a31e69f 100644 --- a/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt +++ b/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt @@ -49,7 +49,6 @@ class GlobalSettingsFragment : PreferenceFragmentCompat() { findPreference("use_material_you")?.setOnPreferenceChangeListener { _, newValue -> val isMaterialYouEnabled = newValue as Boolean StratoApplication.setTheme(isMaterialYouEnabled) - requireActivity().recreate() true } From 4464c3ecbd72d2a052b59e617ff22e342fdf2659 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:10:17 +0530 Subject: [PATCH 4/6] GlobalSettingsFragment: disable ``MaterialYou`` option for Android 11 or below devices --- .../strato/settings/GlobalSettingsFragment.kt | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt b/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt index 18a31e69f..9836770e7 100644 --- a/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt +++ b/app/src/main/java/org/stratoemu/strato/settings/GlobalSettingsFragment.kt @@ -7,6 +7,7 @@ package org.stratoemu.strato.settings import android.content.Intent import android.os.Bundle +import android.os.Build import android.view.View import androidx.preference.Preference import androidx.preference.PreferenceCategory @@ -73,11 +74,23 @@ class GlobalSettingsFragment : PreferenceFragmentCompat() { if (BuildConfig.BUILD_TYPE != "release") findPreference("validation_layer")?.isVisible = true - if (!GpuDriverHelper.supportsForceMaxGpuClocks()) { - val forceMaxGpuClocksPref = findPreference("force_max_gpu_clocks")!! - forceMaxGpuClocksPref.isSelectable = false - forceMaxGpuClocksPref.isChecked = false - forceMaxGpuClocksPref.summary = context!!.getString(R.string.force_max_gpu_clocks_desc_unsupported) + disablePreference("use_material_you", Build.VERSION.SDK_INT < Build.VERSION_CODES.S, null) + disablePreference("force_max_gpu_clocks", !GpuDriverHelper.supportsForceMaxGpuClocks(), context!!.getString(R.string.force_max_gpu_clocks_desc_unsupported)) + } + + private fun disablePreference( + preferenceId: String, + isDisabled: Boolean, + disabledSummary: String? = null + ) { + val preference = findPreference(preferenceId)!! + preference.isSelectable = !isDisabled + preference.isEnabled = !isDisabled + if (preference is TwoStatePreference && isDisabled) { + preference.isChecked = false + } + if (isDisabled && disabledSummary != null) { + preference.summary = disabledSummary } } } From f84b8d7e353ec8405afb658b5308828501ff89a0 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:49:41 +0530 Subject: [PATCH 5/6] fix ui flickering in some devices --- .../main/java/org/stratoemu/strato/MainActivity.kt | 4 +++- .../java/org/stratoemu/strato/StratoApplication.kt | 11 +++++------ .../org/stratoemu/strato/input/ControllerActivity.kt | 2 ++ .../stratoemu/strato/preference/GpuDriverActivity.kt | 2 ++ .../org/stratoemu/strato/settings/SettingsActivity.kt | 4 +++- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/stratoemu/strato/MainActivity.kt b/app/src/main/java/org/stratoemu/strato/MainActivity.kt index fd5f82124..972842307 100644 --- a/app/src/main/java/org/stratoemu/strato/MainActivity.kt +++ b/app/src/main/java/org/stratoemu/strato/MainActivity.kt @@ -42,6 +42,7 @@ import org.stratoemu.strato.settings.EmulationSettings import org.stratoemu.strato.settings.SettingsActivity import org.stratoemu.strato.utils.GpuDriverHelper import org.stratoemu.strato.utils.WindowInsetsHelper +import org.stratoemu.strato.di.getSettings import javax.inject.Inject import kotlin.math.ceil import com.google.android.material.R as MaterialR @@ -104,6 +105,7 @@ class MainActivity : AppCompatActivity() { else -> AppCompatDelegate.MODE_NIGHT_UNSPECIFIED } ) + setTheme(if (getSettings().useMaterialYou) R.style.AppTheme_MaterialYou else R.style.AppTheme) super.onCreate(savedInstanceState) setContentView(binding.root) @@ -160,7 +162,7 @@ class MainActivity : AppCompatActivity() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { StratoApplication.themeChangeFlow.collect { themeId -> - setTheme(themeId) + // TODO(Ishan09811): Add more material color themes recreate() } } diff --git a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt index 41c5d8624..ab38cd9a6 100644 --- a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt +++ b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt @@ -12,6 +12,9 @@ import org.stratoemu.strato.di.getSettings import java.io.File import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch /** * @return The optimal directory for putting public files inside, this may return a private directory if a public directory cannot be retrieved @@ -34,11 +37,8 @@ class StratoApplication : Application() { val themeChangeFlow = _themeChangeFlow.asSharedFlow() fun setTheme(newValue: Boolean) { - if (newValue) { - _themeChangeFlow.tryEmit(R.style.AppTheme_MaterialYou) - } else { - _themeChangeFlow.tryEmit(R.style.AppTheme) - } + val newTheme = if (newValue) R.style.AppTheme_MaterialYou else R.style.AppTheme + CoroutineScope(Dispatchers.Main).launch { _themeChangeFlow.emit(newTheme) } } } @@ -46,6 +46,5 @@ class StratoApplication : Application() { super.onCreate() instance = this System.loadLibrary("skyline") - setTheme(getSettings().useMaterialYou) } } diff --git a/app/src/main/java/org/stratoemu/strato/input/ControllerActivity.kt b/app/src/main/java/org/stratoemu/strato/input/ControllerActivity.kt index cf666e734..76cfe72b5 100644 --- a/app/src/main/java/org/stratoemu/strato/input/ControllerActivity.kt +++ b/app/src/main/java/org/stratoemu/strato/input/ControllerActivity.kt @@ -31,6 +31,7 @@ import org.stratoemu.strato.input.dialog.StickDialog import org.stratoemu.strato.input.onscreen.OnScreenEditActivity import org.stratoemu.strato.settings.AppSettings import org.stratoemu.strato.utils.WindowInsetsHelper +import org.stratoemu.strato.di.getSettings import javax.inject.Inject /** @@ -174,6 +175,7 @@ class ControllerActivity : AppCompatActivity() { * This initializes all of the elements in the activity */ override fun onCreate(state : Bundle?) { + setTheme(if (getSettings().useMaterialYou) R.style.AppTheme_MaterialYou else R.style.AppTheme) super.onCreate(state) if (id < 0 || id > 7) diff --git a/app/src/main/java/org/stratoemu/strato/preference/GpuDriverActivity.kt b/app/src/main/java/org/stratoemu/strato/preference/GpuDriverActivity.kt index 46e6b83d0..5a6fbe488 100644 --- a/app/src/main/java/org/stratoemu/strato/preference/GpuDriverActivity.kt +++ b/app/src/main/java/org/stratoemu/strato/preference/GpuDriverActivity.kt @@ -30,6 +30,7 @@ import org.stratoemu.strato.utils.GpuDriverHelper import org.stratoemu.strato.utils.GpuDriverInstallResult import org.stratoemu.strato.utils.WindowInsetsHelper import org.stratoemu.strato.utils.serializable +import org.stratoemu.strato.di.getSettings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -125,6 +126,7 @@ class GpuDriverActivity : AppCompatActivity() { } override fun onCreate(savedInstanceState : Bundle?) { + setTheme(if (getSettings().useMaterialYou) R.style.AppTheme_MaterialYou else R.style.AppTheme) super.onCreate(savedInstanceState) setContentView(binding.root) diff --git a/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt b/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt index 83594024d..d9639e866 100644 --- a/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt +++ b/app/src/main/java/org/stratoemu/strato/settings/SettingsActivity.kt @@ -37,6 +37,7 @@ import org.stratoemu.strato.preference.dialog.IntegerListPreferenceMaterialDialo import org.stratoemu.strato.preference.dialog.ListPreferenceMaterialDialogFragmentCompat import org.stratoemu.strato.utils.WindowInsetsHelper import org.stratoemu.strato.StratoApplication +import org.stratoemu.strato.di.getSettings import kotlinx.coroutines.launch private const val PREFERENCE_DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG" @@ -64,6 +65,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere * This initializes all of the elements in the activity and displays the settings fragment */ override fun onCreate(savedInstanceState : Bundle?) { + setTheme(if (getSettings().useMaterialYou) R.style.AppTheme_MaterialYou else R.style.AppTheme) super.onCreate(savedInstanceState) setContentView(binding.root) @@ -132,7 +134,7 @@ class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPrefere lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.CREATED) { StratoApplication.themeChangeFlow.collect { themeId -> - setTheme(themeId) + // TODO(Ishan09811): Add more material color themes recreate() } } From 8c5dc83fc4fa1b752a184a773386dd6910225d22 Mon Sep 17 00:00:00 2001 From: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:50:16 +0530 Subject: [PATCH 6/6] Typo --- app/src/main/java/org/stratoemu/strato/StratoApplication.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt index ab38cd9a6..87ef95fd0 100644 --- a/app/src/main/java/org/stratoemu/strato/StratoApplication.kt +++ b/app/src/main/java/org/stratoemu/strato/StratoApplication.kt @@ -33,7 +33,7 @@ class StratoApplication : Application() { val context : Context get() = instance.applicationContext - private val _themeChangeFlow = MutableSharedFlow(replay = 1) + private val _themeChangeFlow = MutableSharedFlow() val themeChangeFlow = _themeChangeFlow.asSharedFlow() fun setTheme(newValue: Boolean) {