Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fun EnvironmentTabContent(state: ContainerConfigState) {
Row {
NoExtractOutlinedTextField(
value = envVarName,
onValueChange = { envVarName = it },
onValueChange = { envVarName = it.trim() },
label = { Text(text = stringResource(R.string.name)) },
singleLine = true,
trailingIcon = {
Expand Down Expand Up @@ -160,7 +160,7 @@ fun EnvironmentTabContent(state: ContainerConfigState) {
val hasSuggestions = selectedEnvVarInfo?.selectionType == EnvVarSelectionType.SUGGESTIONS
NoExtractOutlinedTextField(
value = envVarValue,
onValueChange = { envVarValue = it },
onValueChange = { envVarValue = it.trim() },
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Value field trims on every keystroke, causing incorrect/unnatural entry of spaced env var values.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/app/gamenative/ui/component/dialog/EnvironmentTab.kt, line 163:

<comment>Value field trims on every keystroke, causing incorrect/unnatural entry of spaced env var values.</comment>

<file context>
@@ -160,7 +160,7 @@ fun EnvironmentTabContent(state: ContainerConfigState) {
                         NoExtractOutlinedTextField(
                             value = envVarValue,
-                            onValueChange = { envVarValue = it },
+                            onValueChange = { envVarValue = it.trim() },
                             label = { Text(text = stringResource(R.string.value)) },
                             singleLine = true,
</file context>
Suggested change
onValueChange = { envVarValue = it.trim() },
onValueChange = { envVarValue = it },
Fix with Cubic

label = { Text(text = stringResource(R.string.value)) },
singleLine = true,
trailingIcon = if (hasSuggestions) {
Expand Down Expand Up @@ -202,7 +202,7 @@ fun EnvironmentTabContent(state: ContainerConfigState) {
enabled = envVarName.isNotEmpty(),
onClick = {
val envVars = EnvVars(config.envVars)
envVars.put(envVarName, envVarValue)
envVars.put(envVarName.trim(), envVarValue.trim())
state.config.value = config.copy(envVars = envVars.toString())
state.showEnvVarCreateDialog.value = false
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ fun SettingsEnvVars(
value = value,
suggestions = envVarInfo?.possibleValues ?: emptyList(),
onValueChange = {
envVars.put(identifier, it)
envVars.put(identifier, it.trim())
onEnvVarsChange(envVars)
},
action = envVarAction?.let {
Expand Down Expand Up @@ -106,16 +106,16 @@ fun SettingsEnvVars(
enabled = enabled,
title = { Text(identifier) },
value = value,
onValueChange = {
envVars.put(identifier, it)
onEnvVarsChange(envVars)
},
action = envVarAction?.let {
{ envVarAction(identifier) }
},
)
}
onValueChange = {
envVars.put(identifier, it.trim())
onEnvVarsChange(envVars)
},
action = envVarAction?.let {
{ envVarAction(identifier) }
},
)
}
}
}
}
}
38 changes: 21 additions & 17 deletions app/src/main/java/com/winlator/core/envvars/EnvVarInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ data class EnvVarInfo(
"memory", "gpuload", "version", "api", "cs", "compiler", "samplers",
),
),
// Wine DLL overrides — user types freely or picks a common preset
// More common DLL overrides can be added in future. Only audio related for now
"WINEDLLOVERRIDES" to EnvVarInfo(
identifier = "WINEDLLOVERRIDES",
selectionType = EnvVarSelectionType.SUGGESTIONS,
possibleValues = listOf(
"openal32=native,builtin",
"soft_oal=native",
"openal32=native,builtin;soft_oal=native",
"xaudio2_7=native,builtin",
),
),
"MESA_EXTENSION_MAX_YEAR" to EnvVarInfo(
identifier = "MESA_EXTENSION_MAX_YEAR",
),
Expand Down Expand Up @@ -270,26 +282,18 @@ data class EnvVarInfo(
"MESA_VK_PRESENT_MODE" to EnvVarInfo(
identifier = "MESA_VK_PRESENT_MODE",
),
"DXVK_FILTER_DEVICE_NAME" to EnvVarInfo(
identifier = "DXVK_FILTER_DEVICE_NAME",
selectionType = EnvVarSelectionType.MULTI_SELECT,
possibleValues = listOf(
"NVIDIA GeForce GTX 1080",
"NVIDIA GeForce RTX 3060",
"AMD Radeon RX 580",
"Radeon HD 7900 Series",
),
"MANGOHUD" to EnvVarInfo(
identifier = "MANGOHUD",
selectionType = EnvVarSelectionType.TOGGLE,
possibleValues = listOf("0", "1"),
),
// Wine DLL overrides — user types freely or picks a common preset
// More common DLL overrides can be added in future. Only audio related for now
"WINEDLLOVERRIDES" to EnvVarInfo(
identifier = "WINEDLLOVERRIDES",
"MANGOHUD_CONFIG" to EnvVarInfo(
identifier = "MANGOHUD_CONFIG",
selectionType = EnvVarSelectionType.SUGGESTIONS,
possibleValues = listOf(
"openal32=native,builtin",
"soft_oal=native",
"openal32=native,builtin;soft_oal=native",
"xaudio2_7=native,builtin",
"fps",
"fps_limit=60",
"fps_only",
),
),
)
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/winlator/core/envvars/EnvVars.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public void putAll(String values) {
String[] parts = values.split(" ");
for (String part : parts) {
int index = part.indexOf("=");
if (part.isEmpty() || index < 1) continue;
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new guard prevents crashes on space-containing values but introduces silent data corruption: putAll splits on " ", so a value like DXVK_HUD=fps, frametimes becomes tokens DXVK_HUD=fps, and frametimes. The second token has no = and is now silently skipped, truncating the stored value. The .trim() calls in the UI prevent users from typing spaces, but putAll can still receive space-containing strings from previously-persisted data or programmatic callers. Consider using an escape-aware delimiter (e.g., storing/splitting on a character that doesn't appear in values, or escaping spaces) so round-tripping is lossless.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At app/src/main/java/com/winlator/core/envvars/EnvVars.java, line 26:

<comment>The new guard prevents crashes on space-containing values but introduces silent data corruption: `putAll` splits on `" "`, so a value like `DXVK_HUD=fps, frametimes` becomes tokens `DXVK_HUD=fps,` and `frametimes`. The second token has no `=` and is now silently skipped, truncating the stored value. The `.trim()` calls in the UI prevent users from *typing* spaces, but `putAll` can still receive space-containing strings from previously-persisted data or programmatic callers. Consider using an escape-aware delimiter (e.g., storing/splitting on a character that doesn't appear in values, or escaping spaces) so round-tripping is lossless.</comment>

<file context>
@@ -23,6 +23,7 @@ public void putAll(String values) {
         String[] parts = values.split(" ");
         for (String part : parts) {
             int index = part.indexOf("=");
+            if (part.isEmpty() || index < 1) continue;
             String name = part.substring(0, index);
             String value = part.substring(index+1);
</file context>
Fix with Cubic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyboard will not allow to type spaces. several barriers in place to ensure a space, that could break the environment variable intention, won't go through.

Values should not contain spaces,
so typing "DXVK_HUD=fps, frametimes" should actually always become DXVK_HUD=fps,frametimes and parse correctly as intended.

Before this implementation, entering a space would mean a crash. now it blocks it from happening.

String name = part.substring(0, index);
String value = part.substring(index+1);
data.put(name, value);
Comment on lines 23 to 29
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

putAll still uses values.split(" "), so any env var value containing an unescaped space (e.g. DXVK_HUD=fps, frametimes) will be split into multiple tokens and silently truncated/ignored. Consider either (a) storing env vars using toEscapedString() and teaching putAll to split on unescaped spaces + unescape \ , or (b) validating/rejecting spaces in values at input time with a user-facing error, so values aren’t corrupted.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

@Catpotatos Catpotatos Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested, keyboard doesn't allow spaces to be typed. video shared.

Expand Down
Loading