Skip to content

Commit 73c3ba8

Browse files
committed
Option to use Flatpaks under Linux
This adds a configuration setting "linuxUseFlatpak" which controls whether Steam should be launched as a Flatpak or not. By default this is detected automatically based on the path, but an option in the settings can override the behaviour. If this option is enabled, we first check if we are able to read from our config directory. If not, we display an error and ask the user to give us permission. If we do, then we launch Steam through flatpak rather than the binary directly.
1 parent 0e8902f commit 73c3ba8

File tree

5 files changed

+60
-5
lines changed

5 files changed

+60
-5
lines changed

src/components/settings-components/SettingsView.vue

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,23 @@ import CdnProvider from '../../providers/generic/connection/CdnProvider';
350350
'fa-file-alt',
351351
() => this.emitInvoke('ShowDependencyStrings')
352352
),
353+
new SettingsRow(
354+
'Other',
355+
'Launch as Flatpak (Linux)',
356+
'Launch Steam via flatpak',
357+
async () => {
358+
switch (this.settings.getContext().global.linuxUseFlatpak) {
359+
case null:
360+
return 'Automatic';
361+
case true:
362+
return 'Flatpak';
363+
case false:
364+
return 'Native';
365+
}
366+
},
367+
'fa-exchange-alt',
368+
() => this.emitInvoke('ToggleLinuxUseFlatpak')
369+
),
353370
];
354371
355372
@Watch('search')

src/pages/Manager.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ import ModalCard from '../components/ModalCard.vue';
370370
this.settings.setFunkyMode(value);
371371
}
372372
373+
setLinuxUseFlatpak(value: boolean) {
374+
this.settings.setLinuxUseFlatpak(value);
375+
}
376+
373377
async exportProfile() {
374378
if (!this.localModList.length) {
375379
const err = new R2Error(
@@ -579,6 +583,9 @@ import ModalCard from '../components/ModalCard.vue';
579583
case "ToggleFunkyMode":
580584
this.setFunkyMode(!this.settings.getContext().global.funkyModeEnabled);
581585
break;
586+
case "ToggleLinuxUseFlatpak":
587+
this.setLinuxUseFlatpak(!this.settings.getContext().global.linuxUseFlatpak);
588+
break;
582589
case "SwitchTheme":
583590
this.toggleDarkTheme();
584591
document.documentElement.classList.toggle('html--dark', this.settings.getContext().global.darkTheme);

src/r2mm/launching/runners/linux/SteamGameRunner_Linux.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,50 @@ export default class SteamGameRunner_Linux extends GameRunnerProvider {
5353
if (args instanceof R2Error) {
5454
return args
5555
}
56-
return this.start(game, args);
56+
return this.start(game, args, profile.getProfilePath());
5757
}
5858

5959
public async startVanilla(game: Game, profile: Profile): Promise<void | R2Error> {
6060
const instructions = await GameInstructions.getInstructionsForGame(game, profile);
61-
return this.start(game, instructions.vanillaParameters);
61+
return this.start(game, instructions.vanillaParameters, null);
6262
}
6363

64-
async start(game: Game, args: string): Promise<void | R2Error> {
64+
async start(game: Game, args: string, profiledir: string | null): Promise<void | R2Error> {
6565

6666
const settings = await ManagerSettings.getSingleton(game);
6767
const steamDir = await GameDirectoryResolverProvider.instance.getSteamDirectory();
6868
if(steamDir instanceof R2Error) {
6969
return steamDir;
7070
}
71+
let as_flatpak = settings.getContext().global.linuxUseFlatpak;
72+
if (as_flatpak === null) {
73+
// Assume that if the path contains the flatpak directory we must want to use flatpak
74+
as_flatpak = steamDir.includes("/com.valvesoftware.Steam/");
75+
}
76+
77+
if (as_flatpak && profiledir) {
78+
// Ensure we have permission to read our config dir
79+
const visible = await new Promise((resolve) => {
80+
const check_cmd = `flatpak run --command='sh' com.valvesoftware.Steam -c 'ls "${profiledir}"'`;
81+
exec(check_cmd).on('close', (error) => {
82+
resolve(error == 0);
83+
});
84+
});
85+
if (!visible) {
86+
throw new R2Error('Flatpak Permissions Error',
87+
`The directory "${profiledir}" is not visible from within the Flatpak container`,
88+
'`flatpak override com.valvesoftware.Steam --user --filesystem="${XDG_CONFIG_HOME:-$HOME/.config}/r2modmanPlus-local"` to grant access, then restart Steam.');
89+
}
90+
}
7191

7292
LoggerProvider.instance.Log(LogSeverity.INFO, `Steam folder is: ${steamDir}`);
7393

7494
try {
75-
const cmd = `"${steamDir}/steam.sh" -applaunch ${game.activePlatform.storeIdentifier} ${args} ${settings.getContext().gameSpecific.launchParameters}`;
95+
let cmd = `"${steamDir}/steam.sh" -applaunch ${game.activePlatform.storeIdentifier} ${args} ${settings.getContext().gameSpecific.launchParameters}`;
96+
if (as_flatpak) {
97+
cmd = `flatpak run com.valvesoftware.Steam ${cmd}`;
98+
}
99+
76100
LoggerProvider.instance.Log(LogSeverity.INFO, `Running command: ${cmd}`);
77101
await exec(cmd);
78102
} catch(err) {

src/r2mm/manager/ManagerSettings.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ export default class ManagerSettings {
9797
await this.save();
9898
}
9999

100+
public async setLinuxUseFlatpak(enabled: boolean) {
101+
ManagerSettings.CONTEXT.global.linuxUseFlatpak = enabled;
102+
await this.save();
103+
}
104+
100105
public async expandCards() {
101106
ManagerSettings.CONTEXT.global.expandedCards = true;
102107
await this.save();

src/r2mm/manager/SettingsDexieStore.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ export default class SettingsDexieStore extends Dexie {
119119
favouriteGames: [],
120120
defaultGame: undefined,
121121
defaultStore: undefined,
122-
gameSelectionViewMode: GameSelectionViewMode.CARD
122+
gameSelectionViewMode: GameSelectionViewMode.CARD,
123+
linuxUseFlatpak: null,
123124
},
124125
gameSpecific: {
125126
version: 2,
@@ -197,6 +198,7 @@ export interface ManagerSettingsInterfaceGlobal_V2 {
197198
defaultGame: string | undefined;
198199
defaultStore: StorePlatform | undefined;
199200
gameSelectionViewMode: GameSelectionViewMode;
201+
linuxUseFlatpak: boolean | null;
200202
}
201203

202204
/**

0 commit comments

Comments
 (0)