From edfafd9fadec57ab66df4f88df5b8c57d95adf42 Mon Sep 17 00:00:00 2001
From: Alex Kornitzer <a.kornitzer@me.com>
Date: Sun, 10 May 2020 22:20:48 +0100
Subject: [PATCH 1/2] cocoa: fix mouse movement

The input driver was using absolute coordinate arithmetic while making
use of delta changes for each coordinate, as a result the absolute
change netted to zero. This fixes that and tries to mitigate cursor
event sync issues (sync issues will require more work).
---
 input/drivers/cocoa_input.c | 52 +++++++++++++++++++++----------------
 ui/drivers/ui_cocoa.m       |  4 +--
 2 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/input/drivers/cocoa_input.c b/input/drivers/cocoa_input.c
index dffe1de7e1..05405f2939 100644
--- a/input/drivers/cocoa_input.c
+++ b/input/drivers/cocoa_input.c
@@ -192,35 +192,41 @@ static void cocoa_input_poll(void *data)
       apple->joypad->poll();
    if (apple->sec_joypad)
        apple->sec_joypad->poll();
-
-    apple->mouse_x_last = apple->mouse_rel_x;
-    apple->mouse_y_last = apple->mouse_rel_y;
 }
 
 static int16_t cocoa_mouse_state(cocoa_input_data_t *apple,
       unsigned id)
 {
-   switch (id)
-   {
-      case RETRO_DEVICE_ID_MOUSE_X:
-           return apple->mouse_rel_x - apple->mouse_x_last;
-      case RETRO_DEVICE_ID_MOUSE_Y:
-         return apple->mouse_rel_y - apple->mouse_y_last;
-      case RETRO_DEVICE_ID_MOUSE_LEFT:
-         return apple->mouse_buttons & 1;
-      case RETRO_DEVICE_ID_MOUSE_RIGHT:
-         return apple->mouse_buttons & 2;
-       case RETRO_DEVICE_ID_MOUSE_WHEELUP:
-           return apple->mouse_wu;
-       case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
-           return apple->mouse_wd;
-       case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP:
-           return apple->mouse_wl;
-       case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN:
-           return apple->mouse_wr;
-   }
+  int16_t val;
+  switch (id)
+  {
+     case RETRO_DEVICE_ID_MOUSE_X:
+        val = apple->mouse_rel_x;
+        // NOTE: Because cocoa events are effectively handled async we reset
+        // the delta which we cumulate on each event
+        apple->mouse_rel_x = 0;
+        return val;
+     case RETRO_DEVICE_ID_MOUSE_Y:
+        val = apple->mouse_rel_y;
+        // NOTE: Because cocoa events are effectively handled async we reset
+        // the delta which we cumulate on each event
+        apple->mouse_rel_y = 0;
+        return val;
+     case RETRO_DEVICE_ID_MOUSE_LEFT:
+          return apple->mouse_buttons & 1;
+     case RETRO_DEVICE_ID_MOUSE_RIGHT:
+          return apple->mouse_buttons & 2;
+      case RETRO_DEVICE_ID_MOUSE_WHEELUP:
+          return apple->mouse_wu;
+      case RETRO_DEVICE_ID_MOUSE_WHEELDOWN:
+          return apple->mouse_wd;
+      case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP:
+          return apple->mouse_wl;
+      case RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN:
+          return apple->mouse_wr;
+  }
 
-   return 0;
+  return 0;
 }
 
 static int16_t cocoa_mouse_state_screen(cocoa_input_data_t *apple,
diff --git a/ui/drivers/ui_cocoa.m b/ui/drivers/ui_cocoa.m
index 5528226b1a..0947e632bf 100644
--- a/ui/drivers/ui_cocoa.m
+++ b/ui/drivers/ui_cocoa.m
@@ -132,8 +132,8 @@ static void app_terminate(void)
             pos.y              = 0;
 
             /* Relative */
-            apple->mouse_rel_x = (int16_t)event.deltaX;
-            apple->mouse_rel_y = (int16_t)event.deltaY;
+            apple->mouse_rel_x += (int16_t)event.deltaX;
+            apple->mouse_rel_y += (int16_t)event.deltaY;
 
             /* Absolute */
 #if defined(HAVE_COCOA_METAL)

From c4ee0463aad57ed0b6e52a8cbb691efb048e9953 Mon Sep 17 00:00:00 2001
From: Alex Kornitzer <a.kornitzer@me.com>
Date: Sun, 10 May 2020 22:43:55 +0100
Subject: [PATCH 2/2] cocoa: don't update mouse events when outside nswindow

---
 ui/drivers/ui_cocoa.m | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/ui/drivers/ui_cocoa.m b/ui/drivers/ui_cocoa.m
index 0947e632bf..0a090051f5 100644
--- a/ui/drivers/ui_cocoa.m
+++ b/ui/drivers/ui_cocoa.m
@@ -131,26 +131,26 @@ static void app_terminate(void)
             pos.x              = 0;
             pos.y              = 0;
 
-            /* Relative */
-            apple->mouse_rel_x += (int16_t)event.deltaX;
-            apple->mouse_rel_y += (int16_t)event.deltaY;
-
-            /* Absolute */
 #if defined(HAVE_COCOA_METAL)
             pos = [apple_platform.renderView convertPoint:[event locationInWindow] fromView:nil];
 #elif defined(HAVE_COCOA)
             pos = [[CocoaView get] convertPoint:[event locationInWindow] fromView:nil];
 #endif
+
+            NSInteger window_number = [[[NSApplication sharedApplication] keyWindow] windowNumber];
+            if ([NSWindow windowNumberAtPoint:pos belowWindowWithWindowNumber:0] != window_number) {
+              return;
+            }
+
+            /* Relative */
+            apple->mouse_rel_x += (int16_t)event.deltaX;
+            apple->mouse_rel_y += (int16_t)event.deltaY;
+
+            /* Absolute */
             apple->touches[0].screen_x = (int16_t)pos.x;
             apple->touches[0].screen_y = (int16_t)pos.y;
-
-#if defined(HAVE_COCOA_METAL)
-            mouse_pos = [apple_platform.renderView convertPoint:[event locationInWindow]  fromView:nil];
-#elif defined(HAVE_COCOA)
-            mouse_pos = [[CocoaView get] convertPoint:[event locationInWindow]  fromView:nil];
-#endif
-            apple->window_pos_x = (int16_t)mouse_pos.x;
-            apple->window_pos_y = (int16_t)mouse_pos.y;
+            apple->window_pos_x = (int16_t)pos.x;
+            apple->window_pos_y = (int16_t)pos.y;
          }
          break;
 #if defined(HAVE_COCOA_METAL)