Skip to content
Merged
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
3 changes: 2 additions & 1 deletion app/src/main/app/shell/UnifiedActivityDrawer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ import com.winlator.cmod.feature.setup.SetupWizardActivity
import com.winlator.cmod.feature.library.LibraryItemType
import com.winlator.cmod.feature.library.LinuxApps
import com.winlator.cmod.runtime.linux.LinuxClientInstaller
import com.winlator.cmod.runtime.linux.LinuxRuntime
import com.winlator.cmod.feature.shortcuts.LibraryShortcutUtils
import com.winlator.cmod.feature.shortcuts.LibraryShortcutArtwork
import com.winlator.cmod.feature.artwork.SteamArtworkScraper
Expand Down Expand Up @@ -816,7 +817,7 @@ internal fun UnifiedActivity.AddCustomGameDialog(
isAdding = true
scope.launch(Dispatchers.IO) {
val container = LinuxApps.gamescopeContainer(ContainerManager(context))
if (container == null) {
if (container == null || !LinuxRuntime.isInstalled(context)) {
// The entry lives in the GameScope container, which the Linux Client install creates.
withContext(Dispatchers.Main) {
isAdding = false
Expand Down
8 changes: 6 additions & 2 deletions app/src/main/app/shell/UnifiedActivityHub.kt
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,13 @@ internal fun UnifiedActivity.UnifiedHub() {
val context = LocalContext.current
var showLinuxClient by rememberSaveable { mutableStateOf(false) }
val linuxClient by LinuxClientInstaller.state.collectAsState()
// An install finishing adds the Steam entry, which the Library has to read again to show.
val linuxClientWasWorking = remember { booleanArrayOf(false) }
// An install finishing adds the Steam entry, and an uninstall removes it; the Library reads it again.
LaunchedEffect(linuxClient) {
val found = linuxClient
if (found is LinuxClientInstaller.State.Installed) localLibraryRefreshKey++
val removed = linuxClientWasWorking[0] && found is LinuxClientInstaller.State.Missing
linuxClientWasWorking[0] = found is LinuxClientInstaller.State.Working
if (found is LinuxClientInstaller.State.Installed || removed) localLibraryRefreshKey++
// A newer runtime is put in front of the user once; after that it waits in Stores.
if (found is LinuxClientInstaller.State.UpdateAvailable && found.isNews) {
LinuxClientInstaller.dismissUpdate(context, found)
Expand Down Expand Up @@ -1244,6 +1247,7 @@ internal fun UnifiedActivity.UnifiedHub() {
state = linuxClient,
onStart = { LinuxClientInstaller.start(context) },
onCancelInstall = { LinuxClientInstaller.cancel() },
onUninstall = { LinuxClientInstaller.uninstall(context) },
onDismiss = { showLinuxClient = false },
)
}
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/app/shell/UnifiedActivityStartup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,8 @@ internal fun UnifiedActivity.bootstrapStartupState() {
// The Steam entry's artwork is redrawn here as well as at container creation, so an
// install made by an earlier build picks up the current one.
runCatching {
val manager = ContainerManager(appContext)
LinuxApps.gamescopeContainer(manager)?.let { LinuxApps.ensureSteamShortcut(appContext, it) }
if (LinuxRuntime.isInstalled(appContext)) {
LinuxApps.gamescopeContainer(ContainerManager(appContext))?.let { LinuxApps.ensureSteamShortcut(appContext, it) }
LinuxSteamLibrary.adoptClientInstalls(appContext, LinuxRuntime.rootDir(appContext))
}
}.onFailure { Log.w("UnifiedActivity", "Could not refresh the Steam entries", it) }
Expand Down
84 changes: 71 additions & 13 deletions app/src/main/feature/settings/stores/LinuxClientDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ import androidx.compose.foundation.layout.widthIn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDownward
import androidx.compose.material.icons.outlined.CheckCircle
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
Expand All @@ -36,6 +41,7 @@ import com.winlator.cmod.shared.ui.nav.PaneNavRegistry

private val InstallBlue = Color(0xFF1A9FFF)
private val InstalledGreen = Color(0xFF3FB950)
private val UninstallRed = Color(0xFFFF7A88)
private val DialogTextPrimary = Color(0xFFF0F4FF)
private val DialogTextSecondary = Color(0xFF93A6BC)

Expand All @@ -49,32 +55,65 @@ internal fun LinuxClientDialog(
state: State,
onStart: () -> Unit,
onCancelInstall: () -> Unit,
onUninstall: () -> Boolean,
onDismiss: () -> Unit,
) {
val nav = remember { PaneNavRegistry() }
val installed = state is State.Installed
val accent = if (installed) InstalledGreen else InstallBlue
var confirming by rememberSaveable { mutableStateOf(false) }
var sessionRunning by rememberSaveable { mutableStateOf(false) }
val confirm = confirming && installed
val accent =
when {
confirm -> UninstallRed
installed -> InstalledGreen
else -> InstallBlue
}

Dialog(onDismissRequest = onDismiss) {
DialogPaneNav(nav, onDismiss = onDismiss)
CompositionLocalProvider(LocalPaneNav provides nav) {
PopupDialog(
title = stringResource(R.string.linux_client_title),
message = linuxClientMessage(state),
icon = if (installed) Icons.Outlined.CheckCircle else Icons.Outlined.ArrowDownward,
message =
when {
confirm && sessionRunning -> stringResource(R.string.linux_client_uninstall_session_running)
confirm -> stringResource(R.string.linux_client_uninstall_message)
else -> linuxClientMessage(state)
},
icon =
when {
confirm -> Icons.Outlined.Delete
installed -> Icons.Outlined.CheckCircle
else -> Icons.Outlined.ArrowDownward
},
accentColor = accent,
modifier = Modifier.widthIn(min = 300.dp, max = 420.dp),
content = {
if (state is State.Working) WorkingBody(state)
},
footer = {
LinuxClientFooter(
state = state,
accent = accent,
onStart = onStart,
onCancelInstall = onCancelInstall,
onDismiss = onDismiss,
)
if (confirm) {
UninstallFooter(
onCancel = {
confirming = false
sessionRunning = false
},
onUninstall = {
sessionRunning = !onUninstall()
if (!sessionRunning) confirming = false
},
)
} else {
LinuxClientFooter(
state = state,
accent = accent,
onStart = onStart,
onCancelInstall = onCancelInstall,
onUninstall = { confirming = true },
onDismiss = onDismiss,
)
}
},
)
}
Expand Down Expand Up @@ -111,6 +150,7 @@ internal fun linuxClientStageLabel(stage: Stage): Int =
Stage.DOWNLOAD_STEAM -> R.string.linux_client_stage_download_steam
Stage.INSTALL_STEAM -> R.string.linux_client_stage_install_steam
Stage.LIBRARY -> R.string.linux_client_stage_library
Stage.UNINSTALL -> R.string.linux_client_stage_uninstall
}

@Composable
Expand Down Expand Up @@ -154,18 +194,21 @@ private fun LinuxClientFooter(
accent: Color,
onStart: () -> Unit,
onCancelInstall: () -> Unit,
onUninstall: () -> Unit,
onDismiss: () -> Unit,
) {
// The last step writes the container in one go and cannot be stopped part way.
val single = state is State.Installed || (state is State.Working && state.stage == Stage.LIBRARY)
// The last step writes the container in one go, and an uninstall deletes; neither stops part way.
val single = state is State.Working && (state.stage == Stage.LIBRARY || state.stage == Stage.UNINSTALL)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = if (single) Arrangement.End else Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
when (state) {
State.Installed ->
State.Installed -> {
PopupTextAction(stringResource(R.string.common_ui_uninstall), UninstallRed, onUninstall)
PopupTextAction(stringResource(R.string.common_ui_ok), accent, onDismiss, isEntry = true)
}
is State.Working -> {
if (!single) {
PopupTextAction(stringResource(R.string.common_ui_cancel), DialogTextSecondary, onCancelInstall)
Expand All @@ -187,3 +230,18 @@ private fun LinuxClientFooter(
}
}
}

@Composable
private fun UninstallFooter(
onCancel: () -> Unit,
onUninstall: () -> Unit,
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
PopupTextAction(stringResource(R.string.common_ui_cancel), DialogTextSecondary, onCancel, isEntry = true)
PopupTextAction(stringResource(R.string.common_ui_uninstall), UninstallRed, onUninstall)
}
}
1 change: 1 addition & 0 deletions app/src/main/feature/settings/stores/StoresScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ fun StoresScreen(
LinuxClientInstaller.cancel()
linuxClientDialog = false
},
onUninstall = { LinuxClientInstaller.uninstall(context) },
onDismiss = { linuxClientDialog = false },
)
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-b+es+419/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@
<string name="linux_client_busy">El cliente de Steam para Linux aún se está instalando. Inténtalo de nuevo cuando termine.</string>
<string name="linux_client_update_message">Hay un entorno de Linux más reciente. Al actualizar se conservan tu sesión de Steam, los juegos instalados, las partidas guardadas y los contenedores.</string>
<string name="linux_client_update_session_running">Hay una sesión de Linux en curso. Ciérrala y luego actualiza.</string>
<string name="linux_client_uninstall_message">Al desinstalar se elimina el entorno Linux con el cliente de Steam, su inicio de sesión y Proton, y los juegos y partidas guardadas que contiene. Los juegos de tus otras bibliotecas de Steam siguen instalados.</string>
<string name="linux_client_uninstall_session_running">Hay una sesión de Linux en curso. Ciérrala y luego desinstala.</string>
<string name="linux_client_stage_uninstall">Desinstalando el cliente de Linux</string>
<string name="linux_client_gpu_unsupported">The Linux client draws with the Turnip Vulkan driver, which needs an Adreno GPU. This device has a different GPU.</string>
<string name="linux_client_driver_missing">The display driver of the Linux client is not installed, so the screen would stay black. Install it with Linux Client in Settings > Stores.</string>
<string name="linux_session_failed">La sesión de Linux se detuvo apenas inició. Su registro está en Configuración > Depuración > Abrir administrador de registros; compártelo para que se pueda encontrar la causa.</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-da/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@
<string name="linux_client_busy">Linux Steam-klienten installeres stadig. Prøv igen, når den er færdig.</string>
<string name="linux_client_update_message">Et nyere Linux-miljø er tilgængeligt. Opdateringen bevarer dit Steam-login, installerede spil, gemte spil og containere.</string>
<string name="linux_client_update_session_running">En Linux-session kører. Afslut den, og opdater derefter.</string>
<string name="linux_client_uninstall_message">Afinstallation fjerner Linux-miljøet med Steam-klienten, dens login og Proton samt de spil og gemte data, der ligger i det. Spil i dine andre Steam-biblioteker forbliver installeret.</string>
<string name="linux_client_uninstall_session_running">En Linux-session kører. Afslut den, og afinstaller derefter.</string>
<string name="linux_client_stage_uninstall">Afinstallerer Linux-klienten</string>
<string name="linux_client_gpu_unsupported">The Linux client draws with the Turnip Vulkan driver, which needs an Adreno GPU. This device has a different GPU.</string>
<string name="linux_client_driver_missing">The display driver of the Linux client is not installed, so the screen would stay black. Install it with Linux Client in Settings > Stores.</string>
<string name="linux_session_failed">Linux-sessionen stoppede, så snart den startede. Dens log ligger under Indstillinger > Fejlfinding > Åbn loghåndtering; del den, så årsagen kan findes.</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@
<string name="linux_client_busy">Der Linux-Steam-Client wird noch installiert. Versuche es nach Abschluss erneut.</string>
<string name="linux_client_update_message">Eine neuere Linux-Laufzeitumgebung ist verfügbar. Beim Aktualisieren bleiben Steam-Anmeldung, installierte Spiele, Spielstände und Container erhalten.</string>
<string name="linux_client_update_session_running">Eine Linux-Sitzung läuft. Beende sie und aktualisiere dann.</string>
<string name="linux_client_uninstall_message">Die Deinstallation entfernt die Linux-Laufzeit samt Steam-Client, Anmeldung und Proton sowie die darin gespeicherten Spiele und Spielstände. Spiele in deinen anderen Steam-Bibliotheken bleiben installiert.</string>
<string name="linux_client_uninstall_session_running">Eine Linux-Sitzung läuft. Beende sie und deinstalliere dann.</string>
<string name="linux_client_stage_uninstall">Linux-Client wird deinstalliert</string>
<string name="linux_client_gpu_unsupported">The Linux client draws with the Turnip Vulkan driver, which needs an Adreno GPU. This device has a different GPU.</string>
<string name="linux_client_driver_missing">The display driver of the Linux client is not installed, so the screen would stay black. Install it with Linux Client in Settings > Stores.</string>
<string name="linux_session_failed">Die Linux-Sitzung wurde sofort nach dem Start beendet. Ihr Protokoll liegt unter Einstellungen > Debug > Protokollverwaltung öffnen; teile es, damit die Ursache gefunden werden kann.</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@
<string name="linux_client_busy">El cliente de Steam para Linux aún se está instalando. Inténtalo de nuevo cuando termine.</string>
<string name="linux_client_update_message">Hay un entorno de Linux más reciente. Al actualizar se conservan tu sesión de Steam, los juegos instalados, las partidas guardadas y los contenedores.</string>
<string name="linux_client_update_session_running">Hay una sesión de Linux en curso. Ciérrala y luego actualiza.</string>
<string name="linux_client_uninstall_message">Al desinstalar se elimina el entorno Linux con el cliente de Steam, su inicio de sesión y Proton, y los juegos y partidas guardadas que contiene. Los juegos de tus otras bibliotecas de Steam siguen instalados.</string>
<string name="linux_client_uninstall_session_running">Hay una sesión de Linux en curso. Ciérrala y luego desinstala.</string>
<string name="linux_client_stage_uninstall">Desinstalando el cliente de Linux</string>
<string name="linux_client_gpu_unsupported">The Linux client draws with the Turnip Vulkan driver, which needs an Adreno GPU. This device has a different GPU.</string>
<string name="linux_client_driver_missing">The display driver of the Linux client is not installed, so the screen would stay black. Install it with Linux Client in Settings > Stores.</string>
<string name="linux_session_failed">La sesión de Linux se detuvo nada más iniciarse. Su registro está en Ajustes > Depuración > Abrir gestor de registros; compártelo para que se pueda encontrar la causa.</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-fi/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@
<string name="linux_client_busy">Linux Steam -asiakasta asennetaan yhä. Yritä uudelleen, kun asennus on valmis.</string>
<string name="linux_client_update_message">Uudempi Linux-ympäristö on saatavilla. Päivitys säilyttää Steam-kirjautumisen, asennetut pelit, tallennukset ja säiliöt.</string>
<string name="linux_client_update_session_running">Linux-istunto on käynnissä. Sulje se ja päivitä sitten.</string>
<string name="linux_client_uninstall_message">Asennuksen poisto poistaa Linux-ympäristön Steam-asiakkaineen, kirjautumisineen ja Protoneineen sekä sen sisällä olevat pelit ja tallennukset. Muiden Steam-kirjastojesi pelit pysyvät asennettuina.</string>
<string name="linux_client_uninstall_session_running">Linux-istunto on käynnissä. Sulje se ja poista asennus sitten.</string>
<string name="linux_client_stage_uninstall">Poistetaan Linux-asiakasta</string>
<string name="linux_client_gpu_unsupported">The Linux client draws with the Turnip Vulkan driver, which needs an Adreno GPU. This device has a different GPU.</string>
<string name="linux_client_driver_missing">The display driver of the Linux client is not installed, so the screen would stay black. Install it with Linux Client in Settings > Stores.</string>
<string name="linux_session_failed">Linux-istunto pysähtyi heti käynnistyttyään. Sen loki on kohdassa Asetukset > Virheenkorjaus > Avaa lokien hallinta; jaa se, jotta syy löytyy.</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@
<string name="linux_client_busy">Le client Steam Linux est encore en cours d\'installation. Réessayez une fois terminé.</string>
<string name="linux_client_update_message">Un environnement Linux plus récent est disponible. La mise à jour conserve votre connexion Steam, vos jeux installés, vos sauvegardes et vos conteneurs.</string>
<string name="linux_client_update_session_running">Une session Linux est en cours. Quittez-la, puis mettez à jour.</string>
<string name="linux_client_uninstall_message">La désinstallation supprime l\'environnement Linux avec le client Steam, sa connexion et Proton, ainsi que les jeux et sauvegardes qu\'il contient. Les jeux de vos autres bibliothèques Steam restent installés.</string>
<string name="linux_client_uninstall_session_running">Une session Linux est en cours. Quittez-la, puis désinstallez.</string>
<string name="linux_client_stage_uninstall">Désinstallation du client Linux</string>
<string name="linux_client_gpu_unsupported">The Linux client draws with the Turnip Vulkan driver, which needs an Adreno GPU. This device has a different GPU.</string>
<string name="linux_client_driver_missing">The display driver of the Linux client is not installed, so the screen would stay black. Install it with Linux Client in Settings > Stores.</string>
<string name="linux_session_failed">La session Linux s’est arrêtée dès son démarrage. Son journal se trouve dans Paramètres > Débogage > Ouvrir le gestionnaire des journaux ; partagez-le pour que la cause puisse être trouvée.</string>
Expand Down
Loading
Loading