From c483d7681c45f61b05d1f4b3b2cb00bf80a2e77a Mon Sep 17 00:00:00 2001 From: Chapien Date: Sat, 22 Mar 2025 13:14:27 -0700 Subject: [PATCH 1/9] fix-wm-class.sh now runs while reaper process is running In order to move away from the per game sleep method, I have made it so that fix-wm-class.sh now runs as long as the reaper wrapper process is still running. Should work in 99.9% of cases, tested with UNDERTALE and Pillars. --- fix-wm-class.sh | 6 +++++- sif.py | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/fix-wm-class.sh b/fix-wm-class.sh index fd2c488..2a6a15e 100755 --- a/fix-wm-class.sh +++ b/fix-wm-class.sh @@ -1,3 +1,7 @@ #!/bin/sh WM_CLASS="$([ "$2" ] && echo "$2" || echo "$1")" -xdotool search --sync --name "$1" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ +reaper_pid=$(pidof reaper) +while kill -0 $reaper_pid 2> /dev/null; do + xdotool search --sync --name "$1" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ + sleep 1 +done \ No newline at end of file diff --git a/sif.py b/sif.py index 77363dd..a1d7291 100755 --- a/sif.py +++ b/sif.py @@ -210,8 +210,8 @@ def fix_launch_option(app_id, wm_name, wm_name_alt=""): wm_name, wm_name_alt, ) - elif wm_name == "Pillars of Eternity": - app["LaunchOptions"] += '& sleep 5 && %s "%s";' % (script, wm_name) + # elif wm_name == "Pillars of Eternity": + # app["LaunchOptions"] += '& sleep 5 && %s "%s";' % (script, wm_name) else: app["LaunchOptions"] += '& %s "%s";' % (script, wm_name) vdf.dump(loaded, open(conf_file, "w"), pretty=True) From 9a8aee2ead78ef5ed070db03d1a86679d7b597df Mon Sep 17 00:00:00 2001 From: Chapien Date: Sat, 22 Mar 2025 13:16:35 -0700 Subject: [PATCH 2/9] Removed commented out code --- sif.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/sif.py b/sif.py index a1d7291..a053ff6 100755 --- a/sif.py +++ b/sif.py @@ -210,8 +210,6 @@ def fix_launch_option(app_id, wm_name, wm_name_alt=""): wm_name, wm_name_alt, ) - # elif wm_name == "Pillars of Eternity": - # app["LaunchOptions"] += '& sleep 5 && %s "%s";' % (script, wm_name) else: app["LaunchOptions"] += '& %s "%s";' % (script, wm_name) vdf.dump(loaded, open(conf_file, "w"), pretty=True) From a2a3282960f6b1d875967d35614fe70c486640d0 Mon Sep 17 00:00:00 2001 From: Chapien Date: Sat, 26 Apr 2025 10:11:51 -0700 Subject: [PATCH 3/9] fix-wm-class.sh now monitors processes, and stops running once the process is ended. It extracts the last parameter as the Window Class, so the usasge needs to be fix-wm-class.sh %command% "WM_CLASS". Additionally, it works with gamemoderun, from what little testing I did. However, gamemoderun needs to go before everything else: gamemoderun fix-wm-class.sh %command% "WM_CLASS". Will work on the python script to fix that next. --- fix-wm-class.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/fix-wm-class.sh b/fix-wm-class.sh index 2a6a15e..cf39bac 100755 --- a/fix-wm-class.sh +++ b/fix-wm-class.sh @@ -1,7 +1,15 @@ #!/bin/sh -WM_CLASS="$([ "$2" ] && echo "$2" || echo "$1")" -reaper_pid=$(pidof reaper) -while kill -0 $reaper_pid 2> /dev/null; do - xdotool search --sync --name "$1" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ +LOG_FILE="/tmp/wmfix.log" +LAST=${@:$#} +WM_CLASS="$LAST" +echo "Starting process: $@" > $LOG_FILE +echo "Window Class: $WM_CLASS" >> $LOG_FILE +"$@" & +PID=$! +echo "Process ID: $PID" >> $LOG_FILE +while kill -0 $PID 2> /dev/null; do + echo "Process still running: $(date)" >> $LOG_FILE + xdotool search --sync --name "$LAST" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ sleep 1 -done \ No newline at end of file +done +echo "Process ended: $(date)" >> $LOG_FILE \ No newline at end of file From 4bd432cc67088001096d77973b845e4a165a9dc5 Mon Sep 17 00:00:00 2001 From: Chapien Date: Sat, 26 Apr 2025 10:49:18 -0700 Subject: [PATCH 4/9] Updated sif.py. It now: Finds all instances of %command% in an existing launch option array, and removes them. Strips out any excess whitespace and stores the launch options. Instead of appending to the existing options, the options are now overridden, with any existing options (barring %command%) going before fix-wm-class.sh. This is to facilitate the usage of things like mangohod or gamemoderun. for instance, say a game's launch options are currently gamemoderun %command%. Upon running sif.py, the new command will be gamemoderun PATH_TO_SIF/fix-wm-class.sh %command% WM_CLASS; Tested witn UNDERTALE and Pillars of Eternity. I do not know if it will work with WM_CLASS_ALT games, as at the moment fix-wm-class treats the very last argument it receives as WM_CLASS regardless of anything else. --- sif.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sif.py b/sif.py index a053ff6..85acb21 100755 --- a/sif.py +++ b/sif.py @@ -202,16 +202,19 @@ def fix_launch_option(app_id, wm_name, wm_name_alt=""): app = apps[app_id] if "LaunchOptions" not in app.keys(): app["LaunchOptions"] = "" - app["LaunchOptions"] = sub("&\\s/.*fix-wm-class\\.sh.*?;", "", app["LaunchOptions"]) + app["LaunchOptions"] = sub("\\s/.*fix-wm-class\\.sh.*?;", "", app["LaunchOptions"]) + app["LaunchOptions"] = sub("%command%", "", app["LaunchOptions"]) + launch_options = app["LaunchOptions"].strip() script = str(WM_CLASS_FIXER_SCRIPT) if wm_name_alt: - app["LaunchOptions"] += '& %s "%s" "%s";' % ( + app["LaunchOptions"] = '%s %s %%command%% "%s" "%s";' % ( + launch_options, script, wm_name, wm_name_alt, ) else: - app["LaunchOptions"] += '& %s "%s";' % (script, wm_name) + app["LaunchOptions"] = '%s %s %%command%% "%s";' % (launch_options, script, wm_name) vdf.dump(loaded, open(conf_file, "w"), pretty=True) From 2ac438628868927f358ed2682b7bb21d56feba69 Mon Sep 17 00:00:00 2001 From: Chapien Date: Sat, 26 Apr 2025 10:52:56 -0700 Subject: [PATCH 5/9] Removed logging. --- fix-wm-class.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fix-wm-class.sh b/fix-wm-class.sh index cf39bac..8e9e30d 100755 --- a/fix-wm-class.sh +++ b/fix-wm-class.sh @@ -1,15 +1,10 @@ #!/bin/sh -LOG_FILE="/tmp/wmfix.log" LAST=${@:$#} WM_CLASS="$LAST" -echo "Starting process: $@" > $LOG_FILE -echo "Window Class: $WM_CLASS" >> $LOG_FILE "$@" & PID=$! echo "Process ID: $PID" >> $LOG_FILE while kill -0 $PID 2> /dev/null; do - echo "Process still running: $(date)" >> $LOG_FILE xdotool search --sync --name "$LAST" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ sleep 1 -done -echo "Process ended: $(date)" >> $LOG_FILE \ No newline at end of file +done \ No newline at end of file From fe1b12c9f6568b58cbeb1f1b1565fc53dabdb97e Mon Sep 17 00:00:00 2001 From: Chapien Date: Sat, 26 Apr 2025 10:53:37 -0700 Subject: [PATCH 6/9] Removed logging, take 2 (I missed one) --- fix-wm-class.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/fix-wm-class.sh b/fix-wm-class.sh index 8e9e30d..8040500 100755 --- a/fix-wm-class.sh +++ b/fix-wm-class.sh @@ -3,7 +3,6 @@ LAST=${@:$#} WM_CLASS="$LAST" "$@" & PID=$! -echo "Process ID: $PID" >> $LOG_FILE while kill -0 $PID 2> /dev/null; do xdotool search --sync --name "$LAST" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ sleep 1 From 904610bdc3ff451ca5aa8f03470ea854c9c94e47 Mon Sep 17 00:00:00 2001 From: Chapien Date: Wed, 30 Apr 2025 19:48:22 -0700 Subject: [PATCH 7/9] Updated sif.py. WIP on fix-wm-class.sh I've fixed sif.py to account for the new launch options. I don't know much about regexes, so it *might* be a bit hacky, feel free to change it to be more optimal. However, I am still struggling with fix-wm-class.sh. It turns out, if you surround %command% with quotes, steam automatically inserts 'single quotes' around some of the arguments, breaking the %command%. Double quoting makes it even more nested. Regardless, fix-wm-class.sh now works with Undertale... But not with Pillars of Eternity. The game simply never launches. I suspect the spaces in the folder's name are responsible, so I tried launching it without removing the single quotes it generated. That did not change anything. Interestingly, Steam thinks POE is running without the single quote in args; otherwise, it instantly closes. Finally, I have to launch with $@. "$@" causes neither Undertale nor PoE to launch. Need advice. --- fix-wm-class.sh | 20 +++++++++++++++----- sif.py | 7 ++++--- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/fix-wm-class.sh b/fix-wm-class.sh index 8040500..30b20fc 100755 --- a/fix-wm-class.sh +++ b/fix-wm-class.sh @@ -1,9 +1,19 @@ #!/bin/sh -LAST=${@:$#} -WM_CLASS="$LAST" -"$@" & +WM_CLASS="$([ "$3" ] && echo "$3" || echo "$2")" +WM_NAME=$2 +echo $WM_CLASS > "/tmp/wmlog.log" +echo $WM_NAME >> "/tmp/wmlog.log" +echo $1 >> "/tmp/wmlog.log" +COMMAND=$(echo $1 | tr -d "'") +set -- "${COMMAND}" +echo $@ >> "/tmp/wmlog.log" +$@ & PID=$! +echo $PID >> "/tmp/wmlog.log" while kill -0 $PID 2> /dev/null; do - xdotool search --sync --name "$LAST" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ + xdotool search --sync --name "$WM_NAME" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ + echo "Still running $PID! at $(date)!" >> "/tmp/wmlog.log" sleep 1 -done \ No newline at end of file +done +echo "Completed execution at $(date)!" >> "/tmp/wmlog.log" +exit 0 \ No newline at end of file diff --git a/sif.py b/sif.py index 85acb21..8e33b82 100755 --- a/sif.py +++ b/sif.py @@ -207,14 +207,14 @@ def fix_launch_option(app_id, wm_name, wm_name_alt=""): launch_options = app["LaunchOptions"].strip() script = str(WM_CLASS_FIXER_SCRIPT) if wm_name_alt: - app["LaunchOptions"] = '%s %s %%command%% "%s" "%s";' % ( + app["LaunchOptions"] = '%s %s "%%command%%" "%s" "%s";' % ( launch_options, script, wm_name, wm_name_alt, ) else: - app["LaunchOptions"] = '%s %s %%command%% "%s";' % (launch_options, script, wm_name) + app["LaunchOptions"] = '%s %s "%%command%%" "%s";' % (launch_options, script, wm_name) vdf.dump(loaded, open(conf_file, "w"), pretty=True) @@ -232,7 +232,8 @@ def restore_launch_options(): for app_id in apps.keys(): app = apps[app_id] if "LaunchOptions" in app.keys(): - app["LaunchOptions"] = sub("&\\s/.*fix-wm-class\\.sh.*?;", "", app["LaunchOptions"]) + app["LaunchOptions"] = sub("\\s/.*fix-wm-class\\.sh.*?;", " %command%", app["LaunchOptions"]) + app["LaunchOptions"] = app["LaunchOptions"].strip() vdf.dump(loaded, open(conf_file, "w"), pretty=True) From 62a9c1dc4229d41b433582cb5830285c15fa6f65 Mon Sep 17 00:00:00 2001 From: Chapien Date: Sun, 4 May 2025 16:42:23 -0700 Subject: [PATCH 8/9] Implemented suggestions on fix-wm-class.sh. Should work now. One potential issue, any command line arguments after %command% will be stripped away along with everything after fix-wm-class.sh when running SIF. I can also see a scenario where, say a game runs like: `gamemoderun %command% --some-arg` SIF, if fix-window-class has never been run before, will likely put `gamemoderun --some-arg fix-wm-class.sh %command%` I think this will not work. That said, I don't have enough experience with regexes to fix this, and it's a bit beyond the scope of this change, I think. I believe we should merge this, and handle that behavior in another PR potentially? Alternatively I can try to make it work if pointed in the right direction. For now, I added a message to the users to double check their launch options (which I think they should do anyway): `print("\n * - added fix to game launch options. Please double check to ensure your launch options are correct.")` --- fix-wm-class.sh | 36 +++++++++++++++++++++--------------- sif.py | 11 ++++++++--- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/fix-wm-class.sh b/fix-wm-class.sh index 30b20fc..13f0d28 100755 --- a/fix-wm-class.sh +++ b/fix-wm-class.sh @@ -1,19 +1,25 @@ -#!/bin/sh -WM_CLASS="$([ "$3" ] && echo "$3" || echo "$2")" -WM_NAME=$2 -echo $WM_CLASS > "/tmp/wmlog.log" -echo $WM_NAME >> "/tmp/wmlog.log" -echo $1 >> "/tmp/wmlog.log" -COMMAND=$(echo $1 | tr -d "'") -set -- "${COMMAND}" -echo $@ >> "/tmp/wmlog.log" -$@ & +#!/usr/bin/env sh + +LOG_FILE="/tmp/steam_watcher.log" + +WM_NAME=$1 +echo "WM_NAME: $WM_NAME" > $LOG_FILE +shift +WM_NAME_ALT=$1 +echo "WM_NAME_ALT: $WM_NAME_ALT" >> $LOG_FILE +shift + +WM_CLASS=$WM_NAME_ALT + +echo "Starting process: $@" >> $LOG_FILE +"$@" & + PID=$! -echo $PID >> "/tmp/wmlog.log" +echo "Process ID: $PID" >> $LOG_FILE + while kill -0 $PID 2> /dev/null; do - xdotool search --sync --name "$WM_NAME" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ - echo "Still running $PID! at $(date)!" >> "/tmp/wmlog.log" - sleep 1 + xdotool search --sync --name "$WM_NAME" set_window --classname "$WM_CLASS" --class "$WM_CLASS" %@ + echo "Process still running: $(date)" >> $LOG_FILE + sleep 1 done -echo "Completed execution at $(date)!" >> "/tmp/wmlog.log" exit 0 \ No newline at end of file diff --git a/sif.py b/sif.py index 8e33b82..cd932a5 100755 --- a/sif.py +++ b/sif.py @@ -207,14 +207,19 @@ def fix_launch_option(app_id, wm_name, wm_name_alt=""): launch_options = app["LaunchOptions"].strip() script = str(WM_CLASS_FIXER_SCRIPT) if wm_name_alt: - app["LaunchOptions"] = '%s %s "%%command%%" "%s" "%s";' % ( + app["LaunchOptions"] = '%s %s "%s" "%s" %%command%%;' % ( launch_options, script, wm_name, wm_name_alt, ) else: - app["LaunchOptions"] = '%s %s "%%command%%" "%s";' % (launch_options, script, wm_name) + app["LaunchOptions"] = '%s %s "%s" "%s" %%command%%;' % ( + launch_options, + script, + wm_name, + wm_name, + ) vdf.dump(loaded, open(conf_file, "w"), pretty=True) @@ -719,7 +724,7 @@ def quit_handler(_, __): if steam_detected: print_warning("\nSome games couldn't be fixed due to running Steam.\nExit Steam and try it again.") else: - print("\n * - added fix to game launch options") + print("\n * - added fix to game launch options. Please double check to ensure your launch options are correct.") if options.pretend: print_warning("\nNo changes were made because --pretend option was used.") From 839b2debbdd9c993b06ce1ee1d6f72d0c7a2c0ba Mon Sep 17 00:00:00 2001 From: Chapien Date: Sun, 4 May 2025 16:45:46 -0700 Subject: [PATCH 9/9] Changed double check message. --- sif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sif.py b/sif.py index cd932a5..6d0c15d 100755 --- a/sif.py +++ b/sif.py @@ -724,7 +724,7 @@ def quit_handler(_, __): if steam_detected: print_warning("\nSome games couldn't be fixed due to running Steam.\nExit Steam and try it again.") else: - print("\n * - added fix to game launch options. Please double check to ensure your launch options are correct.") + print("\n * - added fix to game launch options. Double check your launch options just in case.") if options.pretend: print_warning("\nNo changes were made because --pretend option was used.")