_wayland big refactor
This commit is contained in:
@@ -98,7 +98,7 @@ bool SDLCALL SDLPlatform::EventMessageHook(void* userdata, MSG* msg)
|
||||
#undef GET_WINDOW_WITH_HWND
|
||||
}
|
||||
|
||||
bool SDLPlatform::InitPlatform()
|
||||
bool SDLPlatform::InitInternal()
|
||||
{
|
||||
// Workaround required for handling window dragging events properly
|
||||
SDL_SetWindowsMessageHook(&EventMessageHook, nullptr);
|
||||
@@ -109,6 +109,179 @@ bool SDLPlatform::InitPlatform()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventFilterCallback(void* userdata, SDL_Event* event)
|
||||
{
|
||||
Window* draggedWindow = *(Window**)userdata;
|
||||
if (draggedWindow == nullptr)
|
||||
return true;
|
||||
|
||||
// When the window is being dragged on Windows, the internal message loop is blocking
|
||||
// the SDL event queue. We need to handle all relevant events in this event watch callback
|
||||
// to ensure dragging related functionality doesn't break due to engine not getting updated.
|
||||
// This also happens to fix the engine freezing during the dragging operation.
|
||||
|
||||
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
||||
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
||||
{
|
||||
// The internal timer is sending exposed events every ~16ms
|
||||
Engine::OnUpdate();//Scripting::Update(); // For docking updates
|
||||
Engine::OnDraw();
|
||||
return false;
|
||||
}
|
||||
else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
||||
{
|
||||
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
||||
if (window)
|
||||
{
|
||||
bool result = false;
|
||||
window->OnLeftButtonHit(WindowHitCodes::Caption, result);
|
||||
//if (result)
|
||||
// return false;
|
||||
window->HandleEvent(*event);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (event->type == SDL_EVENT_WINDOW_MOVED)
|
||||
{
|
||||
Float2 start = draggedWindowStartPosition;
|
||||
Float2 newPos = Float2(static_cast<float>(event->window.data1), static_cast<float>(event->window.data2));
|
||||
Float2 offset = newPos - start;
|
||||
Float2 mousePos = draggedWindowMousePosition;
|
||||
|
||||
SDL_Event mouseMovedEvent { 0 };
|
||||
mouseMovedEvent.motion.type = SDL_EVENT_MOUSE_MOTION;
|
||||
mouseMovedEvent.motion.windowID = SDL_GetWindowID(draggedWindow->GetSDLWindow());
|
||||
mouseMovedEvent.motion.timestamp = SDL_GetTicksNS();
|
||||
mouseMovedEvent.motion.state = SDL_BUTTON_LEFT;
|
||||
mouseMovedEvent.motion.x = mousePos.X;
|
||||
mouseMovedEvent.motion.y = mousePos.Y;
|
||||
if (window)
|
||||
window->HandleEvent(mouseMovedEvent);
|
||||
if (window)
|
||||
window->HandleEvent(*event);
|
||||
|
||||
return false;
|
||||
}
|
||||
if (window)
|
||||
window->HandleEvent(*event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDLPlatform::PreHandleEvents()
|
||||
{
|
||||
SDL_AddEventWatch(EventFilterCallback, &draggedWindow);
|
||||
}
|
||||
|
||||
void SDLPlatform::PostHandleEvents()
|
||||
{
|
||||
SDL_RemoveEventWatch(watch, &draggedWindow);
|
||||
|
||||
// Handle window dragging release here
|
||||
if (draggedWindow != nullptr)
|
||||
{
|
||||
Float2 mousePosition;
|
||||
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
|
||||
|
||||
// Send simulated mouse up event
|
||||
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.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;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDLWindow::HandleEventInternal(SDL_Event& event)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_EVENT_WINDOW_DESTROYED:
|
||||
{
|
||||
#if USE_EDITOR
|
||||
// Disable file dropping
|
||||
if (_settings.AllowDragAndDrop)
|
||||
{
|
||||
const auto result = RevokeDragDrop((HWND)_handle);
|
||||
if (result != S_OK)
|
||||
LOG(Warning, "Window drag and drop service error: 0x{0:x}:{1}", result, 2);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_MAXIMIZED:
|
||||
{
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 2
|
||||
if (SkipMaximizeEventsCount > 0)
|
||||
{
|
||||
SkipMaximizeEventsCount--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_settings.HasBorder && _settings.HasSizingFrame)
|
||||
{
|
||||
// Restore the window back to previous state
|
||||
SDL_RestoreWindow(_window);
|
||||
|
||||
// Remove the resizable flags from borderless windows and maximize the window again
|
||||
auto style = ::GetWindowLong((HWND)_handle, GWL_STYLE);
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
SDL_MaximizeWindow(_window);
|
||||
|
||||
// Re-enable the resizable borderless flags
|
||||
style = ::GetWindowLong((HWND)_handle, GWL_STYLE) | STYLE_RESIZABLE;
|
||||
::SetWindowLong((HWND)_handle, GWL_STYLE, style);
|
||||
|
||||
// The next SDL_EVENT_WINDOW_RESTORED and SDL_EVENT_WINDOW_MAXIMIZED events should be ignored
|
||||
SkipMaximizeEventsCount = 2;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
{
|
||||
#if BORDERLESS_MAXIMIZE_WORKAROUND == 2
|
||||
if (SkipMaximizeEventsCount > 0)
|
||||
{
|
||||
SkipMaximizeEventsCount--;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
{
|
||||
if (draggedWindow != nullptr && 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);
|
||||
|
||||
SDL_Event event2 = event;
|
||||
event2.button.windowID = draggedWindow->_windowId;
|
||||
event2.button.x = clientPos.X;
|
||||
event2.button.y = clientPos.Y;
|
||||
|
||||
SDLInput::HandleEvent(draggedWindow, event2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDLPlatform::UsesWindows()
|
||||
{
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user