Cocoa: add in handling of "lost" touches on OS X. [bug #2635]
authorEdward Rudd <urkle@outoforder.cc>
Sun, 23 Nov 2014 15:48:52 -0500
changeset 9236 a845edf98a80
parent 9235 ba9988f0daec
child 9237 2cc90bb31777
Cocoa: add in handling of "lost" touches on OS X. [bug #2635] This scenario can occur, for example, when the 4-finger touch sequence is used to switch spaces. the SDL window does not receive the touch up events and ends up thinking there are far more fingers on the pad than there are. So the solution here is everytime a new "touch" appears we can through and check if there are any existing known touches by the OS and if there are none, abut SDL things there are, we simply go through and cancel the SDL touches. Side affects. - the "touch up" won't occur until the users sends a new touch (could be well after the actual release really did occur)
src/video/cocoa/SDL_cocoawindow.m
--- a/src/video/cocoa/SDL_cocoawindow.m	Sun Nov 23 15:39:28 2014 -0500
+++ b/src/video/cocoa/SDL_cocoawindow.m	Sun Nov 23 15:48:52 2014 -0500
@@ -856,6 +856,25 @@
 
 - (void)touchesBeganWithEvent:(NSEvent *) theEvent
 {
+    NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
+    int existingTouchCount = 0;
+
+    for (NSTouch* touch in touches) {
+        if ([touch phase] != NSTouchPhaseBegan) {
+            existingTouchCount++;
+        }
+    }
+    if (existingTouchCount == 0) {
+        SDL_TouchID touchID = (SDL_TouchID)(intptr_t)[[touches anyObject] device];
+        int numFingers = SDL_GetNumTouchFingers(touchID);
+        DLog("Reset Lost Fingers: %d", numFingers);
+        for (--numFingers; numFingers >= 0; --numFingers) {
+            SDL_Finger* finger = SDL_GetTouchFinger(touchID, numFingers);
+            SDL_SendTouch(touchID, finger->id, SDL_FALSE, 0, 0, 0);
+        }
+    }
+
+    DLog("Began Fingers: %lu .. existing: %d", (unsigned long)[touches count], existingTouchCount);
     [self handleTouches:NSTouchPhaseBegan withEvent:theEvent];
 }