Fix parent window position handling with popup/tooltip windows
This commit is contained in:
@@ -260,7 +260,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
desc.AllowDragAndDrop = false;
|
desc.AllowDragAndDrop = false;
|
||||||
desc.IsTopmost = true;
|
desc.IsTopmost = true;
|
||||||
desc.Type = WindowType.Popup;
|
desc.Type = WindowType.Popup;
|
||||||
//desc.Parent = parentWin.Window;
|
desc.Parent = parentWin.Window;
|
||||||
desc.HasSizingFrame = false;
|
desc.HasSizingFrame = false;
|
||||||
OnWindowCreating(ref desc);
|
OnWindowCreating(ref desc);
|
||||||
_window = Platform.CreateWindow(ref desc);
|
_window = Platform.CreateWindow(ref desc);
|
||||||
|
|||||||
@@ -128,14 +128,14 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
|
|||||||
WindowsManager::WindowsLocker.Lock();
|
WindowsManager::WindowsLocker.Lock();
|
||||||
for (auto win : WindowsManager::Windows)
|
for (auto win : WindowsManager::Windows)
|
||||||
{
|
{
|
||||||
if (win->IsFocused())
|
if (win->IsForegroundWindow())
|
||||||
{
|
{
|
||||||
if (win->_settings.Type == WindowType::Tooltip || win->_settings.Type == WindowType::Popup)
|
if (win->_settings.Type == WindowType::Tooltip || win->_settings.Type == WindowType::Popup)
|
||||||
{
|
{
|
||||||
auto focusedParent = win->_settings.Parent;
|
auto focusedParent = win->_settings.Parent;
|
||||||
while (focusedParent != nullptr)
|
while (focusedParent != nullptr)
|
||||||
{
|
{
|
||||||
if (focusedParent->_settings.Type != WindowType::Tooltip && focusedParent->_settings.Type != WindowType::Popup)
|
if (focusedParent->_settings.Parent == nullptr)
|
||||||
{
|
{
|
||||||
_settings.Parent = focusedParent;
|
_settings.Parent = focusedParent;
|
||||||
break;
|
break;
|
||||||
@@ -157,7 +157,7 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
|
|||||||
// The SDL window position is always relative to the parent window
|
// The SDL window position is always relative to the parent window
|
||||||
if (_settings.Parent != nullptr)
|
if (_settings.Parent != nullptr)
|
||||||
{
|
{
|
||||||
auto parentPosition = _settings.Parent->GetPosition();
|
auto parentPosition = _settings.Parent->ClientToScreen(Float2::Zero);
|
||||||
x -= Math::TruncToInt(parentPosition.X);
|
x -= Math::TruncToInt(parentPosition.X);
|
||||||
y -= Math::TruncToInt(parentPosition.Y);
|
y -= Math::TruncToInt(parentPosition.Y);
|
||||||
}
|
}
|
||||||
@@ -169,16 +169,13 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
|
|||||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y);
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, windowWidth);
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, windowWidth);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, windowHeight);
|
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, windowHeight);
|
||||||
|
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN, SDL_TRUE);
|
||||||
if ((flags & SDL_WINDOW_TOOLTIP) != 0)
|
if ((flags & SDL_WINDOW_TOOLTIP) != 0)
|
||||||
{
|
|
||||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, SDL_TRUE);
|
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, SDL_TRUE);
|
||||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, _settings.Parent->_window);
|
|
||||||
}
|
|
||||||
else if ((flags & SDL_WINDOW_POPUP_MENU) != 0)
|
else if ((flags & SDL_WINDOW_POPUP_MENU) != 0)
|
||||||
{
|
|
||||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MENU_BOOLEAN, SDL_TRUE);
|
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MENU_BOOLEAN, SDL_TRUE);
|
||||||
|
if (_settings.Parent != nullptr)
|
||||||
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, _settings.Parent->_window);
|
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, _settings.Parent->_window);
|
||||||
}
|
|
||||||
|
|
||||||
_window = SDL_CreateWindowWithProperties(props);
|
_window = SDL_CreateWindowWithProperties(props);
|
||||||
if (_window == nullptr)
|
if (_window == nullptr)
|
||||||
@@ -841,27 +838,28 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
|
|||||||
|
|
||||||
void SDLWindow::SetPosition(const Float2& position)
|
void SDLWindow::SetPosition(const Float2& position)
|
||||||
{
|
{
|
||||||
int top, left, bottom, right;
|
Int2 topLeftBorder;
|
||||||
SDL_GetWindowBordersSize(_window, &top, &left, &bottom, &right);
|
SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr);
|
||||||
|
|
||||||
// The position is relative to the parent window
|
// The position is relative to the parent window
|
||||||
Float2 newPosition = position;
|
Int2 relativePosition(static_cast<int>(position.X), static_cast<int>(position.Y));
|
||||||
SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
|
relativePosition += topLeftBorder;
|
||||||
if (parent != nullptr)
|
|
||||||
newPosition -= parent->GetClientPosition();
|
|
||||||
|
|
||||||
SDL_SetWindowPosition(_window, static_cast<int>(newPosition.X) + left, static_cast<int>(newPosition.Y) + top);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetWindowPosition(_window, relativePosition.X, relativePosition.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLWindow::SetClientPosition(const Float2& position)
|
void SDLWindow::SetClientPosition(const Float2& position)
|
||||||
{
|
{
|
||||||
// The position is relative to the parent window
|
SDL_SetWindowPosition(_window, static_cast<int>(position.X), static_cast<int>(position.Y));
|
||||||
Float2 newPosition = position;
|
|
||||||
SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
|
|
||||||
if (parent != nullptr)
|
|
||||||
newPosition -= parent->GetClientPosition();
|
|
||||||
|
|
||||||
SDL_SetWindowPosition(_window, static_cast<int>(newPosition.X), static_cast<int>(newPosition.Y));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLWindow::SetIsFullscreen(bool isFullscreen)
|
void SDLWindow::SetIsFullscreen(bool isFullscreen)
|
||||||
@@ -878,16 +876,23 @@ void SDLWindow::SetIsFullscreen(bool isFullscreen)
|
|||||||
|
|
||||||
Float2 SDLWindow::GetPosition() const
|
Float2 SDLWindow::GetPosition() const
|
||||||
{
|
{
|
||||||
int top, left, bottom, right;
|
Int2 topLeftBorder;
|
||||||
SDL_GetWindowBordersSize(_window, &top, &left, &bottom, &right);
|
SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr);
|
||||||
|
|
||||||
// The position is relative to the parent window
|
// The position is relative to the parent window
|
||||||
Float2 newPosition = GetClientPosition();
|
Int2 position;
|
||||||
SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
|
SDL_GetWindowPosition(_window, &position.X, &position.Y);
|
||||||
if (parent != nullptr)
|
position -= topLeftBorder;
|
||||||
newPosition += parent->GetClientPosition();
|
|
||||||
|
|
||||||
return newPosition - Float2(static_cast<float>(left), static_cast<float>(top));
|
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;
|
||||||
|
}
|
||||||
|
return Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
Float2 SDLWindow::GetSize() const
|
Float2 SDLWindow::GetSize() const
|
||||||
@@ -910,42 +915,38 @@ Float2 SDLWindow::GetClientSize() const
|
|||||||
|
|
||||||
Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
|
Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
|
||||||
{
|
{
|
||||||
#if PLATFORM_LINUX
|
// The position is relative to the parent window
|
||||||
auto res1 = screenPos - GetPosition();
|
Int2 position;
|
||||||
auto res1b = screenPos - GetClientPosition();
|
SDL_GetWindowPosition(_window, &position.X, &position.Y);
|
||||||
|
|
||||||
X11::Display* display = (X11::Display*)GetX11Display();
|
SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
|
||||||
if (display)
|
while (parent != nullptr)
|
||||||
{
|
{
|
||||||
X11::Window window = (X11::Window)GetX11WindowHandle();
|
Int2 parentPosition;
|
||||||
if (!display)
|
SDL_GetWindowPosition(parent->_window, &parentPosition.X, &parentPosition.Y);
|
||||||
return screenPos;
|
position += parentPosition;
|
||||||
int32 x, y;
|
parent = parent->_settings.Parent;
|
||||||
X11::Window child;
|
|
||||||
X11::XTranslateCoordinates(display, X11_DefaultRootWindow(display), window, (int32)screenPos.X, (int32)screenPos.Y, &x, &y, &child);
|
|
||||||
|
|
||||||
auto res2 = Float2((float)x, (float)y);
|
|
||||||
if (Float2::DistanceSquared(res1b, res2) > 1)
|
|
||||||
res1 = res1;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return screenPos - GetClientPosition();
|
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
|
||||||
{
|
{
|
||||||
int x, y;
|
// The position is relative to the parent window
|
||||||
SDL_GetWindowPosition(_window, &x, &y);
|
Int2 position;
|
||||||
|
SDL_GetWindowPosition(_window, &position.X, &position.Y);
|
||||||
|
|
||||||
SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
|
SDLWindow* parent = (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) ? _settings.Parent : nullptr;
|
||||||
if (parent != nullptr)
|
while (parent != nullptr)
|
||||||
{
|
{
|
||||||
Float2 parentPos = parent->ClientToScreen(Float2::Zero);
|
Int2 parentPosition;
|
||||||
x += static_cast<int>(parentPos.X);
|
SDL_GetWindowPosition(parent->_window, &parentPosition.X, &parentPosition.Y);
|
||||||
y += static_cast<int>(parentPos.Y);
|
position += parentPosition;
|
||||||
|
parent = parent->_settings.Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientPos + Float2(static_cast<float>(x), static_cast<float>(y));
|
return clientPos + Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDLWindow::FlashWindow()
|
void SDLWindow::FlashWindow()
|
||||||
|
|||||||
Reference in New Issue
Block a user