From ffb76240fd6b8884b8023decb36480bc8a984312 Mon Sep 17 00:00:00 2001
From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
Date: Sat, 7 Nov 2026 14:22:00 -0500
Subject: [PATCH] fix(fex): show which preset Use Default resolves to (#2225)
* fix(fex): show which preset Use Default resolves to and rename FEX defaults to Stock FEX
* test(components): the FEX preset chip names its resolved preset instead of Use Default
* fix(fex): the game settings menu keeps Use Default beside the inherited preset
* fix(fex): inherited preset chip follows the current Default preset
---
.../main/java/com/droiddeck/launcher/ui/ComponentsPage.kt | 7 +++++--
.../main/java/com/droiddeck/launcher/ui/FrontEndSetup.kt | 5 +++--
.../main/java/com/droiddeck/launcher/ui/SessionOverlay.kt | 1 +
app/src/main/res/values/strings.xml | 4 ++--
.../com/droiddeck/launcher/ui/ComponentsPageProfileTest.kt | 4 ++--
5 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/app/src/main/java/com/droiddeck/launcher/ui/ComponentsPage.kt b/app/src/main/java/com/droiddeck/launcher/ui/ComponentsPage.kt
index 2b93f2ad9..fcd2a0512 100644
--- a/app/src/main/java/com/droiddeck/launcher/ui/ComponentsPage.kt
+++ b/app/src/main/java/com/droiddeck/launcher/ui/ComponentsPage.kt
@@ -1183,6 +1183,7 @@ private fun GameComponentOverrides(
open = fexMenu,
enabled = config != null && !busy,
allowInheritance = true,
+ generalPreset = generalFexPreset,
onToggle = { onFexMenu(!fexMenu) },
onDismiss = { onFexMenu(false) },
onPick = onFexPreset,
@@ -1349,15 +1350,16 @@ internal fun FexPresetChip(
onDismiss: () -> Unit,
onPick: (String?) -> Unit,
allowInheritance: Boolean = false,
+ generalPreset: String = preset,
modifier: Modifier = Modifier,
) {
- val chosen = FexPreset.all.firstOrNull { it.id == preset }
+ val chosen = FexPreset.all.firstOrNull { it.id == if (inherited) generalPreset else preset }
val label = when {
preset == GameEnvironment.CUSTOM_FEX_PRESET -> stringResource(R.string.comp_game_fex_custom)
chosen == null -> stringResource(FexPreset.byId("").label)
- inherited -> stringResource(R.string.comp_game_use_general)
else -> stringResource(chosen.label)
}
+ val general = FexPreset.all.firstOrNull { it.id == generalPreset }
Box {
ValueChip(label, open, enabled = enabled, modifier = modifier.widthIn(max = 260.dp), onClick = onToggle)
AnchoredMenu(open && enabled, onDismiss = onDismiss, title = stringResource(R.string.fex_preset_title)) { first ->
@@ -1365,6 +1367,7 @@ internal fun FexPresetChip(
MenuItem(
stringResource(R.string.comp_game_use_general),
checked = inherited,
+ detail = general?.let { stringResource(it.label) },
focusRequester = first,
) { onPick(null); onDismiss() }
}
diff --git a/app/src/main/java/com/droiddeck/launcher/ui/FrontEndSetup.kt b/app/src/main/java/com/droiddeck/launcher/ui/FrontEndSetup.kt
index ac844177d..42158d695 100644
--- a/app/src/main/java/com/droiddeck/launcher/ui/FrontEndSetup.kt
+++ b/app/src/main/java/com/droiddeck/launcher/ui/FrontEndSetup.kt
@@ -833,6 +833,7 @@ internal fun GameSettingsMenus(host: MenuHost, game: com.droiddeck.launcher.fron
)
val appSync = syncLabels[com.droiddeck.launcher.session.SessionPrefs.syncBackend(appContext)]
val useDefault = stringResource(R.string.comp_game_use_general)
+ val generalFex = com.droiddeck.launcher.core.FexPreset.byId(com.droiddeck.launcher.session.SessionPrefs.fexPreset(appContext))
val custom = stringResource(R.string.comp_game_fex_custom)
val customSync = stringResource(R.string.game_sync_custom)
val resetDone = stringResource(R.string.comp_game_reset_done, game.name)
@@ -847,7 +848,7 @@ internal fun GameSettingsMenus(host: MenuHost, game: com.droiddeck.launcher.fron
MenuItem(
stringResource(R.string.fex_preset_title), checked = false, enabled = ready,
detail = when {
- fex == null -> useDefault
+ fex == null -> "$useDefault ยท ${stringResource(generalFex.label)}"
chosen == null -> custom
else -> stringResource(chosen.label)
},
@@ -879,7 +880,7 @@ internal fun GameSettingsMenus(host: MenuHost, game: com.droiddeck.launcher.fron
}
}
AnchoredMenu(host.open == fexKey, onDismiss = { if (host.open == fexKey) host.open = null }, title = stringResource(R.string.fex_preset_title)) { first ->
- MenuItem(useDefault, checked = fex == null, enabled = ready, focusRequester = first) {
+ MenuItem(useDefault, checked = fex == null, enabled = ready, detail = stringResource(generalFex.label), focusRequester = first) {
host.open = key
save { com.droiddeck.launcher.session.GameEnvironmentStore.setGameFexPreset(it, scope, null) }
}
diff --git a/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt b/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt
index 53d533e71..c4803e7a2 100644
--- a/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt
+++ b/app/src/main/java/com/droiddeck/launcher/ui/SessionOverlay.kt
@@ -1239,6 +1239,7 @@ private fun DrawerFexPresetRow(host: MenuHost, a: DrawerActions, modifier: Modif
}
},
allowInheritance = appId != null,
+ generalPreset = a.fexPreset,
modifier = modifier,
)
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1560dfcd4..c0fa84110 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -130,8 +130,8 @@
FEX preset
Applies on the next game launch.
Games
- FEX defaults
- Uses FEX defaults.
+ Stock FEX
+ No FEX tuning applied.
Stability
Safest, slowest settings.
Compatibility
diff --git a/app/src/test/java/com/droiddeck/launcher/ui/ComponentsPageProfileTest.kt b/app/src/test/java/com/droiddeck/launcher/ui/ComponentsPageProfileTest.kt
index 8d9d59f8d..90c8d9685 100644
--- a/app/src/test/java/com/droiddeck/launcher/ui/ComponentsPageProfileTest.kt
+++ b/app/src/test/java/com/droiddeck/launcher/ui/ComponentsPageProfileTest.kt
@@ -168,8 +168,8 @@ class ComponentsPageProfileTest {
compose.onNodeWithText(context.getString(R.string.gpu_system_powervr)).assertIsNotEnabled()
compose.onNodeWithText(context.getString(R.string.cmgr_powervr_dxvk_managed)).assertExists()
val inheritedChoices = compose.onAllNodesWithText(context.getString(R.string.comp_game_use_general))
- inheritedChoices.assertCountEquals(4) // FEX preset, FEX package, Proton and VKD3D remain selectable.
- repeat(4) { inheritedChoices[it].assertIsEnabled() }
+ inheritedChoices.assertCountEquals(3) // FEX package, Proton and VKD3D remain selectable.
+ repeat(3) { inheritedChoices[it].assertIsEnabled() }
val runtimeOptions = compose.onAllNodesWithText(context.getString(R.string.comp_game_runtime_options))
runtimeOptions.assertCountEquals(2)
repeat(2) { runtimeOptions[it].assertIsEnabled() }