schmaldeo / DS4Windows

DS4Windows but maintained
GNU General Public License v3.0
113 stars 8 forks source link

Auto-profile loading by window title now working correctly #20

Closed TheManuel2 closed 1 month ago

TheManuel2 commented 1 month ago

Describe the bug Although DS4W has supported auto-profile loading by window title for a long time, in addition to by process (.exe), it has never really worked well. This is particularly useful for emulators where you might want to use your default profile for navigating the main interface, but then switch to a different profile when a game is loaded.
Most emulators change their window title when a game is loaded, so it's not hard to identify a character in the title that is common among games to load a different profile, but DS4W doesn't recognize the change unless you alt+Tab out of the emulator window and then go back to it.

To Reproduce Steps to reproduce the behavior:

  1. Identify the window titles of any emulator with and without loading a game
  2. Assign an auto profile to the emulator but use the window title field and try to use one of the 3 methods (beginning of string, end of string, and contains a string) so that the profile only loads when the emulator loads a game

Expected behavior Your auto-profile should load only when a game is launched, but not when the emulator is idle just showing its GUI

Screenshots and Logs I'll be happy to provide any logs that might be helpful

Desktop (please complete the following information):

Additional context My main use case is that I often use the controller as mouse so my default profile is used by Controller Companion to navigate Windows, but when I load a game in an emulator, I switch to an auto profile that only has the escape key mapped to the guide button, because I like to use each emulator's native DS4 support. I hope this is not too niche that it would not be worthwhile fixing the auto-profiles feature.

Thanks for picking up DS4Windows!!!

major-sanyi commented 1 month ago

I will look into adding new string operator(s).

TheManuel2 commented 1 month ago

Here are a non-working example and a working example (sort-of):

Yuzu (auto-profiles don't work):

Dolphin (the "sort-of" working example):

Please let me know if you need more information, and thank you again.

schmaldeo commented 1 month ago

I'll work on it today or tomorrow, I think I know what the issue is and how to handle it (SetWinEventHook for EVENT_OBJECT_NAMECHANGE) :))

TheManuel2 commented 1 month ago

Awesome!

schmaldeo commented 1 month ago

It's available in v3.8.2. It works with what I've checked, please check if it works for you and let me know, so I can close the issue if it does :)

Technical notes: didn't use the win event hook for it as the current implementation kinda works around what could be achieved with NT API functions. Instead I'm actually checking for title change in the function that processes current foreground window. It doesn't seem to cause any memory problems + it uses a slightly different implementation of the GetWindowText that uses a char* instead of a StringBuilder. The function uses stackalloc, so the memory is freed as soon as the function returns, therefore any memory leaks should not be a problem.

I also added the Microsoft.Windows.CsWin32 library and I'm planning to modify all the code that interacts with Windows APIs to use this library instead of using the DllImported functions, as in my opinion it's a massive QoL improvement for developers (provides all the types and functions that you want).

TheManuel2 commented 1 month ago

That sounds awesome! I’m eager to try this when I get home tonight.

TheManuel2 commented 1 month ago

I just tested the fixes with 5 different emulators, and it works great, with one exception: Ryujinx.

When opening the emulator's main window, the default profile stays active as it should, and when I launch a game the auto-profile kicks in correctly. However, when stopping emulation (Esc key) and the GUI shows up again, DS4W stays stuck on the loaded auto-profile and does not return to the default one. I tried 4 different window title strings: - bit )$ bit)$

With yuzu everything works beautifully when launching and sopping games. Likewise with Dolphin, although that one always worked well. RPCS3 and CEMU work great too, but those don't have a way to stop emulation and returning to the GUI, so I can't verify if returning from a game relinquishes the auto-profile, nor does it matter on those emulators anyway if emulation can't be stopped :-)

schmaldeo commented 1 month ago

There was a small issue with the logic that's now fixed and available in v3.8.3. Once again, please let me know if it works as you requested.

TheManuel2 commented 1 month ago

Yes! That fixed it. Looks like everything is working great now. Thank you very much!