Skip to content

Commit 2bf4e53

Browse files
committed
- ignore a couple window names
- use "A" window apis (do not convert between wide char and char) - loop windows from the highest Z index
1 parent 72134d7 commit 2bf4e53

File tree

3 files changed

+68
-56
lines changed

3 files changed

+68
-56
lines changed

buildspec.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
},
3939
"name": "replay-buffer-move-to-folder",
4040
"displayName": "Replay Buffer - move to folder",
41-
"version": "1.0.0",
41+
"version": "1.1.0",
4242
"author": "Yelov",
4343
"website": "https://github.com/YelovSK/replay-buffer-move-to-folder",
4444
"email": "hampatrik@gmail.com",

src/plugin-main.c

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,17 @@ with this program. If not, see <https://www.gnu.org/licenses/>
3535
interval = (float)(t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;\
3636
obs_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

4351
OBS_DECLARE_MODULE()
@@ -51,15 +59,21 @@ void on_frontend_event(enum obs_frontend_event event, void *data)
5159
TIMER_START
5260

5361
char *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) {
5769
bfree(replay_path);
70+
obs_log(LOG_ERROR, "Failed to get active window");
5871
return;
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) {
6275
bfree(replay_path);
76+
obs_log(LOG_ERROR, "Failed to move recording");
6377
return;
6478
}
6579

@@ -107,26 +121,13 @@ bool is_fullscreen(HWND hwnd)
107121
wp.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 {
130131
if (!is_fullscreen(hwnd))
131132
continue;
132133

@@ -136,21 +137,35 @@ int get_active_window_path(char *buffer, int buffer_size)
136137
if (is_ignored_path(buffer))
137138
continue;
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+
139149
return SUCCESS;
140-
}
150+
} while (hwnd = GetWindow(hwnd, GW_HWNDNEXT));
141151

142152
// Default to foreground (active) window
143153
obs_log(LOG_INFO, "Defaulting to foreground window");
144154
HWND foreground = GetForegroundWindow();
155+
145156
if (!foreground)
146157
return 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

152167
return SUCCESS;
153-
}
168+
}
154169

155170
int 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)
162177
return 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) {
167181
CloseHandle(h_process);
168182
return FAILURE;
169183
}
170184

171185
CloseHandle(h_process);
172186

173-
convert_tchar_to_char(executable_path, buffer, buffer_size);
174-
175187
return SUCCESS;
176188
}
177189

178190
BOOL 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])) {
182194
return TRUE;
183195
}
184196
}
197+
185198
return 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
195215
char source_dir[MAX_PATH];
196216
if (get_path_without_file(source_file_path, source_dir) == FAILURE)
197217
return FAILURE;
198218

199-
// 3. Construct the new file path
219+
// 2. Construct the new file path
200220
char new_dir[MAX_PATH];
201221
snprintf(new_dir, MAX_PATH, "%s/%s", source_dir, window_name);
202222
char new_file_path[MAX_PATH];
203223
snprintf(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
206226
CreateDirectoryA(new_dir, NULL);
207227

208-
// 5. Move recording
228+
// 4. Move recording
209229
obs_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))
211232
return FAILURE;
212233

213234
return SUCCESS;
@@ -228,12 +249,3 @@ int get_path_without_file(const char *full_path, char *path_without_file)
228249

229250
return 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-
}

src/plugin-support.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ extern const char *PLUGIN_VERSION;
3535
void obs_log(int log_level, const char *format, ...);
3636
extern void blogva(int log_level, const char *format, va_list args);
3737

38-
int get_active_window_path(char *buffer, int buffer_size);
38+
int get_active_window_name(char *buffer, int buffer_size);
3939
BOOL is_ignored_path(const char *path);
40+
BOOL is_ignored_name(const char *name);
4041
int get_executable_path(HWND hwnd, char *buffer, int buffer_size);
41-
BOOL move_file_to_new_location(const char *source_file_path, const char *exe_file_path);
42+
BOOL move_file_to_new_location(const char *source_file_path, const char *exe_file_path);
4243
int get_path_without_file(const char *full_path, char *path_without_file);
43-
void convert_tchar_to_char(const wchar_t *source, char *dest, size_t dest_size);
4444

4545
#ifdef __cplusplus
4646
}

0 commit comments

Comments
 (0)