diff --git a/src/game.cpp b/src/game.cpp index 22b7362..964222a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -251,6 +251,11 @@ void Game::setLaunchProfileConfig(const QString &profileId, const QVariantMap &c } QVariantMap Game::effectiveLaunchConfig() const +{ + return effectiveLaunchConfigForProfile(m_activeLaunchProfile); +} + +QVariantMap Game::effectiveLaunchConfigForProfile(const QString &profileId) const { QVariantMap result; @@ -267,12 +272,12 @@ QVariantMap Game::effectiveLaunchConfig() const result.insert(QStringLiteral("env"), m_launchEnv); } - const QString profileId = m_activeLaunchProfile.trimmed(); - if (profileId.isEmpty() || profileId == QLatin1String("default")) { + const QString id = profileId.trimmed(); + if (id.isEmpty() || id == QLatin1String("default")) { return result; } - const QVariantMap profileConfig = launchProfileConfig(profileId); + const QVariantMap profileConfig = launchProfileConfig(id); if (profileConfig.isEmpty()) { return result; } diff --git a/src/game.h b/src/game.h index 7d02266..00ce69f 100644 --- a/src/game.h +++ b/src/game.h @@ -88,6 +88,7 @@ public: Q_INVOKABLE QVariantMap launchProfileConfig(const QString &profileId) const; Q_INVOKABLE void setLaunchProfileConfig(const QString &profileId, const QVariantMap &config); + QVariantMap effectiveLaunchConfigForProfile(const QString &profileId) const; QVariantMap effectiveLaunchConfig() const; QString platform() const; diff --git a/src/gamelauncher.cpp b/src/gamelauncher.cpp index af90fe9..53cd5e4 100644 --- a/src/gamelauncher.cpp +++ b/src/gamelauncher.cpp @@ -3,6 +3,8 @@ #include "gamelauncher.h" #include "app.h" +#include "gamepadmanager.h" +#include "inputmanager.h" #include #include @@ -108,6 +110,33 @@ static QString discoverDefaultProtonExecutable() return cached; } +static QString profileIdForCurrentUiMode() +{ + const Config *config = App::instance() ? App::instance()->config() : nullptr; + if (!config) { + return QStringLiteral("default"); + } + + if (config->uiMode() == Config::Couch) { + return QStringLiteral("couch"); + } + + if (config->uiMode() == Config::Auto) { + GamepadManager *pad = GamepadManager::instance(); + InputManager *input = InputManager::instance(); + + if (pad && pad->connected()) { + const bool activeGamepad = input && input->activeInput() == InputManager::Gamepad; + const bool noKeyboardMouse = input && !input->hasSeenKeyboardMouse(); + if (activeGamepad || noKeyboardMouse) { + return QStringLiteral("couch"); + } + } + } + + return QStringLiteral("default"); +} + GameLauncher::GameLauncher(QObject *parent) : QObject(parent) { @@ -153,7 +182,8 @@ QVariantMap GameLauncher::resolveLaunchInfo(Game *game) const return info; } - const QVariantMap effectiveLaunchConfig = game->effectiveLaunchConfig(); + const QString profileId = profileIdForCurrentUiMode(); + const QVariantMap effectiveLaunchConfig = game->effectiveLaunchConfigForProfile(profileId); const QString runner = effectiveLaunchConfig.value(QStringLiteral("runner")).toString().trimmed(); const QString runnerPath = effectiveLaunchConfig.value(QStringLiteral("runnerPath")).toString().trimmed(); const QString prefixPath = effectiveLaunchConfig.value(QStringLiteral("prefixPath")).toString().trimmed(); @@ -298,7 +328,8 @@ void GameLauncher::launchGame(Game *game) return; } - const QVariantMap effectiveLaunchConfig = game->effectiveLaunchConfig(); + const QString profileId = profileIdForCurrentUiMode(); + const QVariantMap effectiveLaunchConfig = game->effectiveLaunchConfigForProfile(profileId); const QString runner = effectiveLaunchConfig.value(QStringLiteral("runner")).toString().trimmed(); const QString runnerPath = effectiveLaunchConfig.value(QStringLiteral("runnerPath")).toString().trimmed(); const QString prefixPath = effectiveLaunchConfig.value(QStringLiteral("prefixPath")).toString().trimmed(); diff --git a/src/qml/GameDetailsSheet.qml b/src/qml/GameDetailsSheet.qml index 4bb593f..f3a553d 100644 --- a/src/qml/GameDetailsSheet.qml +++ b/src/qml/GameDetailsSheet.qml @@ -12,7 +12,18 @@ import org.kde.alakarte Kirigami.OverlaySheet { id: detailsSheet - property var game + property var game: null + property int lastNonCouchUiMode: Config.Auto + + readonly property bool effectiveCouchMode: { + if (App.config.uiMode === Config.Couch) return true + if (App.config.uiMode !== Config.Auto) return false + if (GamepadManager.connected) { + if (InputManager.activeInput === InputManager.Gamepad) return true + if (!InputManager.hasSeenKeyboardMouse) return true + } + return false + } readonly property var screenshotsModel: game ? App.mediaManager.screenshotsModel(game) : null @@ -419,13 +430,20 @@ Kirigami.OverlaySheet { } QQC2.Button { - icon.name: "preferences-other" - text: game && game.activeLaunchProfile === "couch" ? i18n("Profile: Couch") : i18n("Profile: Default") + icon.name: "view-fullscreen" + text: detailsSheet.effectiveCouchMode ? i18n("Couch mode: On") : i18n("Couch mode: Off") display: detailsSheet.useCompactLayout ? QQC2.AbstractButton.TextUnderIcon : QQC2.AbstractButton.TextBesideIcon - enabled: !!game - onClicked: if (game) { - game.activeLaunchProfile = (game.activeLaunchProfile === "couch") ? "default" : "couch" - App.saveLibrary() + onClicked: { + if (detailsSheet.effectiveCouchMode) { + if (detailsSheet.lastNonCouchUiMode === Config.Auto) { + App.config.uiMode = Config.Desktop + } else { + App.config.uiMode = detailsSheet.lastNonCouchUiMode + } + } else { + detailsSheet.lastNonCouchUiMode = App.config.uiMode + App.config.uiMode = Config.Couch + } } } diff --git a/src/qml/GameEditDialog.qml b/src/qml/GameEditDialog.qml index 65188a6..8069b1c 100644 --- a/src/qml/GameEditDialog.qml +++ b/src/qml/GameEditDialog.qml @@ -248,7 +248,12 @@ Kirigami.Dialog { executableField.text = game.launchCommand || "" workingDirField.text = game.workingDirectory || "" - dialog.editProfileId = game.activeLaunchProfile === "couch" ? "couch" : "default" + dialog.editProfileId = (App.config.uiMode === Config.Couch + || (App.config.uiMode === Config.Auto + && GamepadManager.connected + && (InputManager.activeInput === InputManager.Gamepad || !InputManager.hasSeenKeyboardMouse))) + ? "couch" + : "default" profileCombo.currentIndex = dialog.profileIndexFromId(dialog.editProfileId) dialog.loadProfileFields() } else {