cocoa: Position non-left mouse button events in background windows correctly. Fixes #4828.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index eed00c9..f4728b3 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -1150,16 +1150,44 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
return NO; /* not a special area, carry on. */
}
+static int
+Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * window, const Uint8 state, const Uint8 button)
+{
+ const SDL_MouseID mouseID = mouse->mouseID;
+ const int clicks = (int) [theEvent clickCount];
+ SDL_Window *focus = SDL_GetKeyboardFocus();
+ int rc;
+
+ // macOS will send non-left clicks to background windows without raising them, so we need to
+ // temporarily adjust the mouse position when this happens, as `mouse` will be tracking
+ // the position in the currently-focused window. We don't (currently) send a mousemove
+ // event for the background window, this just makes sure the button is reported at the
+ // correct position in its own event.
+ if ( focus && ([theEvent window] == ((SDL_WindowData *) focus->driverdata)->nswindow) ) {
+ rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
+ } else {
+printf("BACKGROUND CLICK!\n"); fflush(stdout);
+ const int orig_x = mouse->x;
+ const int orig_y = mouse->y;
+ const NSPoint point = [theEvent locationInWindow];
+ mouse->x = (int) point.x;
+ mouse->y = (int) (window->h - point.y);
+ rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
+ mouse->x = orig_x;
+ mouse->y = orig_y;
+ }
+
+ return rc;
+}
+
- (void)mouseDown:(NSEvent *)theEvent
{
- const SDL_Mouse *mouse = SDL_GetMouse();
+ SDL_Mouse *mouse = SDL_GetMouse();
if (!mouse) {
return;
}
- const SDL_MouseID mouseID = mouse->mouseID;
int button;
- int clicks;
/* Ignore events that aren't inside the client area (i.e. title bar.) */
if ([theEvent window]) {
@@ -1196,9 +1224,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
break;
}
- clicks = (int) [theEvent clickCount];
-
- SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_PRESSED, button, clicks);
+ Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_PRESSED, button);
}
- (void)rightMouseDown:(NSEvent *)theEvent
@@ -1213,14 +1239,12 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
- (void)mouseUp:(NSEvent *)theEvent
{
- const SDL_Mouse *mouse = SDL_GetMouse();
+ SDL_Mouse *mouse = SDL_GetMouse();
if (!mouse) {
return;
}
- const SDL_MouseID mouseID = mouse->mouseID;
int button;
- int clicks;
if ([self processHitTest:theEvent]) {
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
@@ -1247,9 +1271,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
break;
}
- clicks = (int) [theEvent clickCount];
-
- SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_RELEASED, button, clicks);
+ Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_RELEASED, button);
}
- (void)rightMouseUp:(NSEvent *)theEvent