mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-27 19:19:41 +08:00
Moved window state change handling from WM_WINDOWPOSCHANGING to WM_WINDOWPOSCHANGED
Applications might override WM_WINDOWPOSCHANGING which would prevent us from getting the correct window state. This also fixes cases where the window doesn't get WM_SHOWWINDOW, as described in Raymond Chen's blog post: https://devblogs.microsoft.com/oldnewthing/20080115-00/?p=23813
This commit is contained in:
@@ -1088,92 +1088,97 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
case WM_WINDOWPOSCHANGING:
|
case WM_WINDOWPOSCHANGING:
|
||||||
{
|
{
|
||||||
WINDOWPOS *windowpos = (WINDOWPOS*)lParam;
|
WINDOWPOS *windowpos = (WINDOWPOS*)lParam;
|
||||||
|
if (!IsIconic(hwnd) &&
|
||||||
|
!IsZoomed(hwnd) &&
|
||||||
|
(data->window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED)) &&
|
||||||
|
!(data->window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||||
|
/* Use the stored floating size if moving from a fixed-size to floating state. */
|
||||||
|
int fx, fy, fw, fh;
|
||||||
|
|
||||||
if (data->expected_resize) {
|
WIN_AdjustWindowRect(data->window, &fx, &fy, &fw, &fh, SDL_WINDOWRECT_FLOATING);
|
||||||
returnCode = 0;
|
windowpos->x = fx;
|
||||||
}
|
windowpos->y = fy;
|
||||||
|
windowpos->cx = fw;
|
||||||
if (IsIconic(hwnd)) {
|
windowpos->cy = fh;
|
||||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
windowpos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE);
|
||||||
} else if (IsZoomed(hwnd)) {
|
|
||||||
if (data->window->flags & SDL_WINDOW_MINIMIZED) {
|
|
||||||
/* If going from minimized to maximized, send the restored event first. */
|
|
||||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
|
||||||
}
|
|
||||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
|
|
||||||
} else {
|
|
||||||
SDL_bool was_fixed_size = !!(data->window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED));
|
|
||||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
|
||||||
|
|
||||||
/* Send the stored floating size if moving from a fixed-size to floating state. */
|
|
||||||
if (was_fixed_size && !(data->window->flags & SDL_WINDOW_FULLSCREEN)) {
|
|
||||||
int fx, fy, fw, fh;
|
|
||||||
|
|
||||||
WIN_AdjustWindowRect(data->window, &fx, &fy, &fw, &fh, SDL_WINDOWRECT_FLOATING);
|
|
||||||
windowpos->x = fx;
|
|
||||||
windowpos->y = fy;
|
|
||||||
windowpos->cx = fw;
|
|
||||||
windowpos->cy = fh;
|
|
||||||
windowpos->flags &= ~(SWP_NOSIZE | SWP_NOMOVE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case WM_WINDOWPOSCHANGED:
|
case WM_WINDOWPOSCHANGED:
|
||||||
{
|
{
|
||||||
SDL_Window *win;
|
SDL_Window *win;
|
||||||
RECT rect;
|
|
||||||
int x, y;
|
|
||||||
int w, h;
|
|
||||||
const SDL_DisplayID original_displayID = data->last_displayID;
|
const SDL_DisplayID original_displayID = data->last_displayID;
|
||||||
|
const WINDOWPOS *windowpos = (WINDOWPOS *)lParam;
|
||||||
|
const SDL_bool moved = !(windowpos->flags & SWP_NOMOVE);
|
||||||
|
const SDL_bool resized = !(windowpos->flags & SWP_NOSIZE);
|
||||||
|
const SDL_bool iconic = IsIconic(hwnd);
|
||||||
|
const SDL_bool zoomed = IsZoomed(hwnd);
|
||||||
|
|
||||||
if (data->initializing || data->in_border_change) {
|
if (windowpos->flags & SWP_SHOWWINDOW) {
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_SHOWN, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconic) {
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
|
||||||
|
} else if (zoomed) {
|
||||||
|
if (data->window->flags & SDL_WINDOW_MINIMIZED) {
|
||||||
|
/* If going from minimized to maximized, send the restored event first. */
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||||
|
}
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
|
||||||
|
} else if (data->window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED)) {
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (windowpos->flags & SWP_HIDEWINDOW) {
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_HIDDEN, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!moved && !resized) {
|
||||||
|
/* Nothing left to handle */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When the window is minimized it's resized to the dock icon size, ignore this */
|
/* When the window is minimized it's resized to the dock icon size, ignore this */
|
||||||
if (IsIconic(hwnd)) {
|
if (iconic) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetClientRect(hwnd, &rect) || WIN_IsRectEmpty(&rect)) {
|
if (data->initializing) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClientToScreen(hwnd, (LPPOINT)&rect);
|
|
||||||
ClientToScreen(hwnd, (LPPOINT)&rect + 1);
|
if (moved) {
|
||||||
|
RECT rect;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) {
|
||||||
|
ClientToScreen(hwnd, (LPPOINT)&rect);
|
||||||
|
ClientToScreen(hwnd, (LPPOINT)&rect + 1);
|
||||||
|
|
||||||
|
x = rect.left;
|
||||||
|
y = rect.top;
|
||||||
|
|
||||||
|
SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y);
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resized) {
|
||||||
|
RECT rect;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
/* Moving the window from one display to another can change the size of the window (in the handling of SDL_EVENT_WINDOW_MOVED), so we need to re-query the bounds */
|
||||||
|
if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) {
|
||||||
|
w = rect.right;
|
||||||
|
h = rect.bottom;
|
||||||
|
|
||||||
|
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WIN_UpdateClipCursor(data->window);
|
WIN_UpdateClipCursor(data->window);
|
||||||
|
|
||||||
x = rect.left;
|
|
||||||
y = rect.top;
|
|
||||||
|
|
||||||
SDL_GlobalToRelativeForWindow(data->window, x, y, &x, &y);
|
|
||||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MOVED, x, y);
|
|
||||||
|
|
||||||
// Moving the window from one display to another can change the size of the window (in the handling of SDL_EVENT_WINDOW_MOVED), so we need to re-query the bounds
|
|
||||||
if (GetClientRect(hwnd, &rect)) {
|
|
||||||
ClientToScreen(hwnd, (LPPOINT)&rect);
|
|
||||||
ClientToScreen(hwnd, (LPPOINT)&rect + 1);
|
|
||||||
|
|
||||||
WIN_UpdateClipCursor(data->window);
|
|
||||||
|
|
||||||
x = rect.left;
|
|
||||||
y = rect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = rect.right - rect.left;
|
|
||||||
h = rect.bottom - rect.top;
|
|
||||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_RESIZED, w, h);
|
|
||||||
|
|
||||||
#ifdef HIGHDPI_DEBUG
|
|
||||||
SDL_Log("WM_WINDOWPOSCHANGED: Windows client rect (pixels): (%d, %d) (%d x %d)\tSDL client rect (points): (%d, %d) (%d x %d) windows reported dpi %d",
|
|
||||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
|
||||||
x, y, w, h, data->videodata->GetDpiForWindow ? data->videodata->GetDpiForWindow(data->hwnd) : 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Forces a WM_PAINT event */
|
|
||||||
InvalidateRect(hwnd, NULL, FALSE);
|
|
||||||
|
|
||||||
/* Update the window display position */
|
/* Update the window display position */
|
||||||
data->last_displayID = SDL_GetDisplayForWindow(data->window);
|
data->last_displayID = SDL_GetDisplayForWindow(data->window);
|
||||||
|
|
||||||
@@ -1189,6 +1194,10 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
WIN_SetWindowPositionInternal(win, SWP_NOCOPYBITS | SWP_NOACTIVATE, SDL_WINDOWRECT_CURRENT);
|
WIN_SetWindowPositionInternal(win, SWP_NOCOPYBITS | SWP_NOACTIVATE, SDL_WINDOWRECT_CURRENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Forces a WM_PAINT event */
|
||||||
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
|
|||||||
Reference in New Issue
Block a user