sonic2kk / steamtinkerlaunch

Linux wrapper tool for use with the Steam client for custom launch options and 3rd party programs
GNU General Public License v3.0
2.17k stars 73 forks source link

Program started by forked custom command not accessible (GUI and/or shortcuts) #710

Closed berniyh closed 1 year ago

berniyh commented 1 year ago

Hi,

first, thank you for providing steamtinkerlaunch. :)

System Information

Issue Description

I'm running a game (American Truck Simulator via proton) and for that I want to use a head tracker as an input device. I already installed everything needed for the head tracker (linuxtrack), including the wine parts, but for the game to see it, I have to run the Controller.exe before the game starts within the same prefix. So I use the forked custom command capability that steamtinkerlauncher provides and that works, i.e. the tracker camera starts and I can use the head tracking in the game. However, I have two issues with this and I'm not sure here if I'm doing something wrong, if it is an issue within steamtinkerlauncher or maybe it's a proton issue:

  1. The Controller.exe has a GUI where I can set shortcuts. This doesn't open when I start it as the custom command. I never see the window (But it is started, since the tracking works). When I start it manually via wine, I can see the window.
  2. The shortcuts I set for the Controller.exe (tried multiple ones, with and without modifier keys) don't work, e.g. I can't recenter or pause the tracking Is it expected that programs apart from the main window can't grab keys?

Logs

steamtinkerlaunch.log.gz

sonic2kk commented 1 year ago

Hi! Thanks for opening an issue, the information you provided has been very helpful, in particular the log.

First off, I haven't used this custom program before and I also don't own any head tracking equipment, so I may make some incorrect assumptions or have the wrong idea about some things. Given that you have tested this under Wine and it works (thanks for testing this btw), I see no reason why it shouldn't work with SteamTinkerLaunch, so something is definitely going wrong here.

When SteamTinkerLaunch runs a custom command, basically it just runs it with the current game's Proton and in that game's Wineprefix. When it runs that command forked, it runs that given program and the game at the same time.

From what I can see in the code and logs, it seems like it also launches that custom executable from the directory its installed in -- So if you had an executable in something like /home/gaben/Downloads/HalfLife3/hl3.exe, it would cd /home/gaben/Downloads/HalfLife3 and then launch the executable. Then, before the game launches, it would cd back to the directory the script was in previously.

On the subject of EXEs, SteamTinkerLaunch lets you launch both Windows executables (including .bat files) and regular Linux executables like scripts. It tries to determine if a program is a Windows executable and if it is, it launches it with Proton, otherwise it tries to run it as a Linux executable and leaves it up to the system to decide -- We'll come to back to this in a second! :-)


With that background out of the way, onto the issues you described. We'll start with the Controller.exe program.

In the log, these are the relevant lines that I can see:

Fri Jan 6 08:14:36 PM CET 2023 INFO - prepareLaunch - CheckCustomLaunch: Fri Jan 6 08:14:36 PM CET 2023 INFO - checkCustomLaunch - USECUSTOMCMD is set to '1' - trying to start custom program '/home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880.bak/pfx/drive_c/Program Files (x86)/Linuxtrack/Controller.exe' Fri Jan 6 08:14:36 PM CET 2023 INFO - checkCustomLaunch - FORK_CUSTOMCMD is set to 1 - forking the custom program in background and continue Fri Jan 6 08:14:36 PM CET 2023 INFO - launchCustomProg - '/home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880.bak/pfx/drive_c/Program Files (x86)/Linuxtrack/Controller.exe' found Fri Jan 6 08:14:36 PM CET 2023 INFO - launchCustomProg - Changed pwd into the custom directory '/home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880.bak/pfx/drive_c/Program Files (x86)/Linuxtrack' Fri Jan 6 08:14:36 PM CET 2023 INFO - launchCustomProg - '/home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880.bak/pfx/drive_c/Program Files (x86)/Linuxtrack/Controller.exe' doesn't seem to be a MS Windows exe - regular start (without further analysing) Fri Jan 6 08:14:36 PM CET 2023 INFO - launchCustomProg - FORK_CUSTOMCMD is set to 1 - forking the custom program in background and continue Fri Jan 6 08:14:36 PM CET 2023 INFO - launchCustomProg - Changing pwd into previous directory

You may have already spotted a problem, the line that says '<exe path>' doesn't seem to be a MS Windows exe - regular start (without further analysing) -- In this instance, SteamTinkerLaunch's logic for launching a custom program (the launchCustomProg function) thinks that it isn't dealing with a Windows executable, and so it isn't trying to launch it through Proton.

What could be happening here is that when left up to the system to decide how to launch the custom command, somehow it is able to launch it through Wine, but perhaps it is using your system Wine and using the default Wine prefix, which may not be fully compatible with the program. I would also suggest making absolutely, positively sure that the program is being started by SteamTinkerLaunch, and that there is no lingering process :-) I have made mistakes like this in the past. You can check things like this using a System Monitor/Activity Monitor tool, your desktop environment may come with one.

I'm not sure why it doesn't think it's a Windows program. The logic that SteamTinkerLaunch uses to determine if something can boil down to this for our purposes. You can paste this into a terminal and see the output:

if [ "$(file "/home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880.bak/pfx/drive_c/Program Files (x86)/Linuxtrack/Controller.exe" | grep -c "PE32")" -eq 1 ]; then echo "This looks like a Windows program"; else "This is not a Windows program, for some reason"; fi

It is possible that the .bak in the prefix filename is throwing the file command off, but I doubt it. It might also be helpful to run the following command as well and look at the output:

file "/home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880.bak/pfx/drive_c/Program Files (x86)/Linuxtrack/Controller.exe"

A regular exe will return something like PE32 executable (GUI) Intel 80386, for MS Windows, I tested with a few executables on my system and this is what it returned. The grep part of the earlier if statement basically checks if the result of the file command comes back with PE32 in its result, and for some reason it seems like from your log that this check is failing, suggesting that PE32 is not returned anywhere in the result of the file command on that executable. That's why I gave those two commands for you to try, so we can see the output that SteamTinkerLaunch is trying to evaluate against.


Now, for the second issue!

SteamTinkerLaunch has no logic that tries to restrict any sort of key capture. I think that this issue may be related to the first, in that the Controller program may not be running correctly and that is resulting in the key capture not working.

It might be worth trying a different version of Proton than Proton 7.0-5 to run this game, which will change the Proton version used for the custom command as well. Sometimes vanilla Proton does not play nice, and GE-Proton or Proton-tkg can work better (though GE-Proton7-43 has a couple of issues with other third party programs e.g. MO2). No guarantees though, I still think that the issue is that the program you're trying to run is not running properly through SteamTinkerLaunch, and so the input capture is failing.


One note I would like to make as well is that you should make sure any necessary Wine components are installed into the American Truck Simulator prefix. You mentioned there were some Wine components needed (maybe Winetricks?), so I would just like to point out that they'll need to be installed into the game's prefix if they aren't already. That shouldn't be the root issue at the moment since I think the root issue is that SteamTinkerLaunch doesn't think it's launching a Windows program. But it may be useful to know generally.

This may not be the case here either, but I have some general tips that may be useful when using custom commands.

Some custom programs need to be launched before or after a game to work. SteamTinkerLaunch lets you set this for custom commands, so the custom program will launch and then you can set a delay before the game launches, and vice versa.

To launch a custom command before a game, you can use the "Wait for custom command" option. This option is a value in seconds to wait before starting a game. If you know your custom program needs, say, 30 seconds to fully start up, you can set this to 30 seconds and then SteamTinkerLaunch will launch the game executable. I am editing this message to say I just re-read your issue and noticed you mentioned this:

I have to run the Controller.exe before the game starts within the same prefix.

Sorry for missing this the first time, but using the "Wait custom command" option may also be required for you. I didn't see if you used this in your log and I double checked, I could've still missed it though :sweat_smile: Perhaps this is a useful tidbit though. If you need Controller.exe to run before the game, this is the way to do it.

To launch a custom program after a game, you can use the "Inject custom command" checkbox and then set a value in seconds for the "Inject wait" value. This is a value in seconds to wait before launching a custom command. If you know that your game needs to be open or perhaps in a certain state before the command should open, you could give yourself something like 300 seconds before the custom program will start up.


Okay, that was a long reply. That's basically the results of my investigation so far and the information I have to give.

tl;dr - SteamTinkerLaunch doesn't think it's being given a Windows program to launch and we need to figure out why, because with its current logic it won't try to run a program with Wine/Proton if it doesn't think it's being given a Windows program. I haven't encountered this before so a bit more debugging may be needed, but there is a chance be related to the path of the program. It is probably more likely that the result of the file command is not what SteamTinkerLaunch is expecting, and so its if check is failing.

Thanks for the well-structured bug report and background information :-)

berniyh commented 1 year ago

Thanks a lot for the detailed answer. I investigated some more and there are a couple of things here. First, thanks for spotting the .bak thing. That was unintentional. I created a backup of the prefix a couple of months ago, for completely different reasons. I simply picked the wrong path ... In the end, it shouldn't matter, because linuxtrack was installed in both and the files are identical, so it should work either way. Anyway, to be sure, I moved both of these out of the way and started with a new prefix and the problem persists, so it's not that.

I already tried running it outside the prefix with a very recent wine version and unfortunately that does not work, it has to be run in the same prefix. Or rather with the same wineserver instance, I think. I'm not an expert on wine things.

What I did try is to run only the Controller.exe via proton, i.e. the first try was the ONLY_CUSTOMCMD by steamtinkerlaunch and that does not work, it exits almost instantly. More on that later on. Next thing I tried to run it via proton, but from within steam. For that I used

/home/berniyh/Games/SteamLibrary/steamapps/common/"Proton 7.0"/dist/bin/wine /home/berniyh/Games/SteamLibrary/steamapps/compatdata/270880/pfx/drive_c/"Program Files"/Linuxtrack/Controller.exe; echo %command%

as the launch option in steam and this does work. The program spawns and I can set the keys. This basically taught me a couple of things.

  1. The problem with the file type is very likely the problem with steamtinkerlaunch. btw:
    $ file Controller.exe 
    Controller.exe: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=1269cf0e433e15b9c07b81b3ddbbfd4ff6995d46, with debug_info, not stripped
  2. The keyboard shortcuts work, but only as long as the window has focus. i.e. wine applications can't have global shortcuts/hotkeys? I verified this by running Controller.exe outside of proton using regular wine. I spent some time researching this and I'm actually really shocked by this, there is almost nothing to be found about this topic. There are some tutorials, which make use of xdotool, but I'm not sure whether going that route is really a good idea, since xdotool is basically dead. I really would've thought that this is a more common problem and that wine has some mechanisms integrated for global shortcut/hotkey handling

In any case, the shortcut/hotkey thing isn't a problem with steamtinkerlaunch, but rather wine itself. The problem that remains is the handling of this type of executable.

sonic2kk commented 1 year ago

Thanks for verifying the path, I wasn't sure if .bak would be causing any issues or not. I suppose the command is intelligent enough to know to only check for files 😅

I'm not an expert with Wine stuff either, I've been using it for the last ~10 years so I just have accumulated knowledge. Running a program like this in the same prefix as the game is not unheard of so that sounds fine to me.

That's a really interesting find with the result of the file command too. I will have to do some research and see what exactly that ELF file type is. I don't want to change the code and then end up with a scenario where non-Windows programs are detected as Windows programs and a launch is attempted using Proton. So I'll need to do some testing and researching to see if the logic can simply be updated to also check for ELF.

Out of curiosity, is that executable Controller.exe a symlink? I'm not sure how the file command handles symlinks.

So pending a bit of research on my part, this should be a straightforward fix! The logic for checking the type name will likely need changed but I'll need to verify what exactly to change it to, just in case ELF is not right.

That's also really interesting about hotkeys not working. If I recall there is a program called AutoHotKey, I thought that it worked under Wine. In fact I think it can be installed with Winetricks. I thought that program allowed you to set game shortcuts so I also thought that global shortcuts worked with Wine applications. That is a bit of a shock to me as well!


Thanks for your collaboration on the issue, seems we know what's causing the problem now :-)

berniyh commented 1 year ago

That's a really interesting find with the result of the file command too. I will have to do some research and see what exactly that ELF file type is. I don't want to change the code and then end up with a scenario where non-Windows programs are detected as Windows programs and a launch is attempted using Proton. So I'll need to do some testing and researching to see if the logic can simply be updated to also check for ELF.

Or you could just add an option to force the custom command to go through wine. It's not like there aren't a zillion options already, so zillion+1 won't matter that much.

Out of curiosity, is that executable Controller.exe a symlink? I'm not sure how the file command handles symlinks.

So pending a bit of research on my part, this should be a straightforward fix! The logic for checking the type name will likely need changed but I'll need to verify what exactly to change it to, just in case ELF is not right.

No, but it's compiled on Linux, so that might be the reason. Still, it's a program that only runs through wine. For symlinks file will output that it's a symlink, unless you pass the option -L or --dereference, in which case it'll follow the symlink and output the file type.

That's also really interesting about hotkeys not working. If I recall there is a program called AutoHotKey, I thought that it worked under Wine. In fact I think it can be installed with Winetricks. I thought that program allowed you to set game shortcuts so I also thought that global shortcuts worked with Wine applications. That is a bit of a shock to me as well!

I know AHK. I'm using the Neo 2 keyboard layout and on Windows the most common implementation is based on AHK. I have never tried to use it directly though, so not sure about that. (Thankfully on Linux, it's just a layout variant for german, so using it is much easier than on Windows.) Quick research isn't conclusive on whether AHK would work on a global scale when started within wine: https://appdb.winehq.org/objectManager.php?sClass=version&iId=8043 But actually all of these results are really old, so I wouldn't bet on any of it holding true, could be better, could be worse.

There is also a specific port: https://appdb.winehq.org/objectManager.php?sClass=version&iId=17738 That again seems to use xdotool, so it's more or less the same as the howtos I found on the topic.

Thanks for your collaboration on the issue, seems we know what's causing the problem now :-)

You're welcome. ;)

sonic2kk commented 1 year ago

Or you could just add an option to force the custom command to go through wine. It's not like there aren't a zillion options already, so zillion+1 won't matter that much.

Yup, I was actually considering this as well! I think I will add this going forward. There could be a number of cases where it might be useful. It also seems like the most straightforward way to resolve this problem.

I checked a couple of Linux executables and they came back with ELF for some reason. I guess having an option to force a custom command to run with Wine is the best choice here, as I don't see another way to run these kinds of executables.

This is really good to know actually, because I want to add an option to run native Linux programs with the One-Time Run option which currently only supports running programs through Proton. I was planning on mirroring the checks used for the custom command but it's good to know that some additional work may be required for that functionality.

For symlinks file will output that it's a symlink, unless you pass the option -L or --dereference, in which case it'll follow the symlink and output the file type.

Ah! I wasn't sure if it would or not, which is why I asked. I haven't really used the command before today, so that's useful to know. It's unrelated but I actually don't think STL follows symlinks in this case and it may be worth looking into ensuring symlinked EXE files are followed, and if not it may need to be passed this -L option.


For the research on global shortcuts with Wine, boy some of those tests are super old, I see what you mean. I did some quick searching too and like you said it all seems to rely on xdotool, which as you also aluded to is quite a legacy tool. It also isn't future-proof, as Wayland adoption increases it will become less viable to rely on this, and once desktops start defaulting to it and Wine gets Wayland support, this may not be an option at all.

I am not sure what the best solution to this problem is. I am also quite surprised that there isn't more on this, I would've thought this would be an issue sooner. Perhaps you could ask around on some subreddits or IRC channels, though I wouldn't be too sure where to point you. Sorry that I can't do much to resolve this particular problem.


It shouldn't be too much work to add that force option. Once it's added I'll note it here, though it will only be able in SteamTinkerLaunch-git. Feel free to test once it's implemented if you're able, the linked AUR package or other installation methods should work (the Makefile has an uninstall option if you want/need to "build" from source, so you can easily remove it if you need to).

I'll try and get it added ASAP :-)

sonic2kk commented 1 year ago

Actually from looking at the codebase, a number of places in the STL codebase expect file to return PE32 including the check for Windows/Linux games. Interesting, I guess the case like this one is the exception rather than the rule.

Maybe in future there could be an option to force a game as a Windows game too, in case a Windows exe is not correctly detected.

sonic2kk commented 1 year ago

Work on this was pushed in 77e0772. Not sure yet if it will fix the issue but in my own tests the logging around this implementation looked correct, so STL should now use Proton with custom executables if the checkbox is enabled.

This checkbox is on the Game Menu with the other custom command options, and is called "Force Proton with custom command". There is also logging in the steamtinkerlaunch.log that notes when this option has been force enabled.

The SteamTinkerLaunch version was also bumped with this change. The version is v12.12.20230108-1. If you cannot see the checkbox or run into strange issues with the UI, these can be fixed by running rm -rf /dev/shm/steamtinkerlaunch to clear out some temp files. This is what I do during development as sometimes changes do not come into effect when running from source.

With some luck this should get the executable running! :-)

berniyh commented 1 year ago

ELF (Executable and Link Format) is the unix format for executables. The binary is most likely like this because it was created with gcc and ld and there was no cross-compiling. As you noted, PE (Portable Executable) is the corresponding format in the Windows world. I don't know if wine has some special handling for ELF, but obviously it can run ELF Windows programs.

I need to do some checks (e.g. whether the hotkey only persists in this particular program or if it's also the case with other programs), but if those align, then I'll report a bug to wine where I also outline the future problems regarding Wayland that you mentioned.

I'll give the git version a try later on and report back to you.

berniyh commented 1 year ago

Ok, tested it with -git and now it works when I select the force proton option. Also works as designed when forking and continuing with the normal start. Basically everything is fine now, from your perspective. ;) Thanks for the quick help! :)

The other issue, I'll have to figure out another way.

sonic2kk commented 1 year ago

Woohoo, glad to hear it's working! It's a shame about the other issue but I hope you can get it resolved. Feel free to comment on #457 if you find a solution and we could document the steps to get shortcuts working.

Something that may be useful is a tool called ydotool, which is a similar idea to xdotool but it doesn't depend on Xorg. From what I have seen it is not a drop-in replacement for xdotool (and isn't trying to be) but it may let you do similar things. I'm not too sure, I haven't looked into it very extensively (I used it to mess around with an autoclicker for Cookie Clicker :sweat_smile:) but maybe it could be a hint :-)

Good luck and happy tinkering!