@@ -35,9 +35,17 @@ with this program. If not, see <https://www.gnu.org/licenses/>
3535interval = (float)(t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;\
3636obs_log(LOG_INFO, "Done in %f milliseconds", interval);
3737
38- static const char * IGNORES [] = {
38+ // Would ideally use regex, but don't feel like setting up PCRE as a dependency.
39+ static const char * IGNORED_NAMES [] = {
40+ "GameBar" ,
41+ "NVIDIA Overlay" ,
42+ "Widgets" ,
43+ "TabTip" ,
44+ };
45+
46+ static const char * IGNORED_PATHS [] = {
3947"C:\\Windows\\" ,
40- "C:\\Program Files\\Common Files\\microsoft shared\\"
48+ "C:\\Program Files\\Common Files\\microsoft shared\\" ,
4149};
4250
4351OBS_DECLARE_MODULE ()
@@ -51,15 +59,21 @@ void on_frontend_event(enum obs_frontend_event event, void *data)
5159TIMER_START
5260
5361char * replay_path = obs_frontend_get_last_replay ();
62+ if (!replay_path ) {
63+ obs_log (LOG_ERROR , "Failed to fetch the last replay" );
64+ return ;
65+ }
5466
55- char game_path [MAX_PATH ];
56- if (get_active_window_path ( game_path , MAX_PATH ) == FAILURE ) {
67+ char window_name [MAX_PATH ];
68+ if (get_active_window_name ( window_name , MAX_PATH ) == FAILURE ) {
5769bfree (replay_path );
70+ obs_log (LOG_ERROR , "Failed to get active window" );
5871return ;
5972}
6073
61- if (move_file_to_new_location (replay_path , game_path ) == FAILURE ) {
74+ if (move_file_to_new_location (replay_path , window_name ) == FAILURE ) {
6275bfree (replay_path );
76+ obs_log (LOG_ERROR , "Failed to move recording" );
6377return ;
6478}
6579
@@ -107,26 +121,13 @@ bool is_fullscreen(HWND hwnd)
107121wp .rcNormalPosition .bottom >= rc_desktop .bottom );
108122}
109123
110- BOOL starts_with (const char * str , const char * prefix )
111- {
112- if (!str || !prefix ) {
113- return FALSE;
114- }
115-
116- size_t prefix_len = strlen (prefix );
117- size_t str_len = strlen (str );
118- if (prefix_len > str_len ) {
119- return FALSE;
120- }
121-
122- return strncmp (str , prefix , prefix_len ) == 0 ;
123- }
124-
125- int get_active_window_path (char * buffer , int buffer_size )
124+ int get_active_window_name (char * buffer , int buffer_size )
126125{
127- HWND hwnd = NULL ;
126+ // Window with the highest Z index
127+ HWND hwnd = GetTopWindow (GetDesktopWindow ());
128128
129- while ((hwnd = FindWindowEx (NULL , hwnd , NULL , NULL )) != NULL ) {
129+ // Iterate windows from highest Z index to lowest
130+ do {
130131if (!is_fullscreen (hwnd ))
131132continue ;
132133
@@ -136,21 +137,35 @@ int get_active_window_path(char *buffer, int buffer_size)
136137if (is_ignored_path (buffer ))
137138continue ;
138139
140+ // Window name instead of exe name. Not great because some windows have other info, e.g. firefox has the tab name etc.
141+ // At the same time exe name is also not great because it's not always descriptive, e.g. The Finals is running from Discovery.exe
142+ //GetWindowTextA(hwnd, buffer, buffer_size);
143+
144+ _splitpath_s (buffer , NULL , 0 , NULL , 0 , buffer , MAX_PATH , NULL , 0 );
145+
146+ if (is_ignored_name (buffer ))
147+ continue ;
148+
139149return SUCCESS ;
140- }
150+ } while ( hwnd = GetWindow ( hwnd , GW_HWNDNEXT ));
141151
142152// Default to foreground (active) window
143153obs_log (LOG_INFO , "Defaulting to foreground window" );
144154HWND foreground = GetForegroundWindow ();
155+
145156if (!foreground )
146157return FAILURE ;
147158
148- wchar_t wide_buffer [MAX_PATH ];
149- GetWindowText (foreground , wide_buffer , MAX_PATH );
150- convert_tchar_to_char (wide_buffer , buffer , sizeof (buffer ));
159+ if (get_executable_path (foreground , buffer , buffer_size ) == FAILURE )
160+ return FAILURE ;
161+
162+ _splitpath_s (buffer , NULL , 0 , NULL , 0 , buffer , MAX_PATH , NULL , 0 );
163+
164+ if (is_ignored_name (buffer ))
165+ return FAILURE ;
151166
152167return SUCCESS ;
153- }
168+ }
154169
155170int get_executable_path (HWND hwnd , char * buffer , int buffer_size )
156171{
@@ -162,52 +177,58 @@ int get_executable_path(HWND hwnd, char *buffer, int buffer_size)
162177return FAILURE ;
163178}
164179
165- TCHAR executable_path [MAX_PATH ];
166- if (GetModuleFileNameEx (h_process , NULL , executable_path , MAX_PATH ) == 0 ) {
180+ if (GetModuleFileNameExA (h_process , NULL , buffer , MAX_PATH ) == 0 ) {
167181CloseHandle (h_process );
168182return FAILURE ;
169183}
170184
171185CloseHandle (h_process );
172186
173- convert_tchar_to_char (executable_path , buffer , buffer_size );
174-
175187return SUCCESS ;
176188}
177189
178190BOOL is_ignored_path (const char * path )
179191{
180- for (size_t i = 0 ; i < sizeof (IGNORES ) / sizeof (IGNORES [0 ]); i ++ ) {
181- if (starts_with (path , IGNORES [i ])) {
192+ for (size_t i = 0 ; i < sizeof (IGNORED_PATHS ) / sizeof (IGNORED_PATHS [0 ]); i ++ ) {
193+ if (strstr (path , IGNORED_PATHS [i ])) {
182194return TRUE;
183195}
184196}
197+
185198return FALSE;
186199}
187200
188- int move_file_to_new_location (const char * source_file_path , const char * window_file_path )
201+ BOOL is_ignored_name (const char * name )
189202{
190- // 1. Get executable name, e.g. C:\Games\game.exe -> game
191- char window_name [MAX_PATH ];
192- _splitpath_s (window_file_path , NULL , 0 , NULL , 0 , window_name , MAX_PATH , NULL , 0 );
203+ for (size_t i = 0 ; i < sizeof (IGNORED_NAMES ) / sizeof (IGNORED_NAMES [0 ]); i ++ ) {
204+ if (strcmp (name , IGNORED_NAMES [i ]) == 0 ) {
205+ return TRUE;
206+ }
207+ }
193208
194- // 2. Get the replay buffer base folder
209+ return FALSE;
210+ }
211+
212+ int move_file_to_new_location (const char * source_file_path , const char * window_name )
213+ {
214+ // 1. Get the replay buffer base folder
195215char source_dir [MAX_PATH ];
196216if (get_path_without_file (source_file_path , source_dir ) == FAILURE )
197217return FAILURE ;
198218
199- // 3 . Construct the new file path
219+ // 2 . Construct the new file path
200220char new_dir [MAX_PATH ];
201221snprintf (new_dir , MAX_PATH , "%s/%s" , source_dir , window_name );
202222char new_file_path [MAX_PATH ];
203223snprintf (new_file_path , MAX_PATH , "%s/%s" , new_dir , strrchr (source_file_path , '/' ) + 1 );
204224
205- // 4 . Create the directory if it doesn't exist
225+ // 3 . Create the directory if it doesn't exist
206226CreateDirectoryA (new_dir , NULL );
207227
208- // 5 . Move recording
228+ // 4 . Move recording
209229obs_log (LOG_INFO , "Moving %s to %s" , source_file_path , new_file_path );
210- if (!MoveFileA (source_file_path , new_file_path ))
230+
231+ if (!MoveFileA (source_file_path , new_file_path ))
211232return FAILURE ;
212233
213234return SUCCESS ;
@@ -228,12 +249,3 @@ int get_path_without_file(const char *full_path, char *path_without_file)
228249
229250return SUCCESS ;
230251}
231-
232- void convert_tchar_to_char (const wchar_t * source , char * dest , size_t dest_size )
233- {
234- #ifdef _UNICODE
235- wcstombs_s (NULL , dest , dest_size , source , _TRUNCATE );
236- #else
237- strncpy_s (dest , dest_size , source , _TRUNCATE );
238- #endif
239- }
0 commit comments