diff --git a/Source/Engine/Platform/SDL/SDLInput.cpp b/Source/Engine/Platform/SDL/SDLInput.cpp
index 2aafdf1e5..d9d7b1b58 100644
--- a/Source/Engine/Platform/SDL/SDLInput.cpp
+++ b/Source/Engine/Platform/SDL/SDLInput.cpp
@@ -364,7 +364,10 @@ public:
public:
- Float2 GetMousePosition() const
+ ///
+ /// Returns the previous known position of the mouse before entering relative mode.
+ ///
+ Float2 GetOldMousePosition() const
{
return oldPosition;
}
@@ -480,6 +483,7 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
else
{
const Float2 mousePos = window->ClientToScreen({ event.motion.x, event.motion.y });
+ LOG(Info, "motion {},{}, mouse: {}", event.motion.x, event.motion.y, mousePos);
Input::Mouse->OnMouseMove(mousePos, window);
}
return true;
@@ -509,7 +513,7 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
{
// Use the previous visible mouse position here, the event or global
// mouse position would cause input to trigger in other editor windows.
- mousePos = SDLInputImpl::Mouse->GetMousePosition();
+ mousePos = SDLInputImpl::Mouse->GetOldMousePosition();
}
if (event.button.state == SDL_RELEASED)
@@ -531,7 +535,7 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
{
// Use the previous visible mouse position here, the event or global
// mouse position would cause input to trigger in other editor windows.
- mousePos = SDLInputImpl::Mouse->GetMousePosition();
+ mousePos = SDLInputImpl::Mouse->GetOldMousePosition();
}
Input::Mouse->OnMouseWheel(mousePos, delta, window);
diff --git a/Source/Engine/Platform/SDL/SDLPlatform.Linux.cpp b/Source/Engine/Platform/SDL/SDLPlatform.Linux.cpp
index 4223805f0..bb5d722b3 100644
--- a/Source/Engine/Platform/SDL/SDLPlatform.Linux.cpp
+++ b/Source/Engine/Platform/SDL/SDLPlatform.Linux.cpp
@@ -30,6 +30,7 @@ Delegate LinuxPlatform::xEventReceived;
namespace
{
bool UseWayland = false;
+ bool UseXWayland = false;
X11::Display* xDisplay = nullptr;
X11::XIM IM = nullptr;
X11::XIC IC = nullptr;
@@ -847,7 +848,12 @@ bool SDLPlatform::InitPlatform()
return true;
if (!CommandLine::Options.Headless)
+ {
UseWayland = strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0;
+ String waylandDisplay;
+ if (/*!UseWayland &&*/ !Platform::GetEnvironmentVariable(TEXT("WAYLAND_DISPLAY"), waylandDisplay))
+ UseXWayland = waylandDisplay.Length() > 1;
+ }
return false;
}
@@ -920,7 +926,7 @@ bool SDLPlatform::UsesWayland()
bool SDLPlatform::UsesXWayland()
{
- return false;
+ return UseXWayland;
}
bool SDLPlatform::UsesX11()
diff --git a/Source/Engine/Platform/SDL/SDLPlatform.cpp b/Source/Engine/Platform/SDL/SDLPlatform.cpp
index cf17f1597..d4cb428a7 100644
--- a/Source/Engine/Platform/SDL/SDLPlatform.cpp
+++ b/Source/Engine/Platform/SDL/SDLPlatform.cpp
@@ -41,8 +41,7 @@ bool SDLPlatform::Init()
SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "x11", SDL_HINT_OVERRIDE);
else if (CommandLine::Options.Wayland)
SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "wayland", SDL_HINT_OVERRIDE);
- else
- SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "wayland", SDL_HINT_OVERRIDE);
+ // If the hint is not present, SDL will prefer more stable X11 driver over Wayland
#endif
#if PLATFORM_LINUX
diff --git a/Source/Engine/Platform/SDL/SDLWindow.cpp b/Source/Engine/Platform/SDL/SDLWindow.cpp
index 38c086d8b..44d690d36 100644
--- a/Source/Engine/Platform/SDL/SDLWindow.cpp
+++ b/Source/Engine/Platform/SDL/SDLWindow.cpp
@@ -160,12 +160,29 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
}
// The SDL window position is always relative to the parent window
- if (_settings.Parent != nullptr)
- {
+ //x = 5;
+ //y = 5;
+ if (_settings.Parent != nullptr && SDLPlatform::UsesX11())
+ {//(_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup)
+ //if (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup)
+ {
+ auto parentPosition = _settings.Parent->ClientToScreen(Float2::Zero);
+ x -= Math::TruncToInt(parentPosition.X);
+ y -= Math::TruncToInt(parentPosition.Y);
+ }
+ }
+ else if (_settings.Parent != nullptr)
+ {//(_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup)
auto parentPosition = _settings.Parent->ClientToScreen(Float2::Zero);
x -= Math::TruncToInt(parentPosition.X);
y -= Math::TruncToInt(parentPosition.Y);
}
+ if (SDLPlatform::UsesX11() && _settings.Parent != Engine::MainWindow)
+ {
+ auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ x -= (int)monitorBounds.GetLeft();
+ y -= (int)monitorBounds.GetTop();
+ }
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetNumberProperty(props, "flags", flags);
@@ -272,6 +289,11 @@ void* GetNativeWindowPointer(SDL_Window* window)
return windowPtr;
}
+SDL_Window* SDLWindow::GetSDLWindow() const
+{
+ return _window;
+}
+
#if PLATFORM_LINUX
void* SDLWindow::GetWaylandSurfacePtr() const
@@ -811,6 +833,203 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
SDL_SetWindowSize(_window, (int)clientArea.GetWidth(), (int)clientArea.GetHeight());
}
+Int2 GetSDLWindowPosition(const SDLWindow* window)
+{
+ Int2 position;
+ SDL_GetWindowPosition(window->GetSDLWindow(), &position.X, &position.Y);
+#if PLATFORM_LINUX
+ if (SDLPlatform::UsesX11())
+ {
+ if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
+ {
+ auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ position += Int2(monitorBounds.GetTopLeft());
+ }
+ else
+ {
+ auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ position -= Int2(monitorBounds.GetTopLeft());
+ }
+ }
+#endif
+ return position;
+}
+
+void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen = true)
+{
+ // The relative positioning of windows are very inconsistent in different platforms.
+ // On Windows and X11: The child position is relative to parent windows only for tooltip and popup windows.
+ // 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())
+ {
+ // This is correct for ClientToScreen (mouse position transformation)
+ if (clienttoscreen && window->GetSettings().Type != WindowType::Tooltip && window->GetSettings().Type != WindowType::Popup)
+ return;
+
+ SDLWindow* parent = window->GetSettings().Parent;
+ while (parent != nullptr)
+ {
+ if (parent->GetSettings().Type != WindowType::Tooltip && parent->GetSettings().Type != WindowType::Popup)
+ {
+ Int2 parentPosition = GetSDLWindowPosition(parent);
+ relativePosition += parentPosition;
+ break;
+ }
+ //if (parent->GetSettings().Parent == nullptr || (parent->GetSettings().Type != WindowType::Tooltip && parent->GetSettings().Type != WindowType::Popup))
+ // break;
+ parent = parent->GetSettings().Parent;
+ }
+ /*if (parent != nullptr)
+ {
+ Int2 parentPosition = GetSDLWindowPosition(parent);
+ relativePosition += parentPosition;
+ }*/
+ }
+ else if (SDLPlatform::UsesWayland())
+ {
+ SDLWindow* parent = window->GetSettings().Parent;
+ while (parent != nullptr)
+ {
+ if (parent->GetSettings().Parent == nullptr)
+ break;
+ parent = parent->GetSettings().Parent;
+ }
+ if (parent != nullptr)
+ {
+ Int2 parentPosition = GetSDLWindowPosition(parent);
+ if (SDLPlatform::UsesX11())
+ {
+ relativePosition += parentPosition;
+ auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
+ relativePosition += Int2(monitorBounds.GetTopLeft());
+ //relativePosition += Int2(monitorBounds.GetTopLeft());
+ //relativePosition += Int2(monitorBounds.GetTopLeft());
+ }
+ else
+ relativePosition = parentPosition;
+ }
+ }
+ else
+#endif
+ {
+ SDLWindow* parent;
+ if (SDLPlatform::UsesX11())
+ {
+ parent = (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ? window->GetSettings().Parent : window->GetSettings().Parent;
+ //auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ //relativePosition -= Int2(monitorBounds.GetTopLeft());
+ }
+ else
+ parent = (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ? window->GetSettings().Parent : nullptr;
+ while (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);
+ //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;
+ }
+ }
+}
+
+void SetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition)
+{
+ // The relative positioning of windows are very inconsistent in different platforms.
+ // On Windows and X11: The child position is relative to parent windows only for tooltip and popup windows.
+ // 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())
+ {
+ if (window->GetSettings().Type != WindowType::Tooltip && window->GetSettings().Type != WindowType::Popup)
+ return;
+
+ SDLWindow* parent = window->GetSettings().Parent;
+ while (parent != nullptr)
+ {
+ if (parent->GetSettings().Parent == nullptr || (parent->GetSettings().Type != WindowType::Tooltip && parent->GetSettings().Type != WindowType::Popup))
+ break;
+ parent = parent->GetSettings().Parent;
+ }
+ if (parent != nullptr)
+ {
+ Int2 parentPosition = GetSDLWindowPosition(parent);
+ relativePosition += parentPosition;
+ }
+ }
+ else if (SDLPlatform::UsesWayland())
+ {
+ SDLWindow* parent = window->GetSettings().Parent;
+ while (parent != nullptr)
+ {
+ if (parent->GetSettings().Parent == nullptr)
+ break;
+ parent = parent->GetSettings().Parent;
+ }
+ if (parent != nullptr)
+ {
+ Int2 parentPosition = GetSDLWindowPosition(parent);
+ if (SDLPlatform::UsesX11())
+ {
+ relativePosition += parentPosition;
+ auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
+ relativePosition += Int2(monitorBounds.GetTopLeft());
+ //relativePosition += Int2(monitorBounds.GetTopLeft());
+ //relativePosition += Int2(monitorBounds.GetTopLeft());
+ }
+ else
+ relativePosition -= parentPosition;
+
+ }
+ }
+ else
+#endif
+ {
+ SDLWindow* parent;
+ if (SDLPlatform::UsesX11())
+ {
+ parent = (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ? window->GetSettings().Parent : window->GetSettings().Parent;
+ //auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
+ //relativePosition -= Int2(monitorBounds.GetTopLeft());
+ }
+ else
+ parent = (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ? window->GetSettings().Parent : nullptr;
+ while (parent != nullptr)
+ {
+ Int2 parentPosition = GetSDLWindowPosition(parent);
+ relativePosition += (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*/
+ parent = parent->GetSettings().Parent;
+ }
+ }
+}
+
void SDLWindow::SetPosition(const Float2& position)
{
Int2 topLeftBorder;
@@ -819,16 +1038,8 @@ 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;
-
- SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
- while (parent != nullptr)
- {
- Int2 parentPosition;
- SDL_GetWindowPosition(parent->_window, &parentPosition.X, &parentPosition.Y);
- relativePosition -= parentPosition;
- parent = parent->_settings.Parent;
- }
-
+ GetRelativeWindowPosition(this, relativePosition);
+
SDL_SetWindowPosition(_window, relativePosition.X, relativePosition.Y);
}
@@ -855,18 +1066,10 @@ Float2 SDLWindow::GetPosition() const
SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr);
// The position is relative to the parent window
- Int2 position;
- SDL_GetWindowPosition(_window, &position.X, &position.Y);
+ Int2 position = GetSDLWindowPosition(this);
position -= topLeftBorder;
-
- SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
- while (parent != nullptr)
- {
- Int2 parentPosition;
- SDL_GetWindowPosition(parent->_window, &parentPosition.X, &parentPosition.Y);
- position += parentPosition;
- parent = parent->_settings.Parent;
- }
+ GetRelativeWindowPosition(this, position);
+
return Float2(static_cast(position.X), static_cast(position.Y));
}
@@ -891,16 +1094,15 @@ Float2 SDLWindow::GetClientSize() const
Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
{
// The position is relative to the parent window
- Int2 position;
- SDL_GetWindowPosition(_window, &position.X, &position.Y);
+ Int2 position = GetSDLWindowPosition(this);
+ Int2 position2 = position;
+ GetRelativeWindowPosition(this, position);
- SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
- while (parent != nullptr)
+ //LOG(Info, "{} pos {}, rel {}", String(StringAnsi(SDL_GetWindowTitle(_window))), position2, position);
+ if (_settings.Parent != nullptr)
{
- Int2 parentPosition;
- SDL_GetWindowPosition(parent->_window, &parentPosition.X, &parentPosition.Y);
- position += parentPosition;
- parent = parent->_settings.Parent;
+ //LOG(Info, " parent:");
+ //_settings.Parent->ScreenToClient(screenPos);
}
return screenPos - Float2(static_cast(position.X), static_cast(position.Y));
@@ -909,17 +1111,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;
- SDL_GetWindowPosition(_window, &position.X, &position.Y);
-
- SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
- while (parent != nullptr)
- {
- Int2 parentPosition;
- SDL_GetWindowPosition(parent->_window, &parentPosition.X, &parentPosition.Y);
- position += parentPosition;
- parent = parent->_settings.Parent;
- }
+ Int2 position = GetSDLWindowPosition(this);
+ GetRelativeWindowPosition(this, position, true);
return clientPos + Float2(static_cast(position.X), static_cast(position.Y));
}
diff --git a/Source/Engine/Platform/SDL/SDLWindow.h b/Source/Engine/Platform/SDL/SDLWindow.h
index 126989a6f..c02cc2886 100644
--- a/Source/Engine/Platform/SDL/SDLWindow.h
+++ b/Source/Engine/Platform/SDL/SDLWindow.h
@@ -68,6 +68,7 @@ private:
public:
+ SDL_Window* GetSDLWindow() const;
#if PLATFORM_LINUX
void* GetWaylandSurfacePtr() const;
void* GetWaylandDisplay() const;
diff --git a/Source/Engine/UI/GUI/Tooltip.cs b/Source/Engine/UI/GUI/Tooltip.cs
index 7d9195e18..f88092565 100644
--- a/Source/Engine/UI/GUI/Tooltip.cs
+++ b/Source/Engine/UI/GUI/Tooltip.cs
@@ -81,7 +81,7 @@ namespace FlaxEngine.GUI
// Create window
var desc = CreateWindowSettings.Default;
desc.StartPosition = WindowStartPosition.Manual;
- desc.Position = locationSS;
+ desc.Position = new Vector2(5, 5);//locationSS;
desc.Size = dpiSize;
desc.Fullscreen = false;
desc.HasBorder = false;
@@ -220,9 +220,9 @@ namespace FlaxEngine.GUI
else
{
// Position tooltip when mouse moves
- WrapPosition(ref mousePos, 10);
- if (_window)
- _window.Position = mousePos + new Float2(15, 10);
+ //WrapPosition(ref mousePos, 10);
+ //if (_window)
+ // _window.Position = mousePos + new Float2(15, 10);
}
base.Update(deltaTime);