graphics: fix window resize not working properly in some games (#530)

## Link to GitHub Issue, if one exists
n/a

## Description of change
Need to filter out system-created windows (such as `CicMarshalWnd`) when
looking up which window to mess with when user interacts with F11 menu.

While I'm here, clean up the hack for gfdm arena model that remembers
the main window.

## Testing
Tested:

DDR
gfdm arena 4 / 1 window modes
iidx (windowed mode, with/without nosub option)
sdvx with sub windows

Need to check:
full screen games
This commit is contained in:
bicarus
2026-01-22 19:06:31 -08:00
committed by GitHub
parent cb59fe14e9
commit cd14ca800e
4 changed files with 35 additions and 24 deletions
+16 -13
View File
@@ -61,7 +61,6 @@ bool GRAPHICS_SHOW_CURSOR = false;
graphics_orientation GRAPHICS_ADJUST_ORIENTATION = ORIENTATION_NORMAL; graphics_orientation GRAPHICS_ADJUST_ORIENTATION = ORIENTATION_NORMAL;
bool GRAPHICS_WINDOWED = false; bool GRAPHICS_WINDOWED = false;
std::vector<HWND> GRAPHICS_WINDOWS; std::vector<HWND> GRAPHICS_WINDOWS;
std::optional<HWND> GRAPHICS_WINDOW_MAIN;
UINT GRAPHICS_FORCE_REFRESH = 0; UINT GRAPHICS_FORCE_REFRESH = 0;
std::optional<uint32_t> GRAPHICS_FORCE_REFRESH_SUB; std::optional<uint32_t> GRAPHICS_FORCE_REFRESH_SUB;
std::optional<int> GRAPHICS_FORCE_VSYNC_BUFFER; std::optional<int> GRAPHICS_FORCE_VSYNC_BUFFER;
@@ -403,12 +402,10 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC
} }
// gfdm // gfdm
bool is_gitadora_main_window = false;
if (avs::game::is_model({"J32", "J33", "K32", "K33", "L32", "L33", "M32"})) { if (avs::game::is_model({"J32", "J33", "K32", "K33", "L32", "L33", "M32"})) {
// set window name // set window name
if (!lpWindowName) { if (!lpWindowName) {
lpWindowName = "GITADORA"; lpWindowName = "GITADORA";
is_gitadora_main_window = true;
} }
} }
@@ -451,11 +448,6 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC
hWndParent, hMenu, hInstance, lpParam); hWndParent, hMenu, hInstance, lpParam);
GRAPHICS_WINDOWS.push_back(result); GRAPHICS_WINDOWS.push_back(result);
// this is only really needed for arena model, but pre-arena model was single window anyway
if (is_gitadora_main_window) {
GRAPHICS_WINDOW_MAIN = result;
}
if (is_tdj_sub_window) { if (is_tdj_sub_window) {
// TDJ windowed mode: remember the subscreen window handle for later // TDJ windowed mode: remember the subscreen window handle for later
TDJ_SUBSCREEN_WINDOW = result; TDJ_SUBSCREEN_WINDOW = result;
@@ -479,7 +471,12 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC
} }
disable_touch_indicators(result); disable_touch_indicators(result);
log_misc("graphics", "CreateWindowExA returned {}", fmt::ptr(result)); log_misc(
"graphics",
"CreateWindowExA returned {}, {}",
fmt::ptr(result),
lpWindowName ? lpWindowName : "(null)");
return result; return result;
} }
@@ -511,7 +508,8 @@ static HWND WINAPI CreateWindowExW_hook(DWORD dwExStyle, LPCWSTR lpClassName, LP
} }
// windowed mode adjustments // windowed mode adjustments
if (GRAPHICS_WINDOWED) { // check the width to filter out invisible system-created windows
if (GRAPHICS_WINDOWED && nWidth > 0) {
// change window style // change window style
dwExStyle = 0; dwExStyle = 0;
@@ -546,7 +544,12 @@ static HWND WINAPI CreateWindowExW_hook(DWORD dwExStyle, LPCWSTR lpClassName, LP
hWndParent, hMenu, hInstance, lpParam); hWndParent, hMenu, hInstance, lpParam);
GRAPHICS_WINDOWS.push_back(result); GRAPHICS_WINDOWS.push_back(result);
log_misc("graphics", "CreateWindowExW returned {}", fmt::ptr(result)); log_misc(
"graphics",
"CreateWindowExW returned {}, {}",
fmt::ptr(result),
lpWindowName ? ws2s(lpWindowName) : "(null)");
disable_touch_indicators(result); disable_touch_indicators(result);
return result; return result;
} }
@@ -713,7 +716,7 @@ static BOOL WINAPI SetWindowPos_hook(HWND hWnd, HWND hWndInsertAfter,
// prevent gitadora arena model from shifting windows around if the user has preferences // prevent gitadora arena model from shifting windows around if the user has preferences
if (GRAPHICS_WINDOWED && games::gitadora::is_arena_model() && if (GRAPHICS_WINDOWED && games::gitadora::is_arena_model() &&
GRAPHICS_WINDOW_MAIN.has_value() && hWnd == GRAPHICS_WINDOW_MAIN.value() && GRAPHICS_HOOKED_WINDOW.has_value() && hWnd == GRAPHICS_HOOKED_WINDOW.value() &&
cfg::SCREENRESIZE->enable_window_resize) { cfg::SCREENRESIZE->enable_window_resize) {
return TRUE; return TRUE;
} }
@@ -725,7 +728,7 @@ static BOOL WINAPI SetWindowPos_hook(HWND hWnd, HWND hWndInsertAfter,
static BOOL WINAPI ShowWindow_hook(HWND hWnd, int nCmdShow) { static BOOL WINAPI ShowWindow_hook(HWND hWnd, int nCmdShow) {
if (games::gitadora::is_arena_model() && if (games::gitadora::is_arena_model() &&
games::gitadora::ARENA_SINGLE_WINDOW && games::gitadora::ARENA_SINGLE_WINDOW &&
hWnd != GRAPHICS_WINDOW_MAIN) { hWnd != GRAPHICS_HOOKED_WINDOW) {
log_info("graphics", "ShowWindow_hook - hiding sub window {}", fmt::ptr(hWnd)); log_info("graphics", "ShowWindow_hook - hiding sub window {}", fmt::ptr(hWnd));
return true; return true;
} }
+1 -1
View File
@@ -31,7 +31,6 @@ extern bool GRAPHICS_SHOW_CURSOR;
extern bool GRAPHICS_WINDOWED; extern bool GRAPHICS_WINDOWED;
extern graphics_orientation GRAPHICS_ADJUST_ORIENTATION; extern graphics_orientation GRAPHICS_ADJUST_ORIENTATION;
extern std::vector<HWND> GRAPHICS_WINDOWS; extern std::vector<HWND> GRAPHICS_WINDOWS;
extern std::optional<HWND> GRAPHICS_WINDOW_MAIN;
extern UINT GRAPHICS_FORCE_REFRESH; extern UINT GRAPHICS_FORCE_REFRESH;
extern std::optional<uint32_t> GRAPHICS_FORCE_REFRESH_SUB; extern std::optional<uint32_t> GRAPHICS_FORCE_REFRESH_SUB;
extern std::optional<int> GRAPHICS_FORCE_VSYNC_BUFFER; extern std::optional<int> GRAPHICS_FORCE_VSYNC_BUFFER;
@@ -50,6 +49,7 @@ extern std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_WINDOW_SIZE;
extern std::optional<std::string> GRAPHICS_WINDOW_POS; extern std::optional<std::string> GRAPHICS_WINDOW_POS;
extern bool GRAPHICS_WINDOW_ALWAYS_ON_TOP; extern bool GRAPHICS_WINDOW_ALWAYS_ON_TOP;
extern bool GRAPHICS_WINDOW_BACKBUFFER_SCALE; extern bool GRAPHICS_WINDOW_BACKBUFFER_SCALE;
extern std::optional<HWND> GRAPHICS_HOOKED_WINDOW;
extern bool GRAPHICS_IIDX_WSUB; extern bool GRAPHICS_IIDX_WSUB;
extern std::optional<std::string> GRAPHICS_WSUB_SIZE; extern std::optional<std::string> GRAPHICS_WSUB_SIZE;
@@ -24,6 +24,7 @@ std::optional<std::pair<uint32_t, uint32_t>> GRAPHICS_WINDOW_SIZE;
std::optional<std::string> GRAPHICS_WINDOW_POS; std::optional<std::string> GRAPHICS_WINDOW_POS;
bool GRAPHICS_WINDOW_ALWAYS_ON_TOP = false; bool GRAPHICS_WINDOW_ALWAYS_ON_TOP = false;
bool GRAPHICS_WINDOW_BACKBUFFER_SCALE = false; bool GRAPHICS_WINDOW_BACKBUFFER_SCALE = false;
std::optional<HWND> GRAPHICS_HOOKED_WINDOW;
// IIDX Windowed Subscreen - starts out as false, enabled by IIDX module on pre-attach as needed // IIDX Windowed Subscreen - starts out as false, enabled by IIDX module on pre-attach as needed
bool GRAPHICS_IIDX_WSUB = false; bool GRAPHICS_IIDX_WSUB = false;
@@ -56,6 +57,8 @@ void graphics_capture_initial_window(HWND hWnd) {
graphics_load_windowed_parameters(); graphics_load_windowed_parameters();
GRAPHICS_HOOKED_WINDOW = hWnd;
cfg::SCREENRESIZE->init_window_style = GetWindowLong(hWnd, GWL_STYLE); cfg::SCREENRESIZE->init_window_style = GetWindowLong(hWnd, GWL_STYLE);
cfg::SCREENRESIZE->init_window_style_ex = GetWindowLong(hWnd, GWL_EXSTYLE); cfg::SCREENRESIZE->init_window_style_ex = GetWindowLong(hWnd, GWL_EXSTYLE);
@@ -67,8 +70,9 @@ void graphics_capture_initial_window(HWND hWnd) {
RECT rect; RECT rect;
if (!GetClientRect(hWnd, &rect)) { if (!GetClientRect(hWnd, &rect)) {
log_warning( log_warning(
"graphics", "graphics-windowed",
"graphics_capture_initial_window - GetClientRect failed, GLE: {}", "[{}] graphics_capture_initial_window - GetClientRect failed, GLE: {}",
fmt::ptr(hWnd),
GetLastError()); GetLastError());
return; return;
} }
@@ -80,7 +84,8 @@ void graphics_capture_initial_window(HWND hWnd) {
cfg::SCREENRESIZE->init_client_aspect_ratio = (float)client_w / (float)client_h; cfg::SCREENRESIZE->init_client_aspect_ratio = (float)client_w / (float)client_h;
log_debug( log_debug(
"graphics-windowed", "graphics-windowed",
"graphics_capture_initial_window initial window size {}x{}, ratio {}", "[{}] graphics_capture_initial_window initial window size {}x{}, ratio {}",
fmt::ptr(hWnd),
client_w, client_h, cfg::SCREENRESIZE->init_client_aspect_ratio); client_w, client_h, cfg::SCREENRESIZE->init_client_aspect_ratio);
// ensure frame size is captured // ensure frame size is captured
@@ -105,7 +110,8 @@ void graphics_capture_initial_window(HWND hWnd) {
// resize must be done before applying the border // resize must be done before applying the border
if (cfg::SCREENRESIZE->enable_window_resize) { if (cfg::SCREENRESIZE->enable_window_resize) {
log_info( log_info(
"graphics-windowed", "change window rect - window offset: {}x{}, client size: {}x{}", "graphics-windowed", "[{}] change window rect - window offset: {}x{}, client size: {}x{}",
fmt::ptr(hWnd),
cfg::SCREENRESIZE->window_offset_x, cfg::SCREENRESIZE->window_offset_x,
cfg::SCREENRESIZE->window_offset_y, cfg::SCREENRESIZE->window_offset_y,
cfg::SCREENRESIZE->client_width, cfg::SCREENRESIZE->client_width,
@@ -115,12 +121,13 @@ void graphics_capture_initial_window(HWND hWnd) {
// ddr hangs when window frame doesn't have overlapped // ddr hangs when window frame doesn't have overlapped
if (cfg::SCREENRESIZE->window_decoration != cfg::WindowDecorationMode::Default) { if (cfg::SCREENRESIZE->window_decoration != cfg::WindowDecorationMode::Default) {
log_info( log_info(
"graphics-windowed", "change window style - decoration: {}", "graphics-windowed", "[{}] change window style - decoration: {}",
fmt::ptr(hWnd),
cfg::SCREENRESIZE->window_decoration); cfg::SCREENRESIZE->window_decoration);
graphics_update_window_style(hWnd); graphics_update_window_style(hWnd);
} }
if (cfg::SCREENRESIZE->window_always_on_top) { if (cfg::SCREENRESIZE->window_always_on_top) {
log_info("graphics-windowed", "change window z-order - always on top"); log_info("graphics-windowed", "[{}] change window z-order - always on top", fmt::ptr(hWnd));
graphics_update_z_order(hWnd, true); graphics_update_z_order(hWnd, true);
} }
@@ -27,11 +27,12 @@ namespace overlay::windows {
} }
HWND ScreenResize::get_first_window() { HWND ScreenResize::get_first_window() {
// hack for gitadora arena model which races to create many windows // this is ideal
// so [0] is not always the main one if (GRAPHICS_HOOKED_WINDOW.has_value()) {
if (GRAPHICS_WINDOW_MAIN.has_value()) { return GRAPHICS_HOOKED_WINDOW.value();
return GRAPHICS_WINDOW_MAIN.value();
} }
// we typically do not want to check GRAPHICS_WINDOWS because it may include
// system windows (e.g., CicMarshalWnd)
if (GRAPHICS_WINDOWS.size() == 0) { if (GRAPHICS_WINDOWS.size() == 0) {
return NULL; return NULL;
} }