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
2 changes: 1 addition & 1 deletion helper/CouchPlayHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public Q_SLOTS:
* @param username User to run as
* @param compositorUid UID of compositor user (for runtime access setup)
* @param gamescopeArgs Gamescope command-line arguments
* @param gameCommand Command to run inside gamescope (e.g., "steam -tenfoot")
* @param gameCommand Command to run inside gamescope (e.g., "steam -bigpicture")
* @param environment Additional environment variables (VAR=value format)
* @param bindPaths Paths to bind-mount into the unit via --property=BindPaths=
* @return MainPID of launched process, or 0 on failure
Expand Down
3 changes: 2 additions & 1 deletion src/core/GamescopeInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-FileCopyrightText: 2025 CouchPlay Contributors

#include "GamescopeInstance.h"
#include "PresetManager.h"

#include <QDBusConnection>
#include <QDBusInterface>
Expand Down Expand Up @@ -54,7 +55,7 @@ bool GamescopeInstance::start(const QVariantMap &config, int index)
// Fallback to Steam Big Picture if no preset configured
QString gameCommand = config.value(QStringLiteral("presetCommand")).toString();
if (gameCommand.isEmpty()) {
gameCommand = QStringLiteral("steam -tenfoot -steamdeck");
gameCommand = PresetManager::defaultSteamCommand();
}

// Launch via D-Bus helper for uniform handling across all users (including compositor user)
Expand Down
13 changes: 11 additions & 2 deletions src/core/PresetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <KConfigGroup>

static constexpr int CACHE_TTL_HOURS = 24;
static constexpr int FLATPAK_CACHE_VERSION = 2; // bump when builtin preset commands change

PresetManager::PresetManager(QObject *parent)
: QObject(parent)
Expand Down Expand Up @@ -113,6 +114,9 @@ void PresetManager::loadFlatpakCache()
{
KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("couchplayrc"));
KConfigGroup cacheGroup = config->group(QStringLiteral("FlatpakCache"));
if (cacheGroup.readEntry(QStringLiteral("version"), 0) != FLATPAK_CACHE_VERSION) {
return; // stale cache (builtin commands changed) - saveFlatpakCache rewrites it
}

const QStringList keys = cacheGroup.keyList();
QSet<QString> presetIds;
Expand Down Expand Up @@ -149,6 +153,7 @@ void PresetManager::saveFlatpakCache()
{
KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("couchplayrc"));
KConfigGroup cacheGroup = config->group(QStringLiteral("FlatpakCache"));
cacheGroup.writeEntry(QStringLiteral("version"), FLATPAK_CACHE_VERSION);

QString timestamp = QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMddTHHmmss"));
for (const auto &preset : m_builtinPresets) {
Expand All @@ -160,6 +165,10 @@ void PresetManager::saveFlatpakCache()
cacheGroup.sync();
}

QString PresetManager::defaultSteamCommand()
{
return QStringLiteral("steam -bigpicture");
}
void PresetManager::initBuiltinPresets()
{
m_builtinPresets.clear();
Expand All @@ -168,9 +177,9 @@ void PresetManager::initBuiltinPresets()
steam.id = QStringLiteral("steam");
steam.name = QStringLiteral("Steam Big Picture");
steam.flatpakAppId = QStringLiteral("com.valvesoftware.Steam");
steam.flatpakArgs = QStringLiteral("-tenfoot -steamdeck");
steam.flatpakArgs = QStringLiteral("-bigpicture");
steam.command = resolveLaunchCommand(
QStringLiteral("steam -tenfoot -steamdeck"),
defaultSteamCommand(),
steam.flatpakAppId,
steam.flatpakArgs);
steam.iconName = QStringLiteral("steam");
Expand Down
3 changes: 2 additions & 1 deletion src/core/PresetManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct LaunchPreset {
LauncherInfo launcherInfo; // Populated by detection for launcher presets
QStringList sharedDirectories; // Per-preset shared directories for ACL/mount setup
QString flatpakAppId; // e.g., "com.valvesoftware.Steam" (empty = no Flatpak alternative)
QString flatpakArgs; // Extra args for Flatpak launch (e.g., "-tenfoot -steamdeck")
QString flatpakArgs; // Extra args for Flatpak launch (e.g., "-bigpicture")

bool operator==(const LaunchPreset &other) const { return id == other.id; }
};
Expand Down Expand Up @@ -111,6 +111,7 @@ class PresetManager : public QObject

Q_INVOKABLE LaunchPreset getPreset(const QString &id) const;
Q_INVOKABLE QString getCommand(const QString &id) const;
static QString defaultSteamCommand();
Q_INVOKABLE QString getWorkingDirectory(const QString &id) const;
Q_INVOKABLE bool getSteamIntegration(const QString &id) const;
Q_INVOKABLE QString getLauncherId(const QString &id) const;
Expand Down
2 changes: 1 addition & 1 deletion src/core/SessionRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ bool SessionRunner::start()
config[QStringLiteral("steamIntegration")] = m_presetManager->getSteamIntegration(presetId);
} else {
config[QStringLiteral("presetId")] = QStringLiteral("steam");
config[QStringLiteral("presetCommand")] = QStringLiteral("steam -tenfoot -steamdeck");
config[QStringLiteral("presetCommand")] = PresetManager::defaultSteamCommand();
config[QStringLiteral("steamIntegration")] = true;
}

Expand Down
4 changes: 2 additions & 2 deletions tests/test_couchplayhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@ void TestCouchPlayHelper::testLaunchInstance_basicLaunch()
QStringLiteral("player1"),
1000u,
QStringList{QStringLiteral("-W"), QStringLiteral("960")},
QStringLiteral("steam -tenfoot"),
QStringLiteral("steam -bigpicture"),
QStringList{QStringLiteral("ENABLE_GAMESCOPE_WSI=1")},
QStringList());

Expand All @@ -1314,7 +1314,7 @@ void TestCouchPlayHelper::testLaunchInstance_basicLaunch()
QVERIFY(inv.args.contains(QStringLiteral("/usr/bin/gamescope")));
QVERIFY(inv.args.contains(QStringLiteral("-W")));
QVERIFY(inv.args.contains(QStringLiteral("960")));
QVERIFY(inv.args.contains(QStringLiteral("steam -tenfoot")));
QVERIFY(inv.args.contains(QStringLiteral("steam -bigpicture")));
QVERIFY(inv.args.contains(QStringLiteral("-c")));
QVERIFY(inv.args.contains(QStringLiteral("/bin/bash")));
break;
Expand Down
6 changes: 3 additions & 3 deletions tests/test_gamescopeinstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ void TestGamescopeInstance::testSteamLaunchMode()

QVariantMap config;
config[QStringLiteral("presetId")] = QStringLiteral("steam");
config[QStringLiteral("presetCommand")] = QStringLiteral("steam -tenfoot -steamdeck");
config[QStringLiteral("presetCommand")] = QStringLiteral("steam -bigpicture");
config[QStringLiteral("steamIntegration")] = true;
config[QStringLiteral("steamAppId")] = QStringLiteral("1426210"); // It Takes Two
config[QStringLiteral("internalWidth")] = 1920;
Expand Down Expand Up @@ -390,7 +390,7 @@ void TestGamescopeInstance::testSteamLaunchModeNoAppId()

QVariantMap config;
config[QStringLiteral("presetId")] = QStringLiteral("steam");
config[QStringLiteral("presetCommand")] = QStringLiteral("steam -tenfoot -steamdeck");
config[QStringLiteral("presetCommand")] = QStringLiteral("steam -bigpicture");
config[QStringLiteral("steamIntegration")] = true;
// No steamAppId set - this is valid, launches Steam Big Picture
config[QStringLiteral("internalWidth")] = 1920;
Expand Down Expand Up @@ -419,7 +419,7 @@ void TestGamescopeInstance::testSteamModeIsDefault()
QSignalSpy errorSpy(m_instance, &GamescopeInstance::errorOccurred);

QVariantMap config;
// No presetCommand set - should default to "steam -tenfoot -steamdeck"
// No presetCommand set - should default to "steam -bigpicture"
config[QStringLiteral("internalWidth")] = 1920;
config[QStringLiteral("internalHeight")] = 1080;

Expand Down
25 changes: 24 additions & 1 deletion tests/test_presetmanager.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 CouchPlay Contributors

#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QJsonArray>
Expand Down Expand Up @@ -28,6 +29,7 @@ private Q_SLOTS:

void testBuiltinPresetsExist();
void testGetCommand();
void testStaleFlatpakCacheIgnored();
void testGetWorkingDirectory();
void testGetLauncherId();
void testGetSteamIntegration();
Expand Down Expand Up @@ -120,7 +122,7 @@ void TestPresetManager::testGetCommand()
PresetManager manager;

QString steamCommand = manager.getCommand(QStringLiteral("steam"));
QCOMPARE(steamCommand, QStringLiteral("steam -tenfoot -steamdeck"));
QCOMPARE(steamCommand, QStringLiteral("steam -bigpicture"));

QString heroicCommand = manager.getCommand(QStringLiteral("heroic"));
QVERIFY(!heroicCommand.isEmpty());
Expand All @@ -129,6 +131,27 @@ void TestPresetManager::testGetCommand()
QCOMPARE(lutrisCommand, QStringLiteral("lutris"));
}

void TestPresetManager::testStaleFlatpakCacheIgnored()
{
// Pre-seed a stale v1 cache; a fresh timestamp keeps it inside the TTL so
// only the version gate can prevent it from overriding the builtin.
KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("couchplayrc"));
KConfigGroup cacheGroup = config->group(QStringLiteral("FlatpakCache"));
cacheGroup.writeEntry(QStringLiteral("version"), 1);
cacheGroup.writeEntry(QStringLiteral("steam/command"), QStringLiteral("steam -tenfoot -steamdeck"));
cacheGroup.writeEntry(QStringLiteral("steam/timestamp"),
QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMddTHHmmss")));
cacheGroup.sync();

PresetManager manager;
QCOMPARE(manager.getCommand(QStringLiteral("steam")), QStringLiteral("steam -bigpicture"));

// Constructor rewrote the cache at the current version.
cacheGroup = config->group(QStringLiteral("FlatpakCache"));
QCOMPARE(cacheGroup.readEntry(QStringLiteral("version"), 0), 2);
QCOMPARE(cacheGroup.readEntry(QStringLiteral("steam/command")), QStringLiteral("steam -bigpicture"));
}

void TestPresetManager::testGetWorkingDirectory()
{
PresetManager manager;
Expand Down
Loading