aboutsummaryrefslogtreecommitdiff
path: root/libs/basic_games_native
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-16 16:12:46 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-16 16:12:46 -0500
commite41a79a9033761916fa133260ff1849288db7df1 (patch)
treea2e8e45d73fcb12e15cbfaf30e8aa5d02a957481 /libs/basic_games_native
parent66633ead443819df5aacc87b3fd1fdee85cddfde (diff)
Fix Steam game detection in game mode + add result cache
- Prepend STEAM_COMPAT_CLIENT_INSTALL_PATH as first Steam path candidate. Steam always sets this env var when launching any app (including in gamescope/game mode), so it reliably points to the correct Steam root even when $HOME resolves differently inside the gamescope session. - Canonicalize VDF-sourced library paths before dedup in getAllLibraryFolders() so /home/ ↔ /var/home/ symlinks (Bazzite/Fedora immutable distros) don't produce duplicate scan entries. - Cache findSteamGames() results in a static hash. Previously, findSteamGamePath() rebuilt the full library scan 45+ times per launch (once per registered game plugin). Now the scan runs at most once. Fixes game detection on Bazzite in Steam Game Mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/basic_games_native')
-rw-r--r--libs/basic_games_native/src/steamutils.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/libs/basic_games_native/src/steamutils.cpp b/libs/basic_games_native/src/steamutils.cpp
index 28fac2b..ffae0f1 100644
--- a/libs/basic_games_native/src/steamutils.cpp
+++ b/libs/basic_games_native/src/steamutils.cpp
@@ -20,6 +20,16 @@ static QStringList findSteamPaths()
home + "/snap/steam/common/.local/share/Steam",
};
+ // When Steam launches an app (e.g. in game mode) it sets
+ // STEAM_COMPAT_CLIENT_INSTALL_PATH to its own root. Add that as a
+ // candidate so we find the right installation even if $HOME resolves
+ // differently inside the gamescope session.
+ const QString steamEnvPath =
+ QString::fromLocal8Bit(qgetenv("STEAM_COMPAT_CLIENT_INSTALL_PATH"));
+ if (!steamEnvPath.isEmpty()) {
+ candidates.prepend(steamEnvPath);
+ }
+
for (const auto& candidate : candidates) {
QDir dir(candidate);
if (dir.exists("steamapps") || QFile::exists(candidate + "/steam.pid")) {
@@ -68,8 +78,12 @@ static QStringList getAllLibraryFolders(const QString& steamPath)
{"steamapps/libraryfolders.vdf", "config/libraryfolders.vdf"}) {
QString vdfPath = steamPath + "/" + vdfName;
for (const auto& path : parseLibraryFolders(vdfPath)) {
- if (!folders.contains(path)) {
- folders.append(path);
+ // Canonicalize before dedup so /home/ and /var/home/ paths compare equal
+ QString canonical = QFileInfo(path).canonicalFilePath();
+ if (canonical.isEmpty())
+ canonical = path;
+ if (!folders.contains(canonical)) {
+ folders.append(canonical);
}
}
}
@@ -120,8 +134,15 @@ static AppManifest parseAppManifest(const QString& path)
return manifest;
}
+// Cache: built once per process, cleared on explicit refresh.
+static QHash<int, QString> s_steamGamesCache;
+static bool s_steamGamesCacheValid = false;
+
QHash<int, QString> findSteamGames()
{
+ if (s_steamGamesCacheValid)
+ return s_steamGamesCache;
+
QHash<int, QString> games;
for (const auto& steamPath : findSteamPaths()) {
@@ -146,11 +167,12 @@ QHash<int, QString> findSteamGames()
}
}
+ s_steamGamesCache = games;
+ s_steamGamesCacheValid = true;
return games;
}
QString findSteamGamePath(int appId)
{
- auto games = findSteamGames();
- return games.value(appId);
+ return findSteamGames().value(appId);
}