Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to disable runtime #112

Merged
merged 13 commits into from
Jun 12, 2024
8 changes: 8 additions & 0 deletions docs/umu.1.scd
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ _PROTON_VERB_
_UMU_ZENITY_
Optional. Creates a *zenity*[5] popup window when downloading large files.

_UMU_NO_RUNTIME_
Optional and only applicable to Flatpak applications. Disables the usage of the *Steam Linux Runtime*[6] (SLR).

Set to _1_ to disable the entirety of the SLR or _pressure-vessel_ to only disable Pressure Vessel and the container runtime.

Defaults to _pressure-vessel_.

# SEE ALSO

_umu_(5), _winetricks_(1), _zenity_(1)
Expand All @@ -174,6 +181,7 @@ _umu_(5), _winetricks_(1), _zenity_(1)
. https://github.com/Open-Wine-Components/umu-protonfixes
. https://github.com/Open-Wine-Components/umu-database
. https://gitlab.gnome.org/GNOME/zenity
. https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/blob/main/docs/container-runtime.md

# AUTHORS

Expand Down
75 changes: 59 additions & 16 deletions umu/umu_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
from umu_plugins import set_env_toml
from umu_proton import Proton, get_umu_proton
from umu_runtime import setup_umu
from umu_util import get_libc, is_installed_verb, is_winetricks_verb
from umu_util import (
get_libc,
is_installed_verb,
is_steamdeck,
is_winetricks_verb,
)

THREAD_POOL: ThreadPoolExecutor = ThreadPoolExecutor()

Expand Down Expand Up @@ -308,6 +313,25 @@ def set_env(
"" if os.environ.get("UMU_LOG") == "debug" else "1"
)

# Runtime
if FLATPAK_PATH:
env["UMU_NO_RUNTIME"] = os.environ.get("UMU_NO_RUNTIME") or ""

# Currently, running games when using the Steam Runtime in a Flatpak
# environment will cause the game window to not display within the SteamOS
# gamescope session. Note, this is a workaround until the runtime is built
# or the issue is fixed upstream.
# See https://github.com/ValveSoftware/gamescope/issues/1341
if (
not os.environ.get("UMU_NO_RUNTIME")
and FLATPAK_PATH
and is_steamdeck()
and os.environ.get("XDG_CURRENT_DESKTOP") == "gamescope"
):
log.debug("SteamOS gamescope session detected")
log.debug("Disabling Pressure Vessel and container runtime")
env["UMU_NO_RUNTIME"] = "pressure-vessel"

return env


Expand Down Expand Up @@ -371,11 +395,42 @@ def build_command(
env: dict[str, str],
local: Path,
command: list[str],
opts: list[str] = None,
opts: list[str] = [],
) -> list[str]:
"""Build the command to be executed."""
verb: str = env["PROTON_VERB"]

# Will run the game w/o Proton, effectively running the game as is. This
# option is intended for debugging purposes, and is otherwise useless
if env.get("UMU_NO_RUNTIME") == "1":
log.warning("Runtime Platform disabled")
command.extend(
[
env.get("EXE"),
*opts,
],
)
return command

# Only log the warning when running games within SteamOS gamescope session
if (
env.get("UMU_NO_RUNTIME") == "pressure-vessel"
and not is_steamdeck()
and os.environ.get("XDG_CURRENT_DESKTOP") != "gamescope"
):
log.warning("Using Proton without Runtime Platform")

if env.get("UMU_NO_RUNTIME") == "pressure-vessel":
command.extend(
[
Path(env.get("PROTONPATH")).joinpath("proton").as_posix(),
verb,
env.get("EXE"),
*opts,
],
)
return command

# Raise an error if the _v2-entry-point cannot be found
if not local.joinpath("umu").is_file():
err: str = (
Expand All @@ -395,20 +450,6 @@ def build_command(
# Usage: ./winetricks [options] [command|verb|path-to-verb] ...
opts = ["-q", *opts]

if opts:
command.extend(
[
local.joinpath("umu").as_posix(),
"--verb",
verb,
"--",
Path(env.get("PROTONPATH")).joinpath("proton").as_posix(),
verb,
env.get("EXE"),
*opts,
],
)
return command
command.extend(
[
local.joinpath("umu").as_posix(),
Expand All @@ -418,6 +459,7 @@ def build_command(
Path(env.get("PROTONPATH")).joinpath("proton").as_posix(),
verb,
env.get("EXE"),
*opts,
],
)

Expand Down Expand Up @@ -506,6 +548,7 @@ def main() -> int: # noqa: D103
"UMU_ID": "",
"ULWGL_ID": "",
"UMU_ZENITY": "",
"UMU_NO_RUNTIME": "",
}
command: list[str] = []
opts: list[str] = []
Expand Down
6 changes: 6 additions & 0 deletions umu/umu_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ def tearDown(self):
if self.test_winepfx.exists():
rmtree(self.test_winepfx.as_posix())

def test_is_steamdeck(self):
"""Test is_steamdeck."""
self.assertIsInstance(
umu_util.is_steamdeck(), bool, "Expected a boolean"
)

def test_is_installed_verb_noverb(self):
"""Test is_installed_verb when passed an empty verb."""
verb = []
Expand Down
21 changes: 21 additions & 0 deletions umu/umu_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,24 @@ def is_winetricks_verb(
return False

return True


@lru_cache
def is_steamdeck() -> bool:
"""Determine if the host device is a Steam Deck by its CPU model."""
cpu_info: Path = Path("/proc/cpuinfo")
is_sd: bool = False
sd_models: set[str] = {"AMD Custom APU 0405", "AMD Custom APU 0932"}

if not cpu_info.is_file():
return is_sd

with cpu_info.open(mode="r", encoding="utf-8") as file:
for line in file:
if line.startswith("model name"):
_: str = line[line.find(":") + 1 :].strip()
if _ in sd_models:
is_sd = True
break

return is_sd