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;
|
||||
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()) {
|
||||
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
|
||||
Variant *sizep = &size;
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
windows[window_id].rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce);
|
||||
}
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
Rect2i window_client_rect;
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
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.
|
||||
if (window_w > 0 && window_h > 0 && !windows[window_id].preserve_window_size) {
|
||||
windows[window_id].width = window_w;
|
||||
windows[window_id].height = window_h;
|
||||
WINDOWPOS *window_pos_params = (WINDOWPOS *)lParam;
|
||||
WindowData &window = windows[window_id];
|
||||
|
||||
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 (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
|
||||
|
||||
} 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);
|
||||
rect_changed = true;
|
||||
}
|
||||
} else { // When the window has been minimized, preserve its size.
|
||||
windows[window_id].preserve_window_size = true;
|
||||
}
|
||||
|
||||
// Call windows rect change callback.
|
||||
if (!windows[window_id].rect_changed_callback.is_null()) {
|
||||
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
|
||||
Variant *size_ptr = &size;
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
windows[window_id].rect_changed_callback.call((const Variant **)&size_ptr, 1, ret, ce);
|
||||
if (!window.minimized && (!(window_pos_params->flags & SWP_NOMOVE) || window_pos_params->flags & SWP_FRAMECHANGED)) {
|
||||
window.last_pos = window_client_rect.position;
|
||||
rect_changed = true;
|
||||
}
|
||||
|
||||
// The window has been maximized.
|
||||
if (wParam == SIZE_MAXIMIZED) {
|
||||
windows[window_id].maximized = true;
|
||||
windows[window_id].minimized = false;
|
||||
if (rect_changed) {
|
||||
if (!window.rect_changed_callback.is_null()) {
|
||||
Variant size = Rect2i(window.last_pos.x, window.last_pos.y, window.width, window.height);
|
||||
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;
|
||||
GetWindowRect(hWnd, &r);
|
||||
dib_size = Size2i(r.right - r.left, r.bottom - r.top);
|
||||
// Return here to prevent WM_MOVE and WM_SIZE from being sent
|
||||
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-windowposchanged#remarks
|
||||
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;
|
||||
|
||||
case WM_ENTERSIZEMOVE: {
|
||||
Input::get_singleton()->release_pressed_events();
|
||||
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;
|
||||
|
||||
bool preserve_window_size = false;
|
||||
bool pre_fs_valid = false;
|
||||
RECT pre_fs_rect;
|
||||
bool maximized = false;
|
||||
|
|
Loading…
Reference in New Issue