SDL for Mac - only enable global event tap when actually necessary (app has focus and has requested relative mouse mode or has asked for a mouse grab). in other situations the event tap impacts system performance and battery life with no benefit.
1.1 --- a/src/video/cocoa/SDL_cocoamousetap.h Fri Nov 25 14:16:27 2016 -0500
1.2 +++ b/src/video/cocoa/SDL_cocoamousetap.h Sat Nov 26 10:26:22 2016 -0800
1.3 @@ -26,6 +26,7 @@
1.4 #include "SDL_cocoamouse.h"
1.5
1.6 extern void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata);
1.7 +extern void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled);
1.8 extern void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata);
1.9
1.10 #endif /* _SDL_cocoamousetap_h */
2.1 --- a/src/video/cocoa/SDL_cocoamousetap.m Fri Nov 25 14:16:27 2016 -0500
2.2 +++ b/src/video/cocoa/SDL_cocoamousetap.m Sat Nov 26 10:26:22 2016 -0800
2.3 @@ -142,15 +142,12 @@
2.4 {
2.5 SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)data;
2.6
2.7 - /* Create a tap. */
2.8 - CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
2.9 - kCGEventTapOptionDefault, allGrabbedEventsMask,
2.10 - &Cocoa_MouseTapCallback, tapdata);
2.11 + /* Tap was created on main thread but we own it now. */
2.12 + CFMachPortRef eventTap = tapdata->tap;
2.13 if (eventTap) {
2.14 /* Try to create a runloop source we can schedule. */
2.15 CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
2.16 if (runloopSource) {
2.17 - tapdata->tap = eventTap;
2.18 tapdata->runloopSource = runloopSource;
2.19 } else {
2.20 CFRelease(eventTap);
2.21 @@ -202,15 +199,30 @@
2.22
2.23 tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
2.24 if (tapdata->runloopStartedSemaphore) {
2.25 - tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
2.26 - if (!tapdata->thread) {
2.27 - SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
2.28 + tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
2.29 + kCGEventTapOptionDefault, allGrabbedEventsMask,
2.30 + &Cocoa_MouseTapCallback, tapdata);
2.31 + if (tapdata->tap) {
2.32 + tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
2.33 + if (tapdata->thread) {
2.34 + /* Success - early out. Ownership transferred to thread. */
2.35 + return;
2.36 + }
2.37 + CFRelease(tapdata->tap);
2.38 }
2.39 + SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
2.40 }
2.41 + SDL_free(driverdata->tapdata);
2.42 + driverdata->tapdata = NULL;
2.43 +}
2.44
2.45 - if (!tapdata->thread) {
2.46 - SDL_free(driverdata->tapdata);
2.47 - driverdata->tapdata = NULL;
2.48 +void
2.49 +Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
2.50 +{
2.51 + SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
2.52 + if (tapdata && tapdata->tap)
2.53 + {
2.54 + CGEventTapEnable(tapdata->tap, enabled);
2.55 }
2.56 }
2.57
2.58 @@ -246,6 +258,11 @@
2.59 }
2.60
2.61 void
2.62 +Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
2.63 +{
2.64 +}
2.65 +
2.66 +void
2.67 Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
2.68 {
2.69 }
3.1 --- a/src/video/cocoa/SDL_cocoawindow.m Fri Nov 25 14:16:27 2016 -0500
3.2 +++ b/src/video/cocoa/SDL_cocoawindow.m Sat Nov 26 10:26:22 2016 -0800
3.3 @@ -38,6 +38,7 @@
3.4 #include "SDL_cocoavideo.h"
3.5 #include "SDL_cocoashape.h"
3.6 #include "SDL_cocoamouse.h"
3.7 +#include "SDL_cocoamousetap.h"
3.8 #include "SDL_cocoaopengl.h"
3.9 #include "SDL_assert.h"
3.10
3.11 @@ -1634,8 +1635,13 @@
3.12 void
3.13 Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
3.14 {
3.15 + SDL_Mouse *mouse = SDL_GetMouse();
3.16 + SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
3.17 +
3.18 + /* Enable or disable the event tap as necessary */
3.19 + Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed);
3.20 +
3.21 /* Move the cursor to the nearest point in the window */
3.22 - SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
3.23 if (grabbed && data && ![data->listener isMoving]) {
3.24 int x, y;
3.25 CGPoint cgpoint;