From 089346b296906cb6a275b3156f48cb40c0b30823 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 28 Dec 2024 19:41:06 +0200 Subject: [PATCH] _x11 child tooltip fixes progress --- .../Editor/GUI/ContextMenu/ContextMenuBase.cs | 2 + Source/Engine/Platform/SDL/SDLInput.cpp | 2 +- Source/Engine/Platform/SDL/SDLPlatform.cpp | 1 + Source/Engine/Platform/SDL/SDLWindow.cpp | 105 ++++++++++++++---- Source/Engine/UI/GUI/Tooltip.cs | 20 +--- 5 files changed, 95 insertions(+), 35 deletions(-) diff --git a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs index 72244c47c..e9e01f4df 100644 --- a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs +++ b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs @@ -206,6 +206,7 @@ namespace FlaxEditor.GUI.ContextMenu // Create window var desc = CreateWindowSettings.Default; desc.Position = locationSS; + Editor.Log($"contextmenu loc: {locationSS}, in parentloc: {location}"); desc.StartPosition = WindowStartPosition.Manual; desc.Size = dpiSize; desc.Fullscreen = false; @@ -220,6 +221,7 @@ namespace FlaxEditor.GUI.ContextMenu desc.IsTopmost = true; desc.Type = WindowType.Popup; desc.Parent = parentWin.Window; + desc.Title = "ContextMenu"; desc.HasSizingFrame = false; OnWindowCreating(ref desc); _window = Platform.CreateWindow(ref desc); diff --git a/Source/Engine/Platform/SDL/SDLInput.cpp b/Source/Engine/Platform/SDL/SDLInput.cpp index 16507130d..d67226189 100644 --- a/Source/Engine/Platform/SDL/SDLInput.cpp +++ b/Source/Engine/Platform/SDL/SDLInput.cpp @@ -483,7 +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); + LOG(Info, "motion {},{}, mouse: {}, win: {}", event.motion.x, event.motion.y, mousePos, String(window->GetTitle())); Input::Mouse->OnMouseMove(mousePos, window); } return true; diff --git a/Source/Engine/Platform/SDL/SDLPlatform.cpp b/Source/Engine/Platform/SDL/SDLPlatform.cpp index 4e85c629b..adfe7c91c 100644 --- a/Source/Engine/Platform/SDL/SDLPlatform.cpp +++ b/Source/Engine/Platform/SDL/SDLPlatform.cpp @@ -43,6 +43,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); + //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 diff --git a/Source/Engine/Platform/SDL/SDLWindow.cpp b/Source/Engine/Platform/SDL/SDLWindow.cpp index 62a18279f..67a3fa5b2 100644 --- a/Source/Engine/Platform/SDL/SDLWindow.cpp +++ b/Source/Engine/Platform/SDL/SDLWindow.cpp @@ -105,6 +105,8 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) int32 windowHeight = clientHeight; _clientSize = Float2((float)clientWidth, (float)clientHeight); + + if (SDLPlatform::UsesWayland()) { // The compositor seems to crash when something is rendered to the hidden popup window surface @@ -146,10 +148,13 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) { if (win->IsForegroundWindow()) { + _settings.Parent = win; + break; if (win->_settings.Type == WindowType::Tooltip || win->_settings.Type == WindowType::Popup) { auto focusedParent = win->_settings.Parent; - while (focusedParent != nullptr) + _settings.Parent = win; + while (focusedParent != nullptr && (focusedParent->_settings.Type == WindowType::Tooltip || focusedParent->_settings.Type == WindowType::Popup)) { if (focusedParent->_settings.Parent == nullptr) { @@ -157,7 +162,20 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) break; } focusedParent = focusedParent->_settings.Parent; + //_settings.Parent = focusedParent; + //break; } + /*while (focusedParent != nullptr) + { + if (focusedParent->_settings.Parent == nullptr) + { + _settings.Parent = focusedParent; + break; + } + focusedParent = focusedParent->_settings.Parent; + //_settings.Parent = focusedParent; + //break; + }*/ } else _settings.Parent = win; @@ -169,12 +187,31 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) if (_settings.Parent == nullptr) _settings.Parent = Engine::MainWindow; } + else if (_settings.Parent != nullptr && _settings.Parent->_settings.Type != WindowType::Regular && (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup)) + { + auto parent = _settings.Parent->GetSettings().Parent; + while (parent != nullptr) + { + _settings.Parent = parent; + if (_settings.Parent->_settings.Type == WindowType::Regular) + break; + parent = _settings.Parent->GetSettings().Parent; + } + } + 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 - //x = 5; - //y = 5; + Int2 oldpos(x, y); - if (_settings.Parent != nullptr && SDLPlatform::UsesX11()) + if (false && _settings.Parent != nullptr && SDLPlatform::UsesX11()) {//(_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) //if (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup) { @@ -191,26 +228,39 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) 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) { - auto parentParentPosition = parentParent->ClientToScreen(Float2::Zero); - x -= Math::TruncToInt(parentParentPosition.X); - y -= Math::TruncToInt(parentParentPosition.Y); + //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; + }*/ } } if (SDLPlatform::UsesX11() && _settings.Parent != Engine::MainWindow) { - if (_settings.Parent->GetSettings().Type == WindowType::Tooltip || _settings.Parent->GetSettings().Type == WindowType::Popup) + /*if (_settings.Parent->GetSettings().Type == WindowType::Tooltip || _settings.Parent->GetSettings().Type == WindowType::Popup) { } else { - /*auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum); + *//*auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum); x -= (int)monitorBounds.GetLeft(); y -= (int)monitorBounds.GetTop();*/ - } + //} } Int2 oldpos2(x, y); @@ -240,7 +290,7 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) _handle = GetNativeWindowPointer(_window); ASSERT(_handle != nullptr); - SDL_SyncWindow(_window); + //SDL_SyncWindow(_window); #if PLATFORM_LINUX if (SDLPlatform::UsesWayland()) @@ -263,9 +313,9 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings) SDL_GetWindowSizeInPixels(_window, &rect.w, &rect.h); _cachedClientRectangle = Rectangle((float)rect.x, (float)rect.y, (float)rect.w, (float)rect.h); - Int2 newpos = GetClientPosition(); + /*Int2 newpos = GetClientPosition(); //Int2 newposclient = GetClientPosition(); - LOG(Info, "new window at {}, input {}, expected: {}", newpos, oldpos, oldpos2); + LOG(Info, "new window at {}, input {}, expected: {}", newpos, oldpos, oldpos2);*/ //ASSERT(newpos == oldpos || newpos == oldpos2); /*oldpos = newpos; @@ -543,7 +593,7 @@ void SDLWindow::HandleEvent(SDL_Event& event) // X11 doesn't report any mouse events when mouse is over the caption area, send a simulated event instead... Float2 mousePosition; auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y); - if ((buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0) + if ((buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) != 0) SDLPlatform::CheckWindowDragging(this, WindowHitCodes::Caption); } #endif @@ -682,12 +732,11 @@ void SDLWindow::HandleEvent(SDL_Event& event) { SDL_DisplayID display = SDL_GetDisplayForWindow(_window); float scale = SDL_GetDisplayContentScale(display); - if (scale > 0.0f) + if (scale > 0.0f && _dpiScale != scale) { float oldScale = _dpiScale; _dpiScale = scale; _dpi = (int)(_dpiScale * DefaultDPI); - int w = (int)(_cachedClientRectangle.GetWidth() * (scale / oldScale)); int h = (int)(_cachedClientRectangle.GetHeight() * (scale / oldScale)); SDL_SetWindowSize(_window, w, h); @@ -930,12 +979,20 @@ void SDLWindow::BringToFront(bool force) void SDLWindow::SetClientBounds(const Rectangle& clientArea) { + int oldX, oldY; + int oldW, oldH; + SDL_GetWindowPosition(_window, &oldX, &oldY); + SDL_GetWindowSizeInPixels(_window, &oldW, &oldH); + SDL_SetWindowPosition(_window, (int)clientArea.GetLeft(), (int)clientArea.GetTop()); SDL_SetWindowSize(_window, (int)clientArea.GetWidth(), (int)clientArea.GetHeight()); + + LOG(Info, "SetClientBounds changed from ({},{} {}x{}) to ({},{} {}x{})", oldX, oldY, oldW, oldH, + (int)clientArea.GetLeft(), (int)clientArea.GetTop(), (int)clientArea.GetWidth(), (int)clientArea.GetHeight()); } Int2 GetSDLWindowPosition(const SDLWindow* window) -{ +{ Int2 position; SDL_GetWindowPosition(window->GetSDLWindow(), &position.X, &position.Y); #if PLATFORM_LINUX @@ -943,9 +1000,17 @@ Int2 GetSDLWindowPosition(const SDLWindow* window) { if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) { - Int2 parentPosition = GetSDLWindowPosition(window->GetSettings().Parent); + auto parent = window->GetSettings().Parent; + while (parent->GetSettings().Parent != nullptr) + { + Int2 rootParentPosition = GetSDLWindowPosition(parent); + //SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y); + position += rootParentPosition; + parent = parent->GetSettings().Parent; + } + Int2 rootParentPosition = GetSDLWindowPosition(parent); //SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y); - position += parentPosition; + position += rootParentPosition; auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum); //position += Int2(monitorBounds.GetTopLeft()); //auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum); @@ -977,6 +1042,7 @@ void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, //clienttoscreen = false; if (SDLPlatform::UsesX11()) { +#if false // This is correct for ClientToScreen (mouse position transformation) if (clienttoscreen && window->GetSettings().Type != WindowType::Tooltip && window->GetSettings().Type != WindowType::Popup) return; @@ -999,6 +1065,7 @@ void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, Int2 parentPosition = GetSDLWindowPosition(parent); relativePosition += parentPosition; }*/ +#endif } else if (SDLPlatform::UsesWayland()) { diff --git a/Source/Engine/UI/GUI/Tooltip.cs b/Source/Engine/UI/GUI/Tooltip.cs index 219b2ee05..ddc45b7c7 100644 --- a/Source/Engine/UI/GUI/Tooltip.cs +++ b/Source/Engine/UI/GUI/Tooltip.cs @@ -82,15 +82,13 @@ namespace FlaxEngine.GUI _showTarget = target; //WrapPosition(ref locationSS); WrapPosition(ref mousePos, 10); - locationSS = mousePos + new Float2(15, 10); - var ppp = Input.MouseScreenPosition; - //locationSS = new Float2(5, 5); - var bef = locationSS; + locationSS = mousePos; // Create window var desc = CreateWindowSettings.Default; desc.StartPosition = WindowStartPosition.Manual; desc.Position = locationSS; + Editor.Log($"tooltip pos: {Input.MouseScreenPosition}, in parentloc: {location}"); desc.Size = dpiSize; desc.Fullscreen = false; desc.HasBorder = false; @@ -103,8 +101,10 @@ namespace FlaxEngine.GUI desc.AllowDragAndDrop = false; desc.IsTopmost = true; desc.Type = WindowType.Tooltip; + desc.Title = "Tooltip"; desc.HasSizingFrame = false; desc.ShowAfterFirstPaint = true; + desc.Parent = parentWin.RootWindow.Window; _window = Platform.CreateWindow(ref desc); if (_window == null) throw new InvalidOperationException("Failed to create tooltip window."); @@ -114,9 +114,6 @@ namespace FlaxEngine.GUI Visible = true; _window.Show(); _showTarget.OnTooltipShown(this); - - var aff = _window.Position; - Editor.Log($"tooltip startpos: before: {bef}, after {aff}"); } /// @@ -229,19 +226,12 @@ namespace FlaxEngine.GUI // Auto hide if mouse leaves control area Hide(); } - else + else if (false) { // Position tooltip when mouse moves - var ppp = Input.MouseScreenPosition; - var bef = _window.Position; WrapPosition(ref mousePos, 10); - mousePos += new Float2(15, 10); - //mousePos = new Float2(5, 5); - if (_window) _window.Position = mousePos; - var aff = _window.Position; - Editor.Log($"tooltip updatepos: before: {bef}, new {mousePos}, after {aff}"); } base.Update(deltaTime);