_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));