Fix dragged maximized window generating wrong mouse position events
This commit is contained in:
@@ -394,7 +394,7 @@ public:
|
|||||||
Float2 position = window->ScreenToClient(screenPosition);
|
Float2 position = window->ScreenToClient(screenPosition);
|
||||||
SDL_WarpMouseInWindow(static_cast<SDLWindow*>(window)->_window, position.X, position.Y);
|
SDL_WarpMouseInWindow(static_cast<SDLWindow*>(window)->_window, position.X, position.Y);
|
||||||
|
|
||||||
OnMouseMoved(position);
|
OnMouseMoved(screenPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRelativeMode(bool relativeMode, Window* window) final override
|
void SetRelativeMode(bool relativeMode, Window* window) final override
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#if PLATFORM_SDL && PLATFORM_WINDOWS
|
#if PLATFORM_SDL && PLATFORM_WINDOWS
|
||||||
|
|
||||||
#define BORDERLESS_MAXIMIZE_WORKAROUND 2
|
|
||||||
|
|
||||||
#include "SDLPlatform.h"
|
#include "SDLPlatform.h"
|
||||||
#include "SDLInput.h"
|
#include "SDLInput.h"
|
||||||
|
|
||||||
@@ -23,13 +21,12 @@
|
|||||||
#include <oleidl.h>
|
#include <oleidl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX)
|
|
||||||
|
|
||||||
namespace WinImpl
|
namespace WinImpl
|
||||||
{
|
{
|
||||||
Window* DraggedWindow;
|
Window* DraggedWindow;
|
||||||
Float2 DraggedWindowStartPosition = Float2::Zero;
|
Float2 DraggedWindowStartPosition = Float2::Zero;
|
||||||
Float2 DraggedWindowMousePosition = Float2::Zero;
|
Float2 DraggedWindowMousePosition = Float2::Zero;
|
||||||
|
Float2 DraggedWindowSize = Float2::Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The events for releasing the mouse during window dragging are missing, handle the mouse release event here
|
// The events for releasing the mouse during window dragging are missing, handle the mouse release event here
|
||||||
@@ -55,16 +52,16 @@ bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg)
|
|||||||
{
|
{
|
||||||
Window* window;
|
Window* window;
|
||||||
GET_WINDOW_WITH_HWND(window, msg->hwnd);
|
GET_WINDOW_WITH_HWND(window, msg->hwnd);
|
||||||
WinImpl::DraggedWindow = window;
|
Float2 mousePosition(static_cast<float>(static_cast<LONG>(WINDOWS_GET_X_LPARAM(msg->lParam))), static_cast<float>(static_cast<LONG>(WINDOWS_GET_Y_LPARAM(msg->lParam))));
|
||||||
|
|
||||||
WinImpl::DraggedWindowStartPosition = WinImpl::DraggedWindow->GetClientPosition();
|
WinImpl::DraggedWindow = window;
|
||||||
Float2 mousePos(static_cast<float>(static_cast<LONG>(WINDOWS_GET_X_LPARAM(msg->lParam))), static_cast<float>(static_cast<LONG>(WINDOWS_GET_Y_LPARAM(msg->lParam))));
|
WinImpl::DraggedWindowStartPosition = window->GetClientPosition();
|
||||||
WinImpl::DraggedWindowMousePosition = mousePos;
|
WinImpl::DraggedWindowMousePosition = mousePosition - WinImpl::DraggedWindowStartPosition;
|
||||||
WinImpl::DraggedWindowMousePosition -= WinImpl::DraggedWindowStartPosition;
|
WinImpl::DraggedWindowSize = window->GetClientSize();
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
WindowHitCodes hit = static_cast<WindowHitCodes>(msg->wParam);
|
WindowHitCodes hit = static_cast<WindowHitCodes>(msg->wParam);
|
||||||
window->OnHitTest(mousePos, hit, result);
|
window->OnHitTest(mousePosition, hit, result);
|
||||||
//if (result && hit != WindowHitCodes::Caption)
|
//if (result && hit != WindowHitCodes::Caption)
|
||||||
// return false;
|
// return false;
|
||||||
|
|
||||||
@@ -83,24 +80,6 @@ bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg)
|
|||||||
SDL_PushEvent(&event);
|
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<float>(static_cast<LONG>(WINDOWS_GET_X_LPARAM(msg->lParam)));
|
|
||||||
event.button.y = static_cast<float>(static_cast<LONG>(WINDOWS_GET_Y_LPARAM(msg->lParam)));
|
|
||||||
|
|
||||||
SDL_PushEvent(&event);
|
|
||||||
}*/
|
|
||||||
return true;
|
return true;
|
||||||
#undef GET_WINDOW_WITH_HWND
|
#undef GET_WINDOW_WITH_HWND
|
||||||
}
|
}
|
||||||
@@ -131,13 +110,12 @@ bool SDLPlatform::EventFilterCallback(void* userdata, SDL_Event* event)
|
|||||||
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
||||||
{
|
{
|
||||||
// The internal timer is sending exposed events every ~16ms
|
// The internal timer is sending exposed events every ~16ms
|
||||||
Engine::OnUpdate();//Scripting::Update(); // For docking updates
|
Engine::OnUpdate(); // For docking updates
|
||||||
Engine::OnDraw();
|
Engine::OnDraw();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
||||||
{
|
{
|
||||||
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -146,34 +124,40 @@ bool SDLPlatform::EventFilterCallback(void* userdata, SDL_Event* event)
|
|||||||
// return false;
|
// return false;
|
||||||
window->HandleEvent(*event);
|
window->HandleEvent(*event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (event->type == SDL_EVENT_WINDOW_MOVED)
|
else if (event->type == SDL_EVENT_WINDOW_MOVED)
|
||||||
{
|
{
|
||||||
Float2 start = WinImpl::DraggedWindowStartPosition;
|
if (window)
|
||||||
Float2 newPos = Float2(static_cast<float>(event->window.data1), static_cast<float>(event->window.data2));
|
window->HandleEvent(*event);
|
||||||
Float2 offset = newPos - start;
|
|
||||||
Float2 mousePos = WinImpl::DraggedWindowMousePosition;
|
|
||||||
|
|
||||||
|
if (WinImpl::DraggedWindowSize != window->GetClientSize())
|
||||||
|
{
|
||||||
|
// The window size changed while dragging, most likely due to maximized window restoring back to previous size.
|
||||||
|
WinImpl::DraggedWindowStartPosition = window->GetClientPosition();
|
||||||
|
WinImpl::DraggedWindowSize = window->GetClientSize();
|
||||||
|
WinImpl::DraggedWindowMousePosition = WinImpl::DraggedWindowStartPosition + WinImpl::DraggedWindowMousePosition - window->GetClientPosition();
|
||||||
|
}
|
||||||
|
Float2 windowPosition = Float2(static_cast<float>(event->window.data1), static_cast<float>(event->window.data2));
|
||||||
|
Float2 mousePosition = WinImpl::DraggedWindowMousePosition;
|
||||||
|
|
||||||
|
// Generate mouse movement events while dragging the window around
|
||||||
SDL_Event mouseMovedEvent { 0 };
|
SDL_Event mouseMovedEvent { 0 };
|
||||||
mouseMovedEvent.motion.type = SDL_EVENT_MOUSE_MOTION;
|
mouseMovedEvent.motion.type = SDL_EVENT_MOUSE_MOTION;
|
||||||
mouseMovedEvent.motion.windowID = SDL_GetWindowID(WinImpl::DraggedWindow->GetSDLWindow());
|
mouseMovedEvent.motion.windowID = SDL_GetWindowID(WinImpl::DraggedWindow->GetSDLWindow());
|
||||||
mouseMovedEvent.motion.timestamp = SDL_GetTicksNS();
|
mouseMovedEvent.motion.timestamp = SDL_GetTicksNS();
|
||||||
mouseMovedEvent.motion.state = SDL_BUTTON_LEFT;
|
mouseMovedEvent.motion.state = SDL_BUTTON_LEFT;
|
||||||
mouseMovedEvent.motion.x = mousePos.X;
|
mouseMovedEvent.motion.x = mousePosition.X;
|
||||||
mouseMovedEvent.motion.y = mousePos.Y;
|
mouseMovedEvent.motion.y = mousePosition.Y;
|
||||||
if (window)
|
if (window)
|
||||||
window->HandleEvent(mouseMovedEvent);
|
window->HandleEvent(mouseMovedEvent);
|
||||||
if (window)
|
|
||||||
window->HandleEvent(*event);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (window)
|
if (window)
|
||||||
window->HandleEvent(*event);
|
window->HandleEvent(*event);
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLPlatform::PreHandleEvents()
|
void SDLPlatform::PreHandleEvents()
|
||||||
|
|||||||
Reference in New Issue
Block a user