Commit d9a2eff26f1088535c2f6e608be042b524498e7b

Ryan C. Gordon 2019-06-13T21:31:03

cocoa: Another attempt at synthesized mouse/touch events.

diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index 79f7927..7c09272 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -103,11 +103,7 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
     if (hint && (*hint == '0' || SDL_strcasecmp(hint, "false") == 0)) {
         mouse->touch_mouse_events = SDL_FALSE;
     } else {
-#if defined(__MACOSX__)  /* macOS synthesizes its own events for this. */
-        mouse->touch_mouse_events = SDL_FALSE;
-#else
         mouse->touch_mouse_events = SDL_TRUE;
-#endif
     }
 }
 
@@ -387,11 +383,13 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
         mouse->has_position = SDL_TRUE;
     }
 
+#ifndef __MACOSX__  /* all your trackpad input would lack relative motion when not dragging in this case. */
     /* Ignore relative motion positioning the first touch */
     if (mouseID == SDL_TOUCH_MOUSEID && !mouse->buttonstate) {
         xrel = 0;
         yrel = 0;
     }
+#endif
 
     /* Update internal mouse coordinates */
     if (!mouse->relative_mode) {
diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c
index caf5e56..e70214d 100644
--- a/src/events/SDL_touch.c
+++ b/src/events/SDL_touch.c
@@ -32,9 +32,18 @@ static int SDL_num_touch = 0;
 static SDL_Touch **SDL_touchDevices = NULL;
 
 /* for mapping touch events to mice */
+
+#ifndef __MACOSX__  /* don't generate mouse events from touch on macOS, the OS handles that. */
+#define SYNTHESIZE_TOUCH_TO_MOUSE 1
+#else
+#define SYNTHESIZE_TOUCH_TO_MOUSE 0
+#endif
+
+#if SYNTHESIZE_TOUCH_TO_MOUSE
 static SDL_bool finger_touching = SDL_FALSE;
 static SDL_FingerID track_fingerid;
 static SDL_TouchID  track_touchid;
+#endif
 
 /* Public functions */
 int
@@ -245,6 +254,7 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
         return -1;
     }
 
+#if SYNTHESIZE_TOUCH_TO_MOUSE
     /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
     {
         SDL_Mouse *mouse = SDL_GetMouse();
@@ -284,6 +294,7 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
             }
         }
     }
+#endif
 
     finger = SDL_GetFinger(touch, fingerid);
     if (down) {
@@ -349,6 +360,7 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
         return -1;
     }
 
+#if SYNTHESIZE_TOUCH_TO_MOUSE
     /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
     {
         SDL_Mouse *mouse = SDL_GetMouse();
@@ -369,6 +381,7 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
             }
         }
     }
+#endif
 
     finger = SDL_GetFinger(touch,fingerid);
     if (!finger) {
diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m
index 6357871..4769944 100644
--- a/src/video/cocoa/SDL_cocoamouse.m
+++ b/src/video/cocoa/SDL_cocoamouse.m
@@ -375,6 +375,15 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
         return;  /* can happen when returning from fullscreen Space on shutdown */
     }
 
+    SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
+    if ([event subtype] == NSEventSubtypeTouch) {  /* this is a synthetic from the OS */
+        if (mouse->touch_mouse_events) {
+            mouseID = SDL_TOUCH_MOUSEID;   /* Hint is set */
+        } else {
+            return;  /* no hint set, drop this one. */
+        }
+    }
+
     const SDL_bool seenWarp = driverdata->seenWarp;
     driverdata->seenWarp = NO;
 
@@ -408,13 +417,21 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
         DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
     }
 
-    SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)deltaX, (int)deltaY);
+    SDL_SendMouseMotion(mouse->focus, mouseID, 1, (int)deltaX, (int)deltaY);
 }
 
 void
 Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
+    SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
+    if ([event subtype] == NSEventSubtypeTouch) {  /* this is a synthetic from the OS */
+        if (mouse->touch_mouse_events) {
+            mouseID = SDL_TOUCH_MOUSEID;   /* Hint is set */
+        } else {
+            return;  /* no hint set, drop this one. */
+        }
+    }
 
     CGFloat x = -[event deltaX];
     CGFloat y = [event deltaY];
@@ -437,7 +454,7 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
         y = SDL_floor(y);
     }
 
-    SDL_SendMouseWheel(window, mouse->mouseID, x, y, direction);
+    SDL_SendMouseWheel(window, mouseID, x, y, direction);
 }
 
 void
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 75bd03f..f4911e3 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -893,9 +893,19 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
 
 - (void)mouseDown:(NSEvent *)theEvent
 {
+    const SDL_Mouse *mouse = SDL_GetMouse();
+    SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
     int button;
     int clicks;
 
+    if ([theEvent subtype] == NSEventSubtypeTouch) {  /* this is a synthetic from the OS */
+        if (mouse->touch_mouse_events) {
+            mouseID = SDL_TOUCH_MOUSEID;   /* Hint is set */
+        } else {
+            return;  /* no hint set, drop this one. */
+        }
+    }
+
     /* Ignore events that aren't inside the client area (i.e. title bar.) */
     if ([theEvent window]) {
         NSRect windowRect = [[[theEvent window] contentView] frame];
@@ -933,8 +943,6 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
 
     clicks = (int) [theEvent clickCount];
 
-    const SDL_Mouse *mouse = SDL_GetMouse();
-    const SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
     SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_PRESSED, button, clicks);
 }
 
@@ -950,9 +958,19 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
 
 - (void)mouseUp:(NSEvent *)theEvent
 {
+    const SDL_Mouse *mouse = SDL_GetMouse();
+    SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
     int button;
     int clicks;
 
+    if ([theEvent subtype] == NSEventSubtypeTouch) {  /* this is a synthetic from the OS */
+        if (mouse->touch_mouse_events) {
+            mouseID = SDL_TOUCH_MOUSEID;   /* Hint is set */
+        } else {
+            return;  /* no hint set, drop this one. */
+        }
+    }
+
     if ([self processHitTest:theEvent]) {
         SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
         return;  /* stopped dragging, drop event. */
@@ -980,8 +998,6 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
 
     clicks = (int) [theEvent clickCount];
 
-    const SDL_Mouse *mouse = SDL_GetMouse();
-    const SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
     SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_RELEASED, button, clicks);
 }
 
@@ -998,10 +1014,19 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
 - (void)mouseMoved:(NSEvent *)theEvent
 {
     SDL_Mouse *mouse = SDL_GetMouse();
+    SDL_MouseID mouseID = mouse ? mouse->mouseID : 0;
     SDL_Window *window = _data->window;
     NSPoint point;
     int x, y;
 
+    if ([theEvent subtype] == NSEventSubtypeTouch) {  /* this is a synthetic from the OS */
+        if (mouse->touch_mouse_events) {
+            mouseID = SDL_TOUCH_MOUSEID;   /* Hint is set */
+        } else {
+            return;  /* no hint set, drop this one. */
+        }
+    }
+
     if ([self processHitTest:theEvent]) {
         SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
         return;  /* dragging, drop event. */
@@ -1046,7 +1071,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
         }
     }
 
-    SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y);
+    SDL_SendMouseMotion(window, mouseID, 0, x, y);
 }
 
 - (void)mouseDragged:(NSEvent *)theEvent