From dc5dda0f311ea596a5152ec2f8f062f9309eb1d9 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 1 Aug 2023 18:34:03 -0400
Subject: [PATCH] cocoa: Ignore first mouse motion event after enabling
relative mode.
Fixes #7918.
---
src/video/cocoa/SDL_cocoamouse.h | 2 ++
src/video/cocoa/SDL_cocoamouse.m | 10 +++++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/video/cocoa/SDL_cocoamouse.h b/src/video/cocoa/SDL_cocoamouse.h
index aeeb14d05ca5..b85ce1cddc15 100644
--- a/src/video/cocoa/SDL_cocoamouse.h
+++ b/src/video/cocoa/SDL_cocoamouse.h
@@ -40,6 +40,8 @@ typedef struct {
/* What location we last saw the cursor move to. */
CGFloat lastMoveX;
CGFloat lastMoveY;
+ /* If we just turned on relative mode, and should skip a single mouse motion event. */
+ SDL_bool justEnabledRelative;
} SDL_MouseData;
@interface NSCursor (InvisibleCursor)
diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m
index c148296a499e..e85e16c9fba8 100644
--- a/src/video/cocoa/SDL_cocoamouse.m
+++ b/src/video/cocoa/SDL_cocoamouse.m
@@ -293,8 +293,11 @@ static int Cocoa_SetRelativeMouseMode(SDL_bool enabled)
if (enabled) {
if (window) {
/* make sure the mouse isn't at the corner of the window, as this can confuse things if macOS thinks a window resize is happening on the first click. */
+ SDL_MouseData *mousedriverdata = (SDL_MouseData*)SDL_GetMouse()->driverdata;
const CGPoint point = CGPointMake((float)(window->x + (window->w / 2)), (float)(window->y + (window->h / 2)));
- Cocoa_HandleMouseWarp(point.x, point.y);
+ if (mousedriverdata) {
+ mousedriverdata->justEnabledRelative = SDL_TRUE;
+ }
CGWarpMouseCursorPosition(point);
}
DLog("Turning on.");
@@ -465,6 +468,11 @@ void Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
seenWarp = driverdata->seenWarp;
driverdata->seenWarp = NO;
+ if (driverdata->justEnabledRelative) {
+ driverdata->justEnabledRelative = SDL_FALSE;
+ return; // dump the first event back.
+ }
+
location = [NSEvent mouseLocation];
lastMoveX = driverdata->lastMoveX;
lastMoveY = driverdata->lastMoveY;