some linux work from summer
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled

This commit is contained in:
2025-10-12 18:06:23 +03:00
parent eca4f6d9bc
commit c1f6bcb83f
16 changed files with 283 additions and 45 deletions

View File

@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
# Build bindings for all editor configurations # Build bindings for all editor configurations
echo Building C# bindings... echo Building C# bindings...
# TODO: Detect the correct architecture here # TODO: Detect the correct architecture here
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor #Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor

View File

@@ -20,6 +20,6 @@
#define PLATFORM_DESKTOP 1 #define PLATFORM_DESKTOP 1
#define PLATFORM_CACHE_LINE_SIZE 128 #define PLATFORM_CACHE_LINE_SIZE 128
#define PLATFORM_HAS_HEADLESS_MODE 1 #define PLATFORM_HAS_HEADLESS_MODE 1
#define PLATFORM_DEBUG_BREAK __asm__ volatile("int $0x03") #define PLATFORM_DEBUG_BREAK __asm volatile("int $0x03")
#endif #endif

View File

@@ -32,6 +32,7 @@
#include <SDL3/SDL_video.h> #include <SDL3/SDL_video.h>
#include <errno.h> #include <errno.h>
#include <poll.h>
#include <wayland/xdg-shell.h> #include <wayland/xdg-shell.h>
#include <wayland/xdg-toplevel-drag-v1.h> #include <wayland/xdg-toplevel-drag-v1.h>
@@ -81,6 +82,8 @@ public:
namespace WaylandImpl namespace WaylandImpl
{ {
bool DraggingActive = false;
bool DraggingWindow = false;
wl_display* WaylandDisplay = nullptr; wl_display* WaylandDisplay = nullptr;
int64 DragOverFlag = 0; int64 DragOverFlag = 0;
int64 Serial = 0; int64 Serial = 0;
@@ -88,7 +91,11 @@ namespace WaylandImpl
{ {
[](void* data, wl_pointer* wl_pointer, uint32_t serial, wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { }, // Enter event [](void* data, wl_pointer* wl_pointer, uint32_t serial, wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { }, // Enter event
[](void* data, wl_pointer* wl_pointer, uint32_t serial, wl_surface* surface) { }, // Leave event [](void* data, wl_pointer* wl_pointer, uint32_t serial, wl_surface* surface) { }, // Leave event
[](void* data, wl_pointer* wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { }, // Motion event [](void* data, wl_pointer* wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
{
//if (DraggingActive && DraggingWindow)
// LOG(Info, "point {} {}", surface_x, surface_y);
}, // Motion event
[](void* data, wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) // Button event [](void* data, wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) // Button event
{ {
// Store the serial for upcoming drag-and-drop action // Store the serial for upcoming drag-and-drop action
@@ -138,26 +145,86 @@ namespace WaylandImpl
else if (interfaceStr == "wl_data_device_manager") else if (interfaceStr == "wl_data_device_manager")
DataDeviceManager = static_cast<wl_data_device_manager*>(wl_registry_bind(registry, id, &wl_data_device_manager_interface, Math::Min(3U, version))); DataDeviceManager = static_cast<wl_data_device_manager*>(wl_registry_bind(registry, id, &wl_data_device_manager_interface, Math::Min(3U, version)));
}, },
[] (void* data, wl_registry* registry, uint32 id) { }, // Announce global remove event [](void* data, wl_registry* registry, uint32 id) { }, // Announce global remove event
}; };
wl_data_offer* DataOffer = nullptr; // The last accepted offer wl_data_offer* DataOffer = nullptr; // The last accepted offer
StringAnsi DataOfferAcceptedOffer = StringAnsi::Empty;
wl_data_offer_listener DataOfferListener =
{
[](void* data, wl_data_offer* id, const char* mime_type)
{
LOG(Info, "mime: {}", String(mime_type));
if (StringAnsi(mime_type) == "text/plain" && DataOfferAcceptedOffer.IsEmpty())
DataOfferAcceptedOffer = mime_type;
else if (StringAnsi(mime_type) == "flaxengine/window")
DataOfferAcceptedOffer = mime_type;
}, // Offer event
[](void* data, wl_data_offer* id, uint32_t source_actions)
{
LOG(Info, "source actions?");
}, // Source Actions event
[](void* data, wl_data_offer* id, uint32_t dnd_action)
{
LOG(Info, "dnd actions?");
}, // DnD Action event
};
Float2 LastDropPosition = Float2::Zero;
StringView DraggingData = nullptr;
StringAnsi DraggingData2 = nullptr;
wl_data_offer* SelectionOffer = nullptr; wl_data_offer* SelectionOffer = nullptr;
wl_data_device_listener DataDeviceListener = wl_data_device_listener DataDeviceListener =
{ {
[](void* data, wl_data_device* data_device, wl_data_offer* id) { }, // Data offer event [](void* data, wl_data_device* data_device, wl_data_offer* id)
{
LOG(Info, "device offer?");
DataOfferAcceptedOffer = StringAnsi::Empty;
wl_data_offer_add_listener(id, &DataOfferListener, nullptr);
}, // Data offer event
[](void* data, wl_data_device* data_device, uint32 serial, wl_surface* surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer* id) // Enter event [](void* data, wl_data_device* data_device, uint32 serial, wl_surface* surface, wl_fixed_t x, wl_fixed_t y, wl_data_offer* id) // Enter event
{ {
DataOffer = id; DataOffer = id;
SDLWindow* sourceWindow = (SDLWindow*)data; SDLWindow* sourceWindow = (SDLWindow*)data;
if (sourceWindow == nullptr && surface != nullptr)
{
WindowsManager::WindowsLocker.Lock();
for (auto win : WindowsManager::Windows)
{
auto sdlWindow = win->GetSDLWindow();
wl_surface* windowSurface = static_cast<wl_surface*>(SDL_GetPointerProperty(SDL_GetWindowProperties(sdlWindow), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr));
if (windowSurface == surface)
{
sourceWindow = win;
break;
}
}
WindowsManager::WindowsLocker.Unlock();
wl_data_device_set_user_data(data_device, sourceWindow);
}
if (sourceWindow != nullptr) if (sourceWindow != nullptr)
{ {
if (!DataOfferAcceptedOffer.IsEmpty())
wl_data_offer_accept(DataOffer, serial, DataOfferAcceptedOffer.Get());
// Let them know that we support the following action at this given point // Let them know that we support the following action at this given point
wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE); wl_data_offer_set_actions(DataOffer, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
LastDropPosition = Float2(x / 256.0f, y / 256.0f);
SDL_Event dropEvent = { 0 };
dropEvent.drop.type = SDL_EVENT_DROP_BEGIN;
dropEvent.drop.windowID = SDL_GetWindowID(sourceWindow->GetSDLWindow());
dropEvent.drop.timestamp = SDL_GetTicksNS();
dropEvent.drop.x = LastDropPosition.X;
dropEvent.drop.y = LastDropPosition.Y;
SDL_PushEvent(&dropEvent);
} }
else else
{ {
LOG(Info, "window was null, no action");
wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE); wl_data_offer_set_actions(id, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE);
} }
}, },
@@ -165,10 +232,59 @@ namespace WaylandImpl
{ {
// The cursor left the surface area // The cursor left the surface area
if (DataOffer != nullptr) if (DataOffer != nullptr)
{
wl_data_offer_destroy(DataOffer); wl_data_offer_destroy(DataOffer);
DataOffer = nullptr; DataOffer = nullptr;
SDLWindow* sourceWindow = (SDLWindow*)data;
SDLWindow* sourceWindow2 = (SDLWindow*)wl_data_device_get_user_data(data_device);
if (sourceWindow != sourceWindow2)
sourceWindow = sourceWindow;
if (sourceWindow != nullptr)
{
SDLWindow* sourceWindow = (SDLWindow*)data;
SDL_Event dropEvent = { 0 };
dropEvent.drop.type = SDL_EVENT_DROP_COMPLETE;
dropEvent.drop.windowID = SDL_GetWindowID(sourceWindow->GetSDLWindow());
dropEvent.drop.timestamp = SDL_GetTicksNS();
dropEvent.drop.x = LastDropPosition.X;
dropEvent.drop.y = LastDropPosition.Y;
SDL_PushEvent(&dropEvent);
}
else
LOG(Info, "window was null");
}
wl_data_device_set_user_data(data_device, nullptr);
},
[](void* data, wl_data_device* data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y) // Motion event
{
/*if (DataOffer != nullptr)
LOG(Info, "offered motion");
else
LOG(Info, "NO VALID OFFER motion");*/
SDLWindow* sourceWindow = (SDLWindow*)data;
SDLWindow* sourceWindow2 = (SDLWindow*)wl_data_device_get_user_data(data_device);
if (sourceWindow != sourceWindow2)
sourceWindow = sourceWindow;
if (sourceWindow != nullptr)
{
LastDropPosition = Float2(x / 256.0f, y / 256.0f);
//Input::Mouse->OnMouseMove(mousePos, sourceWindow);
SDL_Event dropEvent = { 0 };
dropEvent.drop.type = SDL_EVENT_DROP_POSITION;
dropEvent.drop.windowID = SDL_GetWindowID(sourceWindow->GetSDLWindow());
dropEvent.drop.timestamp = SDL_GetTicksNS();
dropEvent.drop.x = LastDropPosition.X;
dropEvent.drop.y = LastDropPosition.Y;
SDL_PushEvent(&dropEvent);
}
else
LOG(Info, "window was null");
}, },
[](void* data, wl_data_device* data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y) { }, // Motion event
[](void* data, wl_data_device* data_device) // Drop event [](void* data, wl_data_device* data_device) // Drop event
{ {
// The drop is accepted // The drop is accepted
@@ -177,13 +293,37 @@ namespace WaylandImpl
wl_data_offer_finish(DataOffer); wl_data_offer_finish(DataOffer);
wl_data_offer_destroy(DataOffer); wl_data_offer_destroy(DataOffer);
DataOffer = nullptr; DataOffer = nullptr;
{
SDLWindow* sourceWindow = (SDLWindow*)data;
SDL_Event dropEvent = { 0 };
dropEvent.drop.type = SDL_EVENT_DROP_TEXT;
dropEvent.drop.windowID = SDL_GetWindowID(sourceWindow->GetSDLWindow());
dropEvent.drop.timestamp = SDL_GetTicksNS();
dropEvent.drop.x = LastDropPosition.X;
dropEvent.drop.y = LastDropPosition.Y;
dropEvent.drop.data = DraggingData2.Get();
SDL_PushEvent(&dropEvent);
}
{
SDLWindow* sourceWindow = (SDLWindow*)data;
SDL_Event dropEvent = { 0 };
dropEvent.drop.type = SDL_EVENT_DROP_COMPLETE;
dropEvent.drop.windowID = SDL_GetWindowID(sourceWindow->GetSDLWindow());
dropEvent.drop.timestamp = SDL_GetTicksNS();
dropEvent.drop.x = LastDropPosition.X;
dropEvent.drop.y = LastDropPosition.Y;
SDL_PushEvent(&dropEvent);
}
} }
}, },
[](void* data, wl_data_device* data_device, wl_data_offer* id) // Selection event [](void* data, wl_data_device* data_device, wl_data_offer* id) // Selection event
{ {
// Clipboard: We can read the clipboard content // Clipboard: We can read the clipboard content
if (SelectionOffer != nullptr) if (SelectionOffer != nullptr)
{
wl_data_offer_destroy(SelectionOffer); wl_data_offer_destroy(SelectionOffer);
}
SelectionOffer = id; SelectionOffer = id;
}, },
}; };
@@ -211,7 +351,9 @@ namespace WaylandImpl
IGuiData* inputData = static_cast<IGuiData*>(data); IGuiData* inputData = static_cast<IGuiData*>(data);
Platform::AtomicStore(&WaylandImpl::DragOverFlag, 1); Platform::AtomicStore(&WaylandImpl::DragOverFlag, 1);
}, },
[](void* data, wl_data_source* source) { }, // DnD drop performed event [](void* data, wl_data_source* source)
{
}, // DnD drop performed event
[](void* data, wl_data_source* source) // DnD Finished event [](void* data, wl_data_source* source) // DnD Finished event
{ {
// The destination has finally accepted the last given dnd_action // The destination has finally accepted the last given dnd_action
@@ -220,18 +362,20 @@ namespace WaylandImpl
IGuiData* inputData = static_cast<IGuiData*>(data); IGuiData* inputData = static_cast<IGuiData*>(data);
Platform::AtomicStore(&WaylandImpl::DragOverFlag, 1); Platform::AtomicStore(&WaylandImpl::DragOverFlag, 1);
}, },
[](void* data, wl_data_source* source, uint32_t dnd_action) { }, // Action event [](void* data, wl_data_source* source, uint32_t dnd_action)
{
}, // Action event
}; };
wl_data_device* DataDevice = nullptr; wl_data_device* DataDevice = nullptr;
wl_event_queue* EventQueue = nullptr; wl_event_queue* EventQueue = nullptr;
wl_data_device_manager* WrappedDataDeviceManager = nullptr; wl_data_device_manager* WrappedDataDeviceManager = nullptr;
wl_data_device* WrappedDataDevice = nullptr; wl_data_device* WrappedDataDevice = nullptr;
bool DraggingActive = false;
bool DraggingWindow = false;
StringView DraggingData = nullptr;
class DragDropJob : public ThreadPoolTask class DragDropJob : public ThreadPoolTask
{ {
private:
LinuxDropTextData textData;
public: public:
int64 StartFlag = 0; int64 StartFlag = 0;
int64 WaitFlag = 0; int64 WaitFlag = 0;
@@ -240,6 +384,7 @@ namespace WaylandImpl
SDLWindow* DragSourceWindow = nullptr; SDLWindow* DragSourceWindow = nullptr;
Float2 DragOffset = Float2::Zero; Float2 DragOffset = Float2::Zero;
uint32 DragSerial = 0; uint32 DragSerial = 0;
// [ThreadPoolTask] // [ThreadPoolTask]
bool Run() override bool Run() override
@@ -263,15 +408,20 @@ namespace WaylandImpl
WrappedDataDeviceManager = static_cast<wl_data_device_manager*>(wl_proxy_create_wrapper(DataDeviceManager)); WrappedDataDeviceManager = static_cast<wl_data_device_manager*>(wl_proxy_create_wrapper(DataDeviceManager));
wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(WrappedDataDeviceManager), EventQueue); wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(WrappedDataDeviceManager), EventQueue);
DataDevice = wl_data_device_manager_get_data_device(WrappedDataDeviceManager, Seat); //if (!dragWindow)
wl_data_device_add_listener(DataDevice, &DataDeviceListener, nullptr); {
wl_display_roundtrip(WaylandDisplay); DataDevice = wl_data_device_manager_get_data_device(WrappedDataDeviceManager, Seat);
wl_data_device_set_user_data(DataDevice, dragWindow ? DragSourceWindow : Window); wl_data_device_add_listener(DataDevice, &DataDeviceListener, nullptr);
//wl_display_roundtrip(WaylandDisplay);
WrappedDataDevice = static_cast<wl_data_device*>(wl_proxy_create_wrapper(DataDevice));
wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(WrappedDataDevice), EventQueue); WrappedDataDevice = static_cast<wl_data_device*>(wl_proxy_create_wrapper(DataDevice));
wl_proxy_set_queue(reinterpret_cast<wl_proxy*>(WrappedDataDevice), EventQueue);
}
} }
//wl_data_device_set_user_data(DataDevice, dragWindow ? DragSourceWindow : Window);
LOG(Info, "POPULATED");
// Offer data for consumption, the data source is destroyed elsewhere // Offer data for consumption, the data source is destroyed elsewhere
wl_data_source* dataSource = wl_data_device_manager_create_data_source(WrappedDataDeviceManager); wl_data_source* dataSource = wl_data_device_manager_create_data_source(WrappedDataDeviceManager);
wl_data_source* wrappedDataSource = (wl_data_source*)wl_proxy_create_wrapper(dataSource); wl_data_source* wrappedDataSource = (wl_data_source*)wl_proxy_create_wrapper(dataSource);
@@ -288,8 +438,8 @@ namespace WaylandImpl
wl_data_source_offer(dataSource, "text/plain;charset=utf-8"); wl_data_source_offer(dataSource, "text/plain;charset=utf-8");
wl_data_source_set_actions(dataSource, WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); wl_data_source_set_actions(dataSource, WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE | WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
} }
LinuxDropTextData textData;
textData.Text = *DraggingData; textData.Text = *DraggingData;
DraggingData2 = StringAnsi(DraggingData);
wl_data_source_add_listener(dataSource, &DataSourceListener, &textData); wl_data_source_add_listener(dataSource, &DataSourceListener, &textData);
// Begin dragging operation // Begin dragging operation
@@ -326,8 +476,8 @@ namespace WaylandImpl
} }
} }
if (wl_display_roundtrip_queue(WaylandDisplay, EventQueue) == -1) if (wl_display_roundtrip_queue(WaylandDisplay, EventQueue) == -1) { }
LOG(Warning, "wl_display_roundtrip_queue failed, errno: {}", errno); //LOG(Warning, "wl_display_roundtrip_queue failed, errno: {}", errno);
} }
if (toplevelDrag != nullptr) if (toplevelDrag != nullptr)
@@ -347,6 +497,9 @@ namespace WaylandImpl
Platform::AtomicStore(&DragOverFlag, 1); Platform::AtomicStore(&DragOverFlag, 1);
wl_data_device_set_user_data(DataDevice, nullptr);
LOG(Info, "CLEARED");
if (wrappedDataSource != nullptr) if (wrappedDataSource != nullptr)
wl_proxy_wrapper_destroy(wrappedDataSource); wl_proxy_wrapper_destroy(wrappedDataSource);
@@ -357,10 +510,10 @@ namespace WaylandImpl
} }
// We can't release the queue immediately due to some resources being still used for a while // We can't release the queue immediately due to some resources being still used for a while
/*if (WaylandQueue != nullptr) /*if (EventQueue != nullptr)
{ {
wl_event_queue_destroy(WaylandQueue); wl_event_queue_destroy(EventQueue);
WaylandQueue = nullptr; EventQueue = nullptr;
}*/ }*/
return false; return false;
@@ -1052,6 +1205,29 @@ DragDropEffect Window::DoDragDropX11(const StringView& data)
void SDLPlatform::PreHandleEvents() void SDLPlatform::PreHandleEvents()
{ {
if (WaylandImpl::EventQueue != nullptr && !WaylandImpl::DraggingActive)
{
//wl_display_flush(WaylandImpl::WaylandDisplay);
while (wl_display_prepare_read_queue(WaylandImpl::WaylandDisplay, WaylandImpl::EventQueue) != 0)
wl_display_dispatch_queue_pending(WaylandImpl::WaylandDisplay, WaylandImpl::EventQueue);
wl_display_flush(WaylandImpl::WaylandDisplay);
//while (wl_display_prepare_read_queue(WaylandImpl::WaylandDisplay, WaylandImpl::EventQueue) == 0)
{
pollfd query = { wl_display_get_fd(WaylandImpl::WaylandDisplay), POLLIN, 0 };
auto ret = poll(&query, 1, 0);
if (ret <= 0)
{
wl_display_cancel_read(WaylandImpl::WaylandDisplay);
//break;
}
else
wl_display_read_events(WaylandImpl::WaylandDisplay);
//wl_display_dispatch_queue_pending(WaylandImpl::WaylandDisplay, WaylandImpl::EventQueue);
}
//wl_display_flush(WaylandImpl::WaylandDisplay);
wl_display_dispatch_queue_pending(WaylandImpl::WaylandDisplay, WaylandImpl::EventQueue);
}
} }
void SDLPlatform::PostHandleEvents() void SDLPlatform::PostHandleEvents()
@@ -1105,7 +1281,7 @@ bool SDLWindow::HandleEventInternal(SDL_Event& event)
case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_BUTTON_UP:
case SDL_EVENT_MOUSE_MOTION: case SDL_EVENT_MOUSE_MOTION:
{ {
if (SDLPlatform::UsesWayland() && WaylandImpl::DraggingActive) if (WaylandImpl::DraggingActive)
{ {
// Ignore mouse events in dragged window // Ignore mouse events in dragged window
return true; return true;
@@ -1137,6 +1313,8 @@ bool SDLWindow::HandleEventInternal(SDL_Event& event)
LinuxDropTextData textData; LinuxDropTextData textData;
LinuxDropFilesData filesData; LinuxDropFilesData filesData;
LOG(Info, "drop event");
if (WaylandImpl::DraggingActive && (event.type == SDL_EVENT_DROP_BEGIN || event.type == SDL_EVENT_DROP_POSITION)) if (WaylandImpl::DraggingActive && (event.type == SDL_EVENT_DROP_BEGIN || event.type == SDL_EVENT_DROP_POSITION))
{ {
// We don't have the window dragging data during these events... // We don't have the window dragging data during these events...
@@ -1144,6 +1322,14 @@ bool SDLWindow::HandleEventInternal(SDL_Event& event)
} }
textData.Text = text; textData.Text = text;
/*if (WaylandImpl::DraggingActive && event.type == SDL_EVENT_DROP_POSITION)
{
Input::Mouse->OnMouseMove(mousePos, this);
LOG(Info, "mouse {}", mousePos);
}*/
if (event.type == SDL_EVENT_DROP_BEGIN) if (event.type == SDL_EVENT_DROP_BEGIN)
{ {
// We don't know the type of dragged data at this point, so call the events for both types // We don't know the type of dragged data at this point, so call the events for both types
@@ -1154,6 +1340,8 @@ bool SDLWindow::HandleEventInternal(SDL_Event& event)
} }
else if (event.type == SDL_EVENT_DROP_POSITION) else if (event.type == SDL_EVENT_DROP_POSITION)
{ {
LOG(Info, "drop pos");
// While dragging external data or windows, we can track the mouse position.
Input::Mouse->OnMouseMove(ClientToScreen(mousePos), this); Input::Mouse->OnMouseMove(ClientToScreen(mousePos), this);
// We don't know the type of dragged data at this point, so call the events for both types // We don't know the type of dragged data at this point, so call the events for both types
@@ -1696,6 +1884,15 @@ void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
base::SetHighDpiAwarenessEnabled(enable); base::SetHighDpiAwarenessEnabled(enable);
} }
bool SDLPlatform::GetHasFocus()
{
// We need to be focused in order to report mouse positions from dragging events
if (WaylandImpl::DraggingActive)
return true;
return base::GetHasFocus();
}
bool SDLPlatform::UsesWindows() bool SDLPlatform::UsesWindows()
{ {
return false; return false;

View File

@@ -248,6 +248,15 @@ void SDLPlatform::OpenUrl(const StringView& url)
SDL_OpenURL(urlStr.GetText()); SDL_OpenURL(urlStr.GetText());
} }
#if !PLATFORM_LINUX
bool SDLPlatform::GetHasFocus()
{
return base::GetHasFocus();
}
#endif
Float2 SDLPlatform::GetMousePosition() Float2 SDLPlatform::GetMousePosition()
{ {
#if PLATFORM_LINUX #if PLATFORM_LINUX

View File

@@ -80,6 +80,7 @@ public:
static int32 GetDpi(); static int32 GetDpi();
static String GetUserLocaleName(); static String GetUserLocaleName();
static void OpenUrl(const StringView& url); static void OpenUrl(const StringView& url);
static bool GetHasFocus();
static Float2 GetMousePosition(); static Float2 GetMousePosition();
static void SetMousePosition(const Float2& pos); static void SetMousePosition(const Float2& pos);
static Float2 GetDesktopSize(); static Float2 GetDesktopSize();

View File

@@ -246,6 +246,7 @@ namespace Flax.Build
args.Add("/unsafe"); args.Add("/unsafe");
args.Add("/fullpaths"); args.Add("/fullpaths");
args.Add("/filealign:512"); args.Add("/filealign:512");
args.Add("/reportanalyzer");
#if USE_NETCORE #if USE_NETCORE
args.Add($"/langversion:{dotnetSdk.CSharpLanguageVersion}"); args.Add($"/langversion:{dotnetSdk.CSharpLanguageVersion}");
args.Add(string.Format("/nullable:{0}", buildOptions.ScriptingAPI.CSharpNullableReferences.ToString().ToLowerInvariant())); args.Add(string.Format("/nullable:{0}", buildOptions.ScriptingAPI.CSharpNullableReferences.ToString().ToLowerInvariant()));

View File

@@ -186,6 +186,8 @@ namespace Flax.Build
// Find system-installed SDK // Find system-installed SDK
string dotnetPath = Environment.GetEnvironmentVariable("DOTNET_ROOT"); string dotnetPath = Environment.GetEnvironmentVariable("DOTNET_ROOT");
if (dotnetPath != null && !Directory.Exists(dotnetPath))
dotnetPath = null;
string rid, ridFallback, arch; string rid, ridFallback, arch;
IEnumerable<string> dotnetSdkVersions = null, dotnetRuntimeVersions = null; IEnumerable<string> dotnetSdkVersions = null, dotnetRuntimeVersions = null;
switch (architecture) switch (architecture)
@@ -226,10 +228,11 @@ namespace Flax.Build
} }
case TargetPlatform.Linux: case TargetPlatform.Linux:
{ {
// TODO
rid = $"linux-{arch}"; rid = $"linux-{arch}";
ridFallback = Utilities.ReadProcessOutput("dotnet", "--info").Split('\n').FirstOrDefault(x => x.StartsWith(" RID:"), "").Replace("RID:", "").Trim(); ridFallback = Utilities.ReadProcessOutput("dotnet", "--info").Split('\n').FirstOrDefault(x => x.StartsWith(" RID:"), "").Replace("RID:", "").Trim();
if (string.IsNullOrEmpty(dotnetPath)) if (string.IsNullOrEmpty(dotnetPath))
dotnetPath ??= SearchForDotnetLocationLinux(); dotnetPath = SearchForDotnetLocationLinux();
break; break;
} }
case TargetPlatform.Mac: case TargetPlatform.Mac:
@@ -576,6 +579,7 @@ namespace Flax.Build
return "/usr/lib/dotnet"; return "/usr/lib/dotnet";
if (Environment.GetEnvironmentVariable("PATH") is string globalBinPath) // Searching for dotnet binary if (Environment.GetEnvironmentVariable("PATH") is string globalBinPath) // Searching for dotnet binary
return globalBinPath.Split(':').FirstOrDefault(x => File.Exists(Path.Combine(x, "dotnet"))); return globalBinPath.Split(':').FirstOrDefault(x => File.Exists(Path.Combine(x, "dotnet")));
Log.Warning("dotnet path find returned null");
return null; return null;
} }
} }

View File

@@ -1,5 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Flax.Build; using Flax.Build;
@@ -42,6 +43,8 @@ namespace Flax.Deps.Dependencies
/// <inheritdoc /> /// <inheritdoc />
public override void Build(BuildOptions options) public override void Build(BuildOptions options)
{ {
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
var root = options.IntermediateFolder; var root = options.IntermediateFolder;
var moduleFilename = "assimp.Build.cs"; var moduleFilename = "assimp.Build.cs";
string configHeaderFilePath = null; string configHeaderFilePath = null;
@@ -131,7 +134,7 @@ namespace Flax.Deps.Dependencies
// Build for Linux // Build for Linux
RunCmake(root, platform, TargetArchitecture.x64, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + globalConfig, envVars); RunCmake(root, platform, TargetArchitecture.x64, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + globalConfig, envVars);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars); Utilities.Run("make", $"-j{concurrency}", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
configHeaderFilePath = Path.Combine(root, "include", "assimp", "config.h"); configHeaderFilePath = Path.Combine(root, "include", "assimp", "config.h");
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64); var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
Utilities.FileCopy(Path.Combine(root, "lib", "libassimp.a"), Path.Combine(depsFolder, "libassimp.a")); Utilities.FileCopy(Path.Combine(root, "lib", "libassimp.a"), Path.Combine(depsFolder, "libassimp.a"));
@@ -143,7 +146,7 @@ namespace Flax.Deps.Dependencies
foreach (var architecture in new[] { TargetArchitecture.x64, TargetArchitecture.ARM64 }) foreach (var architecture in new[] { TargetArchitecture.x64, TargetArchitecture.ARM64 })
{ {
RunCmake(root, platform, architecture, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + globalConfig); RunCmake(root, platform, architecture, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + globalConfig);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("make", $"-j{concurrency}", null, root, Utilities.RunOptions.ThrowExceptionOnError);
configHeaderFilePath = Path.Combine(root, "include", "assimp", "config.h"); configHeaderFilePath = Path.Combine(root, "include", "assimp", "config.h");
var depsFolder = GetThirdPartyFolder(options, platform, architecture); var depsFolder = GetThirdPartyFolder(options, platform, architecture);
Utilities.FileCopy(Path.Combine(root, "lib", "libassimp.a"), Path.Combine(depsFolder, "libassimp.a")); Utilities.FileCopy(Path.Combine(root, "lib", "libassimp.a"), Path.Combine(depsFolder, "libassimp.a"));

View File

@@ -1,5 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -184,6 +185,8 @@ namespace Flax.Deps.Dependencies
break; break;
} }
} }
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
envVars.Add("CMAKE_BUILD_PARALLEL_LEVEL", concurrency.ToString());
// Print the NvCloth version // Print the NvCloth version
Log.Info($"Building {File.ReadAllLines(Path.Combine(root, "README.md"))[0].Trim()} to {platform} {architecture}"); Log.Info($"Building {File.ReadAllLines(Path.Combine(root, "README.md"))[0].Trim()} to {platform} {architecture}");

View File

@@ -304,8 +304,11 @@ namespace Flax.Deps.Dependencies
} }
break; break;
case TargetPlatform.Linux: case TargetPlatform.Linux:
Utilities.Run("make", null, null, Path.Combine(projectGenDir, "compiler", "linux-" + configuration), Utilities.RunOptions.ConsoleLogOutput); {
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
Utilities.Run("make", $"-j{concurrency}", null, Path.Combine(projectGenDir, "compiler", "linux-" + configuration), Utilities.RunOptions.ConsoleLogOutput);
break; break;
}
case TargetPlatform.Mac: case TargetPlatform.Mac:
Utilities.Run("xcodebuild", "-project PhysXSDK.xcodeproj -alltargets -configuration " + configuration, null, Path.Combine(projectGenDir, "compiler", preset), Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("xcodebuild", "-project PhysXSDK.xcodeproj -alltargets -configuration " + configuration, null, Path.Combine(projectGenDir, "compiler", preset), Utilities.RunOptions.ConsoleLogOutput);
break; break;

View File

@@ -47,7 +47,7 @@ namespace Flax.Deps.Dependencies
public override void Build(BuildOptions options) public override void Build(BuildOptions options)
{ {
string root = options.IntermediateFolder; string root = options.IntermediateFolder;
string configuration = "Release"; string configuration = "Debug";
bool buildStatic = true; bool buildStatic = true;
var configs = new string[] var configs = new string[]
{ {

View File

@@ -1,5 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
@@ -44,6 +45,8 @@ namespace Flax.Deps.Dependencies
/// <inheritdoc /> /// <inheritdoc />
public override void Build(BuildOptions options) public override void Build(BuildOptions options)
{ {
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
var root = options.IntermediateFolder; var root = options.IntermediateFolder;
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
var configuration = "Release"; var configuration = "Release";
@@ -112,7 +115,7 @@ namespace Flax.Deps.Dependencies
SetupDirectory(buildDir, true); SetupDirectory(buildDir, true);
Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run(Path.Combine(root, "configure"), string.Join(" ", settings) + " --prefix=\"" + buildDir + "\"", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars); Utilities.Run(Path.Combine(root, "configure"), string.Join(" ", settings) + " --prefix=\"" + buildDir + "\"", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("make", $"-j{concurrency}", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("make", "install", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("make", "install", null, root, Utilities.RunOptions.ThrowExceptionOnError);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64); var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
var filename = "libcurl.a"; var filename = "libcurl.a";
@@ -156,7 +159,7 @@ namespace Flax.Deps.Dependencies
Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("chmod", "+x install-sh", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("chmod", "+x install-sh", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run(Path.Combine(root, "configure"), string.Join(" ", settings) + " --host=" + archName + " --prefix=\"" + buildDir + "\"", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars); Utilities.Run(Path.Combine(root, "configure"), string.Join(" ", settings) + " --host=" + archName + " --prefix=\"" + buildDir + "\"", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("make", $"-j{concurrency}", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("make", "install", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("make", "install", null, root, Utilities.RunOptions.ThrowExceptionOnError);
var depsFolder = GetThirdPartyFolder(options, platform, architecture); var depsFolder = GetThirdPartyFolder(options, platform, architecture);
var filename = "libcurl.a"; var filename = "libcurl.a";

View File

@@ -1,5 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
@@ -52,6 +53,8 @@ namespace Flax.Deps.Dependencies
/// <inheritdoc /> /// <inheritdoc />
public override void Build(BuildOptions options) public override void Build(BuildOptions options)
{ {
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
var root = options.IntermediateFolder; var root = options.IntermediateFolder;
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
var filesToKeep = new[] var filesToKeep = new[]
@@ -61,7 +64,7 @@ namespace Flax.Deps.Dependencies
// Get the source // Get the source
if (!File.Exists(packagePath)) if (!File.Exists(packagePath))
Downloader.DownloadFileFromUrlToPath("https://sourceforge.net/projects/freetype/files/freetype2/2.13.2/ft2132.zip/download", packagePath); Downloader.DownloadFileFromUrlToPath("https://sourceforge.net/projects/freetype/files/freetype2/2.13.3/ft2133.zip/download", packagePath);
using (ZipArchive archive = ZipFile.Open(packagePath, ZipArchiveMode.Read)) using (ZipArchive archive = ZipFile.Open(packagePath, ZipArchiveMode.Read))
{ {
var newRoot = Path.Combine(root, archive.Entries.First().FullName); var newRoot = Path.Combine(root, archive.Entries.First().FullName);
@@ -117,15 +120,18 @@ namespace Flax.Deps.Dependencies
var envVars = new Dictionary<string, string> var envVars = new Dictionary<string, string>
{ {
{ "CC", "clang-" + Configuration.LinuxClangMinVer }, { "CC", "clang-" + Configuration.LinuxClangMinVer },
{ "CC_FOR_BUILD", "clang-" + Configuration.LinuxClangMinVer } { "CC_FOR_BUILD", "clang-" + Configuration.LinuxClangMinVer },
{ "CMAKE_BUILD_PARALLEL_LEVEL", concurrency.ToString() },
}; };
// Fix scripts // Fix scripts
Utilities.Run("sed", "-i -e \'s/\r$//\' autogen.sh", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars); Log.Warning("fixing");
Utilities.Run("sed", "-i -e \'s/\r$//\' configure", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars); Utilities.Run("sed", "-i 's/abc$//' autogen.sh", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
Utilities.Run("sed", "-i 's/abc$//' configure", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
Utilities.Run("chmod", "+x autogen.sh", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("chmod", "+x autogen.sh", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError); Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Log.Warning("running");
Utilities.Run(Path.Combine(root, "autogen.sh"), null, null, root, Utilities.RunOptions.Default, envVars); Utilities.Run(Path.Combine(root, "autogen.sh"), null, null, root, Utilities.RunOptions.Default, envVars);
// Disable using libpng even if it's found on the system // Disable using libpng even if it's found on the system
@@ -234,7 +240,7 @@ namespace Flax.Deps.Dependencies
{ {
SetupDirectory(buildDir, true); SetupDirectory(buildDir, true);
RunCmake(buildDir, platform, architecture, ".. -DCMAKE_BUILD_TYPE=Release"); RunCmake(buildDir, platform, architecture, ".. -DCMAKE_BUILD_TYPE=Release");
BuildCmake(buildDir); BuildCmake(buildDir, envVars: new Dictionary<string, string>() { {"CMAKE_BUILD_PARALLEL_LEVEL", concurrency.ToString()} });
var depsFolder = GetThirdPartyFolder(options, platform, architecture); var depsFolder = GetThirdPartyFolder(options, platform, architecture);
Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName)); Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName));
} }

View File

@@ -1,5 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using System;
using System.IO; using System.IO;
using Flax.Build; using Flax.Build;
@@ -41,6 +42,8 @@ namespace Flax.Deps.Dependencies
/// <inheritdoc /> /// <inheritdoc />
public override void Build(BuildOptions options) public override void Build(BuildOptions options)
{ {
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
var root = options.IntermediateFolder; var root = options.IntermediateFolder;
var installDir = Path.Combine(root, "install"); var installDir = Path.Combine(root, "install");
var configuration = "Release"; var configuration = "Release";
@@ -111,7 +114,7 @@ namespace Flax.Deps.Dependencies
// Build for Linux // Build for Linux
RunCmake(root, platform, TargetArchitecture.x64, cmakeArgs); RunCmake(root, platform, TargetArchitecture.x64, cmakeArgs);
Utilities.Run("cmake", string.Format("--build . --config {0} --target install", configuration), null, buildDir, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("cmake", string.Format("--build . --config {0} --target install", configuration), null, buildDir, Utilities.RunOptions.ConsoleLogOutput);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("make", $"-j{concurrency}", null, root, Utilities.RunOptions.ConsoleLogOutput);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64); var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
foreach (var file in outputFiles) foreach (var file in outputFiles)
{ {
@@ -142,7 +145,7 @@ namespace Flax.Deps.Dependencies
{ {
RunCmake(root, platform, architecture, cmakeArgs); RunCmake(root, platform, architecture, cmakeArgs);
Utilities.Run("cmake", string.Format("--build . --config {0} --target install", configuration), null, buildDir, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("cmake", string.Format("--build . --config {0} --target install", configuration), null, buildDir, Utilities.RunOptions.ConsoleLogOutput);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("make", $"-j{concurrency}", null, root, Utilities.RunOptions.ConsoleLogOutput);
var depsFolder = GetThirdPartyFolder(options, platform, architecture); var depsFolder = GetThirdPartyFolder(options, platform, architecture);
foreach (var file in outputFiles) foreach (var file in outputFiles)
{ {

View File

@@ -14,7 +14,7 @@ namespace Flax.Build
/// Specifies the minimum Clang compiler version to use on Linux (eg. 10). /// Specifies the minimum Clang compiler version to use on Linux (eg. 10).
/// </summary> /// </summary>
[CommandLine("linuxClangMinVer", "<version>", "Specifies the minimum Clang compiler version to use on Linux (eg. 10).")] [CommandLine("linuxClangMinVer", "<version>", "Specifies the minimum Clang compiler version to use on Linux (eg. 10).")]
public static string LinuxClangMinVer = "13"; public static string LinuxClangMinVer = "14";
} }
} }

View File

@@ -103,8 +103,13 @@ namespace Flax.Build.Platforms
StripPath = UnixPlatform.Which("strip"); StripPath = UnixPlatform.Which("strip");
ObjcopyPath = UnixPlatform.Which("objcopy"); ObjcopyPath = UnixPlatform.Which("objcopy");
LdPath = UnixPlatform.Which("ld.lld"); //LdPath = UnixPlatform.Which("ld.mold");
LdKind = "lld"; //LdKind = "mold";
if (LdPath == null)
{
LdPath = UnixPlatform.Which("ld.lld");
LdKind = "lld";
}
if (LdPath == null) if (LdPath == null)
{ {
LdPath = UnixPlatform.Which("ld.gold"); LdPath = UnixPlatform.Which("ld.gold");