From 22786bef52abbadfaf304054a91863784bb925df Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:11:50 -0700 Subject: [PATCH] fix: detect gamescope displays before performing window setup (#171) * umu_util: add function to detect steamos * umu_run: add functionality to detect gamescope displays * umu_run: update gamescope window setup logic * umu_run: handle None type when there are no gamescope displays * umu_run: remove device check * umu_run: add debug statements * umu_run: list all files in /tmp/.X11-unix * umu_util: fix device check * umu_run: connect to expected displays when on steamos * umu_run: fix comment * umu_run: update comments * umu_run: close the displays * umu_util: refactor function to return the id value * umu_run: update logic * umu_run: remove unused var * umu_util: add debug statement for id * umu_run: remove unused functions * umu_util: update debug statement * umu_util: update comment * umu_run: sort import statements * umu_util: cite container interface document * umu_run: update type in function header --- umu/umu_run.py | 37 ++++++++++++++++++++++++++++++------- umu/umu_util.py | 27 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 960eb838..1eedc77f 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -45,7 +45,12 @@ from umu.umu_plugins import set_env_toml from umu.umu_proton import get_umu_proton from umu.umu_runtime import setup_umu -from umu.umu_util import get_libc, is_installed_verb, is_winetricks_verb +from umu.umu_util import ( + get_libc, + get_osrelease_id, + is_installed_verb, + is_winetricks_verb, +) AnyPath = os.PathLike | str @@ -501,7 +506,9 @@ def set_steam_game_property( log.exception(e) -def get_gamescope_baselayer_order(d: display.Display) -> list[int] | None: +def get_gamescope_baselayer_order( + d: display.Display, +) -> list[int] | None: """Get the gamescope base layer seq on the primary root window.""" try: root_primary: Window = d.screen().root @@ -677,16 +684,32 @@ def run_command(command: list[AnyPath]) -> int: cwd=cwd, ) - if os.environ.get("XDG_CURRENT_DESKTOP") == "gamescope": - # :0 is where the primary xwayland server is on the Steam Deck + # Currently, Flatpak apps that use umu as their runtime will not have their + # game window brought to the foreground due to the base layer being out of + # order. Ensure we're in a steamos gamescope session before fixing them + # See https://github.com/ValveSoftware/gamescope/issues/1341 + if ( + get_osrelease_id() == "steamos" + and os.environ.get("XDG_CURRENT_DESKTOP") == "gamescope" + ): + log.debug("SteamOS gamescope session detected") + # Currently, steamos creates two xwayland servers at :0 and :1 + # Despite the socket for display :0 being hidden at /tmp/.x11-unix in + # the Flatpak, it is still possible to connect to it. d_primary = display.Display(":0") gamescope_baselayer_sequence = get_gamescope_baselayer_order(d_primary) + # Connect to the display associated with the game + # Display :1 will be visible in the Flatpak + if d_primary and os.environ.get("STEAM_MULTIPLE_XWAYLANDS") == "1": + d_secondary = display.Display(":1") + # Dont do window fuckery if we're not inside gamescope - if gamescope_baselayer_sequence and not os.environ.get("EXE", "").endswith( - "winetricks" + if ( + d_secondary + and gamescope_baselayer_sequence + and not os.environ.get("EXE", "").endswith("winetricks") ): - d_secondary = display.Display(":1") d_secondary.screen().root.change_attributes( event_mask=X.SubstructureNotifyMask ) diff --git a/umu/umu_util.py b/umu/umu_util.py index 31b8a87c..d2560f44 100644 --- a/umu/umu_util.py +++ b/umu/umu_util.py @@ -1,3 +1,4 @@ +import os from ctypes.util import find_library from functools import lru_cache from pathlib import Path @@ -158,3 +159,29 @@ def find_obsolete() -> None: # $HOME/.local/share if (ulwgl := home.joinpath(".local", "share", "ULWGL")).is_dir(): log.warning("'%s' is obsolete", ulwgl) + + +def get_osrelease_id() -> str: + """Get the identity of the host OS.""" + release: Path + osid: str = "" + + # Flatpak follows the Container Interface outlined by systemd + # See https://systemd.io/CONTAINER_INTERFACE + if os.environ.get("container") == "flatpak": # noqa: SIM112 + release = Path("/run/host/os-release") + else: + release = Path("/etc/os-release") + + if not release.is_file(): + log.debug("File '%s' could not be found", release) + return osid + + with release.open(mode="r", encoding="utf-8") as file: + for line in file: + if line.startswith("ID="): + osid = line.removeprefix("ID=").strip() + log.debug("OS: %s", osid) + break + + return osid