Compare commits
10 Commits
ef8f6b8d47
...
d5f64dcbaa
| Author | SHA1 | Date | |
|---|---|---|---|
| d5f64dcbaa | |||
| ef83dd5377 | |||
| bc241afc09 | |||
| 1357d882cd | |||
| fd0617f3ae | |||
| 61cadd0fdf | |||
| 9552103c58 | |||
| 51132b1bd4 | |||
| 02f446ccfd | |||
| 26012d0b74 |
@@ -12,6 +12,6 @@ cd "`dirname "$0"`"
|
||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
||||
|
||||
# Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
#echo Building C# bindings...
|
||||
# TODO: Detect the correct architecture here
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||
#Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||
|
||||
@@ -1591,22 +1591,21 @@ namespace FlaxEditor.Viewport
|
||||
else
|
||||
EndMouseCapture();
|
||||
}
|
||||
|
||||
_prevInput = _input;
|
||||
#if PLATFORM_SDL
|
||||
_prevInput = _input;
|
||||
bool useMouse = IsControllingMouse || ContainsPoint(ref _viewMousePos) || _prevInput.IsControllingMouse;
|
||||
if (canUseInput && ContainsFocus)
|
||||
_input.Gather(win.Window, useMouse, ref _prevInput);
|
||||
else
|
||||
_input.Clear();
|
||||
#else
|
||||
bool useMouse = IsControllingMouse || (Mathf.IsInRange(_viewMousePos.X, 0, Width) && Mathf.IsInRange(_viewMousePos.Y, 0, Height));
|
||||
_prevInput = _input;
|
||||
var hit = GetChildAt(_viewMousePos, c => c.Visible && !(c is CanvasRootControl) && !(c is UIEditorRoot));
|
||||
if (_prevInput.IsControllingMouse)
|
||||
hit = null;
|
||||
#else
|
||||
bool useMouse = IsControllingMouse || ContainsPoint(ref _viewMousePos);
|
||||
var hit = GetChildAt(_viewMousePos, c => c.Visible && !(c is CanvasRootControl) && !(c is UIEditorRoot));
|
||||
#endif
|
||||
if (canUseInput && ContainsFocus && hit == null)
|
||||
_input.Gather(win.Window, useMouse, ref _prevInput);
|
||||
else
|
||||
_input.Clear();
|
||||
#endif
|
||||
|
||||
// Track controlling mouse state change
|
||||
bool wasControllingMouse = _prevInput.IsControllingMouse;
|
||||
|
||||
@@ -1061,7 +1061,7 @@ namespace FlaxEditor.Windows
|
||||
_cursorVisible = Screen.CursorVisible;
|
||||
_cursorLockMode = Screen.CursorLock;
|
||||
Screen.CursorVisible = true;
|
||||
if (Screen.CursorLock == CursorLockMode.Clipped)
|
||||
if (Screen.CursorLock == CursorLockMode.Clipped || Screen.CursorLock == CursorLockMode.Locked)
|
||||
Screen.CursorLock = CursorLockMode.None;
|
||||
|
||||
// Defocus
|
||||
|
||||
@@ -18,7 +18,7 @@ void AndroidVulkanPlatform::GetDeviceExtensions(Array<const char*>& extensions,
|
||||
extensions.Add(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
void AndroidVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface)
|
||||
void AndroidVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
|
||||
{
|
||||
ASSERT(window);
|
||||
void* windowHandle = window->GetNativePtr();
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
// Support more backbuffers in case driver decides to use more
|
||||
#define VULKAN_BACK_BUFFERS_COUNT_MAX 8
|
||||
|
||||
class GPUDeviceVulkan;
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for the Vulkan API support for Android platform.
|
||||
/// </summary>
|
||||
@@ -17,7 +19,7 @@ class AndroidVulkanPlatform : public VulkanPlatformBase
|
||||
public:
|
||||
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void GetDeviceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface);
|
||||
static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface);
|
||||
};
|
||||
|
||||
typedef AndroidVulkanPlatform VulkanPlatform;
|
||||
|
||||
@@ -192,7 +192,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
|
||||
ASSERT_LOW_LAYER(_backBuffers.Count() == 0);
|
||||
|
||||
// Create platform-dependent surface
|
||||
VulkanPlatform::CreateSurface(_window, GPUDeviceVulkan::Instance, &_surface);
|
||||
VulkanPlatform::CreateSurface(_window, _device, GPUDeviceVulkan::Instance, &_surface);
|
||||
if (_surface == VK_NULL_HANDLE)
|
||||
{
|
||||
LOG(Warning, "Failed to create Vulkan surface.");
|
||||
|
||||
@@ -30,7 +30,7 @@ void LinuxVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions,
|
||||
extensions.Add(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
void LinuxVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface)
|
||||
void LinuxVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
|
||||
{
|
||||
#if !PLATFORM_SDL
|
||||
void* windowHandle = window->GetNativePtr();
|
||||
@@ -41,22 +41,21 @@ void LinuxVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkS
|
||||
VALIDATE_VULKAN_RESULT(vkCreateXlibSurfaceKHR(instance, &surfaceCreateInfo, nullptr, surface));
|
||||
#else
|
||||
SDLWindow* sdlWindow = static_cast<Window*>(window);
|
||||
X11::Window x11Window = (X11::Window)sdlWindow->GetX11WindowHandle();
|
||||
wl_surface* waylandSurface = (wl_surface*)sdlWindow->GetWaylandSurfacePtr();
|
||||
if (waylandSurface != nullptr)
|
||||
void* windowHandle = window->GetNativePtr();
|
||||
if (SDLPlatform::UsesWayland())
|
||||
{
|
||||
VkWaylandSurfaceCreateInfoKHR surfaceCreateInfo;
|
||||
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR);
|
||||
surfaceCreateInfo.display = (wl_display*)sdlWindow->GetWaylandDisplay();
|
||||
surfaceCreateInfo.surface = waylandSurface;
|
||||
surfaceCreateInfo.surface = (wl_surface*)windowHandle;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateWaylandSurfaceKHR(instance, &surfaceCreateInfo, nullptr, surface));
|
||||
}
|
||||
else if (x11Window != 0)
|
||||
else if (SDLPlatform::UsesX11())
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR surfaceCreateInfo;
|
||||
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR);
|
||||
surfaceCreateInfo.dpy = (X11::Display*)sdlWindow->GetX11Display();
|
||||
surfaceCreateInfo.window = x11Window;
|
||||
surfaceCreateInfo.window = (X11::Window)windowHandle;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateXlibSurfaceKHR(instance, &surfaceCreateInfo, nullptr, surface));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
// Prevent wierd error 'Invalid VkValidationCacheEXT Object'
|
||||
#define VULKAN_USE_VALIDATION_CACHE 0
|
||||
|
||||
class GPUDeviceVulkan;
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for the Vulkan API support for Linux platform.
|
||||
/// </summary>
|
||||
@@ -19,7 +21,7 @@ class LinuxVulkanPlatform : public VulkanPlatformBase
|
||||
{
|
||||
public:
|
||||
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* outSurface);
|
||||
static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* outSurface);
|
||||
};
|
||||
|
||||
typedef LinuxVulkanPlatform VulkanPlatform;
|
||||
|
||||
@@ -5,22 +5,39 @@
|
||||
#include "MacVulkanPlatform.h"
|
||||
#include "../RenderToolsVulkan.h"
|
||||
#include "Engine/Platform/Window.h"
|
||||
#include "Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
void MacVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers)
|
||||
{
|
||||
extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
extensions.Add(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
|
||||
extensions.Add(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
|
||||
extensions.Add(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
void MacVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface)
|
||||
void MacVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
|
||||
{
|
||||
void* windowHandle = window->GetNativePtr();
|
||||
NSWindow* nswindow = (NSWindow*)windowHandle;
|
||||
VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo;
|
||||
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK);
|
||||
surfaceCreateInfo.pView = (void*)nswindow.contentView;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateMacOSSurfaceMVK(instance, &surfaceCreateInfo, nullptr, surface));
|
||||
#if PLATFORM_SDL
|
||||
nswindow.contentView.wantsLayer = YES;
|
||||
nswindow.contentView.layer = [CAMetalLayer layer];
|
||||
#endif
|
||||
if (device->InstanceExtensions.Contains(VK_EXT_METAL_SURFACE_EXTENSION_NAME))
|
||||
{
|
||||
VkMetalSurfaceCreateInfoEXT surfaceCreateInfo;
|
||||
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT);
|
||||
surfaceCreateInfo.pLayer = (CAMetalLayer*)nswindow.contentView.layer;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateMetalSurfaceEXT(instance, &surfaceCreateInfo, nullptr, surface));
|
||||
}
|
||||
else
|
||||
{
|
||||
VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo;
|
||||
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK);
|
||||
surfaceCreateInfo.pView = (void*)nswindow.contentView;
|
||||
VALIDATE_VULKAN_RESULT(vkCreateMacOSSurfaceMVK(instance, &surfaceCreateInfo, nullptr, surface));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
// General/Validation Error:0 VK_ERROR_INITIALIZATION_FAILED: Could not create MTLCounterSampleBuffer for query pool of type VK_QUERY_TYPE_TIMESTAMP. Reverting to emulated behavior. (Error code 0): Cannot allocate sample buffer
|
||||
#define VULKAN_USE_QUERIES 0
|
||||
|
||||
class GPUDeviceVulkan;
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for the Vulkan API support for Mac platform.
|
||||
/// </summary>
|
||||
@@ -18,7 +20,7 @@ class MacVulkanPlatform : public VulkanPlatformBase
|
||||
{
|
||||
public:
|
||||
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* outSurface);
|
||||
static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* outSurface);
|
||||
};
|
||||
|
||||
typedef MacVulkanPlatform VulkanPlatform;
|
||||
|
||||
@@ -14,7 +14,7 @@ void Win32VulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions,
|
||||
extensions.Add(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
void Win32VulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface)
|
||||
void Win32VulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
|
||||
{
|
||||
void* windowHandle = window->GetNativePtr();
|
||||
VkWin32SurfaceCreateInfoKHR surfaceCreateInfo;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#define VULKAN_USE_PLATFORM_WIN32_KHX 1
|
||||
#define VULKAN_USE_CREATE_WIN32_SURFACE 1
|
||||
|
||||
class GPUDeviceVulkan;
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for the Vulkan API support for Win32 platform.
|
||||
/// </summary>
|
||||
@@ -17,7 +19,7 @@ class Win32VulkanPlatform : public VulkanPlatformBase
|
||||
{
|
||||
public:
|
||||
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface);
|
||||
static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface);
|
||||
};
|
||||
|
||||
typedef Win32VulkanPlatform VulkanPlatform;
|
||||
|
||||
@@ -14,7 +14,7 @@ void iOSVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions, Ar
|
||||
extensions.Add(VK_MVK_IOS_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
void iOSVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface)
|
||||
void iOSVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
|
||||
{
|
||||
void* windowHandle = window->GetNativePtr();
|
||||
// Create surface on a main UI Thread
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
// General/Validation Error:0 VK_ERROR_INITIALIZATION_FAILED: Could not create MTLCounterSampleBuffer for query pool of type VK_QUERY_TYPE_TIMESTAMP. Reverting to emulated behavior. (Error code 0): Cannot allocate sample buffer
|
||||
#define VULKAN_USE_QUERIES 0
|
||||
|
||||
class GPUDeviceVulkan;
|
||||
|
||||
/// <summary>
|
||||
/// The implementation for the Vulkan API support for iOS platform.
|
||||
/// </summary>
|
||||
@@ -18,7 +20,7 @@ class iOSVulkanPlatform : public VulkanPlatformBase
|
||||
{
|
||||
public:
|
||||
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
|
||||
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* outSurface);
|
||||
static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* outSurface);
|
||||
};
|
||||
|
||||
typedef iOSVulkanPlatform VulkanPlatform;
|
||||
|
||||
@@ -273,6 +273,7 @@ bool MacPlatform::Init()
|
||||
CFRelease(computerName);
|
||||
}
|
||||
|
||||
#if !PLATFORM_SDL
|
||||
// Find the maximum scale of the display to handle high-dpi displays scaling factor
|
||||
{
|
||||
NSArray* screenArray = [NSScreen screens];
|
||||
@@ -297,6 +298,7 @@ bool MacPlatform::Init()
|
||||
|
||||
Input::Mouse = New<MacMouse>();
|
||||
Input::Keyboard = New<MacKeyboard>();
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -423,11 +425,15 @@ String MacPlatform::GetMainDirectory()
|
||||
return path;
|
||||
}
|
||||
|
||||
#if !PLATFORM_SDL
|
||||
|
||||
Window* MacPlatform::CreateWindow(const CreateWindowSettings& settings)
|
||||
{
|
||||
return New<MacWindow>(settings);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int32 MacPlatform::CreateProcess(CreateProcessSettings& settings)
|
||||
{
|
||||
LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments);
|
||||
|
||||
1153
Source/Engine/Platform/Mac/MacWindow.DragDrop.cpp
Normal file
1153
Source/Engine/Platform/Mac/MacWindow.DragDrop.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_MAC
|
||||
#if PLATFORM_MAC && !PLATFORM_SDL
|
||||
|
||||
#include "../Window.h"
|
||||
#include "Engine/Platform/Apple/AppleUtils.h"
|
||||
|
||||
@@ -432,6 +432,12 @@ public:
|
||||
Mouse::SetRelativeMode(relativeMode, window);
|
||||
if (!SDL_SetWindowRelativeMouseMode(windowHandle, relativeMode))
|
||||
LOG(Error, "Failed to set mouse relative mode: {0}", String(SDL_GetError()));
|
||||
|
||||
#if PLATFORM_MAC
|
||||
// Warping right before entering relative mode seems to generate motion event for relative mode
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_EVENT_MOUSE_MOTION);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsRelative(Window* window) const override
|
||||
@@ -450,7 +456,7 @@ class SDLGamepad : public Gamepad
|
||||
{
|
||||
private:
|
||||
|
||||
SDL_Gamepad* _gamepad;
|
||||
SDL_Gamepad* _gamepad = nullptr;
|
||||
SDL_JoystickID _instanceId;
|
||||
|
||||
public:
|
||||
@@ -621,8 +627,6 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
|
||||
SDLGamepad* gamepad = SDLGamepad::GetGamepadById(event.gaxis.which);
|
||||
SDL_GamepadAxis axis = (SDL_GamepadAxis)event.gaxis.axis;
|
||||
gamepad->OnAxisMotion(axis, event.gaxis.value);
|
||||
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_AXIS_MOTION");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
@@ -631,16 +635,12 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
|
||||
SDLGamepad* gamepad = SDLGamepad::GetGamepadById(event.gbutton.which);
|
||||
SDL_GamepadButton button = (SDL_GamepadButton)event.gbutton.button;
|
||||
gamepad->OnButtonState(button, event.gbutton.down);
|
||||
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_BUTTON_");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
{
|
||||
Input::Gamepads.Add(New<SDLGamepad>(event.gdevice.which));
|
||||
Input::OnGamepadsChanged();
|
||||
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_ADDED");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
@@ -656,40 +656,38 @@ bool SDLInput::HandleEvent(SDLWindow* window, SDL_Event& event)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_REMOVED");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||
{
|
||||
auto ev = event.gdevice;
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_REMAPPED");
|
||||
LOG(Info, "TODO: SDL_EVENT_GAMEPAD_REMAPPED");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
|
||||
{
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN");
|
||||
LOG(Info, "TODO: SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
|
||||
{
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION");
|
||||
LOG(Info, "TODO: SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
|
||||
{
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_TOUCHPAD_UP");
|
||||
LOG(Info, "TODO: SDL_EVENT_GAMEPAD_TOUCHPAD_UP");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
|
||||
{
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_SENSOR_UPDATE");
|
||||
LOG(Info, "TODO: SDL_EVENT_GAMEPAD_SENSOR_UPDATE");
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
|
||||
{
|
||||
auto ev = event.gdevice;
|
||||
LOG(Info, "SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED");
|
||||
LOG(Info, "TODO: SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -707,6 +705,7 @@ Guid GetGamepadGuid(SDL_JoystickID instanceId)
|
||||
SDLGamepad::SDLGamepad(SDL_JoystickID instanceId)
|
||||
: SDLGamepad(SDL_OpenGamepad(instanceId), instanceId)
|
||||
{
|
||||
LOG(Info, "Gamepad connected: {}", String(SDL_GetGamepadName(_gamepad)));
|
||||
}
|
||||
|
||||
SDLGamepad::SDLGamepad(SDL_Gamepad* gamepad, SDL_JoystickID instanceId)
|
||||
@@ -726,6 +725,7 @@ SDLGamepad::~SDLGamepad()
|
||||
void SDLGamepad::SetVibration(const GamepadVibrationState& state)
|
||||
{
|
||||
Gamepad::SetVibration(state);
|
||||
LOG(Info, "TODO: SDLGamepad::SetVibration");
|
||||
}
|
||||
|
||||
bool SDLGamepad::UpdateState()
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "Engine/Platform/Linux/IncludeX11.h"
|
||||
|
||||
#include <SDL3/SDL_clipboard.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_hints.h>
|
||||
#include <SDL3/SDL_messagebox.h>
|
||||
@@ -655,7 +656,7 @@ DragDropEffect Window::DoDragDropX11(const StringView& data)
|
||||
#if !PLATFORM_SDL
|
||||
X11::Window mainWindow = _window;
|
||||
#else
|
||||
X11::Window mainWindow = static_cast<X11::Window>(GetX11WindowHandle());
|
||||
X11::Window mainWindow = reinterpret_cast<X11::Window>(GetNativePtr());
|
||||
#endif
|
||||
|
||||
// Make sure SDL hasn't grabbed the pointer, and force ungrab it
|
||||
@@ -1104,7 +1105,7 @@ void SDLClipboard::SetText(const StringView& text)
|
||||
|
||||
if (X11Impl::xDisplay)
|
||||
{
|
||||
X11::Window window = (X11::Window)(mainWindow->GetX11WindowHandle());
|
||||
X11::Window window = (X11::Window)(mainWindow->GetNativePtr());
|
||||
X11Impl::ClipboardText.Set(text.Get(), text.Length());
|
||||
X11::XSetSelectionOwner(X11Impl::xDisplay, X11Impl::xAtomClipboard, window, CurrentTime); // CLIPBOARD
|
||||
//X11::XSetSelectionOwner(xDisplay, xAtomPrimary, window, CurrentTime); // XA_PRIMARY
|
||||
@@ -1113,9 +1114,7 @@ void SDLClipboard::SetText(const StringView& text)
|
||||
//X11::XGetSelectionOwner(xDisplay, xAtomPrimary);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Warning, "Wayland clipboard support is not implemented yet."); // TODO: Wayland
|
||||
}
|
||||
SDL_SetClipboardText(StringAnsi(text).GetText());
|
||||
}
|
||||
|
||||
void SDLClipboard::SetRawData(const Span<byte>& data)
|
||||
@@ -1136,7 +1135,7 @@ String SDLClipboard::GetText()
|
||||
return result;
|
||||
if (X11Impl::xDisplay)
|
||||
{
|
||||
X11::Window window = static_cast<X11::Window>(mainWindow->GetX11WindowHandle());
|
||||
X11::Window window = reinterpret_cast<X11::Window>(mainWindow->GetNativePtr());
|
||||
|
||||
X11Impl::ClipboardGetText(result, X11Impl::xAtomClipboard, X11Impl::xAtomUTF8String, window);
|
||||
if (result.HasChars())
|
||||
@@ -1152,8 +1151,7 @@ String SDLClipboard::GetText()
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Warning, "Wayland clipboard is not implemented yet."); // TODO: Wayland
|
||||
return String::Empty;
|
||||
return String(SDL_GetClipboardText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,587 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "SDLInput.h"
|
||||
#if PLATFORM_SDL && PLATFORM_MAC
|
||||
|
||||
static_assert(false, "TODO");
|
||||
#include "SDLWindow.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Engine/CommandLine.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "Engine/Input/Input.h"
|
||||
#include "Engine/Input/Mouse.h"
|
||||
#include "Engine/Platform/IGuiData.h"
|
||||
#include "Engine/Platform/MessageBox.h"
|
||||
#include "Engine/Platform/Platform.h"
|
||||
#include "Engine/Platform/WindowsManager.h"
|
||||
#include "Engine/Platform/Base/DragDropHelper.h"
|
||||
#include "Engine/Platform/SDL/SDLClipboard.h"
|
||||
#include "Engine/Platform/Unix/UnixFile.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
|
||||
#include "Engine/Platform/Apple/AppleUtils.h"
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_hints.h>
|
||||
#include <SDL3/SDL_messagebox.h>
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
#include <SDL3/SDL_system.h>
|
||||
#include <SDL3/SDL_timer.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
|
||||
namespace MacImpl
|
||||
{
|
||||
Window* DraggedWindow = nullptr;
|
||||
String DraggingData = String();
|
||||
Float2 DraggingPosition;
|
||||
Nullable<Float2> LastMouseDragPosition;
|
||||
#if USE_EDITOR
|
||||
//CriticalSection MacDragLocker;
|
||||
bool DraggingActive = false;
|
||||
bool DraggingIgnoreEvent = false;
|
||||
NSDraggingSession* MacDragSession = nullptr;
|
||||
//DoDragDropJob* MacDragJob = nullptr;
|
||||
int64 MacDragExitFlag = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
class MacDropData : public IGuiData
|
||||
{
|
||||
public:
|
||||
Type CurrentType;
|
||||
String AsText;
|
||||
Array<String> AsFiles;
|
||||
|
||||
Type GetType() const override
|
||||
{
|
||||
return CurrentType;
|
||||
}
|
||||
String GetAsText() const override
|
||||
{
|
||||
return AsText;
|
||||
}
|
||||
void GetAsFiles(Array<String>* files) const override
|
||||
{
|
||||
files->Add(AsFiles);
|
||||
}
|
||||
};
|
||||
|
||||
bool SDLPlatform::InitInternal()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDLPlatform::UsesWindows()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDLPlatform::UsesWayland()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDLPlatform::UsesX11()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SDLPlatform::EventFilterCallback(void* userdata, SDL_Event* event)
|
||||
{
|
||||
Window* draggedWindow = *(Window**)userdata;
|
||||
if (draggedWindow == nullptr)
|
||||
{
|
||||
if (MacImpl::DraggingActive)
|
||||
{
|
||||
// Handle events during drag operation here since the normal event loop is blocked
|
||||
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
||||
{
|
||||
LOG(Info, "Window exposed event");
|
||||
// The internal timer is sending exposed events every ~16ms
|
||||
#if USE_EDITOR
|
||||
// Flush any single-frame shapes to prevent memory leaking (eg. via terrain collision debug during scene drawing with PhysicsColliders or PhysicsDebug flag)
|
||||
DebugDraw::UpdateContext(nullptr, 0.0f);
|
||||
#endif
|
||||
Engine::OnUpdate(); // For docking updates
|
||||
Engine::OnDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
||||
if (window)
|
||||
window->HandleEvent(*event);
|
||||
|
||||
// We do not receive events at steady rate to keep the engine updated...
|
||||
#if USE_EDITOR
|
||||
// Flush any single-frame shapes to prevent memory leaking (eg. via terrain collision debug during scene drawing with PhysicsColliders or PhysicsDebug flag)
|
||||
DebugDraw::UpdateContext(nullptr, 0.0f);
|
||||
#endif
|
||||
Engine::OnUpdate(); // For docking updates
|
||||
Engine::OnDraw();
|
||||
|
||||
if (event->type == SDL_EVENT_DROP_BEGIN || event->type == SDL_EVENT_DROP_FILE || event->type == SDL_EVENT_DROP_TEXT)
|
||||
return true; // Filtering these event stops other following events from getting added to the queue
|
||||
else
|
||||
LOG(Info, "Unhandled event: {}", event->type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
// When the window is being dragged on Windows, the internal message loop is blocking
|
||||
// the SDL event queue. We need to handle all relevant events in this event watch callback
|
||||
// to ensure dragging related functionality doesn't break due to engine not getting updated.
|
||||
// This also happens to fix the engine freezing during the dragging operation.
|
||||
#if false
|
||||
SDLWindow* window = SDLWindow::GetWindowFromEvent(*event);
|
||||
if (event->type == SDL_EVENT_WINDOW_EXPOSED)
|
||||
{
|
||||
// The internal timer is sending exposed events every ~16ms
|
||||
Engine::OnUpdate(); // For docking updates
|
||||
Engine::OnDraw();
|
||||
return false;
|
||||
}
|
||||
else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
bool result = false;
|
||||
window->OnLeftButtonHit(WindowHitCodes::Caption, result);
|
||||
//if (result)
|
||||
// return false;
|
||||
window->HandleEvent(*event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (event->type == SDL_EVENT_WINDOW_MOVED)
|
||||
{
|
||||
if (window)
|
||||
window->HandleEvent(*event);
|
||||
|
||||
/*if (WinImpl::DraggedWindowSize != window->GetClientSize())
|
||||
{
|
||||
// The window size changed while dragging, most likely due to maximized window restoring back to previous size.
|
||||
WinImpl::DraggedWindowMousePosition = WinImpl::DraggedWindowStartPosition + WinImpl::DraggedWindowMousePosition - window->GetClientPosition();
|
||||
WinImpl::DraggedWindowStartPosition = window->GetClientPosition();
|
||||
WinImpl::DraggedWindowSize = window->GetClientSize();
|
||||
}
|
||||
Float2 windowPosition = Float2(static_cast<float>(event->window.data1), static_cast<float>(event->window.data2));
|
||||
Float2 mousePosition = WinImpl::DraggedWindowMousePosition;
|
||||
|
||||
// Generate mouse movement events while dragging the window around
|
||||
SDL_Event mouseMovedEvent { 0 };
|
||||
mouseMovedEvent.motion.type = SDL_EVENT_MOUSE_MOTION;
|
||||
mouseMovedEvent.motion.windowID = SDL_GetWindowID(WinImpl::DraggedWindow->GetSDLWindow());
|
||||
mouseMovedEvent.motion.timestamp = SDL_GetTicksNS();
|
||||
mouseMovedEvent.motion.state = SDL_BUTTON_LEFT;
|
||||
mouseMovedEvent.motion.x = mousePosition.X;
|
||||
mouseMovedEvent.motion.y = mousePosition.Y;
|
||||
if (window)
|
||||
window->HandleEvent(mouseMovedEvent);*/
|
||||
|
||||
return false;
|
||||
}
|
||||
if (window)
|
||||
window->HandleEvent(*event);
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDLPlatform::PreHandleEvents()
|
||||
{
|
||||
SDL_SetEventFilter(EventFilterCallback, &MacImpl::DraggedWindow);
|
||||
}
|
||||
|
||||
void SDLPlatform::PostHandleEvents()
|
||||
{
|
||||
SDL_SetEventFilter(EventFilterCallback, &MacImpl::DraggedWindow);
|
||||
|
||||
// Handle window dragging release here
|
||||
if (MacImpl::DraggedWindow != nullptr)
|
||||
{
|
||||
Float2 mousePosition;
|
||||
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
|
||||
bool buttonReleased = (buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) == 0;
|
||||
if (buttonReleased)
|
||||
{
|
||||
// Send simulated mouse up event
|
||||
SDL_Event buttonUpEvent { 0 };
|
||||
buttonUpEvent.motion.type = SDL_EVENT_MOUSE_BUTTON_UP;
|
||||
buttonUpEvent.button.down = false;
|
||||
buttonUpEvent.motion.windowID = SDL_GetWindowID(MacImpl::DraggedWindow->GetSDLWindow());
|
||||
buttonUpEvent.motion.timestamp = SDL_GetTicksNS();
|
||||
buttonUpEvent.motion.state = SDL_BUTTON_LEFT;
|
||||
buttonUpEvent.button.clicks = 1;
|
||||
buttonUpEvent.motion.x = mousePosition.X;
|
||||
buttonUpEvent.motion.y = mousePosition.Y;
|
||||
MacImpl::DraggedWindow->HandleEvent(buttonUpEvent);
|
||||
MacImpl::DraggedWindow = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SDLWindow::HandleEventInternal(SDL_Event& event)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
{
|
||||
// Quartz doesn't report any mouse events when mouse is over the caption area, send a simulated event instead...
|
||||
Float2 mousePosition;
|
||||
auto buttons = SDL_GetGlobalMouseState(&mousePosition.X, &mousePosition.Y);
|
||||
if ((buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) != 0)
|
||||
{
|
||||
if (MacImpl::DraggedWindow == nullptr)
|
||||
{
|
||||
// TODO: verify mouse position, window focus
|
||||
bool result = false;
|
||||
OnLeftButtonHit(WindowHitCodes::Caption, result);
|
||||
if (result)
|
||||
MacImpl::DraggedWindow = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
Float2 mousePos = Platform::GetMousePosition();
|
||||
Input::Mouse->OnMouseMove(mousePos, this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
{
|
||||
if (MacImpl::LastMouseDragPosition.HasValue())
|
||||
{
|
||||
// SDL reports wrong mouse position after dragging has ended
|
||||
Float2 mouseClientPosition = ScreenToClient(MacImpl::LastMouseDragPosition.GetValue());
|
||||
event.button.x = mouseClientPosition.X;
|
||||
event.button.y = mouseClientPosition.Y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
if (MacImpl::LastMouseDragPosition.HasValue())
|
||||
MacImpl::LastMouseDragPosition.Reset();
|
||||
if (MacImpl::DraggedWindow != nullptr)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||
{
|
||||
OnDragLeave(); // Check for release of mouse button too?
|
||||
break;
|
||||
}
|
||||
//case SDL_EVENT_CLIPBOARD_UPDATE:
|
||||
case SDL_EVENT_DROP_BEGIN:
|
||||
case SDL_EVENT_DROP_POSITION:
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
case SDL_EVENT_DROP_TEXT:
|
||||
case SDL_EVENT_DROP_COMPLETE:
|
||||
{
|
||||
{
|
||||
// HACK: We can't use Wayland listeners due to SDL also using them at the same time causes
|
||||
// some of the events to drop and make it impossible to implement dragging on application side.
|
||||
// We can get enough information through SDL_EVENT_DROP_* events to fill in the blanks for the
|
||||
// drag and drop implementation.
|
||||
|
||||
auto dpiScale = GetDpiScale();
|
||||
Float2 mousePos = Float2(event.drop.x * dpiScale, event.drop.y * dpiScale);
|
||||
DragDropEffect effect = DragDropEffect::None;
|
||||
String text(event.drop.data);
|
||||
MacDropData dropData;
|
||||
|
||||
if (MacImpl::DraggingActive)
|
||||
{
|
||||
// We don't have the window dragging data during these events...
|
||||
text = MacImpl::DraggingData;
|
||||
mousePos = ScreenToClient(MacImpl::DraggingPosition);
|
||||
|
||||
// Ensure mouse position is updated while dragging
|
||||
Input::Mouse->OnMouseMove(MacImpl::DraggingPosition, this);
|
||||
MacImpl::LastMouseDragPosition = MacImpl::DraggingPosition;
|
||||
}
|
||||
dropData.AsText = text;
|
||||
|
||||
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
|
||||
if (!MacImpl::DraggingActive)
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Files;
|
||||
OnDragEnter(&dropData, mousePos, effect);
|
||||
}
|
||||
if (effect == DragDropEffect::None)
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Text;
|
||||
OnDragEnter(&dropData, mousePos, effect);
|
||||
}
|
||||
}
|
||||
else if (event.type == SDL_EVENT_DROP_POSITION)
|
||||
{
|
||||
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
|
||||
if (!MacImpl::DraggingActive)
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Files;
|
||||
OnDragOver(&dropData, mousePos, effect);
|
||||
}
|
||||
if (effect == DragDropEffect::None)
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Text;
|
||||
OnDragOver(&dropData, mousePos, effect);
|
||||
}
|
||||
}
|
||||
else if (event.type == SDL_EVENT_DROP_FILE)
|
||||
{
|
||||
text.Split('\n', dropData.AsFiles);
|
||||
dropData.CurrentType = IGuiData::Type::Files;
|
||||
OnDragDrop(&dropData, mousePos, effect);
|
||||
}
|
||||
else if (event.type == SDL_EVENT_DROP_TEXT)
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Text;
|
||||
OnDragDrop(&dropData, mousePos, effect);
|
||||
}
|
||||
else if (event.type == SDL_EVENT_DROP_COMPLETE)
|
||||
{
|
||||
OnDragLeave();
|
||||
if (MacImpl::DraggingActive)
|
||||
{
|
||||
// The previous drop events needs to be flushed to avoid processing them twice
|
||||
SDL_FlushEvents(SDL_EVENT_DROP_FILE, SDL_EVENT_DROP_POSITION);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Implement handling for feedback effect result (https://github.com/libsdl-org/SDL/issues/10448)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SDLPlatform::SetHighDpiAwarenessEnabled(bool enable)
|
||||
{
|
||||
// TODO: This is now called before Platform::Init, ensure the scaling is changed accordingly during Platform::Init (see ApplePlatform::SetHighDpiAwarenessEnabled)
|
||||
}
|
||||
|
||||
|
||||
inline bool IsWindowInvalid(Window* win)
|
||||
{
|
||||
WindowsManager::WindowsLocker.Lock();
|
||||
const bool hasWindow = WindowsManager::Windows.Contains(win);
|
||||
WindowsManager::WindowsLocker.Unlock();
|
||||
return !hasWindow || !win;
|
||||
}
|
||||
|
||||
Float2 GetWindowTitleSize(const SDLWindow* window)
|
||||
{
|
||||
Float2 size = Float2::Zero;
|
||||
if (window->GetSettings().HasBorder)
|
||||
{
|
||||
NSRect frameStart = [(NSWindow*)window->GetNativePtr() frameRectForContentRect:NSMakeRect(0, 0, 0, 0)];
|
||||
size.Y = frameStart.size.height;
|
||||
}
|
||||
return size * MacPlatform::ScreenScale;
|
||||
}
|
||||
|
||||
Float2 GetMousePosition(SDLWindow* window, NSEvent* event)
|
||||
{
|
||||
NSRect frame = [(NSWindow*)window->GetNativePtr() frame];
|
||||
NSPoint point = [event locationInWindow];
|
||||
return Float2(point.x, frame.size.height - point.y) * MacPlatform::ScreenScale - GetWindowTitleSize(window);
|
||||
}
|
||||
|
||||
Float2 GetMousePosition(SDLWindow* window, const NSPoint& point)
|
||||
{
|
||||
NSRect frame = [(NSWindow*)window->GetNativePtr() frame];
|
||||
CGRect screenBounds = CGDisplayBounds(CGMainDisplayID());
|
||||
return Float2(point.x, screenBounds.size.height - point.y) * MacPlatform::ScreenScale;
|
||||
}
|
||||
|
||||
void GetDragDropData(const SDLWindow* window, id<NSDraggingInfo> sender, Float2& mousePos, MacDropData& dropData)
|
||||
{
|
||||
NSRect frame = [(NSWindow*)window->GetNativePtr() frame];
|
||||
NSPoint point = [sender draggingLocation];
|
||||
mousePos = Float2(point.x, frame.size.height - point.y) * MacPlatform::ScreenScale - GetWindowTitleSize(window);
|
||||
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
||||
if ([[pasteboard types] containsObject:NSPasteboardTypeString])
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Text;
|
||||
dropData.AsText = AppleUtils::ToString((CFStringRef)[pasteboard stringForType:NSPasteboardTypeString]);
|
||||
}
|
||||
else
|
||||
{
|
||||
dropData.CurrentType = IGuiData::Type::Files;
|
||||
NSArray* files = [pasteboard readObjectsForClasses:@[[NSURL class]] options:nil];
|
||||
for (int32 i = 0; i < [files count]; i++)
|
||||
{
|
||||
NSString* url = [[files objectAtIndex:i] path];
|
||||
NSString* file = [NSURL URLWithString:url].path;
|
||||
dropData.AsFiles.Add(AppleUtils::ToString((CFStringRef)file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSDragOperation GetDragDropOperation(DragDropEffect dragDropEffect)
|
||||
{
|
||||
NSDragOperation result = NSDragOperationCopy;
|
||||
switch (dragDropEffect)
|
||||
{
|
||||
case DragDropEffect::None:
|
||||
//result = NSDragOperationNone;
|
||||
break;
|
||||
case DragDropEffect::Copy:
|
||||
result = NSDragOperationCopy;
|
||||
break;
|
||||
case DragDropEffect::Move:
|
||||
result = NSDragOperationMove;
|
||||
break;
|
||||
case DragDropEffect::Link:
|
||||
result = NSDragOperationLink;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef INCLUDED_IN_SDL
|
||||
|
||||
|
||||
@interface ClipboardDataProviderImpl : NSObject <NSPasteboardItemDataProvider, NSDraggingSource>
|
||||
{
|
||||
@public
|
||||
SDLWindow* Window;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ClipboardDataProviderImpl
|
||||
|
||||
// NSPasteboardItemDataProvider
|
||||
// ---
|
||||
|
||||
- (void)pasteboard:(nullable NSPasteboard*)pasteboard item:(NSPasteboardItem*)item provideDataForType:(NSPasteboardType)type
|
||||
{
|
||||
LOG(Info, "pasteboard");
|
||||
if (IsWindowInvalid(Window)) return;
|
||||
[pasteboard setString:(NSString*)AppleUtils::ToString(MacImpl::DraggingData) forType:NSPasteboardTypeString];
|
||||
}
|
||||
|
||||
- (void)pasteboardFinishedWithDataProvider:(NSPasteboard*)pasteboard
|
||||
{
|
||||
LOG(Info, "pasteboardFinishedWithDataProvider");
|
||||
}
|
||||
|
||||
// NSDraggingSource
|
||||
// ---
|
||||
|
||||
- (NSDragOperation)draggingSession:(NSDraggingSession*)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
|
||||
{
|
||||
if (IsWindowInvalid(Window))
|
||||
return NSDragOperationNone;
|
||||
|
||||
switch(context)
|
||||
{
|
||||
case NSDraggingContextOutsideApplication:
|
||||
LOG(Info, "draggingSession sourceOperationMaskForDraggingContext: outside");
|
||||
return NSDragOperationCopy;
|
||||
case NSDraggingContextWithinApplication:
|
||||
LOG(Info, "draggingSession sourceOperationMaskForDraggingContext: inside");
|
||||
return NSDragOperationCopy;
|
||||
default:
|
||||
LOG(Info, "draggingSession sourceOperationMaskForDraggingContext: unknown");
|
||||
return NSDragOperationMove;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession*)session willBeginAtPoint:(NSPoint)screenPoint
|
||||
{
|
||||
LOG(Info, "draggingSession willBeginAtPoint");
|
||||
MacImpl::DraggingPosition = GetMousePosition(Window, screenPoint);
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession*)session movedToPoint:(NSPoint)screenPoint
|
||||
{
|
||||
//LOG(Info, "draggingSession movedToPoint");
|
||||
MacImpl::DraggingPosition = GetMousePosition(Window, screenPoint);
|
||||
}
|
||||
|
||||
- (void)draggingSession:(NSDraggingSession*)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
|
||||
{
|
||||
LOG(Info, "draggingSession endedAtPoint");
|
||||
MacImpl::DraggingPosition = GetMousePosition(Window, screenPoint);
|
||||
#if USE_EDITOR
|
||||
// Stop background worker once the drag ended
|
||||
if (MacImpl::MacDragSession && MacImpl::MacDragSession == session)
|
||||
Platform::AtomicStore(&MacImpl::MacDragExitFlag, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data)
|
||||
{
|
||||
NSWindow* window = (NSWindow*)_handle;
|
||||
ClipboardDataProviderImpl* clipboardDataProvider = [ClipboardDataProviderImpl alloc];
|
||||
clipboardDataProvider->Window = this;
|
||||
|
||||
// Create mouse drag event
|
||||
NSEvent* event = [NSEvent
|
||||
mouseEventWithType:NSEventTypeLeftMouseDragged
|
||||
location:window.mouseLocationOutsideOfEventStream
|
||||
modifierFlags:0
|
||||
timestamp:NSApp.currentEvent.timestamp
|
||||
windowNumber:window.windowNumber
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:1.0];
|
||||
|
||||
// Create drag item
|
||||
NSPasteboardItem* pasteItem = [NSPasteboardItem new];
|
||||
[pasteItem setDataProvider:clipboardDataProvider forTypes:[NSArray arrayWithObjects:NSPasteboardTypeString, nil]];
|
||||
NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:pasteItem];
|
||||
[dragItem setDraggingFrame:NSMakeRect(event.locationInWindow.x, event.locationInWindow.y, 100, 100) contents:nil];
|
||||
|
||||
// Start dragging session
|
||||
NSDraggingSession* draggingSession = [window.contentView beginDraggingSessionWithItems:[NSArray arrayWithObject:dragItem] event:event source:clipboardDataProvider];
|
||||
DragDropEffect result = DragDropEffect::None;
|
||||
|
||||
#if USE_EDITOR
|
||||
// Create background worker that will keep updating GUI (perform rendering)
|
||||
ASSERT(!MacImpl::MacDragSession);
|
||||
MacImpl::MacDragSession = draggingSession;
|
||||
MacImpl::MacDragExitFlag = 0;
|
||||
MacImpl::DraggingData = data;
|
||||
MacImpl::DraggingActive = true;
|
||||
while (Platform::AtomicRead(&MacImpl::MacDragExitFlag) == 0)
|
||||
{
|
||||
// The internal event loop will block here during the drag operation,
|
||||
// events are processed in the event filter callback instead.
|
||||
SDLPlatform::Tick();
|
||||
Platform::Sleep(1);
|
||||
}
|
||||
MacImpl::DraggingActive = false;
|
||||
MacImpl::DraggingData.Clear();
|
||||
MacImpl::MacDragSession = nullptr;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DragDropEffect SDLWindow::DoDragDrop(const StringView& data, const Float2& offset, Window* dragSourceWindow)
|
||||
{
|
||||
Show();
|
||||
return DragDropEffect::None;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -104,7 +104,8 @@ bool SDLPlatform::Init()
|
||||
if (InitInternal())
|
||||
return true;
|
||||
|
||||
if (UsesWindows() || UsesX11())
|
||||
#if !PLATFORM_MAC
|
||||
if (!UsesWayland())
|
||||
{
|
||||
// Disable SDL clipboard support
|
||||
SDL_SetEventEnabled(SDL_EVENT_CLIPBOARD_UPDATE, false);
|
||||
@@ -116,6 +117,7 @@ bool SDLPlatform::Init()
|
||||
SDL_SetEventEnabled(SDL_EVENT_DROP_COMPLETE, false);
|
||||
SDL_SetEventEnabled(SDL_EVENT_DROP_POSITION, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
SDLInput::Init();
|
||||
SDLWindow::Init();
|
||||
@@ -225,20 +227,22 @@ void SDLPlatform::OpenUrl(const StringView& url)
|
||||
|
||||
Float2 SDLPlatform::GetMousePosition()
|
||||
{
|
||||
Float2 pos;
|
||||
#if PLATFORM_LINUX
|
||||
if (UsesWayland())
|
||||
{
|
||||
// Wayland doesn't support reporting global mouse position,
|
||||
// use the last known reported position we got from received window events.
|
||||
pos = Input::GetMouseScreenPosition();
|
||||
//if (!SDL_GetGlobalMouseState(&pos.X, &pos.Y))
|
||||
// LOG(Error, "SDL_GetGlobalMouseState() failed");
|
||||
return Input::GetMouseScreenPosition();
|
||||
}
|
||||
else if (UsesX11())
|
||||
if (UsesX11())
|
||||
#elif PLATFORM_LINUX || PLATFORM_MAC
|
||||
{
|
||||
Float2 pos;
|
||||
SDL_GetGlobalMouseState(&pos.X, &pos.Y);
|
||||
else
|
||||
pos = Input::GetMouseScreenPosition();
|
||||
return pos;
|
||||
return pos;
|
||||
}
|
||||
#endif
|
||||
return Input::GetMouseScreenPosition();
|
||||
}
|
||||
|
||||
void SDLPlatform::SetMousePosition(const Float2& pos)
|
||||
|
||||
@@ -11,7 +11,10 @@ typedef struct tagMSG MSG;
|
||||
#elif PLATFORM_LINUX
|
||||
#include "Engine/Platform/Linux/LinuxPlatform.h"
|
||||
union _XEvent;
|
||||
#elif PLATFORM_MAC
|
||||
#include "Engine/Platform/Mac/MacPlatform.h"
|
||||
#else
|
||||
static_assert(false, "Unsupported Platform");
|
||||
#endif
|
||||
|
||||
class SDLWindow;
|
||||
@@ -29,8 +32,13 @@ class FLAXENGINE_API SDLPlatform
|
||||
: public LinuxPlatform
|
||||
{
|
||||
using base = LinuxPlatform;
|
||||
#elif PLATFORM_MAC
|
||||
: public MacPlatform
|
||||
{
|
||||
using base = MacPlatform;
|
||||
#else
|
||||
{
|
||||
static_assert(false, "Unsupported Platform");
|
||||
#endif
|
||||
friend SDLWindow;
|
||||
|
||||
@@ -42,9 +50,11 @@ private:
|
||||
static bool HandleEvent(SDL_Event& event);
|
||||
#if PLATFORM_WINDOWS
|
||||
static bool EventMessageHook(void* userdata, MSG* msg);
|
||||
static bool SDLPlatform::EventFilterCallback(void* userdata, SDL_Event* event);
|
||||
static bool EventFilterCallback(void* userdata, SDL_Event* event);
|
||||
#elif PLATFORM_LINUX
|
||||
static bool X11EventHook(void* userdata, _XEvent* xevent);
|
||||
#elif PLATFORM_MAC
|
||||
static bool EventFilterCallback(void* userdata, SDL_Event* event);
|
||||
#endif
|
||||
static void PreHandleEvents();
|
||||
static void PostHandleEvents();
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#endif
|
||||
#elif PLATFORM_LINUX
|
||||
#include "Engine/Platform/Linux/IncludeX11.h"
|
||||
#elif PLATFORM_MAC
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#else
|
||||
static_assert(false, "Unsupported Platform");
|
||||
#endif
|
||||
|
||||
#define DefaultDPI 96
|
||||
@@ -153,8 +157,18 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
|
||||
_dpiScale = SDL_GetWindowDisplayScale(_window);
|
||||
_dpi = Math::TruncToInt(_dpiScale * DefaultDPI);
|
||||
|
||||
SDL_SetWindowMinimumSize(_window, Math::TruncToInt(_settings.MinimumSize.X), Math::TruncToInt(_settings.MinimumSize.Y));
|
||||
SDL_SetWindowMaximumSize(_window, Math::TruncToInt(_settings.MaximumSize.X), Math::TruncToInt(_settings.MaximumSize.Y));
|
||||
Int2 minimumSize(Math::TruncToInt(_settings.MinimumSize.X) , Math::TruncToInt(_settings.MinimumSize.Y));
|
||||
Int2 maximumSize(Math::TruncToInt(_settings.MaximumSize.X) , Math::TruncToInt(_settings.MaximumSize.Y));
|
||||
|
||||
SDL_SetWindowMinimumSize(_window, minimumSize.X, minimumSize.Y);
|
||||
#if PLATFORM_MAC
|
||||
// BUG: The maximum size is not enforced correctly, set it to real high value instead
|
||||
if (maximumSize.X == 0)
|
||||
maximumSize.X = 999999;
|
||||
if (maximumSize.Y == 0)
|
||||
maximumSize.Y = 999999;
|
||||
#endif
|
||||
SDL_SetWindowMaximumSize(_window, maximumSize.X, maximumSize.Y);
|
||||
|
||||
SDL_SetWindowHitTest(_window, &OnWindowHitTest, this);
|
||||
InitSwapChain();
|
||||
@@ -178,6 +192,11 @@ SDLWindow::SDLWindow(const CreateWindowSettings& settings)
|
||||
if (xdndAware != 0)
|
||||
X11::XChangeProperty(xDisplay, (X11::Window)_handle, xdndAware, (X11::Atom)4, 32, PropModeReplace, (unsigned char*)&xdndVersion, 1);
|
||||
}
|
||||
#elif PLATFORM_MAC
|
||||
NSWindow* win = ((NSWindow*)_handle);
|
||||
NSView* view = win.contentView;
|
||||
[win unregisterDraggedTypes];
|
||||
[win registerForDraggedTypes:@[NSPasteboardTypeFileURL, NSPasteboardTypeString, (NSString*)kUTTypeFileURL, (NSString*)kUTTypeUTF8PlainText]];
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -202,21 +221,11 @@ SDL_Window* SDLWindow::GetSDLWindow() const
|
||||
|
||||
#if PLATFORM_LINUX
|
||||
|
||||
void* SDLWindow::GetWaylandSurfacePtr() const
|
||||
{
|
||||
return SDL_GetPointerProperty(SDL_GetWindowProperties(_window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
|
||||
}
|
||||
|
||||
void* SDLWindow::GetWaylandDisplay() const
|
||||
{
|
||||
return SDL_GetPointerProperty(SDL_GetWindowProperties(_window), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr);
|
||||
}
|
||||
|
||||
uintptr SDLWindow::GetX11WindowHandle() const
|
||||
{
|
||||
return (uintptr)SDL_GetNumberProperty(SDL_GetWindowProperties(_window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
}
|
||||
|
||||
void* SDLWindow::GetX11Display() const
|
||||
{
|
||||
return SDL_GetPointerProperty(SDL_GetWindowProperties(_window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
|
||||
|
||||
@@ -56,7 +56,6 @@ public:
|
||||
~SDLWindow();
|
||||
|
||||
private:
|
||||
|
||||
static SDLWindow* GetWindowFromEvent(const SDL_Event& event);
|
||||
static SDLWindow* GetWindowWithSDLWindow(SDL_Window* window);
|
||||
void HandleEvent(SDL_Event& event);
|
||||
@@ -64,18 +63,10 @@ private:
|
||||
void CheckForWindowResize();
|
||||
void UpdateCursor();
|
||||
|
||||
#if PLATFORM_LINUX
|
||||
DragDropEffect DoDragDropWayland(const StringView& data, Window* dragSourceWindow = nullptr, Float2 dragOffset = Float2::Zero);
|
||||
DragDropEffect DoDragDropX11(const StringView& data);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
SDL_Window* GetSDLWindow() const;
|
||||
#if PLATFORM_LINUX
|
||||
void* GetWaylandSurfacePtr() const;
|
||||
void* GetWaylandDisplay() const;
|
||||
uintptr GetX11WindowHandle() const;
|
||||
void* GetX11Display() const;
|
||||
#endif
|
||||
|
||||
@@ -128,6 +119,10 @@ public:
|
||||
Windows::HRESULT __stdcall DragLeave() override;
|
||||
Windows::HRESULT __stdcall Drop(Windows::IDataObject* pDataObj, Windows::DWORD grfKeyState, Windows::POINTL pt, Windows::DWORD* pdwEffect) override;
|
||||
#endif
|
||||
#if PLATFORM_LINUX
|
||||
DragDropEffect DoDragDropWayland(const StringView& data, Window* dragSourceWindow = nullptr, Float2 dragOffset = Float2::Zero);
|
||||
DragDropEffect DoDragDropX11(const StringView& data);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -265,10 +265,12 @@ class AppleThread;
|
||||
typedef AppleThread Thread;
|
||||
class MacClipboard;
|
||||
typedef MacClipboard Clipboard;
|
||||
#if !PLATFORM_SDL
|
||||
class MacPlatform;
|
||||
typedef MacPlatform Platform;
|
||||
class MacWindow;
|
||||
typedef MacWindow Window;
|
||||
#endif
|
||||
class UnixNetwork;
|
||||
typedef UnixNetwork Network;
|
||||
class UserBase;
|
||||
|
||||
1
Source/ThirdParty/volk/volk.Build.cs
vendored
1
Source/ThirdParty/volk/volk.Build.cs
vendored
@@ -43,6 +43,7 @@ public class volk : ThirdPartyModule
|
||||
break;
|
||||
case TargetPlatform.Mac:
|
||||
options.PublicDefinitions.Add("VK_USE_PLATFORM_MACOS_MVK");
|
||||
options.PublicDefinitions.Add("VK_USE_PLATFORM_METAL_EXT");
|
||||
break;
|
||||
case TargetPlatform.iOS:
|
||||
options.PublicDefinitions.Add("VK_USE_PLATFORM_IOS_MVK");
|
||||
|
||||
3365
Source/ThirdParty/volk/volk.c
vendored
Normal file
3365
Source/ThirdParty/volk/volk.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1485
Source/ThirdParty/volk/volk.cpp
vendored
1485
Source/ThirdParty/volk/volk.cpp
vendored
File diff suppressed because it is too large
Load Diff
1305
Source/ThirdParty/volk/volk.h
vendored
1305
Source/ThirdParty/volk/volk.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -300,7 +300,9 @@ namespace Flax.Build
|
||||
|
||||
public static bool WithSDL(NativeCpp.BuildOptions options)
|
||||
{
|
||||
bool supportedPlatform = options.Platform.Target == TargetPlatform.Windows || options.Platform.Target == TargetPlatform.Linux;
|
||||
bool supportedPlatform = options.Platform.Target == TargetPlatform.Windows ||
|
||||
options.Platform.Target == TargetPlatform.Linux ||
|
||||
options.Platform.Target == TargetPlatform.Mac;
|
||||
return UseSDL && supportedPlatform;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace Flax.Deps.Dependencies
|
||||
return new[]
|
||||
{
|
||||
TargetPlatform.Mac,
|
||||
TargetPlatform.iOS,
|
||||
};
|
||||
default: return new TargetPlatform[0];
|
||||
}
|
||||
@@ -48,7 +47,7 @@ namespace Flax.Deps.Dependencies
|
||||
public override void Build(BuildOptions options)
|
||||
{
|
||||
string root = options.IntermediateFolder;
|
||||
string configuration = "Release";
|
||||
string configuration = "Debug";
|
||||
const bool buildStatic = true;
|
||||
var configs = new string[]
|
||||
{
|
||||
@@ -63,6 +62,7 @@ namespace Flax.Deps.Dependencies
|
||||
"-DSDL_RENDER_VULKAN=OFF",
|
||||
|
||||
"-DSDL_DIRECTX=OFF",
|
||||
"-DSDL_METAL=OFF",
|
||||
"-DSDL_VULKAN=OFF",
|
||||
"-DSDL_OPENGL=OFF",
|
||||
"-DSDL_OPENGLES=OFF",
|
||||
@@ -88,9 +88,9 @@ namespace Flax.Deps.Dependencies
|
||||
Path.Combine(root, "include", "SDL3"),
|
||||
};
|
||||
|
||||
CloneGitRepo(root, "https://github.com/libsdl-org/SDL");
|
||||
GitFetch(root);
|
||||
GitResetToCommit(root, "877399b2b2cf21e67554ed9046410f268ce1d1b2"); // 3.2.10
|
||||
//CloneGitRepo(root, "https://github.com/libsdl-org/SDL");
|
||||
//GitFetch(root);
|
||||
//GitResetToCommit(root, "337f012de28fff96dc3ad023d08345b6f7cad1ef"); // 3.2.10
|
||||
|
||||
foreach (var platform in options.Platforms)
|
||||
{
|
||||
@@ -123,8 +123,9 @@ namespace Flax.Deps.Dependencies
|
||||
break;
|
||||
}
|
||||
case TargetPlatform.Linux:
|
||||
case TargetPlatform.Mac:
|
||||
{
|
||||
foreach (var architecture in new TargetArchitecture[] { TargetArchitecture.x64 })
|
||||
foreach (var architecture in new [] { TargetArchitecture.x64, TargetArchitecture.ARM64 })
|
||||
{
|
||||
var buildDir = Path.Combine(root, "build-" + architecture.ToString());
|
||||
|
||||
@@ -147,11 +148,6 @@ namespace Flax.Deps.Dependencies
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TargetPlatform.Mac:
|
||||
{
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,14 @@ namespace Flax.Build.Platforms
|
||||
options.LinkEnv.InputLibraries.Add("Cocoa.framework");
|
||||
options.LinkEnv.InputLibraries.Add("QuartzCore.framework");
|
||||
options.LinkEnv.InputLibraries.Add("AVFoundation.framework");
|
||||
|
||||
// SDL3 requires the following frameworks:
|
||||
options.LinkEnv.InputLibraries.Add("Foundation.framework");
|
||||
options.LinkEnv.InputLibraries.Add("GameController.framework");
|
||||
options.LinkEnv.InputLibraries.Add("Carbon.framework");
|
||||
options.LinkEnv.InputLibraries.Add("ForceFeedback.framework");
|
||||
options.LinkEnv.InputLibraries.Add("UniformTypeIdentifiers.framework");
|
||||
options.LinkEnv.InputLibraries.Add("CoreHaptics.framework");
|
||||
}
|
||||
|
||||
protected override void AddArgsCommon(BuildOptions options, List<string> args)
|
||||
|
||||
Reference in New Issue
Block a user