_wayland dragging good

This commit is contained in:
2025-01-10 11:28:22 +02:00
parent 2fc6e95ec3
commit ce5cfa6b21
4 changed files with 63 additions and 22 deletions

View File

@@ -2,6 +2,8 @@
#include <errno.h>
#include "Engine/Engine/Time.h"
#include "Engine/Graphics/RenderTask.h"
#include "Engine/Platform/Base/DragDropHelper.h"
#include "Engine/Platform/Unix/UnixFile.h"
@@ -576,14 +578,14 @@ public:
int64 ExitFlag = 0;
StringView data;
SDLWindow* window;
SDLWindow* mainwindow;
int64 dragOver = 0;
int64 waitFlag = 0;
// [ThreadPoolTask]
bool Run() override
{
Scripting::GetScriptsDomain()->Dispatch();
bool dragWindow = data == String("notawindow");
wl_display* wrappedDisplay = WaylandDisplay;//(wl_display*)wl_proxy_create_wrapper(WaylandDisplay);
//wl_proxy_set_queue((wl_proxy*)wrappedDisplay, queue);
@@ -614,7 +616,7 @@ public:
/*auto */dataDevice = wl_data_device_manager_get_data_device(wrappedManager, WaylandSeat);
wl_data_device_add_listener(dataDevice, &WaylandDataDeviceListener, nullptr);
wl_display_roundtrip(wrappedDisplay);
wl_data_device_set_user_data(dataDevice, window);
wl_data_device_set_user_data(dataDevice, dragWindow ? mainwindow : window);
wrappedDataDevice = (wl_data_device*)wl_proxy_create_wrapper(dataDevice);
wl_proxy_set_queue((wl_proxy*)wrappedDataDevice, WaylandQueue);
}
@@ -623,7 +625,7 @@ public:
dataSource = wl_data_device_manager_create_data_source(wrappedManager);
wrappedDataSource = (wl_data_source*)wl_proxy_create_wrapper(dataSource);
wl_proxy_set_queue((wl_proxy*)wrappedDataSource, WaylandQueue);
if (data == String("awindow"))
if (dragWindow)
{
wl_data_source_offer(dataSource, "flaxengine/window");
wl_data_source_offer(dataSource, "text/plain;charset=utf-8"); // TODO: needs support for custom mime-types in SDL
@@ -641,6 +643,9 @@ public:
textData.Window = window;
textData.dragOver = &dragOver;
auto _window = window->GetSDLWindow();
auto _mainwindow = mainwindow->GetSDLWindow();
//if (!window->IsVisible())
// _window = mainwindow->GetSDLWindow();
//wl_data_source_set_user_data(wrappedDataSource, &textData);
wl_data_source_add_listener(dataSource, &WaylandDataSourceListener, &textData);
@@ -660,13 +665,13 @@ public:
xdg_toplevel* wrappedToplevel = nullptr;
{
wl_surface* origin = (wl_surface*)SDL_GetPointerProperty(SDL_GetWindowProperties(_window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
wl_surface* origin = (wl_surface*)SDL_GetPointerProperty(SDL_GetWindowProperties(_mainwindow), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
wl_surface* icon = nullptr;
uint32 id = ImplicitGrabSerial;
//id = (uint32)SDL_GetNumberProperty(SDL_GetGlobalProperties(), "wayland.serial", 0);
wl_data_device_start_drag((wl_data_device*)SDL_GetPointerProperty(SDL_GetGlobalProperties(), "wayland.data_device", wrappedDataDevice), dataSource, origin, icon, id);
if (data == String("awindow"))
if (dragWindow)
{
if (toplevel != nullptr)
{
@@ -729,7 +734,7 @@ public:
if (wl_display_roundtrip_queue(wrappedDisplay, WaylandQueue) == -1)
LOG(Warning, "err wl_display_roundtrip_queue: {}", errno);
if (toplevel == nullptr && data == String("awindow"))
if (toplevel == nullptr && dragWindow)
{
if (Platform::AtomicRead(&waitFlag) != 0)
{
@@ -811,11 +816,45 @@ DragDropEffect Window::DoDragDropWayland(const StringView& data)
// For drag-and-drop, we need to setup the event queue in separate thread to avoid racing issues
// while SDL is dispatching the main Wayland event queue when receiving the data offer from us.
// Show()?
{
if (!_visible)
{
if (_showAfterFirstPaint)
{
if (RenderTask)
RenderTask->Enabled = true;
}
else
SDL_ShowWindow(_window);
}
WindowBase::Show();
}
//while (true)
{
const double time = Platform::GetTimeSeconds();
// Update game logic
if (Time::OnBeginUpdate(time))
{
Engine::OnUpdate();
Engine::OnLateUpdate();
Time::OnEndUpdate();
}
SDLPlatform::Tick();
Engine::OnDraw();
Platform::Sleep(1);
}
waylandDraggingActive = true;
auto task = New<WaylandDragDropJob>();
task->data = data;
task->window = this;
task->mainwindow = Engine::MainWindow;
task->dragOver = 0;
Task::StartNew(task);
while (task->GetState() == TaskState::Queued)
@@ -826,15 +865,15 @@ DragDropEffect Window::DoDragDropWayland(const StringView& data)
Platform::Sleep(1);
}
Show();
//Show();
//Focus();
int counter = 100;
while (Platform::AtomicRead(&task->dragOver) == 0)
{
SDLPlatform::Tick();
Engine::OnUpdate(); // For docking updates
Engine::OnDraw();
//Scripting::Update(); // For docking updates
//Engine::OnDraw();
Platform::Sleep(1);
@@ -1720,7 +1759,7 @@ void WaylandRegistryGlobal(void* data, wl_registry *registry, uint32 id, const c
StringAnsi interfaceStr(interface);
//LOG(Info, "WaylandRegistryGlobal id: {}, interface: {}", id, String(interface));
if (interfaceStr == "xdg_toplevel_drag_manager_v1")
DragManager = (xdg_toplevel_drag_manager_v1*)wl_registry_bind(registry, id, &xdg_toplevel_drag_manager_v1_interface, 1U);
DragManager = (xdg_toplevel_drag_manager_v1*)wl_registry_bind(registry, id, &xdg_toplevel_drag_manager_v1_interface, Math::Min(1U, version));
else if (interfaceStr == "wl_seat")
{
WaylandSeat = (wl_seat*)wl_registry_bind(registry, id, &wl_seat_interface, Math::Min(9U, version));

View File

@@ -144,8 +144,8 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
flags |= SDL_WINDOW_TRANSPARENT;
// Disable parenting of child windows as those are always on top of the parent window and never show up in taskbar
//if (_settings.Parent != nullptr && (_settings.Type != WindowType::Tooltip && _settings.Type != WindowType::Popup))
// _settings.Parent = nullptr;
if (_settings.Parent != nullptr && (_settings.Type != WindowType::Tooltip && _settings.Type != WindowType::Popup))
_settings.Parent = nullptr;
if (_settings.Parent != nullptr && _settings.Parent->_settings.Type != WindowType::Regular && (_settings.Type == WindowType::Tooltip || _settings.Type == WindowType::Popup))
{
@@ -406,7 +406,7 @@ SDLWindow* SDLWindow::GetWindowWithSDLWindow(SDL_Window* window)
void SDLWindow::HandleEvent(SDL_Event& event)
{
if (_isClosing)
if (_isClosing || waylandDraggingActive)
return;
switch (event.type)
@@ -792,10 +792,10 @@ void SDLWindow::Show()
}
SDL_ShowWindow(_window);
if (_settings.AllowInput && _settings.ActivateWhenFirstShown)
/*if (_settings.AllowInput && _settings.ActivateWhenFirstShown)
Focus();
else if (_settings.Parent == nullptr)
BringToFront();
BringToFront();*/
// Reused top-most windows (DockHintWindow) doesn't stay on top for some reason
if (_settings.IsTopmost && _settings.Type != WindowType::Tooltip)
@@ -925,10 +925,10 @@ bool SDLWindow::IsForegroundWindow() const
void SDLWindow::BringToFront(bool force)
{
auto activateWhenRaised = SDL_GetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED);
/*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_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_RAISED, activateWhenRaised);*/
}
void SDLWindow::SetClientBounds(const Rectangle& clientArea)
@@ -1108,7 +1108,7 @@ String SDLWindow::GetTitle() const
void SDLWindow::SetTitle(const StringView& title)
{
SDL_SetWindowTitle(_window, title.ToStringAnsi().Get());
//SDL_SetWindowTitle(_window, title.ToStringAnsi().Get());
}
void SDLWindow::StartTrackingMouse(bool useMouseScreenOffset)
@@ -1303,7 +1303,7 @@ void SDLWindow::StartDragging(const Float2& offset)
{
LOG(Info, "StartDragging {}", offset);
DoDragDropWayland(String("awindow"));
DoDragDropWayland(String("notawindow"));
/*
_dragOver = true;