From 5027da2339b0bdb42e8238a523a44fb74de2bbbe Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 21:15:19 -0800 Subject: [PATCH 01/15] umu_consts: add enum for gamescope atom names --- umu/umu_consts.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/umu/umu_consts.py b/umu/umu_consts.py index a8247e992..82b44ee1a 100644 --- a/umu/umu_consts.py +++ b/umu/umu_consts.py @@ -1,6 +1,15 @@ import os +from enum import Enum from pathlib import Path + +class GamescopeAtom(Enum): + """Represent Gamescope-specific X11 atom names.""" + + SteamGame = "STEAM_GAME" + BaselayerAppId = "GAMESCOPECTRL_BASELAYER_APPID" + + CONFIG = "umu_version.json" STEAM_COMPAT: Path = Path.home().joinpath( From 339a0c064e390f01b9e0b7ca217d00a76dd4ca52 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 21:20:22 -0800 Subject: [PATCH 02/15] umu_run: use enum when referring to atom name --- umu/umu_run.py | 57 +++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 51f7e8397..422255e23 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -32,13 +32,14 @@ from Xlib.protocol.rq import Event from Xlib.xobject.drawable import Window -from umu import __version__ +from umu import __container_runtime__, __version__ from umu.umu_consts import ( PR_SET_CHILD_SUBREAPER, PROTON_VERBS, STEAM_COMPAT, STEAM_WINDOW_ID, UMU_LOCAL, + GamescopeAtom, ) from umu.umu_log import log from umu.umu_plugins import set_env_toml @@ -388,18 +389,20 @@ def set_steam_game_property( try: window: Window = d.create_resource_object("window", int(window_id)) window.change_property( - d.get_atom("STEAM_GAME"), + d.get_atom(GamescopeAtom.SteamGame.value), Xatom.CARDINAL, 32, [steam_assigned_layer_id], ) log.debug( - "Successfully set STEAM_GAME property for window ID: %s", + "Successfully set %s property for window ID: %s", + GamescopeAtom.SteamGame.value, window_id, ) except Exception as e: log.error( - "Error setting STEAM_GAME property for window ID: %s", + "Error setting %s property for window ID: %s", + GamescopeAtom.SteamGame.value, window_id, ) log.exception(e) @@ -411,21 +414,20 @@ def get_gamescope_baselayer_order( """Get the gamescope base layer seq on the primary root window.""" try: root_primary: Window = d.screen().root - # Intern the atom for GAMESCOPECTRL_BASELAYER_APPID - atom = d.get_atom("GAMESCOPECTRL_BASELAYER_APPID") - + atom = d.get_atom(GamescopeAtom.BaselayerAppId.value) # Get the property value prop: GetProperty | None = root_primary.get_full_property( atom, Xatom.CARDINAL ) - if prop: # Extract and return the value return prop.value # type: ignore - log.debug("GAMESCOPECTRL_BASELAYER_APPID property not found") + log.debug("%s property not found", GamescopeAtom.BaselayerAppId.value) except Exception as e: - log.error("Error getting GAMESCOPECTRL_BASELAYER_APPID property") + log.error( + "Error getting %s property", GamescopeAtom.BaselayerAppId.value + ) log.exception(e) return None @@ -439,7 +441,7 @@ def rearrange_gamescope_baselayer_order( rearranged: list[int] = list(sequence) steam_layer_id: int = get_steam_layer_id(os.environ) - log.debug("Base layer sequence: %s", sequence) + log.debug("%s: %s", GamescopeAtom.BaselayerAppId.value, sequence) if not steam_layer_id: return None @@ -453,9 +455,9 @@ def rearrange_gamescope_baselayer_order( log.exception(e) return None - # Steam's window should be last, while assigned layer 2nd to last - rearranged = [*rearranged[:-1], steam_layer_id, STEAM_WINDOW_ID] - log.debug("Rearranging base layer sequence") + # Steam's window should be last, while assigned app id 2nd to last + rearranged = [*rearranged[:-1], steam_appid, STEAM_WINDOW_ID] + log.debug("Rearranging %s", GamescopeAtom.BaselayerAppId.value) log.debug("'%s' -> '%s'", sequence, rearranged) return rearranged, steam_layer_id @@ -467,16 +469,18 @@ def set_gamescope_baselayer_order( """Set a new gamescope base layer seq on the primary root window.""" try: # Intern the atom for GAMESCOPECTRL_BASELAYER_APPID - atom = d.get_atom("GAMESCOPECTRL_BASELAYER_APPID") - + atom = d.get_atom(GamescopeAtom.BaselayerAppId.value) # Set the property value d.screen().root.change_property(atom, Xatom.CARDINAL, 32, rearranged) log.debug( - "Successfully set GAMESCOPECTRL_BASELAYER_APPID property: %s", + "Successfully set %s property: %s", + GamescopeAtom.BaselayerAppId.value, ", ".join(map(str, rearranged)), ) except Exception as e: - log.error("Error setting GAMESCOPECTRL_BASELAYER_APPID property") + log.error( + "Error setting %s property", GamescopeAtom.BaselayerAppId.value + ) log.exception(e) @@ -511,11 +515,12 @@ def monitor_baselayer( """Monitor for broken gamescope baselayer sequences.""" root_primary: Window = d_primary.screen().root rearranged_gamescope_baselayer: tuple[list[int], int] | None = None - atom = d_primary.get_atom("GAMESCOPECTRL_BASELAYER_APPID") + atom = d_primary.get_atom(GamescopeAtom.BaselayerAppId.value) root_primary.change_attributes(event_mask=X.PropertyChangeMask) log.debug( - "Monitoring base layers under display '%s'...", + "Monitoring %s property for DISPLAY=%s...", + GamescopeAtom.BaselayerAppId.value, d_primary.get_display_name(), ) @@ -539,8 +544,16 @@ def monitor_baselayer( # Check if the layer sequence has changed to the broken one if prop and prop.value[-1] != STEAM_WINDOW_ID: - log.debug("Broken base layer sequence detected") - log.debug("Property value for atom '%s': %s", atom, prop.value) + log.debug( + "Broken %s property detected, will rearrange...", + GamescopeAtom.BaselayerAppId.value, + ) + log.debug( + "%s has atom %s: %s", + GamescopeAtom.BaselayerAppId.value, + atom, + prop.value, + ) rearranged_gamescope_baselayer = ( rearrange_gamescope_baselayer_order(prop.value) ) From cfebaaf3998b8ed4a35d98f9901b5946e1f13d0c Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 21:27:58 -0800 Subject: [PATCH 03/15] umu_run: convert atom value's array to list - In the past this lead to subtle bugs in comparison expressions. --- umu/umu_run.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 422255e23..451bcb51e 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -6,6 +6,7 @@ import time from _ctypes import CFuncPtr from argparse import Namespace +from array import array from collections.abc import MutableMapping from concurrent.futures import Future, ThreadPoolExecutor from contextlib import suppress @@ -420,9 +421,10 @@ def get_gamescope_baselayer_order( prop: GetProperty | None = root_primary.get_full_property( atom, Xatom.CARDINAL ) - if prop: - # Extract and return the value - return prop.value # type: ignore + # For GAMESCOPECTRL_BASELAYER_APPID, the value is a u32 array + if prop and prop.value and isinstance(prop.value, array): + # Convert data to a Python list for safety + return prop.value.tolist() log.debug("%s property not found", GamescopeAtom.BaselayerAppId.value) except Exception as e: log.error( From 106501ad876e16f067dab9dcd62262723d8c0579 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:09:37 -0800 Subject: [PATCH 04/15] umu_run: rename function to get_gamescope_baselayer_appid --- umu/umu_run.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 451bcb51e..8186c04d7 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -409,7 +409,7 @@ def set_steam_game_property( log.exception(e) -def get_gamescope_baselayer_order( +def get_gamescope_baselayer_appid( d: display.Display, ) -> list[int] | None: """Get the gamescope base layer seq on the primary root window.""" @@ -631,10 +631,9 @@ def run_in_steammode(proc: Popen) -> int: xdisplay(":0") as d_primary, xdisplay(":1") as d_secondary, ): - gamescope_baselayer_sequence = get_gamescope_baselayer_order( + gamescope_baselayer_sequence = get_gamescope_baselayer_appid( d_primary ) - # Dont do window fuckery if we're not inside gamescope if ( gamescope_baselayer_sequence From c576b80c2e2a00f192bab2f5751d1e0bb3e9c8ad Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:11:46 -0800 Subject: [PATCH 05/15] umu_run: rename function to rearrange_gamescope_baselayer_appid --- umu/umu_run.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 8186c04d7..afb24c617 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -435,7 +435,7 @@ def get_gamescope_baselayer_appid( return None -def rearrange_gamescope_baselayer_order( +def rearrange_gamescope_baselayer_appid( sequence: list[int], ) -> tuple[list[int], int] | None: """Rearrange a gamescope base layer sequence retrieved from a window.""" @@ -526,8 +526,8 @@ def monitor_baselayer( d_primary.get_display_name(), ) - # Get a rearranged sequence from GAMESCOPECTRL_BASELAYER_APPID. - rearranged_gamescope_baselayer = rearrange_gamescope_baselayer_order( + # Rearranged GAMESCOPECTRL_BASELAYER_APPID + rearranged_gamescope_baselayer = rearrange_gamescope_baselayer_appid( gamescope_baselayer_sequence ) @@ -557,7 +557,7 @@ def monitor_baselayer( prop.value, ) rearranged_gamescope_baselayer = ( - rearrange_gamescope_baselayer_order(prop.value) + rearrange_gamescope_baselayer_appid(prop.value) ) if rearranged_gamescope_baselayer: From d68d612361c8d2b8547617dab6e17965866f6c5d Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:13:53 -0800 Subject: [PATCH 06/15] umu_run: rename function to set_gamescope_baselayer_appid --- umu/umu_run.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index afb24c617..c0543f66d 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -465,7 +465,7 @@ def rearrange_gamescope_baselayer_appid( return rearranged, steam_layer_id -def set_gamescope_baselayer_order( +def set_gamescope_baselayer_appid( d: display.Display, rearranged: list[int] ) -> None: """Set a new gamescope base layer seq on the primary root window.""" @@ -534,7 +534,7 @@ def monitor_baselayer( # Set the rearranged sequence from GAMESCOPECTRL_BASELAYER_APPID. if rearranged_gamescope_baselayer: rearranged, _ = rearranged_gamescope_baselayer - set_gamescope_baselayer_order(d_primary, rearranged) + set_gamescope_baselayer_appid(d_primary, rearranged) rearranged_gamescope_baselayer = None while True: @@ -562,7 +562,7 @@ def monitor_baselayer( if rearranged_gamescope_baselayer: rearranged, _ = rearranged_gamescope_baselayer - set_gamescope_baselayer_order(d_primary, rearranged) + set_gamescope_baselayer_appid(d_primary, rearranged) rearranged_gamescope_baselayer = None continue From ff3453c17b183b594b0a92747c66433005206993 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:19:39 -0800 Subject: [PATCH 07/15] umu_run: rename function to get_steam_appid --- umu/umu_run.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index c0543f66d..8d4b4ce6f 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -441,15 +441,15 @@ def rearrange_gamescope_baselayer_appid( """Rearrange a gamescope base layer sequence retrieved from a window.""" # Note: 'sequence' is actually an array type with unsigned integers rearranged: list[int] = list(sequence) - steam_layer_id: int = get_steam_layer_id(os.environ) + steam_appid: int = get_steam_appid(os.environ) log.debug("%s: %s", GamescopeAtom.BaselayerAppId.value, sequence) - if not steam_layer_id: + if not steam_appid: return None try: - rearranged.remove(steam_layer_id) + rearranged.remove(steam_appid) except ValueError as e: # Case when the layer ID isn't in GAMESCOPECTRL_BASELAYER_APPID # One case this can occur is if the client overrides Steam's env vars @@ -462,7 +462,7 @@ def rearrange_gamescope_baselayer_appid( log.debug("Rearranging %s", GamescopeAtom.BaselayerAppId.value) log.debug("'%s' -> '%s'", sequence, rearranged) - return rearranged, steam_layer_id + return rearranged, steam_appid def set_gamescope_baselayer_appid( @@ -486,9 +486,9 @@ def set_gamescope_baselayer_appid( log.exception(e) -def get_steam_layer_id(env: MutableMapping) -> int: - """Get the Steam layer ID from the host environment variables.""" steam_layer_id: int = 0 +def get_steam_appid(env: MutableMapping) -> int: + """Get the Steam app ID from the host environment variables.""" if path := env.get("STEAM_COMPAT_TRANSCODED_MEDIA_PATH"): # Suppress cases when value is not a number or empty tuple @@ -574,7 +574,7 @@ def monitor_windows( ) -> None: """Monitor for new windows and assign them Steam's layer ID.""" window_ids: set[str] | None = None - steam_assigned_layer_id: int = get_steam_layer_id(os.environ) + steam_appid: int = get_steam_appid(os.environ) log.debug( "Waiting for windows under display '%s'...", From 05a5f7d4ca7a6200dda8849e665789825a7aa191 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:26:40 -0800 Subject: [PATCH 08/15] umu_run: update identifiers --- umu/umu_run.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 8d4b4ce6f..e27ce35c7 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -381,11 +381,10 @@ def get_window_client_ids(d: display.Display) -> set[str] | None: def set_steam_game_property( d: display.Display, window_ids: list[str] | set[str], - steam_assigned_layer_id: int, + steam_assigned_appid: int, ) -> None: """Set Steam's assigned layer ID on a list of windows.""" - log.debug("steam_layer: %s", steam_assigned_layer_id) - + log.debug("Steam app ID: %s", steam_assigned_appid) for window_id in window_ids: try: window: Window = d.create_resource_object("window", int(window_id)) @@ -393,7 +392,7 @@ def set_steam_game_property( d.get_atom(GamescopeAtom.SteamGame.value), Xatom.CARDINAL, 32, - [steam_assigned_layer_id], + [steam_assigned_appid], ) log.debug( "Successfully set %s property for window ID: %s", @@ -486,9 +485,9 @@ def set_gamescope_baselayer_appid( log.exception(e) - steam_layer_id: int = 0 def get_steam_appid(env: MutableMapping) -> int: """Get the Steam app ID from the host environment variables.""" + steam_appid: int = 0 if path := env.get("STEAM_COMPAT_TRANSCODED_MEDIA_PATH"): # Suppress cases when value is not a number or empty tuple @@ -507,7 +506,7 @@ def get_steam_appid(env: MutableMapping) -> int: with suppress(ValueError, IndexError): return int(Path(path).parts[-2]) - return steam_layer_id + return steam_appid def monitor_baselayer( @@ -584,7 +583,7 @@ def monitor_windows( while not window_ids: window_ids = get_window_client_ids(d_secondary) - set_steam_game_property(d_secondary, window_ids, steam_assigned_layer_id) + set_steam_game_property(d_secondary, window_ids, steam_appid) log.debug( "Monitoring for new windows under display '%s'...", @@ -606,7 +605,7 @@ def monitor_windows( log.debug("Difference: %s", diff) log.debug("New windows detected") window_ids |= diff - set_steam_game_property(d_secondary, diff, steam_assigned_layer_id) + set_steam_game_property(d_secondary, diff, steam_appid) def run_in_steammode(proc: Popen) -> int: From 154164274e99bf857102fabca8c0207230f9eaa1 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:28:00 -0800 Subject: [PATCH 09/15] umu_run: rename function to get_window_ids --- umu/umu_run.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index e27ce35c7..cfbbe1ae0 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -363,11 +363,10 @@ def build_command( ) -def get_window_client_ids(d: display.Display) -> set[str] | None: - """Get the list of new client windows under the root window.""" +def get_window_ids(d: display.Display) -> set[str] | None: + """Get the list of window ids under the root window for a display.""" try: event: Event = d.next_event() - if event.type == X.CreateNotify: return { child.id for child in d.screen().root.query_tree().children @@ -581,7 +580,7 @@ def monitor_windows( ) while not window_ids: - window_ids = get_window_client_ids(d_secondary) + window_ids = get_window_ids(d_secondary) set_steam_game_property(d_secondary, window_ids, steam_appid) @@ -592,9 +591,7 @@ def monitor_windows( # Check if the window sequence has changed while True: - current_window_ids: set[str] | None = get_window_client_ids( - d_secondary - ) + current_window_ids: set[str] | None = get_window_ids(d_secondary) if not current_window_ids: continue From 01b1002ca9204755ed558dcc4b089cbc9df18f5e Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:28:51 -0800 Subject: [PATCH 10/15] umu_run: rename function to monitor monitor_baselayer_appid --- umu/umu_run.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index cfbbe1ae0..469f83f2c 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -508,7 +508,7 @@ def get_steam_appid(env: MutableMapping) -> int: return steam_appid -def monitor_baselayer( +def monitor_baselayer_appid( d_primary: display.Display, gamescope_baselayer_sequence: list[int], ) -> None: @@ -652,7 +652,7 @@ def run_in_steammode(proc: Popen) -> int: # Monitor for broken baselayers baselayer_thread = threading.Thread( - target=monitor_baselayer, + target=monitor_baselayer_appid, args=(d_primary, gamescope_baselayer_sequence), ) baselayer_thread.daemon = True From 7cf11fc7fa196f1746a61cfd73dd99986e706bf6 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:29:57 -0800 Subject: [PATCH 11/15] umu_run: update comments --- umu/umu_run.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 469f83f2c..713c9a120 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -92,7 +92,7 @@ def check_env( GAMEID is strictly required and the client is responsible for setting this. When the client only sets the GAMEID, the WINE prefix directory will be - created as ~/Games/umu/GAMEID. + created as $HOME/Games/umu/$GAMEID. """ if not os.environ.get("GAMEID"): err: str = "Environment variable not set or is empty: GAMEID" @@ -410,7 +410,7 @@ def set_steam_game_property( def get_gamescope_baselayer_appid( d: display.Display, ) -> list[int] | None: - """Get the gamescope base layer seq on the primary root window.""" + """Get the GAMESCOPECTRL_BASELAYER_APPID value on the primary root window.""" try: root_primary: Window = d.screen().root # Intern the atom for GAMESCOPECTRL_BASELAYER_APPID @@ -436,8 +436,7 @@ def get_gamescope_baselayer_appid( def rearrange_gamescope_baselayer_appid( sequence: list[int], ) -> tuple[list[int], int] | None: - """Rearrange a gamescope base layer sequence retrieved from a window.""" - # Note: 'sequence' is actually an array type with unsigned integers + """Rearrange the GAMESCOPECTRL_BASELAYER_APPID value retrieved from a window.""" rearranged: list[int] = list(sequence) steam_appid: int = get_steam_appid(os.environ) @@ -449,9 +448,9 @@ def rearrange_gamescope_baselayer_appid( try: rearranged.remove(steam_appid) except ValueError as e: - # Case when the layer ID isn't in GAMESCOPECTRL_BASELAYER_APPID + # Case when the app ID isn't in GAMESCOPECTRL_BASELAYER_APPID # One case this can occur is if the client overrides Steam's env vars - # that we get the layer ID from + # that we get the app ID from log.exception(e) return None @@ -466,7 +465,7 @@ def rearrange_gamescope_baselayer_appid( def set_gamescope_baselayer_appid( d: display.Display, rearranged: list[int] ) -> None: - """Set a new gamescope base layer seq on the primary root window.""" + """Set a new gamescope GAMESCOPECTRL_BASELAYER_APPID on the primary root window.""" try: # Intern the atom for GAMESCOPECTRL_BASELAYER_APPID atom = d.get_atom(GamescopeAtom.BaselayerAppId.value) @@ -512,7 +511,7 @@ def monitor_baselayer_appid( d_primary: display.Display, gamescope_baselayer_sequence: list[int], ) -> None: - """Monitor for broken gamescope baselayer sequences.""" + """Monitor for broken GAMESCOPECTRL_BASELAYER_APPID values.""" root_primary: Window = d_primary.screen().root rearranged_gamescope_baselayer: tuple[list[int], int] | None = None atom = d_primary.get_atom(GamescopeAtom.BaselayerAppId.value) @@ -529,7 +528,7 @@ def monitor_baselayer_appid( gamescope_baselayer_sequence ) - # Set the rearranged sequence from GAMESCOPECTRL_BASELAYER_APPID. + # Set the rearranged GAMESCOPECTRL_BASELAYER_APPID if rearranged_gamescope_baselayer: rearranged, _ = rearranged_gamescope_baselayer set_gamescope_baselayer_appid(d_primary, rearranged) @@ -570,7 +569,7 @@ def monitor_baselayer_appid( def monitor_windows( d_secondary: display.Display, ) -> None: - """Monitor for new windows and assign them Steam's layer ID.""" + """Monitor for new windows for a display and assign them Steam's assigned app ID.""" window_ids: set[str] | None = None steam_appid: int = get_steam_appid(os.environ) @@ -635,14 +634,11 @@ def run_in_steammode(proc: Popen) -> int: gamescope_baselayer_sequence and os.environ.get("PROTON_VERB") == "waitforexitandrun" ): - # Note: If the executable is one that exists in the WINE prefix - # or container it is possible that umu wil hang when running a - # game within a gamescope session d_secondary.screen().root.change_attributes( event_mask=X.SubstructureNotifyMask ) - # Monitor for new windows + # Monitor for new windows for the DISPLAY associated with game window_thread = threading.Thread( target=monitor_windows, args=(d_secondary,), @@ -650,7 +646,7 @@ def run_in_steammode(proc: Popen) -> int: window_thread.daemon = True window_thread.start() - # Monitor for broken baselayers + # Monitor for broken GAMESCOPECTRL_BASELAYER_APPID baselayer_thread = threading.Thread( target=monitor_baselayer_appid, args=(d_primary, gamescope_baselayer_sequence), @@ -678,7 +674,6 @@ def run_command(command: tuple[Path | str, ...]) -> int: os.environ.get("XDG_CURRENT_DESKTOP") == "gamescope" or os.environ.get("XDG_SESSION_DESKTOP") == "gamescope" ) - # Note: STEAM_MULTIPLE_XWAYLANDS is steam mode specific and is # documented to be a legacy env var. is_steammode: bool = ( From 67cb94bd8d2e69aca8dcd1e7851f33b194fbde1f Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:31:29 -0800 Subject: [PATCH 12/15] umu_run: update log statements --- umu/umu_run.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 713c9a120..ffee54e7a 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -574,7 +574,7 @@ def monitor_windows( steam_appid: int = get_steam_appid(os.environ) log.debug( - "Waiting for windows under display '%s'...", + "Waiting for new windows IDs for DISPLAY=%s...", d_secondary.get_display_name(), ) @@ -584,7 +584,7 @@ def monitor_windows( set_steam_game_property(d_secondary, window_ids, steam_appid) log.debug( - "Monitoring for new windows under display '%s'...", + "Monitoring for new window IDs for DISPLAY=%s...", d_secondary.get_display_name(), ) @@ -596,10 +596,9 @@ def monitor_windows( continue if diff := current_window_ids.difference(window_ids): - log.debug("Seen windows: %s", window_ids) - log.debug("Current windows: %s", current_window_ids) - log.debug("Difference: %s", diff) - log.debug("New windows detected") + log.debug("New window IDs detected: %s", window_ids) + log.debug("Current tracked windows IDs: %s", current_window_ids) + log.debug("Window IDs set difference: %s", diff) window_ids |= diff set_steam_game_property(d_secondary, diff, steam_appid) From 5144f8879f4b820caecdbd1c631c6db38f961de6 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:36:11 -0800 Subject: [PATCH 13/15] umu_run: remove non-existent imported var --- umu/umu_run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index ffee54e7a..9088bc162 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -33,7 +33,7 @@ from Xlib.protocol.rq import Event from Xlib.xobject.drawable import Window -from umu import __container_runtime__, __version__ +from umu import __version__ from umu.umu_consts import ( PR_SET_CHILD_SUBREAPER, PROTON_VERBS, From 9fdabd3a06d160067fbbcbb003bfea39aef3be4b Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sat, 23 Nov 2024 22:40:00 -0800 Subject: [PATCH 14/15] umu_test: update symbols in tests --- umu/umu_test.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/umu/umu_test.py b/umu/umu_test.py index 4f5218012..1852851ca 100644 --- a/umu/umu_test.py +++ b/umu/umu_test.py @@ -207,7 +207,7 @@ def test_get_steam_layer_id(self): os.environ["STEAM_COMPAT_MEDIA_PATH"] = "foo" os.environ["STEAM_FOSSILIZE_DUMP_PATH"] = "bar" os.environ["DXVK_STATE_CACHE_PATH"] = "baz" - result = umu_run.get_steam_layer_id(os.environ) + result = umu_run.get_steam_appid(os.environ) self.assertEqual( result, @@ -270,7 +270,7 @@ def test_rearrange_gamescope_baselayer_order_none(self): # it has been tampered by the client or by some middleware. os.environ["STEAM_COMPAT_TRANSCODED_MEDIA_PATH"] = "/123" baselayer = [1, steam_window_id, steam_layer_id] - result = umu_run.rearrange_gamescope_baselayer_order(baselayer) + result = umu_run.rearrange_gamescope_baselayer_appid(baselayer) self.assertTrue(result is None, f"Expected None, received '{result}'") @@ -284,13 +284,13 @@ def test_rearrange_gamescope_baselayer_order_broken(self): """ steam_window_id = 769 os.environ["STEAM_COMPAT_TRANSCODED_MEDIA_PATH"] = "/123" - steam_layer_id = umu_run.get_steam_layer_id(os.environ) + steam_layer_id = umu_run.get_steam_appid(os.environ) baselayer = [1, steam_window_id, steam_layer_id] expected = ( [baselayer[0], steam_layer_id, steam_window_id], steam_layer_id, ) - result = umu_run.rearrange_gamescope_baselayer_order(baselayer) + result = umu_run.rearrange_gamescope_baselayer_appid(baselayer) self.assertEqual( result, @@ -303,7 +303,7 @@ def test_rearrange_gamescope_baselayer_order_invalid(self): baselayer = [] self.assertTrue( - umu_run.rearrange_gamescope_baselayer_order(baselayer) is None, + umu_run.rearrange_gamescope_baselayer_appid(baselayer) is None, "Expected None", ) @@ -311,9 +311,9 @@ def test_rearrange_gamescope_baselayer_order(self): """Test rearrange_gamescope_baselayer_order when passed a sequence.""" steam_window_id = 769 os.environ["STEAM_COMPAT_TRANSCODED_MEDIA_PATH"] = "/123" - steam_layer_id = umu_run.get_steam_layer_id(os.environ) + steam_layer_id = umu_run.get_steam_appid(os.environ) baselayer = [1, steam_layer_id, steam_window_id] - result = umu_run.rearrange_gamescope_baselayer_order(baselayer) + result = umu_run.rearrange_gamescope_baselayer_appid(baselayer) # Original sequence should be returned when Steam's window ID is last self.assertTrue( From 8b09771115b3494f30a28c0a085c0102a8d410e9 Mon Sep 17 00:00:00 2001 From: R1kaB3rN <100738684+R1kaB3rN@users.noreply.github.com> Date: Sun, 24 Nov 2024 00:02:34 -0800 Subject: [PATCH 15/15] umu_run: fix mypy lint --- umu/umu_run.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/umu/umu_run.py b/umu/umu_run.py index 9088bc162..d37042788 100755 --- a/umu/umu_run.py +++ b/umu/umu_run.py @@ -412,6 +412,7 @@ def get_gamescope_baselayer_appid( ) -> list[int] | None: """Get the GAMESCOPECTRL_BASELAYER_APPID value on the primary root window.""" try: + baselayer_appid: list[int] root_primary: Window = d.screen().root # Intern the atom for GAMESCOPECTRL_BASELAYER_APPID atom = d.get_atom(GamescopeAtom.BaselayerAppId.value) @@ -422,7 +423,8 @@ def get_gamescope_baselayer_appid( # For GAMESCOPECTRL_BASELAYER_APPID, the value is a u32 array if prop and prop.value and isinstance(prop.value, array): # Convert data to a Python list for safety - return prop.value.tolist() + baselayer_appid = prop.value.tolist() + return baselayer_appid log.debug("%s property not found", GamescopeAtom.BaselayerAppId.value) except Exception as e: log.error(