consider all layout types when checking for custom layouts without file

fixes #1490
This commit is contained in:
Helium314 2025-04-21 07:37:42 +02:00
parent da7ab05920
commit d15a97ccba
2 changed files with 39 additions and 17 deletions

View file

@ -143,6 +143,20 @@ object LayoutUtilsCustom {
return file return file
} }
/** @return whether a layout has no file and was removed from [layouts] */
fun removeMissingLayouts(layouts: EnumMap<LayoutType, String>, context: Context): Boolean {
var removed = false
LayoutType.entries.forEach { type ->
val name = layouts[type] ?: return@forEach
if (!isCustomLayout(name) || getLayoutFiles(type, context).any { it.name == name })
return@forEach
// no file for custom layout
layouts.remove(type)
removed = true
}
return removed
}
// this goes into prefs and file names, so do not change! // this goes into prefs and file names, so do not change!
const val CUSTOM_LAYOUT_PREFIX = "custom." const val CUSTOM_LAYOUT_PREFIX = "custom."
private const val TAG = "LayoutUtilsCustom" private const val TAG = "LayoutUtilsCustom"

View file

@ -13,12 +13,14 @@ import helium314.keyboard.compat.locale
import helium314.keyboard.keyboard.KeyboardSwitcher import helium314.keyboard.keyboard.KeyboardSwitcher
import helium314.keyboard.latin.RichInputMethodManager import helium314.keyboard.latin.RichInputMethodManager
import helium314.keyboard.latin.common.Constants.Separators import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET
import helium314.keyboard.latin.common.LocaleUtils import helium314.keyboard.latin.common.LocaleUtils
import helium314.keyboard.latin.define.DebugFlags import helium314.keyboard.latin.define.DebugFlags
import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Defaults
import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.settings.SettingsSubtype import helium314.keyboard.latin.settings.SettingsSubtype
import helium314.keyboard.latin.settings.SettingsSubtype.Companion.toSettingsSubtype import helium314.keyboard.latin.settings.SettingsSubtype.Companion.toSettingsSubtype
import helium314.keyboard.latin.utils.LayoutType.Companion.toExtraValue
import helium314.keyboard.latin.utils.ScriptUtils.script import helium314.keyboard.latin.utils.ScriptUtils.script
import java.util.Locale import java.util.Locale
@ -164,10 +166,11 @@ object SubtypeSettings {
fun reloadEnabledSubtypes(context: Context) { fun reloadEnabledSubtypes(context: Context) {
enabledSubtypes.clear() enabledSubtypes.clear()
removeInvalidCustomSubtypes(context) removeMissingCustomLayouts(context)
loadAdditionalSubtypes(context.prefs()) loadAdditionalSubtypes(context.prefs())
loadEnabledSubtypes(context) loadEnabledSubtypes(context)
RichInputMethodManager.getInstance().refreshSubtypeCaches() if (RichInputMethodManager.isInitialized())
RichInputMethodManager.getInstance().refreshSubtypeCaches()
} }
fun createSettingsSubtypes(prefSubtypes: String): List<SettingsSubtype> = fun createSettingsSubtypes(prefSubtypes: String): List<SettingsSubtype> =
@ -187,7 +190,7 @@ object SubtypeSettings {
reloadSystemLocales(context) reloadSystemLocales(context)
loadResourceSubtypes(context.resources) loadResourceSubtypes(context.resources)
removeInvalidCustomSubtypes(context) removeMissingCustomLayouts(context)
loadAdditionalSubtypes(context.prefs()) loadAdditionalSubtypes(context.prefs())
loadEnabledSubtypes(context) loadEnabledSubtypes(context)
} }
@ -215,22 +218,27 @@ object SubtypeSettings {
} }
} }
// remove custom subtypes without a layout file // remove layouts without a layout file from custom subtypes
private fun removeInvalidCustomSubtypes(context: Context) { // should not be necessary, but better fall back to default instead of crashing when encountering a bug
private fun removeMissingCustomLayouts(context: Context) {
val prefs = context.prefs() val prefs = context.prefs()
val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!.split(Separators.SETS) val additionalSubtypes = prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, Defaults.PREF_ADDITIONAL_SUBTYPES)!!
val customLayoutFiles by lazy { LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, context).map { it.name } } .split(Separators.SETS).map { it.toSettingsSubtype() }
val subtypesToRemove = mutableListOf<String>() additionalSubtypes.forEach { subtype ->
additionalSubtypes.forEach { val layouts = LayoutType.getLayoutMap(subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET) ?: "")
val name = it.toSettingsSubtype().mainLayoutName() ?: SubtypeLocaleUtils.QWERTY if (LayoutUtilsCustom.removeMissingLayouts(layouts, context)) {
if (!LayoutUtilsCustom.isCustomLayout(name)) return@forEach // layout file is missing -> adjust the subtype to use the modified layout map
if (name !in customLayoutFiles) val newSubtype = if (layouts.isEmpty()) subtype.without(KEYBOARD_LAYOUT_SET)
subtypesToRemove.add(it) else subtype.with(KEYBOARD_LAYOUT_SET, layouts.toExtraValue())
SubtypeUtilsAdditional.changeAdditionalSubtype(subtype, newSubtype, context)
val message = "removing custom layouts without file from subtype $subtype"
if (DebugFlags.DEBUG_ENABLED)
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
Log.w(TAG, message)
// we return here, because changeAdditionalSubtype calls reloadEnabledSubtypes, which calls this method
return
}
} }
if (subtypesToRemove.isEmpty()) return
Log.w(TAG, "removing custom subtypes without main layout files: $subtypesToRemove")
// todo: now we have a qwerty fallback anyway, consider removing this method (makes bugs more obvious to users)
prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, additionalSubtypes.filterNot { it in subtypesToRemove }.joinToString(Separators.SETS)).apply()
} }
private fun loadAdditionalSubtypes(prefs: SharedPreferences) { private fun loadAdditionalSubtypes(prefs: SharedPreferences) {