6 Commits

Author SHA1 Message Date
5274a96a42 _begin refactor, windows fixes
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
2025-01-01 02:05:15 +02:00
aac2920f03 Update SDL3 2025-01-01 02:04:30 +02:00
18711a2a14 Fix window ShowInTaskbar setting 2025-01-01 02:01:13 +02:00
87e6c465a0 _sdl binary 2024-12-31 01:16:36 +02:00
e44b2a292a _update sdl 2024-12-31 01:16:31 +02:00
d1d148d5a7 _sdl build fix 2024-12-31 01:16:25 +02:00
14 changed files with 480 additions and 123 deletions

View File

@@ -243,6 +243,8 @@ namespace FlaxEditor.GUI.Docking
{ {
var baseWinPos = _toMove.Window.Window.Position; var baseWinPos = _toMove.Window.Window.Position;
_dragOffset = mouseScreenPosition - baseWinPos; _dragOffset = mouseScreenPosition - baseWinPos;
Editor.Log($"_dragOffset: {_dragOffset}, mouse: {mouseScreenPosition}, basewinpos: {baseWinPos}");
} }
private void UpdateRects() private void UpdateRects()

View File

@@ -483,7 +483,12 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
else else
{ {
const Float2 mousePos = window->ClientToScreen({ event.motion.x, event.motion.y }); const Float2 mousePos = window->ClientToScreen({ event.motion.x, event.motion.y });
//LOG(Info, "motion {},{}, mouse: {}, win: {}", event.motion.x, event.motion.y, mousePos, String(window->GetTitle())); Int2 p;
Float2 wp = window->ClientToScreen({0, 0});
//SDL_GetWindowPosition(window->GetSDLWindow(), &p.X, &p.Y);
p.X = wp.X;
p.Y = wp.Y;
//LOG(Info, "motion {},{}, mouse: {}, win: {}, winpos {},{}", event.motion.x, event.motion.y, mousePos, String(window->GetTitle()), p.X, p.Y);
Input::Mouse->OnMouseMove(mousePos, window); Input::Mouse->OnMouseMove(mousePos, window);
} }
return true; return true;

View File

@@ -64,6 +64,8 @@ bool SDLPlatform::Init()
SDL_SetHint(SDL_HINT_WINDOWS_ERASE_BACKGROUND_MODE, "0"); SDL_SetHint(SDL_HINT_WINDOWS_ERASE_BACKGROUND_MODE, "0");
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0"); // Already handled during platform initialization SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0"); // Already handled during platform initialization
SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1"); // Allow borderless windows to be resizable on Windows SDL_SetHint("SDL_BORDERLESS_RESIZABLE_STYLE", "1"); // Allow borderless windows to be resizable on Windows
//SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "1");
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, "0"); SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, "0");
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // Needed for tracking mode SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, "1"); // Needed for tracking mode
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "1"); // Is this needed? SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, "1"); // Is this needed?

View File

@@ -54,6 +54,9 @@ void SetSDLWindowPosition(SDLWindow* window, const int x, const int y);
void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen = true); void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen = true);
void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* parent, int32& xRel, int32& yRel); void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* parent, int32& xRel, int32& yRel);
Int2 GetSDLWindowScreenPosition(const SDLWindow* window);
void SetSDLWindowScreenPosition(SDLWindow* window, const int x, const int y);
class SDLDropFilesData : public IGuiData class SDLDropFilesData : public IGuiData
{ {
public: public:
@@ -119,6 +122,8 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
uint32 flags = SDL_WINDOW_HIDDEN; uint32 flags = SDL_WINDOW_HIDDEN;
if (_settings.Type == WindowType::Utility) if (_settings.Type == WindowType::Utility)
flags |= SDL_WINDOW_UTILITY; flags |= SDL_WINDOW_UTILITY;
else if (_settings.Type == WindowType::Regular && !_settings.ShowInTaskbar)
flags |= SDL_WINDOW_UTILITY;
else if (_settings.Type == WindowType::Tooltip) else if (_settings.Type == WindowType::Tooltip)
flags |= SDL_WINDOW_TOOLTIP; flags |= SDL_WINDOW_TOOLTIP;
else if (_settings.Type == WindowType::Popup) else if (_settings.Type == WindowType::Popup)
@@ -155,8 +160,8 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
if (win->_settings.Type == WindowType::Tooltip || win->_settings.Type == WindowType::Popup) if (win->_settings.Type == WindowType::Tooltip || win->_settings.Type == WindowType::Popup)
{ {
auto focusedParent = win->_settings.Parent; auto focusedParent = win->_settings.Parent;
_settings.Parent = win; //_settings.Parent = win;
while (focusedParent != nullptr && (focusedParent->_settings.Type == WindowType::Tooltip || focusedParent->_settings.Type == WindowType::Popup)) while (focusedParent != nullptr /*&& (focusedParent->_settings.Type == WindowType::Tooltip || focusedParent->_settings.Type == WindowType::Popup)*/)
{ {
if (focusedParent->_settings.Parent == nullptr) if (focusedParent->_settings.Parent == nullptr)
{ {
@@ -203,62 +208,11 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
} }
} }
} }
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
Int2 oldpos(x, y); Int2 oldpos(x, y);
if (_settings.Parent != nullptr) if (_settings.Parent != nullptr)
{ {
#if PLATFORM_WINDOWS
auto parentPosition = _settings.Parent->ClientToScreen(Float2::Zero);
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)
{
//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;
}*/
}
#else
SetRelativeWindowPosition(_settings.Type, _settings.Parent, x, y); SetRelativeWindowPosition(_settings.Type, _settings.Parent, x, y);
#endif
}
if (SDLPlatform::UsesX11() && _settings.Parent != Engine::MainWindow)
{
/*if (_settings.Parent->GetSettings().Type == WindowType::Tooltip || _settings.Parent->GetSettings().Type == WindowType::Popup)
{
}
else
{
*//*auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
x -= (int)monitorBounds.GetLeft();
y -= (int)monitorBounds.GetTop();*/
//}
} }
Int2 oldpos2(x, y); Int2 oldpos2(x, y);
@@ -321,9 +275,10 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
SDL_GetWindowSize(_window, &rect2.w, &rect2.h); SDL_GetWindowSize(_window, &rect2.w, &rect2.h);
_cachedClientRectangle = Rectangle((float)rect.x, (float)rect.y, (float)rect.w, (float)rect.h); _cachedClientRectangle = Rectangle((float)rect.x, (float)rect.y, (float)rect.w, (float)rect.h);
Int2 sdlpos(rect.x, rect.y);
Int2 newpos = GetClientPosition(); Int2 newpos = GetClientPosition();
Int2 newposclient = GetSDLWindowPosition(this); Int2 newposclient = GetSDLWindowScreenPosition(this);
//LOG(Info, "new window at {}, input {}, expected: {}", newposclient, oldpos, oldpos2); LOG(Info, "new window, sdl: {}, input {}, relative: {}", sdlpos, oldpos, newposclient);
//ASSERT(newpos == oldpos || newpos == oldpos2); //ASSERT(newpos == oldpos || newpos == oldpos2);
/*oldpos = newpos; /*oldpos = newpos;
@@ -747,7 +702,7 @@ void SDLWindow::HandleEvent(SDL_Event& event)
_dpi = (int)(_dpiScale * DefaultDPI); _dpi = (int)(_dpiScale * DefaultDPI);
int w = (int)(_cachedClientRectangle.GetWidth() * (scale / oldScale)); int w = (int)(_cachedClientRectangle.GetWidth() * (scale / oldScale));
int h = (int)(_cachedClientRectangle.GetHeight() * (scale / oldScale)); int h = (int)(_cachedClientRectangle.GetHeight() * (scale / oldScale));
_cachedClientRectangle.Size = Float2(w, h); _cachedClientRectangle.Size = Float2(static_cast<float>(w), static_cast<float>(h));
SDL_SetWindowSize(_window, w, h); SDL_SetWindowSize(_window, w, h);
// TODO: Recalculate fonts // TODO: Recalculate fonts
} }
@@ -990,7 +945,8 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
{ {
int oldX, oldY; int oldX, oldY;
int oldW, oldH; int oldW, oldH;
SDL_GetWindowPosition(_window, &oldX, &oldY); //SDL_GetWindowPosition(_window, &oldX, &oldY);
Int2 asd = GetSDLWindowScreenPosition(this); oldX = asd.X; oldY = asd.Y;
SDL_GetWindowSizeInPixels(_window, &oldW, &oldH); SDL_GetWindowSizeInPixels(_window, &oldW, &oldH);
int newX = (int)clientArea.GetLeft(); int newX = (int)clientArea.GetLeft();
@@ -998,8 +954,9 @@ void SDLWindow::SetClientBounds(const Rectangle& clientArea)
int newW = (int)clientArea.GetWidth(); int newW = (int)clientArea.GetWidth();
int newH = (int)clientArea.GetHeight(); int newH = (int)clientArea.GetHeight();
//if (newX != oldX || newY != oldY) if (newX != oldX || newY != oldY)
SetSDLWindowPosition(this, newX, newY); SetSDLWindowScreenPosition(this, newX, newY);
//SetSDLWindowPosition(this, newX, newY);
SDL_SetWindowSize(_window, newW, newH); SDL_SetWindowSize(_window, newW, newH);
LOG(Info, "SetClientBounds changed from ({},{} {}x{}) to ({},{} {}x{})", oldX, oldY, oldW, oldH, LOG(Info, "SetClientBounds changed from ({},{} {}x{}) to ({},{} {}x{})", oldX, oldY, oldW, oldH,
@@ -1052,6 +1009,22 @@ Int2 GetSDLWindowPosition(const SDLWindow* window)
//SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y); //SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//position += rootParentPosition; //position += rootParentPosition;
} }
#endif
#if PLATFORM_WINDOWS
if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
{
auto oldPos = position;
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
//rootParentPosition = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position += rootParentPosition;
parent = parent->GetSettings().Parent;
}
}
#endif #endif
return position; return position;
} }
@@ -1088,6 +1061,111 @@ void SetSDLWindowPosition(SDLWindow* window, const int x, const int y)
SDL_SetWindowPosition(window->GetSDLWindow(), x, y); SDL_SetWindowPosition(window->GetSDLWindow(), x, y);
} }
Int2 GetSDLWindowScreenPosition(const SDLWindow* window)
{
Int2 position;
SDL_GetWindowPosition(window->GetSDLWindow(), &position.X, &position.Y);
#if PLATFORM_LINUX
if (SDLPlatform::UsesX11())
{
#if X11_WINDOW_POSITION_WORKAROUND
if (/*window->GetSettings().Type == WindowType::Tooltip ||*/ window->GetSettings().Type == WindowType::Popup)
{
auto oldPos = position;
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
//rootParentPosition = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position += rootParentPosition;
parent = parent->GetSettings().Parent;
}
}
#endif
}
else if (SDLPlatform::UsesWayland())
{
// Wayland doesn't support reporting window position in screen-space
/*auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 parentPosition;// = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
position += parentPosition;
parent = parent->GetSettings().Parent;
}*/
//Int2 rootParentPosition = GetSDLWindowPosition(parent);
//SDL_GetWindowPosition(window->GetSettings().Parent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//position += rootParentPosition;
}
#endif
#if PLATFORM_WINDOWS
if (true)
{
Int2 rel(0, 0);
SetRelativeWindowPosition(window->GetSettings().Type, window->GetSettings().Parent, rel.X, rel.Y);
position -= rel;
}
else
//if (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup)
{
auto oldPos = position;
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
//rootParentPosition = GetSDLWindowPosition(parent);
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position += rootParentPosition;
if (parent->GetSettings().Parent == nullptr)
position -= rootParentPosition;
parent = parent->GetSettings().Parent;
}
}
#endif
GetRelativeWindowPosition(window, position, true); // windows NOOP
return position;
}
void SetSDLWindowScreenPosition(SDLWindow* window, const int xx, const int yy)
{
Int2 relativePosition(xx, yy);
SetRelativeWindowPosition(window->GetSettings().Type, window->GetSettings().Parent, relativePosition.X, relativePosition.Y);
#if PLATFORM_LINUX
if (SDLPlatform::UsesX11())
{
#if X11_WINDOW_POSITION_WORKAROUND
if (/*window->GetSettings().Type == WindowType::Tooltip ||*/ window->GetSettings().Type == WindowType::Popup)
{
Int2 position(x, y);
auto parent = window->GetSettings().Parent;
while (parent != nullptr)
{
Int2 rootParentPosition;
SDL_GetWindowPosition(parent->GetSDLWindow(), &rootParentPosition.X, &rootParentPosition.Y);
position -= rootParentPosition;
parent = parent->GetSettings().Parent;
}
return;
}
#endif
}
else if (SDLPlatform::UsesWayland())
{
int oldX, oldY;
SDL_GetWindowPosition(window->GetSDLWindow(), &oldX, &oldY);
if (x == oldX && y == oldY)
return;
}
#endif
SDL_SetWindowPosition(window->GetSDLWindow(), relativePosition.X, relativePosition.Y);
}
void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen) void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition, bool clienttoscreen)
{ {
// The relative positioning of windows are very inconsistent in different platforms. // The relative positioning of windows are very inconsistent in different platforms.
@@ -1095,11 +1173,6 @@ void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition,
// On X11: The child position is always relative to parent windows. // On X11: The child position is always relative to parent windows.
// On Wayland: The child position is relative to root parent window. // On Wayland: The child position is relative to root parent window.
/*if (SDLPlatform::UsesX11())
{
return;
}*/
#if PLATFORM_LINUX #if PLATFORM_LINUX
//clienttoscreen = false; //clienttoscreen = false;
if (SDLPlatform::UsesX11()) if (SDLPlatform::UsesX11())
@@ -1170,18 +1243,24 @@ void GetRelativeWindowPosition(const SDLWindow* window, Int2& relativePosition,
//relativePosition -= Int2(monitorBounds.GetTopLeft()); //relativePosition -= Int2(monitorBounds.GetTopLeft());
} }
else else
parent = (window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ? window->GetSettings().Parent : nullptr; parent = /*(window->GetSettings().Type == WindowType::Tooltip || window->GetSettings().Type == WindowType::Popup) ?*/ window->GetSettings().Parent /*: nullptr*/;
while (parent != nullptr) if (parent != nullptr)
{ {
//break; //break;
Int2 parentPosition = GetSDLWindowPosition(parent); //Int2 parentPosition = GetSDLWindowPosition(parent);
relativePosition += (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parentPosition : -parentPosition; //relativePosition += parentPosition;//(parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parentPosition : -parentPosition;
auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum); //auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
//relativePosition += Int2(monitorBounds.GetTopLeft()); //relativePosition += Int2(monitorBounds.GetTopLeft());
//relativePosition -= parentPosition; //relativePosition -= parentPosition;
/*if (SDLPlatform::UsesX11()) /*if (SDLPlatform::UsesX11())
parent = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parent->GetSettings().Parent : nullptr; parent = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parent->GetSettings().Parent : nullptr;
else*/ else*/
//if (parent->GetSettings().Parent == nullptr)
{
Int2 parentPosition = GetSDLWindowPosition(parent);
relativePosition += parentPosition;
//break;
}
parent = parent->GetSettings().Parent; parent = parent->GetSettings().Parent;
} }
} }
@@ -1194,11 +1273,6 @@ void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* theParent
// On X11: The child position is always relative to parent windows. // On X11: The child position is always relative to parent windows.
// On Wayland: The child position is relative to root parent window. // On Wayland: The child position is relative to root parent window.
/*if (SDLPlatform::UsesX11())
{
return;
}*/
#if PLATFORM_LINUX #if PLATFORM_LINUX
if (SDLPlatform::UsesX11()) if (SDLPlatform::UsesX11())
{ {
@@ -1309,29 +1383,50 @@ void SetRelativeWindowPosition(const WindowType windowType, SDLWindow* theParent
else else
#endif #endif
{ {
SDLWindow* parent; return;
if (SDLPlatform::UsesX11()) //if (windowType != WindowType::Popup && windowType != WindowType::Tooltip)
// return;
SDLWindow* topParent = nullptr;
bool workaround = false;
while (theParent != nullptr)
{ {
parent = (windowType == WindowType::Tooltip || windowType == WindowType::Popup) ? theParent : theParent; Int2 parentPosition;// = GetSDLWindowScreenPosition(theParent);
//auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum); SDL_GetWindowPosition(theParent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
//relativePosition -= Int2(monitorBounds.GetTopLeft()); xRel -= parentPosition.X;
yRel -= parentPosition.Y;
/*
if (workaround && theParent->GetSettings().Parent == nullptr)
{
topParent = theParent;
}
if (theParent->GetSettings().Parent != nullptr && (windowType == WindowType::Popup || windowType == WindowType::Tooltip || windowType == WindowType::Utility))
{
if (theParent->GetSettings().Type != WindowType::Popup && theParent->GetSettings().Type != WindowType::Tooltip && theParent->GetSettings().Type != WindowType::Utility)
workaround = true;
}*/
theParent = theParent->GetSettings().Parent;
//if (theParent != nullptr && (theParent->GetSettings().Type == WindowType::Popup || theParent->GetSettings().Type == WindowType::Tooltip))
// break;
/*if (theParent != nullptr)
{
Int2 parentPosition = GetSDLWindowPosition(theParent);
xRel -= parentPosition.X;
yRel -= parentPosition.Y;
//theParent = theParent->GetSettings().Parent;
}*/
} }
else
parent = (windowType == WindowType::Tooltip || windowType == WindowType::Popup) ? theParent : nullptr; if (topParent != nullptr && workaround)
while (parent != nullptr)
{ {
Int2 parentPosition = GetSDLWindowPosition(parent); Int2 parentPosition;// = GetSDLWindowScreenPosition(theParent);
Int2 rel = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parentPosition : -parentPosition; SDL_GetWindowPosition(topParent->GetSDLWindow(), &parentPosition.X, &parentPosition.Y);
xRel += rel.X; xRel -= parentPosition.X;
yRel += rel.Y; yRel -= parentPosition.Y;
auto monitorBounds = Platform::GetMonitorBounds(Float2::Minimum);
//relativePosition += Int2(monitorBounds.GetTopLeft());
//relativePosition += parentPosition;
/*if (SDLPlatform::UsesX11())
parent = (parent->GetSettings().Type == WindowType::Tooltip || parent->GetSettings().Type == WindowType::Popup) ? parent->GetSettings().Parent : nullptr;
else*/
parent = parent->GetSettings().Parent;
} }
} }
} }
@@ -1343,7 +1438,7 @@ void SDLWindow::SetPosition(const Float2& position)
// The position is relative to the parent window // The position is relative to the parent window
Int2 relativePosition(static_cast<int>(position.X), static_cast<int>(position.Y)); Int2 relativePosition(static_cast<int>(position.X), static_cast<int>(position.Y));
relativePosition += topLeftBorder; relativePosition += topLeftBorder;
SetRelativeWindowPosition(GetSettings().Type, GetSettings().Parent, relativePosition.X, relativePosition.Y); //SetRelativeWindowPosition(GetSettings().Type, GetSettings().Parent, relativePosition.X, relativePosition.Y);
if (SDLPlatform::UsesX11()) if (SDLPlatform::UsesX11())
{ {
@@ -1351,7 +1446,7 @@ void SDLWindow::SetPosition(const Float2& position)
relativePosition += Int2(monitorBounds.GetTopLeft()); relativePosition += Int2(monitorBounds.GetTopLeft());
} }
SetSDLWindowPosition(this, relativePosition.X, relativePosition.Y); SetSDLWindowScreenPosition(this, relativePosition.X, relativePosition.Y);
SDL_SyncWindow(_window); SDL_SyncWindow(_window);
Int2 newPos; Int2 newPos;
@@ -1362,6 +1457,8 @@ void SDLWindow::SetPosition(const Float2& position)
newPos = GetPosition(); newPos = GetPosition();
//if (!(newPos.X == position.X && newPos.Y == position.Y)) //if (!(newPos.X == position.X && newPos.Y == position.Y))
// ASSERT(false); // ASSERT(false);
//LOG(Info, "SetPosition before: {}, after {}, relative {}", position, newPos, relativePosition);
} }
void SDLWindow::SetClientPosition(const Float2& position) void SDLWindow::SetClientPosition(const Float2& position)
@@ -1387,9 +1484,9 @@ Float2 SDLWindow::GetPosition() const
SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr); SDL_GetWindowBordersSize(_window, &topLeftBorder.Y, &topLeftBorder.X, nullptr, nullptr);
// The position is relative to the parent window // The position is relative to the parent window
Int2 position = GetSDLWindowPosition(this); Int2 position = GetSDLWindowScreenPosition(this);
position -= topLeftBorder; position -= topLeftBorder;
GetRelativeWindowPosition(this, position); //GetRelativeWindowPosition(this, position);
return Float2(static_cast<float>(position.X), static_cast<float>(position.Y)); return Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
} }
@@ -1415,9 +1512,9 @@ Float2 SDLWindow::GetClientSize() const
Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
{ {
// The position is relative to the parent window // The position is relative to the parent window
Int2 position = GetSDLWindowPosition(this); Int2 position = GetSDLWindowScreenPosition(this);
Int2 position2 = position; //Int2 position2 = position;
GetRelativeWindowPosition(this, position); //GetRelativeWindowPosition(this, position);
//LOG(Info, "{} pos {}, rel {}", String(StringAnsi(SDL_GetWindowTitle(_window))), position2, position); //LOG(Info, "{} pos {}, rel {}", String(StringAnsi(SDL_GetWindowTitle(_window))), position2, position);
if (_settings.Parent != nullptr) if (_settings.Parent != nullptr)
@@ -1432,8 +1529,8 @@ Float2 SDLWindow::ScreenToClient(const Float2& screenPos) const
Float2 SDLWindow::ClientToScreen(const Float2& clientPos) const Float2 SDLWindow::ClientToScreen(const Float2& clientPos) const
{ {
// The position is relative to the parent window // The position is relative to the parent window
Int2 position = GetSDLWindowPosition(this); Int2 position = GetSDLWindowScreenPosition(this);
GetRelativeWindowPosition(this, position, true); //GetRelativeWindowPosition(this, position, true);
return clientPos + Float2(static_cast<float>(position.X), static_cast<float>(position.Y)); return clientPos + Float2(static_cast<float>(position.X), static_cast<float>(position.Y));
} }

View File

@@ -114,6 +114,7 @@ namespace FlaxEngine.GUI
Visible = true; Visible = true;
_window.Show(); _window.Show();
_showTarget.OnTooltipShown(this); _showTarget.OnTooltipShown(this);
once = true;
} }
/// <summary> /// <summary>
@@ -204,7 +205,7 @@ namespace FlaxEngine.GUI
var rightBottomLocationSS = locationSS + dpiSize; var rightBottomLocationSS = locationSS + dpiSize;
// Prioritize tooltip placement within parent window, fall back to virtual desktop // Prioritize tooltip placement within parent window, fall back to virtual desktop
if (rightBottomMonitorBounds.Y < rightBottomLocationSS.Y) /*if (rightBottomMonitorBounds.Y < rightBottomLocationSS.Y)
{ {
// Direction: up // Direction: up
locationSS.Y -= dpiSize.Y + flipOffset; locationSS.Y -= dpiSize.Y + flipOffset;
@@ -213,9 +214,11 @@ namespace FlaxEngine.GUI
{ {
// Direction: left // Direction: left
locationSS.X -= dpiSize.X + flipOffset * 2; locationSS.X -= dpiSize.X + flipOffset * 2;
} }*/
} }
bool once = true;
/// <inheritdoc /> /// <inheritdoc />
public override void Update(float deltaTime) public override void Update(float deltaTime)
{ {
@@ -226,7 +229,18 @@ namespace FlaxEngine.GUI
// Auto hide if mouse leaves control area // Auto hide if mouse leaves control area
Hide(); Hide();
} }
else //if (false) else if (true)
{
if (_window)
_window.Position = _window.Position;
if (once)
{
once = false;
_window.ClientSize = _window.ClientSize + new Float2(2, 2);
}
}
else if (false)
{ {
// Position tooltip when mouse moves // Position tooltip when mouse moves
WrapPosition(ref mousePos, 10); WrapPosition(ref mousePos, 10);

Binary file not shown.

View File

@@ -144,7 +144,7 @@ typedef enum SDL_AsyncIOResult
{ {
SDL_ASYNCIO_COMPLETE, /**< request was completed without error */ SDL_ASYNCIO_COMPLETE, /**< request was completed without error */
SDL_ASYNCIO_FAILURE, /**< request failed for some reason; check SDL_GetError()! */ SDL_ASYNCIO_FAILURE, /**< request failed for some reason; check SDL_GetError()! */
SDL_ASYNCIO_CANCELLED /**< request was cancelled before completing. */ SDL_ASYNCIO_CANCELED /**< request was canceled before completing. */
} SDL_AsyncIOResult; } SDL_AsyncIOResult;
/** /**

View File

@@ -212,6 +212,7 @@ typedef enum SDL_EventType
SDL_EVENT_FINGER_DOWN = 0x700, SDL_EVENT_FINGER_DOWN = 0x700,
SDL_EVENT_FINGER_UP, SDL_EVENT_FINGER_UP,
SDL_EVENT_FINGER_MOTION, SDL_EVENT_FINGER_MOTION,
SDL_EVENT_FINGER_CANCELED,
/* 0x800, 0x801, and 0x802 were the Gesture events from SDL2. Do not reuse these values! sdl2-compat needs them! */ /* 0x800, 0x801, and 0x802 were the Gesture events from SDL2. Do not reuse these values! sdl2-compat needs them! */
@@ -764,7 +765,7 @@ typedef struct SDL_RenderEvent
*/ */
typedef struct SDL_TouchFingerEvent typedef struct SDL_TouchFingerEvent
{ {
SDL_EventType type; /**< SDL_EVENT_FINGER_MOTION or SDL_EVENT_FINGER_DOWN or SDL_EVENT_FINGER_UP */ SDL_EventType type; /**< SDL_EVENT_FINGER_DOWN, SDL_EVENT_FINGER_UP, SDL_EVENT_FINGER_MOTION, or SDL_EVENT_FINGER_CANCELED */
Uint32 reserved; Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_TouchID touchID; /**< The touch device id */ SDL_TouchID touchID; /**< The touch device id */

View File

@@ -149,6 +149,29 @@
* [here](https://github.com/TheSpydog/SDL_gpu_examples) * [here](https://github.com/TheSpydog/SDL_gpu_examples)
* . * .
* *
* ## Performance considerations
*
* Here are some basic tips for maximizing your rendering performance.
*
* - Beginning a new render pass is relatively expensive. Use as few render
* passes as you can.
* - Minimize the amount of state changes. For example, binding a pipeline is
* relatively cheap, but doing it hundreds of times when you don't need to
* will slow the performance significantly.
* - Perform your data uploads as early as possible in the frame.
* - Don't churn resources. Creating and releasing resources is expensive.
* It's better to create what you need up front and cache it.
* - Don't use uniform buffers for large amounts of data (more than a matrix
* or so). Use a storage buffer instead.
* - Use cycling correctly. There is a detailed explanation of cycling further
* below.
* - Use culling techniques to minimize pixel writes. The less writing the GPU
* has to do the better. Culling can be a very advanced topic but even
* simple culling techniques can boost performance significantly.
*
* In general try to remember the golden rule of performance: doing things is
* more expensive than not doing things. Don't Touch The Driver!
*
* ## FAQ * ## FAQ
* *
* **Question: When are you adding more advanced features, like ray tracing or * **Question: When are you adding more advanced features, like ray tracing or
@@ -174,6 +197,16 @@
* reflection to extract the required information from the shader * reflection to extract the required information from the shader
* automatically instead of manually filling in the struct's values. * automatically instead of manually filling in the struct's values.
* *
* **Question: My application isn't performing very well. Is this the GPU
* API's fault?**
*
* Answer: No. Long answer: The GPU API is a relatively thin layer over the
* underlying graphics API. While it's possible that we have done something
* inefficiently, it's very unlikely especially if you are relatively
* inexperienced with GPU rendering. Please see the performance tips above and
* make sure you are following them. Additionally, tools like RenderDoc can be
* very helpful for diagnosing incorrect behavior and performance issues.
*
* ## System Requirements * ## System Requirements
* *
* **Vulkan:** Supported on Windows, Linux, Nintendo Switch, and certain * **Vulkan:** Supported on Windows, Linux, Nintendo Switch, and certain

View File

@@ -2391,13 +2391,21 @@ extern "C" {
/** /**
* Request SDL_AppIterate() be called at a specific rate. * Request SDL_AppIterate() be called at a specific rate.
* *
* This number is in Hz, so "60" means try to iterate 60 times per second. * If this is set to a number, it represents Hz, so "60" means try to iterate
* 60 times per second. "0" means to iterate as fast as possible. Negative
* values are illegal, but reserved, in case they are useful in a future
* revision of SDL.
*
* There are other strings that have special meaning. If set to "waitevent",
* SDL_AppIterate will not be called until new event(s) have arrived (and been
* processed by SDL_AppEvent). This can be useful for apps that are completely
* idle except in response to input.
* *
* On some platforms, or if you are using SDL_main instead of SDL_AppIterate, * On some platforms, or if you are using SDL_main instead of SDL_AppIterate,
* this hint is ignored. When the hint can be used, it is allowed to be * this hint is ignored. When the hint can be used, it is allowed to be
* changed at any time. * changed at any time.
* *
* This defaults to 60, and specifying NULL for the hint's value will restore * This defaults to 0, and specifying NULL for the hint's value will restore
* the default. * the default.
* *
* This hint can be set anytime. * This hint can be set anytime.

View File

@@ -31,9 +31,9 @@
/* #undef SDL_VENDOR_INFO */ /* #undef SDL_VENDOR_INFO */
#ifdef SDL_VENDOR_INFO #ifdef SDL_VENDOR_INFO
#define SDL_REVISION "SDL3-3.1.7-preview-3.1.6-509-g8cc4735d74 (" SDL_VENDOR_INFO ")" #define SDL_REVISION "SDL3-3.1.7-release-2.0.14-11837-g4286c8328 (" SDL_VENDOR_INFO ")"
#else #else
#define SDL_REVISION "SDL3-3.1.7-preview-3.1.6-509-g8cc4735d74" #define SDL_REVISION "SDL3-3.1.7-release-2.0.14-11837-g4286c8328"
#endif #endif
#endif /* SDL_revision_h_ */ #endif /* SDL_revision_h_ */

View File

@@ -22,7 +22,198 @@
/** /**
* # CategoryStorage * # CategoryStorage
* *
* SDL storage container management. * The storage API is a high-level API designed to abstract away the
* portability issues that come up when using something lower-level (in SDL's
* case, this sits on top of SDL_filesystem). It is significantly more
* restrictive than a typical filesystem API, for a number of reasons:
*
* 1. **What to Access:** A common pitfall with existing filesystem APIs is
* the assumption that all storage is monolithic. However, many other
* platforms (game consoles in particular) are more strict about what _type_
* of filesystem is being accessed; for example, game content and user data
* are usually two separate storage devices with entirely different
* characteristics (and possibly different low-level APIs altogether!). 2.
* **How to Access:** Another common mistake is applications assuming that all
* storage is universally writeable - again, many platforms treat game content
* and user data as two separate storage devices, and only user data is
* writeable while game content is read-only. 3. **When to Access:** The most
* common portability issue with filesystem access is _timing_ - you cannot
* always assume that the storage device is always accessible all of the time,
* nor can you assume that there are no limits to how long you have access to
* a particular device.
*
* Consider the following example:
*
* ```
* void ReadGameData(void)
* {
* extern char** fileNames;
* extern size_t numFiles;
* for (size_t i = 0; i < numFiles; i += 1) {
* FILE *data = fopen(fileNames[i], "rwb");
* if (data == NULL) {
* // Something bad happened!
* } else {
* // A bunch of stuff happens here
* fclose(data);
* }
* }
* }
*
* void ReadSave(void)
* {
* FILE *save = fopen("saves/save0.sav", "rb");
* if (save == NULL) {
* // Something bad happened!
* } else {
* // A bunch of stuff happens here
* fclose(save);
* }
* }
*
* void WriteSave(void)
* {
* FILE *save = fopen("saves/save0.sav", "wb");
* if (save == NULL) {
* // Something bad happened!
* } else {
* // A bunch of stuff happens here
* fclose(save);
* }
* }
* ```
*
* Going over the bullet points again:
*
* 1. **What to Access:** This code accesses a global filesystem; game data
* and saves are all presumed to be in the current working directory (which
* may or may not be the game's installation folder!). 2. **How to Access:**
* This code assumes that content paths are writeable, and that save data is
* also writeable despite being in the same location as the game data. 3.
* **When to Access:** This code assumes that they can be called at any time,
* since the filesystem is always accessible and has no limits on how long the
* filesystem is being accessed.
*
* Due to these assumptions, the filesystem code is not portable and will fail
* under these common scenarios:
*
* - The game is installed on a device that is read-only, both content loading
* and game saves will fail or crash outright
* - Game/User storage is not implicitly mounted, so no files will be found
* for either scenario when a platform requires explicitly mounting
* filesystems
* - Save data may not be safe since the I/O is not being flushed or
* validated, so an error occurring elsewhere in the program may result in
* missing/corrupted save data
*
* When using, SDL_Storage, these types of problems are virtually impossible
* to trip over:
*
* ```
* void ReadGameData(void)
* {
* extern char** fileNames;
* extern size_t numFiles;
*
* SDL_Storage *title = SDL_OpenTitleStorage(NULL, 0);
* if (title == NULL) {
* // Something bad happened!
* }
* while (!SDL_StorageReady(title)) {
* SDL_Delay(1);
* }
*
* for (size_t i = 0; i < numFiles; i += 1) {
* void* dst;
* Uint64 dstLen = 0;
*
* if (SDL_GetStorageFileSize(title, fileNames[i], &dstLen) && dstLen > 0) {
* dst = SDL_malloc(dstLen);
* if (SDL_ReadStorageFile(title, fileNames[i], dst, dstLen)) {
* // A bunch of stuff happens here
* } else {
* // Something bad happened!
* }
* SDL_free(dst);
* } else {
* // Something bad happened!
* }
* }
*
* SDL_CloseStorage(title);
* }
*
* void ReadSave(void)
* {
* SDL_Storage *user = SDL_OpenUserStorage("libsdl", "Storage Example", 0);
* if (user == NULL) {
* // Something bad happened!
* }
* while (!SDL_StorageReady(user)) {
* SDL_Delay(1);
* }
*
* Uint64 saveLen = 0;
* if (SDL_GetStorageFileSize(user, "save0.sav", &saveLen) && saveLen > 0) {
* void* dst = SDL_malloc(saveLen);
* if (SDL_ReadStorageFile(user, "save0.sav", dst, saveLen)) {
* // A bunch of stuff happens here
* } else {
* // Something bad happened!
* }
* SDL_free(dst);
* } else {
* // Something bad happened!
* }
*
* SDL_CloseStorage(user);
* }
*
* void WriteSave(void)
* {
* SDL_Storage *user = SDL_OpenUserStorage("libsdl", "Storage Example", 0);
* if (user == NULL) {
* // Something bad happened!
* }
* while (!SDL_StorageReady(user)) {
* SDL_Delay(1);
* }
*
* extern void *saveData; // A bunch of stuff happened here...
* extern Uint64 saveLen;
* if (!SDL_WriteStorageFile(user, "save0.sav", saveData, saveLen)) {
* // Something bad happened!
* }
*
* SDL_CloseStorage(user);
* }
* ```
*
* Note the improvements that SDL_Storage makes:
*
* 1. **What to Access:** This code explicitly reads from a title or user
* storage device based on the context of the function. 2. **How to Access:**
* This code explicitly uses either a read or write function based on the
* context of the function. 3. **When to Access:** This code explicitly opens
* the device when it needs to, and closes it when it is finished working with
* the filesystem.
*
* The result is an application that is significantly more robust against the
* increasing demands of platforms and their filesystems!
*
* A publicly available example of an SDL_Storage backend is the
* [Steam Cloud](https://partner.steamgames.com/doc/features/cloud)
* backend - you can initialize Steamworks when starting the program, and then
* SDL will recognize that Steamworks is initialized and automatically use
* ISteamRemoteStorage when the application opens user storage. More
* importantly, when you _open_ storage it knows to begin a "batch" of
* filesystem operations, and when you _close_ storage it knows to end and
* flush the batch. This is used by Steam to support
* [Dynamic Cloud Sync](https://steamcommunity.com/groups/steamworks/announcements/detail/3142949576401813670)
* ; users can save data on one PC, put the device to sleep, and then continue
* playing on another PC (and vice versa) with the save data fully
* synchronized across all devices, allowing for a seamless experience without
* having to do full restarts of the program.
*/ */
#ifndef SDL_storage_h_ #ifndef SDL_storage_h_
@@ -40,8 +231,6 @@
extern "C" { extern "C" {
#endif #endif
/* !!! FIXME: Don't let this ship without async R/W support!!! */
/** /**
* Function interface for SDL_Storage. * Function interface for SDL_Storage.
* *
@@ -266,6 +455,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetStorageFileSize(SDL_Storage *storage, co
* Synchronously read a file from a storage container into a client-provided * Synchronously read a file from a storage container into a client-provided
* buffer. * buffer.
* *
* The value of `length` must match the length of the file exactly; call
* SDL_GetStorageFileSize() to get this value. This behavior may be relaxed in
* a future release.
*
* \param storage a storage container to read from. * \param storage a storage container to read from.
* \param path the relative path of the file to read. * \param path the relative path of the file to read.
* \param destination a client-provided buffer to read the file into. * \param destination a client-provided buffer to read the file into.

View File

@@ -116,7 +116,7 @@ typedef enum SDL_ThreadState
SDL_THREAD_UNKNOWN, /**< The thread is not valid */ SDL_THREAD_UNKNOWN, /**< The thread is not valid */
SDL_THREAD_ALIVE, /**< The thread is currently running */ SDL_THREAD_ALIVE, /**< The thread is currently running */
SDL_THREAD_DETACHED, /**< The thread is detached and can't be waited on */ SDL_THREAD_DETACHED, /**< The thread is detached and can't be waited on */
SDL_THREAD_COMPLETE, /**< The thread has finished and should be cleaned up with SDL_WaitThread() */ SDL_THREAD_COMPLETE /**< The thread has finished and should be cleaned up with SDL_WaitThread() */
} SDL_ThreadState; } SDL_ThreadState;
/** /**

View File

@@ -48,7 +48,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";
const bool buildStatic = true; const bool buildStatic = true;
var configs = new string[] var configs = new string[]
{ {
@@ -88,8 +88,9 @@ namespace Flax.Deps.Dependencies
Path.Combine(root, "include", "SDL3"), Path.Combine(root, "include", "SDL3"),
}; };
CloneGitRepoFastSince(root, "https://github.com/libsdl-org/SDL.git", new DateTime(2024, 12, 29)); //CloneGitRepoFastSince(root, "https://github.com/Kontrabant/SDL", new DateTime(2024, 12, 29));
GitResetToCommit(root, "8cc4735d74a1ce89c5fceb48b021872c8c563174"); CloneGitRepo(root, "https://github.com/Kontrabant/SDL");
GitResetToCommit(root, "0777bff39efaa197ded98b1b64e3dd5b3845a011");
foreach (var platform in options.Platforms) foreach (var platform in options.Platforms)
{ {
@@ -110,8 +111,9 @@ namespace Flax.Deps.Dependencies
var solutionPath = Path.Combine(buildDir, "SDL3.sln"); var solutionPath = Path.Combine(buildDir, "SDL3.sln");
RunCmake(root, platform, architecture, $"-B\"{buildDir}\" -DSDL_SHARED={(!buildStatic ? "ON" : "OFF")} -DSDL_STATIC={(buildStatic ? "ON" : "OFF")} -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL " + string.Join(" ", configs)); RunCmake(root, platform, architecture, $"-B\"{buildDir}\" -DCMAKE_INSTALL_PREFIX=\"{buildDir}\" -DSDL_SHARED={(!buildStatic ? "ON" : "OFF")} -DSDL_STATIC={(buildStatic ? "ON" : "OFF")} -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL " + string.Join(" ", configs));
Deploy.VCEnvironment.BuildSolution(solutionPath, configuration, architecture.ToString()); Deploy.VCEnvironment.BuildSolution(solutionPath, configuration, architecture.ToString());
Utilities.Run("cmake", $"--build . --target install --config {configuration}", null, buildDir, Utilities.RunOptions.DefaultTool);
// Copy binaries // Copy binaries
var depsFolder = GetThirdPartyFolder(options, platform, architecture); var depsFolder = GetThirdPartyFolder(options, platform, architecture);
@@ -134,7 +136,7 @@ namespace Flax.Deps.Dependencies
directoriesToCopy.Add(Path.Combine(buildDir, "include", "SDL3")); directoriesToCopy.Add(Path.Combine(buildDir, "include", "SDL3"));
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency); int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
RunCmake(root, platform, architecture, $"-B\"{buildDir}\" -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_INSTALL_PREFIX=\"{buildDir}\" -DSDL_SHARED={(!buildStatic ? "ON" : "OFF")} -DSDL_STATIC={(buildStatic ? "ON" : "OFF")} -DCMAKE_POSITION_INDEPENDENT_CODE=ON " + string.Join(" ", configs)); RunCmake(root, platform, architecture, $"-B\"{buildDir}\" -DCMAKE_INSTALL_PREFIX=\"{buildDir}\" -DSDL_SHARED={(!buildStatic ? "ON" : "OFF")} -DSDL_STATIC={(buildStatic ? "ON" : "OFF")} -DCMAKE_POSITION_INDEPENDENT_CODE=ON " + string.Join(" ", configs));
BuildCmake(buildDir, configuration, new Dictionary<string, string>() { {"CMAKE_BUILD_PARALLEL_LEVEL", concurrency.ToString()} }); BuildCmake(buildDir, configuration, new Dictionary<string, string>() { {"CMAKE_BUILD_PARALLEL_LEVEL", concurrency.ToString()} });
Utilities.Run("cmake", $"--build . --target install --config {configuration}", null, buildDir, Utilities.RunOptions.DefaultTool); Utilities.Run("cmake", $"--build . --target install --config {configuration}", null, buildDir, Utilities.RunOptions.DefaultTool);