mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40: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
|
// call original
|
||||||
HWND result = CreateWindowExA_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
|
HWND result = CreateWindowExA_orig(dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
|
||||||
hWndParent, hMenu, hInstance, lpParam);
|
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
|
// call original
|
||||||
HWND result = CreateWindowExW_orig(
|
HWND result = CreateWindowExW_orig(
|
||||||
dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight,
|
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_resize_breaks_game();
|
||||||
bool graphics_window_move_and_resize_breaks_game();
|
bool graphics_window_move_and_resize_breaks_game();
|
||||||
void graphics_load_windowed_subscreen_parameters();
|
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 change_primary_monitor(const std::string &monitor_name);
|
||||||
void update_monitor_on_boot(std::optional<graphics_orientation> target_orientation, UINT target_refresh_rate);
|
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;
|
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