diff --git a/Source/Editor/GUI/Docking/DockHintWindow.cs b/Source/Editor/GUI/Docking/DockHintWindow.cs index f7ca09d7c..11c8d8a70 100644 --- a/Source/Editor/GUI/Docking/DockHintWindow.cs +++ b/Source/Editor/GUI/Docking/DockHintWindow.cs @@ -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() diff --git a/Source/Engine/Platform/SDL/SDLInput.cpp b/Source/Engine/Platform/SDL/SDLInput.cpp index 11877d60a..3b4276dbb 100644 --- a/Source/Engine/Platform/SDL/SDLInput.cpp +++ b/Source/Engine/Platform/SDL/SDLInput.cpp @@ -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; diff --git a/Source/Engine/Platform/SDL/SDLPlatform.cpp b/Source/Engine/Platform/SDL/SDLPlatform.cpp index 39cb30da4..dac8dda0e 100644 --- a/Source/Engine/Platform/SDL/SDLPlatform.cpp +++ b/Source/Engine/Platform/SDL/SDLPlatform.cpp @@ -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? diff --git a/Source/Engine/Platform/SDL/SDLWindow.cpp b/Source/Engine/Platform/SDL/SDLWindow.cpp index a008e7461..efb0eab75 100644 --- a/Source/Engine/Platform/SDL/SDLWindow.cpp +++ b/Source/Engine/Platform/SDL/SDLWindow.cpp @@ -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(w), static_cast(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(position.X), static_cast(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(position.X), static_cast(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(position.X), static_cast(position.Y)); } diff --git a/Source/Engine/UI/GUI/Tooltip.cs b/Source/Engine/UI/GUI/Tooltip.cs index 7988159b5..28380084a 100644 --- a/Source/Engine/UI/GUI/Tooltip.cs +++ b/Source/Engine/UI/GUI/Tooltip.cs @@ -114,6 +114,7 @@ namespace FlaxEngine.GUI Visible = true; _window.Show(); _showTarget.OnTooltipShown(this); + once = true; } /// @@ -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; + /// 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);