From d9a2eff26f1088535c2f6e608be042b524498e7b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 13 Jun 2019 21:31:03 -0400 Subject: [PATCH] cocoa: Another attempt at synthesized mouse/touch events. --- src/events/SDL_mouse.c | 6 ++---- src/events/SDL_touch.c | 13 ++++++++++++ src/video/cocoa/SDL_cocoamouse.m | 21 +++++++++++++++++-- src/video/cocoa/SDL_cocoawindow.m | 35 ++++++++++++++++++++++++++----- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 79f792714f4cf..7c0927238f068 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 caf5e5644ba90..e70214d166131 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 635787162706e..47699447e98f8 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -375,6 +375,15 @@ + (NSCursor *)invisibleCursor 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 @@ + (NSCursor *)invisibleCursor 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 @@ + (NSCursor *)invisibleCursor 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 75bd03fa4e326..f4911e3592c7e 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -893,9 +893,19 @@ - (BOOL)processHitTest:(NSEvent *)theEvent - (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 @@ - (void)mouseDown:(NSEvent *)theEvent 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 @@ - (void)otherMouseDown:(NSEvent *)theEvent - (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 @@ - (void)mouseUp:(NSEvent *)theEvent 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 @@ - (void)otherMouseUp:(NSEvent *)theEvent - (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 @@ - (void)mouseMoved:(NSEvent *)theEvent } } - SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y); + SDL_SendMouseMotion(window, mouseID, 0, x, y); } - (void)mouseDragged:(NSEvent *)theEvent