Fix mouse relative mode activation triggering mouse move events on Mac

This commit is contained in:
2025-04-21 14:07:16 +03:00
parent 26012d0b74
commit 02f446ccfd
5 changed files with 42 additions and 13 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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)

View File

@@ -50,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();

View File

@@ -31,7 +31,7 @@
#elif PLATFORM_LINUX
#include "Engine/Platform/Linux/IncludeX11.h"
#elif PLATFORM_MAC
#include <Cocoa/Cocoa.h>
#else
static_assert(false, "Unsupported Platform");
#endif
@@ -157,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();
@@ -182,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