mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 14:20:42 -07:00
graphics: fix window position if out of bounds (#630)
## Link to GitHub Issue or related Pull Request, if one exists #618 ## Description of change Before calling `CreateWindowEx[A/W]`, check dimensions of the window about to be created, and check if it will be out of bounds (completely or partially). If it's completely out of bounds, move it to `(0, 0)` to prevent crashes or rendering issues. ## Testing Tested popn and sdvx.
This commit is contained in:
@@ -368,6 +368,10 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC
|
||||
}
|
||||
}
|
||||
|
||||
if (GRAPHICS_WINDOWED) {
|
||||
graphics_window_check_bounds_before_creation(x, y, nWidth, nHeight);
|
||||
}
|
||||
|
||||
// call original
|
||||
HWND result = CreateWindowExA_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
|
||||
hWndParent, hMenu, hInstance, lpParam);
|
||||
@@ -468,6 +472,10 @@ static HWND WINAPI CreateWindowExW_hook(DWORD dwExStyle, LPCWSTR lpClassName, LP
|
||||
}
|
||||
}
|
||||
|
||||
if (GRAPHICS_WINDOWED) {
|
||||
graphics_window_check_bounds_before_creation(x, y, nWidth, nHeight);
|
||||
}
|
||||
|
||||
// call original
|
||||
HWND result = CreateWindowExW_orig(
|
||||
dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
|
||||
|
||||
@@ -108,6 +108,7 @@ bool graphics_window_decoration_change_crashes_game();
|
||||
bool graphics_window_resize_breaks_game();
|
||||
bool graphics_window_move_and_resize_breaks_game();
|
||||
void graphics_load_windowed_subscreen_parameters();
|
||||
void graphics_window_check_bounds_before_creation(int &x, int &y, const int width, const int height);
|
||||
|
||||
void change_primary_monitor(const std::string &monitor_name);
|
||||
void update_monitor_on_boot(std::optional<graphics_orientation> target_orientation, UINT target_refresh_rate);
|
||||
@@ -560,3 +560,56 @@ bool graphics_window_resize_breaks_game() {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void graphics_window_check_bounds_before_creation(int &x, int &y, const int width, const int height) {
|
||||
RECT rect = {
|
||||
.left = x,
|
||||
.top = y,
|
||||
.right = x + width,
|
||||
.bottom = y + height
|
||||
};
|
||||
|
||||
HMONITOR mon = MonitorFromRect(&rect, MONITOR_DEFAULTTONULL);
|
||||
if (mon != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_warning(
|
||||
"graphics-windowed",
|
||||
"window is completely out of bounds, resetting position: ({}, {}) => (0, 0)",
|
||||
x, y);
|
||||
x = 0;
|
||||
y = 0;
|
||||
rect = {
|
||||
.left = x,
|
||||
.top = y,
|
||||
.right = x + width,
|
||||
.bottom = y + height
|
||||
};
|
||||
|
||||
mon = MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO mi = {};
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (!GetMonitorInfo(mon, &mi)) {
|
||||
log_warning(
|
||||
"graphics-windowed",
|
||||
"failed to get monitor info for out of bounds window");
|
||||
return;
|
||||
}
|
||||
|
||||
log_misc(
|
||||
"graphics-windowed",
|
||||
"nearest monitor for this window has work area ({}, {}),({}, {})",
|
||||
mi.rcWork.left, mi.rcWork.top, mi.rcWork.right, mi.rcWork.bottom);
|
||||
|
||||
RECT bounds = mi.rcWork;
|
||||
const bool fully_visible =
|
||||
(rect.left >= bounds.left &&
|
||||
rect.top >= bounds.top &&
|
||||
rect.right <= bounds.right &&
|
||||
rect.bottom <= bounds.bottom);
|
||||
|
||||
if (!fully_visible) {
|
||||
log_warning("graphics-windowed", "window will not be fully visible on monitor");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user