_window dragging X11 fixed
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-20 22:31:13 +02:00
parent e45075f7d8
commit 3dd9612ae4
7 changed files with 97 additions and 57 deletions

View File

@@ -111,7 +111,7 @@ namespace FlaxEditor.GUI.Docking
window.DoDragDrop("", _dragOffset, window);
}
//window.Show();
//window.BringToFront();
//window.Focus();
@@ -159,7 +159,8 @@ namespace FlaxEditor.GUI.Docking
if (_toMove == null)
return;
_toMove.Window.Window.Opacity = 1.0f;
if (_toMove.Window != null)
_toMove.Window.Window.Opacity = 1.0f;
// Check if window won't be docked
if (_toSet == DockState.Float)
@@ -391,7 +392,7 @@ namespace FlaxEditor.GUI.Docking
// Make sure the all the dock hint areas are not under other windows
_toDock?.RootWindow.Window.BringToFront();
_toMove.RootWindow.Window.BringToFront();
//_toMove.RootWindow.Window.BringToFront(); // Doesn't work on X11
// Make the dragged window transparent when dock hints are visible
_toMove.Window.Window.Opacity = _toDock == null ? 1.0f : 0.4f;

View File

@@ -1595,6 +1595,11 @@ void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
base::SetHighDpiAwarenessEnabled(enable);
}
bool SDLPlatform::UsesWindows()
{
return false;
}
bool SDLPlatform::UsesWayland()
{
if (xDisplay == nullptr && WaylandDisplay == nullptr)

View File

@@ -18,7 +18,7 @@
#if true
Window* draggedWindow = nullptr;
extern Window* draggedWindow;
Float2 draggedWindowStartPosition = Float2::Zero;
Float2 draggedWindowMousePosition = Float2::Zero;
@@ -114,6 +114,26 @@ bool SDLPlatform::InitPlatform()
return false;
}
bool SDLPlatform::UsesWindows()
{
return true;
}
bool SDLPlatform::UsesWayland()
{
return false;
}
bool SDLPlatform::UsesXWayland()
{
return false;
}
bool SDLPlatform::UsesX11()
{
return false;
}
void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
{
// Other supported values: "permonitor", "permonitorv2"

View File

@@ -30,6 +30,11 @@
#define DefaultDPI 96
Window* draggedWindow = nullptr;
#if PLATFORM_WINDOWS
extern Float2 draggedWindowStartPosition;
extern Float2 draggedWindowMousePosition;
#endif
uint32 SDLPlatform::DraggedWindowId = 0;
namespace
@@ -47,7 +52,7 @@ bool SDLPlatform::Init()
SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "wayland", SDL_HINT_OVERRIDE);
else
SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "wayland", SDL_HINT_OVERRIDE);
//SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "x11", SDL_HINT_OVERRIDE);
SDL_SetHintWithPriority(SDL_HINT_VIDEO_DRIVER, "x11", SDL_HINT_OVERRIDE);
#endif
#if PLATFORM_LINUX
@@ -144,10 +149,6 @@ bool SDLPlatform::CheckWindowDragging(Window* window, WindowHitCodes hit)
return handled;
}
extern Window* draggedWindow;
extern Float2 draggedWindowStartPosition;
extern Float2 draggedWindowMousePosition;
void SDLPlatform::Tick()
{
SDLInput::Update();
@@ -209,6 +210,7 @@ void SDLPlatform::Tick()
}
#endif
#if PLATFORM_WINDOWS
auto watch = [](void* userdata, SDL_Event* event) -> bool
{
Window* draggedWindow = *(Window**)userdata;
@@ -264,6 +266,7 @@ void SDLPlatform::Tick()
};
SDL_AddEventWatch(watch, &draggedWindow);
#endif
SDL_PumpEvents();
SDL_Event events[32];
@@ -279,22 +282,35 @@ void SDLPlatform::Tick()
SDLPlatform::HandleEvent(events[i]);
}
#if PLATFORM_WINDOWS
SDL_RemoveEventWatch(watch, &draggedWindow);
#endif
// Handle Windows and X11 window dragging release
if (draggedWindow != nullptr)
{
// We are no longer dragging since event loop is no longer blocked
SDL_Event event{ 0 };
event.button.type = SDL_EVENT_MOUSE_BUTTON_UP;
event.button.down = false;
event.button.timestamp = SDL_GetTicksNS();
event.button.windowID = SDL_GetWindowID(draggedWindow->GetSDLWindow());
event.button.button = SDL_BUTTON_LEFT;
event.button.clicks = 1;
event.button.x = 0;//static_cast<float>(static_cast<LONG>(WINDOWS_GET_X_LPARAM(msg->lParam)));
event.button.y = 0;//static_cast<float>(static_cast<LONG>(WINDOWS_GET_Y_LPARAM(msg->lParam)));
Float2 mousePosition;
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
bool buttonReleased = (buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) == 0;
if (buttonReleased || UsesWindows())
{
// Send simulated mouse up event
SDL_Event buttonUpEvent { 0 };
buttonUpEvent.motion.type = SDL_EVENT_MOUSE_BUTTON_UP;
buttonUpEvent.button.down = false;
buttonUpEvent.motion.windowID = SDL_GetWindowID(draggedWindow->GetSDLWindow());
buttonUpEvent.motion.timestamp = SDL_GetTicksNS();
buttonUpEvent.motion.state = SDL_BUTTON_LEFT;
buttonUpEvent.button.clicks = 1;
buttonUpEvent.motion.x = mousePosition.X;
buttonUpEvent.motion.y = mousePosition.Y;
draggedWindow->HandleEvent(buttonUpEvent);
//SDL_PushEvent(&buttonUpEvent);
SDL_PushEvent(&event);
draggedWindow = nullptr;
SDL_SetWindowAlwaysOnTop(draggedWindow->GetSDLWindow(), false);
draggedWindow->BringToFront();
draggedWindow = nullptr;
}
}
}
@@ -350,18 +366,16 @@ void SDLPlatform::OpenUrl(const StringView& url)
Float2 SDLPlatform::GetMousePosition()
{
Float2 pos;
#if PLATFORM_LINUX
if (UsesWayland())
{
// Wayland doesn't support reporting global mouse position.
// Use the last known reported position we got from window events.
// Wayland doesn't support reporting global mouse position,
// use the last known reported position we got from received window events.
pos = Input::GetMouseScreenPosition();
}
//else
// SDL_GetGlobalMouseState(&pos.X, &pos.Y);
#else
pos = Input::GetMouseScreenPosition();
#endif
else if (UsesX11())
SDL_GetGlobalMouseState(&pos.X, &pos.Y);
else
pos = Input::GetMouseScreenPosition();
return pos;
}
@@ -410,25 +424,6 @@ Window* SDLPlatform::CreateWindow(const CreateWindowSettings& settings)
return New<SDLWindow>(settings);
}
#if !PLATFORM_LINUX
bool SDLPlatform::UsesWayland()
{
return false;
}
bool SDLPlatform::UsesXWayland()
{
return false;
}
bool SDLPlatform::UsesX11()
{
return false;
}
#endif
#if PLATFORM_LINUX
DialogResult MessageBox::Show(Window* parent, const StringView& text, const StringView& caption, MessageBoxButtons buttons, MessageBoxIcon icon)
{

View File

@@ -57,6 +57,7 @@ public:
#if PLATFORM_LINUX
static void* GetXDisplay();
#endif
static bool UsesWindows();
static bool UsesWayland();
static bool UsesXWayland();
static bool UsesX11();

View File

@@ -48,6 +48,8 @@ extern xdg_wm_base* WaylandXdgWmBase;
extern bool waylandDraggingActive;
#endif
extern Window* draggedWindow;
#define DefaultDPI 96
namespace
@@ -406,8 +408,6 @@ SDLWindow* SDLWindow::GetWindowWithSDLWindow(SDL_Window* window)
return nullptr;
}
extern Window* draggedWindow;
void SDLWindow::HandleEvent(SDL_Event& event)
{
if (_isClosing)
@@ -467,13 +467,19 @@ void SDLWindow::HandleEvent(SDL_Event& event)
{
_cachedClientRectangle.Location = Float2(static_cast<float>(event.window.data1), static_cast<float>(event.window.data2));
#if PLATFORM_LINUX
if (SDLPlatform::UsesX11() && !SDLPlatform::UsesXWayland())
if (SDLPlatform::UsesX11())
{
// 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_MASK(SDL_BUTTON_LEFT)) != 0)
SDLPlatform::CheckWindowDragging(this, WindowHitCodes::Caption);
if ((buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) != 0 && draggedWindow == nullptr)
{
// TODO: verify mouse position, window focus
bool result = false;
OnLeftButtonHit(WindowHitCodes::Caption, result);
if (result)
draggedWindow = this;
}
}
#endif
return;
@@ -764,6 +770,7 @@ void SDLWindow::HandleEvent(SDL_Event& event)
#endif
{
LOG(Info, "SDL_EVENT_MOUSE_BUTTON_UP: {}", GetTitle());
#if PLATFORM_WINDOWS
if (draggedWindow != nullptr && draggedWindow->_windowId != event.button.windowID)
{
// Send the button event to dragged window as well
@@ -777,6 +784,7 @@ void SDLWindow::HandleEvent(SDL_Event& event)
SDLInput::HandleEvent(draggedWindow, event2);
}
#endif
}
break;
}
@@ -839,8 +847,8 @@ void SDLWindow::Hide()
SDL_HideWindow(_window);
#if PLATFORM_LINUX
if (SDLPlatform::UsesWayland() && _dragOver)
StopDragging();
//if (SDLPlatform::UsesWayland() && _dragOver)
// StopDragging();
#endif
WindowBase::Hide();
@@ -951,6 +959,14 @@ void SDLWindow::BringToFront(bool force)
SDL_RaiseWindow(_window);
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED, activateWhenRaised);
#endif
if (SDLPlatform::UsesX11())
{
auto activateWhenRaised = SDL_GetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED);
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED, "0");
SDL_RaiseWindow(_window);
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED, activateWhenRaised);
SDL_SyncWindow(_window);
}
}
void SDLWindow::SetClientBounds(const Rectangle& clientArea)
@@ -1311,12 +1327,14 @@ DragDropEffect SDLWindow::DoDragDrop(const StringView& data, const Float2& offse
}
#if PLATFORM_LINUX
if (SDLPlatform::UsesWayland()
if (SDLPlatform::UsesWayland())
DoDragDropWayland(String("notawindow"), dragSourceWindow, dragOffset);
else
#endif
{
SDL_SetWindowAlwaysOnTop(_window, true);
Show();
//draggingActive = true;
/*auto watch = [](void* userdata, SDL_Event* event) -> bool

View File

@@ -103,7 +103,7 @@ public:
String GetTitle() const override;
void SetTitle(const StringView& title) override;
DragDropEffect DoDragDrop(const StringView& data) override;
DragDropEffect DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow);
DragDropEffect DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow) override;
void StartTrackingMouse(bool useMouseScreenOffset) override;
void EndTrackingMouse() override;
void StartClippingCursor(const Rectangle& bounds) override;