_begin refactor, windows fixes
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-01 02:05:15 +02:00
parent aac2920f03
commit 5274a96a42
5 changed files with 224 additions and 106 deletions

View File

@@ -243,6 +243,8 @@ namespace FlaxEditor.GUI.Docking
{
var baseWinPos = _toMove.Window.Window.Position;
_dragOffset = mouseScreenPosition - baseWinPos;
Editor.Log($"_dragOffset: {_dragOffset}, mouse: {mouseScreenPosition}, basewinpos: {baseWinPos}");
}
private void UpdateRects()

View File

@@ -483,7 +483,12 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
else
{
const Float2 mousePos = window->ClientToScreen({ event.motion.x, event.motion.y });
//LOG(Info, "motion {},{}, mouse: {}, win: {}", event.motion.x, event.motion.y, mousePos, String(window->GetTitle()));
Int2 p;
Float2 wp = window->ClientToScreen({0, 0});
//SDL_GetWindowPosition(window->GetSDLWindow(), &p.X, &p.Y);
p.X = wp.X;
p.Y = wp.Y;
//LOG(Info, "motion {},{}, mouse: {}, win: {}, winpos {},{}", event.motion.x, event.motion.y, mousePos, String(window->GetTitle()), p.X, p.Y);
Input::Mouse->OnMouseMove(mousePos, window);
}
return true;

View File

@@ -64,6 +64,8 @@ bool SDLPlatform::Init()
SDL_SetHint(SDL_HINT_WINDOWS_ERASE_BACKGROUND_MODE, "0");
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0"); // Already handled during platform initialization
SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1"); // Allow borderless windows to be resizable on Windows
//SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "1");
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, "0");
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // Needed for tracking mode
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "1"); // Is this needed?

View File

@@ -54,6 +54,9 @@ void SetSDLWindowPosition(SDLWindow* window, const int x, const int y);
void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen = true);
void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* parent, int32& xRel, int32& yRel);
Int2 GetSDLWindowScreenPosition(const SDLWindow* window);
void SetSDLWindowScreenPosition(SDLWindow* window, const int x, const int y);
class SDLDropFilesData : public IGuiData
{
public:
@@ -157,8 +160,8 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
if (win->_settings.Type == WindowType::Tooltip || win->_settings.Type == WindowType::Popup)
{
auto focusedParent = win->_settings.Parent;
_settings.Parent = win;
while (focusedParent != nullptr && (focusedParent->_settings.Type == WindowType::Tooltip || focusedParent->_settings.Type == WindowType::Popup))
//_settings.Parent = win;
while (focusedParent != nullptr /*&& (focusedParent->_settings.Type == WindowType::Tooltip || focusedParent->_settings.Type == WindowType::Popup)*/)
{
if (focusedParent->_settings.Parent == nullptr)
{
@@ -205,62 +208,11 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
}
}
}
if ((_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup))
{
if (_settings.Parent != nullptr && (_settings.Parent->GetSettings().Type == WindowType::Tooltip || _settings.Parent->GetSettings().Type == WindowType::Popup))
{
x += 0;
}
}
//LOG(Info, "{}x{}, parent: {}", x, y, _settings.Parent != nullptr ? _settings.Parent->GetTitle() : String("null"));
// The SDL window position is always relative to the parent window
Int2 oldpos(x, y);
if (_settings.Parent != nullptr)
{
#if PLATFORM_WINDOWS
auto parentPosition = _settings.Parent->ClientToScreen(Float2::Zero);
x -= Math::TruncToInt(parentPosition.X);
y -= Math::TruncToInt(parentPosition.Y);
auto parentType = _settings.Parent->GetSettings().Type;
auto parentParent = _settings.Parent->GetSettings().Parent;
if (parentParent != nullptr)
{
//if (parentType != WindowType::Popup && parentType != WindowType::Tooltip)
{
auto parentParentType = parentParent->GetSettings().Type;
//if (parentParentType != WindowType::Popup && parentParentType != WindowType::Tooltip)
{
auto parentParentPosition = parentParent->ClientToScreen(Float2::Zero);
x -= Math::TruncToInt(parentParentPosition.X);
y -= Math::TruncToInt(parentParentPosition.Y);
}
}
/*else
{
// submenu of context menu
x += 0;
}*/
}
#else
SetRelativeWindowPosition(_settings.Type, _settings.Parent, x, y);
#endif
}
if (SDLPlatform::UsesX11() && _settings.Parent != Engine::MainWindow)
{
/*if (_settings.Parent->GetSettings().Type == WindowType::Tooltip || _settings.Parent->GetSettings().Type == WindowType::Popup)
{
}
else
{
*//*auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
x -= (int)monitorBounds.GetLeft();
y -= (int)monitorBounds.GetTop();*/
//}
}
Int2 oldpos2(x, y);
@@ -323,9 +275,10 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
SDL_GetWindowSize(_window, &rect2.w, &rect2.h);
_cachedClientRectangle = Rectangle((float)rect.x, (float)rect.y, (float)rect.w, (float)rect.h);
Int2 sdlpos(rect.x, rect.y);
Int2 newpos = GetClientPosition();
Int2 newposclient = GetSDLWindowPosition(this);
//LOG(Info, "new window at {}, input {}, expected: {}", newposclient, oldpos, oldpos2);
Int2 newposclient = GetSDLWindowScreenPosition(this);
LOG(Info, "new window, sdl: {}, input {}, relative: {}", sdlpos, oldpos, newposclient);
//ASSERT(newpos == oldpos || newpos == oldpos2);
/*oldpos = newpos;
@@ -749,7 +702,7 @@ void SDLWindow::HandleEvent(SDL_Event& event)
_dpi = (int)(_dpiScale * DefaultDPI);
int w = (int)(_cachedClientRectangle.GetWidth() * (scale / oldScale));
int h = (int)(_cachedClientRectangle.GetHeight() * (scale / oldScale));
_cachedClientRectangle.Size = Float2(w, h);
_cachedClientRectangle.Size = Float2(static_cast<float>(w), static_cast<float>(h));
SDL_SetWindowSize(_window, w, h);
// TODO: Recalculate fonts
}
@@ -992,7 +945,8 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
{
int oldX, oldY;
int oldW, oldH;
SDL_GetWindowPosition(_window, &oldX, &oldY);
//SDL_GetWindowPosition(_window, &oldX, &oldY);
Int2 asd = GetSDLWindowScreenPosition(this); oldX = asd.X; oldY = asd.Y;
SDL_GetWindowSizeInPixels(_window, &oldW, &oldH);
int newX = (int)clientArea.GetLeft();
@@ -1000,8 +954,9 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
int newW = (int)clientArea.GetWidth();
int newH = (int)clientArea.GetHeight();
//if (newX != oldX || newY != oldY)
SetSDLWindowPosition(this, newX, newY);
if (newX != oldX || newY != oldY)
SetSDLWindowScreenPosition(this, newX, newY);
//SetSDLWindowPosition(this, newX, newY);
SDL_SetWindowSize(_window, newW, newH);
LOG(Info, "SetClientBounds changed from ({},{} {}x{}) to ({},{} {}x{})", oldX, oldY, oldW, oldH,
@@ -1054,6 +1009,22 @@ Int2 GetSDLWindowPosition(const SDLWindow* window)
//SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//position += rootParentPosition;
}
#endif
#if PLATFORM_WINDOWS
if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
{
auto oldPos = position;
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
//rootParentPosition = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position += rootParentPosition;
parent = parent->GetSettings().Parent;
}
}
#endif
return position;
}
@@ -1090,6 +1061,111 @@ void SetSDLWindowPosition(SDLWindow* window, const int x, const int y)
SDL_SetWindowPosition(window->GetSDLWindow(), x, y);
}
Int2 GetSDLWindowScreenPosition(const SDLWindow* window)
{
Int2 position;
SDL_GetWindowPosition(window->GetSDLWindow(), &position.X, &position.Y);
#if PLATFORM_LINUX
if (SDLPlatform::UsesX11())
{
#if X11_WINDOW_POSITION_WORKAROUND
if (/*window->GetSettings().Type == WindowType::Tooltip ||*/ window->GetSettings().Type == WindowType::Popup)
{
auto oldPos = position;
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
//rootParentPosition = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position += rootParentPosition;
parent = parent->GetSettings().Parent;
}
}
#endif
}
else if (SDLPlatform::UsesWayland())
{
// Wayland doesn't support reporting window position in screen-space
/*auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 parentPosition;// = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
position += parentPosition;
parent = parent->GetSettings().Parent;
}*/
//Int2 rootParentPosition = GetSDLWindowPosition(parent);
//SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//position += rootParentPosition;
}
#endif
#if PLATFORM_WINDOWS
if (true)
{
Int2 rel(0, 0);
SetRelativeWindowPosition(window->GetSettings().Type, window->GetSettings().Parent, rel.X, rel.Y);
position -= rel;
}
else
//if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
{
auto oldPos = position;
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
//rootParentPosition = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position += rootParentPosition;
if (parent->GetSettings().Parent == nullptr)
position -= rootParentPosition;
parent = parent->GetSettings().Parent;
}
}
#endif
GetRelativeWindowPosition(window, position, true); // windows NOOP
return position;
}
void SetSDLWindowScreenPosition(SDLWindow* window, const int xx, const int yy)
{
Int2 relativePosition(xx, yy);
SetRelativeWindowPosition(window->GetSettings().Type, window->GetSettings().Parent, relativePosition.X, relativePosition.Y);
#if PLATFORM_LINUX
if (SDLPlatform::UsesX11())
{
#if X11_WINDOW_POSITION_WORKAROUND
if (/*window->GetSettings().Type == WindowType::Tooltip ||*/ window->GetSettings().Type == WindowType::Popup)
{
Int2 position(x, y);
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position -= rootParentPosition;
parent = parent->GetSettings().Parent;
}
return;
}
#endif
}
else if (SDLPlatform::UsesWayland())
{
int oldX, oldY;
SDL_GetWindowPosition(window->GetSDLWindow(), &oldX, &oldY);
if (x == oldX && y == oldY)
return;
}
#endif
SDL_SetWindowPosition(window->GetSDLWindow(), relativePosition.X, relativePosition.Y);
}
void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen)
{
// The relative positioning of windows are very inconsistent in different platforms.
@@ -1097,11 +1173,6 @@ void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition,
// On X11: The child position is always relative to parent windows.
// On Wayland: The child position is relative to root parent window.
/*if (SDLPlatform::UsesX11())
{
return;
}*/
#if PLATFORM_LINUX
//clienttoscreen = false;
if (SDLPlatform::UsesX11())
@@ -1172,18 +1243,24 @@ void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition,
//relativePosition -= Int2(monitorBounds.GetTopLeft());
}
else
parent = (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ? window->GetSettings().Parent : nullptr;
while (parent != nullptr)
parent = /*(window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ?*/ window->GetSettings().Parent /*: nullptr*/;
if (parent != nullptr)
{
//break;
Int2 parentPosition = GetSDLWindowPosition(parent);
relativePosition += (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parentPosition : -parentPosition;
auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
//Int2 parentPosition = GetSDLWindowPosition(parent);
//relativePosition += parentPosition;//(parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parentPosition : -parentPosition;
//auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
//relativePosition += Int2(monitorBounds.GetTopLeft());
//relativePosition -= parentPosition;
/*if (SDLPlatform::UsesX11())
parent = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parent->GetSettings().Parent : nullptr;
else*/
//if (parent->GetSettings().Parent == nullptr)
{
Int2 parentPosition = GetSDLWindowPosition(parent);
relativePosition += parentPosition;
//break;
}
parent = parent->GetSettings().Parent;
}
}
@@ -1196,11 +1273,6 @@ void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* theParent
// On X11: The child position is always relative to parent windows.
// On Wayland: The child position is relative to root parent window.
/*if (SDLPlatform::UsesX11())
{
return;
}*/
#if PLATFORM_LINUX
if (SDLPlatform::UsesX11())
{
@@ -1311,29 +1383,50 @@ void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* theParent
else
#endif
{
SDLWindow* parent;
if (SDLPlatform::UsesX11())
return;
//if (windowType != WindowType::Popup && windowType != WindowType::Tooltip)
// return;
SDLWindow* topParent = nullptr;
bool workaround = false;
while (theParent != nullptr)
{
parent = (windowType == WindowType::Tooltip || windowType == WindowType::Popup) ? theParent : theParent;
//auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
//relativePosition -= Int2(monitorBounds.GetTopLeft());
Int2 parentPosition;// = GetSDLWindowScreenPosition(theParent);
SDL_GetWindowPosition(theParent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
xRel -= parentPosition.X;
yRel -= parentPosition.Y;
/*
if (workaround && theParent->GetSettings().Parent == nullptr)
{
topParent = theParent;
}
if (theParent->GetSettings().Parent != nullptr && (windowType == WindowType::Popup || windowType == WindowType::Tooltip || windowType == WindowType::Utility))
{
if (theParent->GetSettings().Type != WindowType::Popup && theParent->GetSettings().Type != WindowType::Tooltip && theParent->GetSettings().Type != WindowType::Utility)
workaround = true;
}*/
theParent = theParent->GetSettings().Parent;
//if (theParent != nullptr && (theParent->GetSettings().Type == WindowType::Popup || theParent->GetSettings().Type == WindowType::Tooltip))
// break;
/*if (theParent != nullptr)
{
Int2 parentPosition = GetSDLWindowPosition(theParent);
xRel -= parentPosition.X;
yRel -= parentPosition.Y;
//theParent = theParent->GetSettings().Parent;
}*/
}
else
parent = (windowType == WindowType::Tooltip || windowType == WindowType::Popup) ? theParent : nullptr;
while (parent != nullptr)
if (topParent != nullptr && workaround)
{
Int2 parentPosition = GetSDLWindowPosition(parent);
Int2 rel = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parentPosition : -parentPosition;
xRel += rel.X;
yRel += rel.Y;
auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
//relativePosition += Int2(monitorBounds.GetTopLeft());
//relativePosition += parentPosition;
/*if (SDLPlatform::UsesX11())
parent = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parent->GetSettings().Parent : nullptr;
else*/
parent = parent->GetSettings().Parent;
Int2 parentPosition;// = GetSDLWindowScreenPosition(theParent);
SDL_GetWindowPosition(topParent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
xRel -= parentPosition.X;
yRel -= parentPosition.Y;
}
}
}
@@ -1345,7 +1438,7 @@ void SDLWindow::SetPosition(const Float2& position)
// The position is relative to the parent window
Int2 relativePosition(static_cast<int>(position.X), static_cast<int>(position.Y));
relativePosition += topLeftBorder;
SetRelativeWindowPosition(GetSettings().Type, GetSettings().Parent, relativePosition.X, relativePosition.Y);
//SetRelativeWindowPosition(GetSettings().Type, GetSettings().Parent, relativePosition.X, relativePosition.Y);
if (SDLPlatform::UsesX11())
{
@@ -1353,7 +1446,7 @@ void SDLWindow::SetPosition(const Float2& position)
relativePosition += Int2(monitorBounds.GetTopLeft());
}
SetSDLWindowPosition(this, relativePosition.X, relativePosition.Y);
SetSDLWindowScreenPosition(this, relativePosition.X, relativePosition.Y);
SDL_SyncWindow(_window);
Int2 newPos;
@@ -1364,6 +1457,8 @@ void SDLWindow::SetPosition(const Float2& position)
newPos = GetPosition();
//if (!(newPos.X == position.X && newPos.Y == position.Y))
// ASSERT(false);
//LOG(Info, "SetPosition before: {}, after {}, relative {}", position, newPos, relativePosition);
}
void SDLWindow::SetClientPosition(const Float2& position)
@@ -1389,9 +1484,9 @@ Float2 SDLWindow::GetPosition() const
SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr);
// The position is relative to the parent window
Int2 position = GetSDLWindowPosition(this);
Int2 position = GetSDLWindowScreenPosition(this);
position -= topLeftBorder;
GetRelativeWindowPosition(this, position);
//GetRelativeWindowPosition(this, position);
return Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
}
@@ -1417,9 +1512,9 @@ Float2 SDLWindow::GetClientSize() const
Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
{
// The position is relative to the parent window
Int2 position = GetSDLWindowPosition(this);
Int2 position2 = position;
GetRelativeWindowPosition(this, position);
Int2 position = GetSDLWindowScreenPosition(this);
//Int2 position2 = position;
//GetRelativeWindowPosition(this, position);
//LOG(Info, "{} pos {}, rel {}", String(StringAnsi(SDL_GetWindowTitle(_window))), position2, position);
if (_settings.Parent != nullptr)
@@ -1434,8 +1529,8 @@ Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
Float2 SDLWindow::ClientToScreen(const Float2& clientPos) const
{
// The position is relative to the parent window
Int2 position = GetSDLWindowPosition(this);
GetRelativeWindowPosition(this, position, true);
Int2 position = GetSDLWindowScreenPosition(this);
//GetRelativeWindowPosition(this, position, true);
return clientPos + Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
}

View File

@@ -114,6 +114,7 @@ namespace FlaxEngine.GUI
Visible = true;
_window.Show();
_showTarget.OnTooltipShown(this);
once = true;
}
/// <summary>
@@ -204,7 +205,7 @@ namespace FlaxEngine.GUI
var rightBottomLocationSS = locationSS + dpiSize;
// Prioritize tooltip placement within parent window, fall back to virtual desktop
if (rightBottomMonitorBounds.Y < rightBottomLocationSS.Y)
/*if (rightBottomMonitorBounds.Y < rightBottomLocationSS.Y)
{
// Direction: up
locationSS.Y -= dpiSize.Y + flipOffset;
@@ -213,9 +214,11 @@ namespace FlaxEngine.GUI
{
// Direction: left
locationSS.X -= dpiSize.X + flipOffset * 2;
}
}*/
}
bool once = true;
/// <inheritdoc />
public override void Update(float deltaTime)
{
@@ -226,7 +229,18 @@ namespace FlaxEngine.GUI
// Auto hide if mouse leaves control area
Hide();
}
else //if (false)
else if (true)
{
if (_window)
_window.Position = _window.Position;
if (once)
{
once = false;
_window.ClientSize = _window.ClientSize + new Float2(2, 2);
}
}
else if (false)
{
// Position tooltip when mouse moves
WrapPosition(ref mousePos, 10);