Simplify DisplayServerWindows pos/size message handling
Replace WM_MOVE and WM_SIZE message handling with WM_POSCHANGED instead. This is for multiple reasons: 1) Microsoft suggest using WM_POSCHANGED is more efficient 2) RectChanged callback is only called once for most window operations 3) Simplifies message handling code
This commit is contained in:
parent
2c85f2a8f6
commit
d14165dae9
@ -2646,98 +2646,72 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case WM_MOVE: {
|
|
||||||
if (!IsIconic(windows[window_id].hWnd)) {
|
|
||||||
int x = int16_t(LOWORD(lParam));
|
|
||||||
int y = int16_t(HIWORD(lParam));
|
|
||||||
windows[window_id].last_pos = Point2(x, y);
|
|
||||||
|
|
||||||
if (!windows[window_id].rect_changed_callback.is_null()) {
|
case WM_WINDOWPOSCHANGED: {
|
||||||
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
|
Rect2i window_client_rect;
|
||||||
Variant *sizep = &size;
|
{
|
||||||
Variant ret;
|
RECT rect;
|
||||||
Callable::CallError ce;
|
GetClientRect(hWnd, &rect);
|
||||||
windows[window_id].rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce);
|
ClientToScreen(hWnd, (POINT *)&rect.left);
|
||||||
}
|
ClientToScreen(hWnd, (POINT *)&rect.right);
|
||||||
|
window_client_rect = Rect2i(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
|
||||||
}
|
}
|
||||||
} break;
|
|
||||||
case WM_SIZE: {
|
|
||||||
// Ignore window size change when a SIZE_MINIMIZED event is triggered.
|
|
||||||
if (wParam != SIZE_MINIMIZED) {
|
|
||||||
// The new width and height of the client area.
|
|
||||||
int window_w = LOWORD(lParam);
|
|
||||||
int window_h = HIWORD(lParam);
|
|
||||||
|
|
||||||
// Set new value to the size if it isn't preserved.
|
WINDOWPOS *window_pos_params = (WINDOWPOS *)lParam;
|
||||||
if (window_w > 0 && window_h > 0 && !windows[window_id].preserve_window_size) {
|
WindowData &window = windows[window_id];
|
||||||
windows[window_id].width = window_w;
|
|
||||||
windows[window_id].height = window_h;
|
bool rect_changed = false;
|
||||||
|
if (!(window_pos_params->flags & SWP_NOSIZE) || window_pos_params->flags & SWP_FRAMECHANGED) {
|
||||||
|
int screen_id = window_get_current_screen(window_id);
|
||||||
|
Size2i screen_size = screen_get_size(screen_id);
|
||||||
|
Point2i screen_position = screen_get_position(screen_id);
|
||||||
|
|
||||||
|
window.maximized = false;
|
||||||
|
window.minimized = false;
|
||||||
|
window.fullscreen = false;
|
||||||
|
|
||||||
|
if (IsIconic(hWnd)) {
|
||||||
|
window.minimized = true;
|
||||||
|
} else if (IsZoomed(hWnd)) {
|
||||||
|
window.maximized = true;
|
||||||
|
} else if (window_client_rect.position == screen_position && window_client_rect.size == screen_size) {
|
||||||
|
window.fullscreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.minimized) {
|
||||||
|
window.width = window_client_rect.size.width;
|
||||||
|
window.height = window_client_rect.size.height;
|
||||||
|
|
||||||
#if defined(VULKAN_ENABLED)
|
#if defined(VULKAN_ENABLED)
|
||||||
if (context_vulkan && window_created) {
|
if (context_vulkan && window_created) {
|
||||||
context_vulkan->window_resize(window_id, windows[window_id].width, windows[window_id].height);
|
context_vulkan->window_resize(window_id, window.width, window.height);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
rect_changed = true;
|
||||||
} else { // If the size is preserved.
|
|
||||||
windows[window_id].preserve_window_size = false;
|
|
||||||
|
|
||||||
// Restore the old size.
|
|
||||||
window_set_size(Size2(windows[window_id].width, windows[window_id].height), window_id);
|
|
||||||
}
|
}
|
||||||
} else { // When the window has been minimized, preserve its size.
|
|
||||||
windows[window_id].preserve_window_size = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call windows rect change callback.
|
if (!window.minimized && (!(window_pos_params->flags & SWP_NOMOVE) || window_pos_params->flags & SWP_FRAMECHANGED)) {
|
||||||
if (!windows[window_id].rect_changed_callback.is_null()) {
|
window.last_pos = window_client_rect.position;
|
||||||
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
|
rect_changed = true;
|
||||||
Variant *size_ptr = &size;
|
|
||||||
Variant ret;
|
|
||||||
Callable::CallError ce;
|
|
||||||
windows[window_id].rect_changed_callback.call((const Variant **)&size_ptr, 1, ret, ce);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The window has been maximized.
|
if (rect_changed) {
|
||||||
if (wParam == SIZE_MAXIMIZED) {
|
if (!window.rect_changed_callback.is_null()) {
|
||||||
windows[window_id].maximized = true;
|
Variant size = Rect2i(window.last_pos.x, window.last_pos.y, window.width, window.height);
|
||||||
windows[window_id].minimized = false;
|
const Variant *args[] = { &size };
|
||||||
|
Variant ret;
|
||||||
|
Callable::CallError ce;
|
||||||
|
window.rect_changed_callback.call(args, 1, ret, ce);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// The window has been minimized.
|
|
||||||
else if (wParam == SIZE_MINIMIZED) {
|
|
||||||
windows[window_id].maximized = false;
|
|
||||||
windows[window_id].minimized = true;
|
|
||||||
windows[window_id].preserve_window_size = false;
|
|
||||||
}
|
|
||||||
// The window has been resized, but neither the SIZE_MINIMIZED nor SIZE_MAXIMIZED value applies.
|
|
||||||
else if (wParam == SIZE_RESTORED) {
|
|
||||||
windows[window_id].maximized = false;
|
|
||||||
windows[window_id].minimized = false;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
if (is_layered_allowed() && layered_window) {
|
|
||||||
DeleteObject(hBitmap);
|
|
||||||
|
|
||||||
RECT r;
|
// Return here to prevent WM_MOVE and WM_SIZE from being sent
|
||||||
GetWindowRect(hWnd, &r);
|
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-windowposchanged#remarks
|
||||||
dib_size = Size2i(r.right - r.left, r.bottom - r.top);
|
return 0;
|
||||||
|
|
||||||
BITMAPINFO bmi;
|
|
||||||
ZeroMemory(&bmi, sizeof(BITMAPINFO));
|
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
bmi.bmiHeader.biWidth = dib_size.x;
|
|
||||||
bmi.bmiHeader.biHeight = dib_size.y;
|
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
|
||||||
bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4;
|
|
||||||
hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, nullptr, 0x0);
|
|
||||||
SelectObject(hDC_dib, hBitmap);
|
|
||||||
|
|
||||||
ZeroMemory(dib_data, dib_size.x * dib_size.y * 4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case WM_ENTERSIZEMOVE: {
|
case WM_ENTERSIZEMOVE: {
|
||||||
Input::get_singleton()->release_pressed_events();
|
Input::get_singleton()->release_pressed_events();
|
||||||
windows[window_id].move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
|
windows[window_id].move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
|
||||||
|
@ -326,7 +326,6 @@ class DisplayServerWindows : public DisplayServer {
|
|||||||
|
|
||||||
Vector<Vector2> mpath;
|
Vector<Vector2> mpath;
|
||||||
|
|
||||||
bool preserve_window_size = false;
|
|
||||||
bool pre_fs_valid = false;
|
bool pre_fs_valid = false;
|
||||||
RECT pre_fs_rect;
|
RECT pre_fs_rect;
|
||||||
bool maximized = false;
|
bool maximized = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user