_stink
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
#if PLATFORM_SDL && PLATFORM_WINDOWS
|
||||
|
||||
#define BORDERLESS_MAXIMIZE_WORKAROUND 2
|
||||
|
||||
#include "SDLPlatform.h"
|
||||
#include "SDLInput.h"
|
||||
|
||||
@@ -16,9 +18,15 @@
|
||||
#include <SDL3/SDL_system.h>
|
||||
#include <SDL3/SDL_timer.h>
|
||||
|
||||
extern Window* draggedWindow;
|
||||
Float2 draggedWindowStartPosition = Float2::Zero;
|
||||
Float2 draggedWindowMousePosition = Float2::Zero;
|
||||
namespace WinImpl
|
||||
{
|
||||
Window* DraggedWindow;
|
||||
Float2 DraggedWindowStartPosition = Float2::Zero;
|
||||
Float2 DraggedWindowMousePosition = Float2::Zero;
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 2
|
||||
int SkipMaximizeEventsCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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)
|
||||
@@ -39,7 +47,7 @@ bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg)
|
||||
ASSERT((window) != nullptr); \
|
||||
} while (false)
|
||||
|
||||
if (draggedWindow != nullptr)
|
||||
if (WinImpl::DraggedWindow != nullptr)
|
||||
{
|
||||
LOG(Info, "event hook message: {}", msg->message);
|
||||
}
|
||||
@@ -48,12 +56,12 @@ bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg)
|
||||
{
|
||||
Window* window;
|
||||
GET_WINDOW_WITH_HWND(window, msg->hwnd);
|
||||
draggedWindow = window;
|
||||
WinImpl::DraggedWindow = window;
|
||||
|
||||
draggedWindowStartPosition = draggedWindow->GetClientPosition();
|
||||
WinImpl::DraggedWindowStartPosition = WinImpl::DraggedWindow->GetClientPosition();
|
||||
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))));
|
||||
draggedWindowMousePosition = mousePos;
|
||||
draggedWindowMousePosition -= draggedWindowStartPosition;
|
||||
WinImpl::DraggedWindowMousePosition = mousePos;
|
||||
WinImpl::DraggedWindowMousePosition -= WinImpl::DraggedWindowStartPosition;
|
||||
|
||||
bool result = false;
|
||||
WindowHitCodes hit = static_cast<WindowHitCodes>(msg->wParam);
|
||||
@@ -70,8 +78,8 @@ bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg)
|
||||
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;
|
||||
event.button.x = WinImpl::DraggedWindowMousePosition.X;
|
||||
event.button.y = WinImpl::DraggedWindowMousePosition.Y;
|
||||
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
@@ -144,14 +152,14 @@ bool EventFilterCallback(void* userdata, SDL_Event* event)
|
||||
}
|
||||
else if (event->type == SDL_EVENT_WINDOW_MOVED)
|
||||
{
|
||||
Float2 start = draggedWindowStartPosition;
|
||||
Float2 start = WinImpl::DraggedWindowStartPosition;
|
||||
Float2 newPos = Float2(static_cast<float>(event->window.data1), static_cast<float>(event->window.data2));
|
||||
Float2 offset = newPos - start;
|
||||
Float2 mousePos = draggedWindowMousePosition;
|
||||
Float2 mousePos = WinImpl::DraggedWindowMousePosition;
|
||||
|
||||
SDL_Event mouseMovedEvent { 0 };
|
||||
mouseMovedEvent.motion.type = SDL_EVENT_MOUSE_MOTION;
|
||||
mouseMovedEvent.motion.windowID = SDL_GetWindowID(draggedWindow->GetSDLWindow());
|
||||
mouseMovedEvent.motion.windowID = SDL_GetWindowID(WinImpl::DraggedWindow->GetSDLWindow());
|
||||
mouseMovedEvent.motion.timestamp = SDL_GetTicksNS();
|
||||
mouseMovedEvent.motion.state = SDL_BUTTON_LEFT;
|
||||
mouseMovedEvent.motion.x = mousePos.X;
|
||||
@@ -171,15 +179,15 @@ bool EventFilterCallback(void* userdata, SDL_Event* event)
|
||||
|
||||
void SDLPlatform::PreHandleEvents()
|
||||
{
|
||||
SDL_AddEventWatch(EventFilterCallback, &draggedWindow);
|
||||
SDL_AddEventWatch(EventFilterCallback, &WinImpl::DraggedWindow);
|
||||
}
|
||||
|
||||
void SDLPlatform::PostHandleEvents()
|
||||
{
|
||||
SDL_RemoveEventWatch(watch, &draggedWindow);
|
||||
SDL_RemoveEventWatch(watch, &WinImpl::DraggedWindow);
|
||||
|
||||
// Handle window dragging release here
|
||||
if (draggedWindow != nullptr)
|
||||
if (WinImpl::DraggedWindow != nullptr)
|
||||
{
|
||||
Float2 mousePosition;
|
||||
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
|
||||
@@ -188,14 +196,14 @@ void SDLPlatform::PostHandleEvents()
|
||||
SDL_Event buttonUpEvent { 0 };
|
||||
buttonUpEvent.motion.type = SDL_EVENT_MOUSE_BUTTON_UP;
|
||||
buttonUpEvent.button.down = false;
|
||||
buttonUpEvent.motion.windowID = SDL_GetWindowID(draggedWindow->GetSDLWindow());
|
||||
buttonUpEvent.motion.windowID = SDL_GetWindowID(WinImpl::DraggedWindow->GetSDLWindow());
|
||||
buttonUpEvent.motion.timestamp = SDL_GetTicksNS();
|
||||
buttonUpEvent.motion.state = SDL_BUTTON_LEFT;
|
||||
buttonUpEvent.button.clicks = 1;
|
||||
buttonUpEvent.motion.x = mousePosition.X;
|
||||
buttonUpEvent.motion.y = mousePosition.Y;
|
||||
draggedWindow->HandleEvent(buttonUpEvent);
|
||||
draggedWindow = nullptr;
|
||||
WinImpl::DraggedWindow->HandleEvent(buttonUpEvent);
|
||||
WinImpl::DraggedWindow = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,18 +268,18 @@ bool SDLWindow::HandleEventInternal(SDL_Event& event)
|
||||
}
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
if (draggedWindow != nullptr && draggedWindow->_windowId != event.button.windowID)
|
||||
if (WinImpl::DraggedWindow != nullptr && WinImpl::DraggedWindow->_windowId != event.button.windowID)
|
||||
{
|
||||
// Send the button event to dragged window as well
|
||||
Float2 mousePos = ClientToScreen({ event.button.x, event.button.y });
|
||||
Float2 clientPos = draggedWindow->ScreenToClient(mousePos);
|
||||
Float2 clientPos = WinImpl::DraggedWindow->ScreenToClient(mousePos);
|
||||
|
||||
SDL_Event event2 = event;
|
||||
event2.button.windowID = draggedWindow->_windowId;
|
||||
event2.button.windowID = WinImpl::DraggedWindow->_windowId;
|
||||
event2.button.x = clientPos.X;
|
||||
event2.button.y = clientPos.Y;
|
||||
|
||||
SDLInput::HandleEvent(draggedWindow, event2);
|
||||
SDLInput::HandleEvent(WinImpl::DraggedWindow, event2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -297,10 +305,68 @@ bool SDLPlatform::UsesX11()
|
||||
return false;
|
||||
}
|
||||
|
||||
void SDLWindow::Maximize()
|
||||
{
|
||||
if (!_settings.AllowMaximize)
|
||||
return;
|
||||
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 1
|
||||
// Workaround for "SDL_BORDERLESS_RESIZABLE_STYLE" hint not working as expected when maximizing windows
|
||||
auto style = ::GetWindowLong((HWND)_handle, GWL_STYLE);
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
SDL_MaximizeWindow(_window);
|
||||
|
||||
style = ::GetWindowLong((HWND)_handle, GWL_STYLE) | STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
#else
|
||||
SDL_MaximizeWindow(_window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDLWindow::Restore()
|
||||
{
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 1
|
||||
// Workaround for "SDL_BORDERLESS_RESIZABLE_STYLE" hint not working as expected when maximizing windows
|
||||
auto style = ::GetWindowLong((HWND)_handle, GWL_STYLE);
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
SDL_RestoreWindow(_window);
|
||||
|
||||
style = ::GetWindowLong((HWND)_handle, GWL_STYLE) | STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
#else
|
||||
SDL_RestoreWindow(_window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDLWindow::Focus()
|
||||
{
|
||||
auto activateWhenRaised = SDL_GetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED);
|
||||
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED, "1");
|
||||
|
||||
// Forcing the window to focus causes issues with opening context menus while window is maximized
|
||||
//auto forceRaiseWindow = SDL_GetHint(SDL_HINT_FORCE_RAISEWINDOW);
|
||||
//SDL_SetHint(SDL_HINT_FORCE_RAISEWINDOW, "1");
|
||||
|
||||
SDL_RaiseWindow(_window);
|
||||
|
||||
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED, activateWhenRaised);
|
||||
//SDL_SetHint(SDL_HINT_FORCE_RAISEWINDOW, forceRaiseWindow);
|
||||
}
|
||||
|
||||
void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
|
||||
{
|
||||
// Other supported values: "permonitor", "permonitorv2"
|
||||
SDL_SetHint("SDL_WINDOWS_DPI_AWARENESS", enable ? "system" : "unaware");
|
||||
}
|
||||
|
||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow)
|
||||
{
|
||||
Show();
|
||||
return DragDropEffect::None;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user