_relative positioning fix
Some checks are pending
Build Android / Game (Android, Release ARM64) (push) Waiting to run
Build iOS / Game (iOS, Release ARM64) (push) Waiting to run
Build Linux / Editor (Linux, Development x64) (push) Waiting to run
Build Linux / Game (Linux, Release x64) (push) Waiting to run
Build macOS / Editor (Mac, Development ARM64) (push) Waiting to run
Build macOS / Game (Mac, Release ARM64) (push) Waiting to run
Build Windows / Editor (Windows, Development x64) (push) Waiting to run
Build Windows / Game (Windows, Release x64) (push) Waiting to run
Cooker / Cook (Mac) (push) Waiting to run
Tests / Tests (Linux) (push) Waiting to run
Tests / Tests (Windows) (push) Waiting to run

This commit is contained in:
2025-01-02 00:59:18 +02:00
parent a547689f69
commit 2acf71c499

View File

@@ -48,8 +48,9 @@ namespace
void* GetNativeWindowPointer(SDL_Window* window); void* GetNativeWindowPointer(SDL_Window* window);
SDL_HitTestResult OnWindowHitTest(SDL_Window* win, const SDL_Point* area, void* data); SDL_HitTestResult OnWindowHitTest(SDL_Window* win, const SDL_Point* area, void* data);
void GetRelativeWindowOffset(WindowType type, SDLWindow* parentWindow, Int2& positionOffset);
void SetSDLWindowScreenPosition(SDLWindow* window, const int x, const int y); Int2 GetSDLWindowScreenPosition(const SDLWindow* window);
void SetSDLWindowScreenPosition(const SDLWindow* window, const int x, const int y);
class SDLDropFilesData : public IGuiData class SDLDropFilesData : public IGuiData
{ {
@@ -97,13 +98,8 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
, _dragOver(false) , _dragOver(false)
#endif #endif
{ {
int32 x = Math::TruncToInt(settings.Position.X); Int2 clientSize(Math::TruncToInt(settings.Size.X), Math::TruncToInt(settings.Size.Y));
int32 y = Math::TruncToInt(settings.Position.Y); _clientSize = Float2(clientSize);
int32 clientWidth = Math::TruncToInt(settings.Size.X);
int32 clientHeight = Math::TruncToInt(settings.Size.Y);
int32 windowWidth = clientWidth;
int32 windowHeight = clientHeight;
_clientSize = Float2((float)clientWidth, (float)clientHeight);
if (SDLPlatform::UsesWayland()) if (SDLPlatform::UsesWayland())
{ {
@@ -154,16 +150,18 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
} }
#endif #endif
} }
// It should be noted that SDL creates the window in client-space coordinates (ignoring window decorations) // The window position needs to be relative to the parent window
Int2 relativePosition(Math::TruncToInt(settings.Position.X), Math::TruncToInt(settings.Position.Y));
GetRelativeWindowOffset(_settings.Type, _settings.Parent, relativePosition);
SDL_PropertiesID props = SDL_CreateProperties(); SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags);
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, settings.Title.ToStringAnsi().Get()); SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, settings.Title.ToStringAnsi().Get());
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, relativePosition.X);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, relativePosition.Y);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, windowWidth); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, clientSize.X);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, windowHeight); SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, clientSize.Y);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN, true); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN, true);
if ((flags & SDL_WINDOW_TOOLTIP) != 0) if ((flags & SDL_WINDOW_TOOLTIP) != 0)
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, true); SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, true);
@@ -192,10 +190,10 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
SDL_DisplayID display = SDL_GetDisplayForWindow(_window); SDL_DisplayID display = SDL_GetDisplayForWindow(_window);
_dpiScale = SDL_GetWindowDisplayScale(_window); _dpiScale = SDL_GetWindowDisplayScale(_window);
_dpi = (int)(_dpiScale * DefaultDPI); _dpi = Math::TruncToInt(_dpiScale * DefaultDPI);
SDL_SetWindowMinimumSize(_window, (int)_settings.MinimumSize.X, (int)_settings.MinimumSize.Y); SDL_SetWindowMinimumSize(_window, Math::TruncToInt(_settings.MinimumSize.X), Math::TruncToInt(_settings.MinimumSize.Y));
SDL_SetWindowMaximumSize(_window, (int)_settings.MaximumSize.X, (int)_settings.MaximumSize.Y); SDL_SetWindowMaximumSize(_window, Math::TruncToInt(_settings.MaximumSize.X), Math::TruncToInt(_settings.MaximumSize.Y));
SDL_SetWindowHitTest(_window, &OnWindowHitTest, this); SDL_SetWindowHitTest(_window, &OnWindowHitTest, this);
InitSwapChain(); InitSwapChain();
@@ -857,7 +855,42 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
SDL_SetWindowSize(_window, newW, newH); SDL_SetWindowSize(_window, newW, newH);
} }
void SetSDLWindowScreenPosition(SDLWindow* window, const int x, const int y) bool IsPopupWindow(WindowType type)
{
return type == WindowType::Popup || type == WindowType::Tooltip;
}
void GetRelativeWindowOffset(WindowType type, SDLWindow* parentWindow, Int2& positionOffset)
{
if (!IsPopupWindow(type))
return;
SDLWindow* window = parentWindow;
while (window != nullptr)
{
Int2 parentPosition;
SDL_GetWindowPosition(window->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
positionOffset -= parentPosition;
if (!IsPopupWindow(window->GetSettings().Type))
break;
window = window->GetSettings().Parent;
}
}
Int2 GetSDLWindowScreenPosition(const SDLWindow* window)
{
Int2 relativeOffset(0, 0);
GetRelativeWindowOffset(window->GetSettings().Type, window->GetSettings().Parent, relativeOffset);
Int2 position;
SDL_GetWindowPosition(window->GetSDLWindow(), &position.X, &position.Y);
return position - relativeOffset;
}
void SetSDLWindowScreenPosition(const SDLWindow* window, const int x, const int y)
{ {
#if PLATFORM_LINUX #if PLATFORM_LINUX
/*if (SDLPlatform::UsesWayland()) /*if (SDLPlatform::UsesWayland())
@@ -868,7 +901,9 @@ void SetSDLWindowScreenPosition(SDLWindow* window, const int x, const int y)
return; return;
}*/ }*/
#endif #endif
SDL_SetWindowPosition(window->GetSDLWindow(), x, y); Int2 relativePosition(x, y);
GetRelativeWindowOffset(window->GetSettings().Type, window->GetSettings().Parent, relativePosition);
SDL_SetWindowPosition(window->GetSDLWindow(), relativePosition.X, relativePosition.Y);
} }
void SDLWindow::SetPosition(const Float2& position) void SDLWindow::SetPosition(const Float2& position)
@@ -911,8 +946,7 @@ Float2 SDLWindow::GetPosition() const
Int2 topLeftBorder; Int2 topLeftBorder;
SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr); SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr);
Int2 position; Int2 position = GetSDLWindowScreenPosition(this);
SDL_GetWindowPosition(_window, &position.X, &position.Y);
position -= topLeftBorder; position -= topLeftBorder;
return Float2(static_cast<float>(position.X), static_cast<float>(position.Y)); return Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
@@ -938,17 +972,13 @@ Float2 SDLWindow::GetClientSize() const
Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
{ {
Int2 position; Int2 position = GetSDLWindowScreenPosition(this);
SDL_GetWindowPosition(_window, &position.X, &position.Y);
return screenPos - Float2(static_cast<float>(position.X), static_cast<float>(position.Y)); return screenPos - Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
} }
Float2 SDLWindow::ClientToScreen(const Float2& clientPos) const Float2 SDLWindow::ClientToScreen(const Float2& clientPos) const
{ {
Int2 position; Int2 position = GetSDLWindowScreenPosition(this);
SDL_GetWindowPosition(_window, &position.X, &position.Y);
return clientPos + Float2(static_cast<float>(position.X), static_cast<float>(position.Y)); return clientPos + Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
} }
@@ -1103,7 +1133,7 @@ void SDLWindow::UpdateCursor()
{ {
if (_cursor == CursorType::Hidden) if (_cursor == CursorType::Hidden)
{ {
SDL_HideCursor(); //SDL_HideCursor();
if (_isTrackingMouse) if (_isTrackingMouse)
Input::Mouse->SetRelativeMode(true, this); Input::Mouse->SetRelativeMode(true, this);