// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #if PLATFORM_SDL && PLATFORM_WINDOWS #include "SDLPlatform.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Platform/WindowsManager.h" #include "Engine/Platform/Win32/IncludeWindowsHeaders.h" #include "Engine/Input/Mouse.h" #include #include #include #include #include "SDLInput.h" #include #if true extern Window* draggedWindow; Float2 draggedWindowStartPosition = Float2::Zero; Float2 draggedWindowMousePosition = Float2::Zero; // The events for releasing the mouse during window dragging are missing, handle the mouse release event here bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg) { #define GET_WINDOW_WITH_HWND(window, hwnd) \ do { \ (window) = nullptr; \ WindowsManager::WindowsLocker.Lock(); \ for (int32 i = 0; i < WindowsManager::Windows.Count(); i++) \ { \ if (WindowsManager::Windows[i]->GetNativePtr() == (hwnd)) \ { \ (window) = WindowsManager::Windows[i]; \ break; \ } \ } \ WindowsManager::WindowsLocker.Unlock(); \ ASSERT((window) != nullptr); \ } while (false) if (draggedWindow != nullptr) { LOG(Info, "event hook message: {}", msg->message); } if (msg->message == WM_NCLBUTTONDOWN) { Window* window; GET_WINDOW_WITH_HWND(window, msg->hwnd); draggedWindow = window; draggedWindowStartPosition = draggedWindow->GetClientPosition(); Float2 mousePos(static_cast(static_cast(WINDOWS_GET_X_LPARAM(msg->lParam))), static_cast(static_cast(WINDOWS_GET_Y_LPARAM(msg->lParam)))); draggedWindowMousePosition = mousePos; draggedWindowMousePosition -= draggedWindowStartPosition; bool result = false; WindowHitCodes hit = static_cast(msg->wParam); window->OnHitTest(mousePos, hit, result); //if (result && hit != WindowHitCodes::Caption) // return false; if (hit == WindowHitCodes::Caption) { SDL_Event event{ 0 }; event.button.type = SDL_EVENT_MOUSE_BUTTON_DOWN; event.button.down = true; event.button.timestamp = SDL_GetTicksNS(); event.button.windowID = SDL_GetWindowID(window->GetSDLWindow()); event.button.button = SDL_BUTTON_LEFT; event.button.clicks = 1; event.button.x = draggedWindowMousePosition.X; event.button.y = draggedWindowMousePosition.Y; SDL_PushEvent(&event); } } /*else if (msg->message == WM_NCLBUTTONUP || msg->message == WM_CAPTURECHANGED) { windowDragging = false; Window* window; GET_WINDOW_WITH_HWND(window, msg->hwnd); SDL_Event event{ 0 }; event.button.type = SDL_EVENT_MOUSE_BUTTON_UP; event.button.down = false; event.button.timestamp = SDL_GetTicksNS(); event.button.windowID = SDL_GetWindowID(window->GetSDLWindow()); event.button.button = SDL_BUTTON_LEFT; event.button.clicks = 1; event.button.x = static_cast(static_cast(WINDOWS_GET_X_LPARAM(msg->lParam))); event.button.y = static_cast(static_cast(WINDOWS_GET_Y_LPARAM(msg->lParam))); SDL_PushEvent(&event); }*/ return true; #undef GET_WINDOW_WITH_HWND } #endif bool SDLPlatform::InitPlatform() { #if true // Workaround required for handling window dragging events properly for DockHintWindow SDL_SetWindowsMessageHook(&EventMessageHook, nullptr); #endif if (WindowsPlatform::Init()) return true; return false; } bool SDLPlatform::UsesWindows() { return true; } bool SDLPlatform::UsesWayland() { return false; } bool SDLPlatform::UsesXWayland() { return false; } bool SDLPlatform::UsesX11() { return false; } void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable) { // Other supported values: "permonitor", "permonitorv2" SDL_SetHint("SDL_WINDOWS_DPI_AWARENESS", enable ? "system" : "unaware"); } #endif