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 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
diff --git a/src/video/cocoa/SDL_cocoamousetap.h b/src/video/cocoa/SDL_cocoamousetap.h
index af92314..795248a 100644
--- a/src/video/cocoa/SDL_cocoamousetap.h
+++ b/src/video/cocoa/SDL_cocoamousetap.h
@@ -26,6 +26,7 @@
#include "SDL_cocoamouse.h"
extern void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata);
+extern void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled);
extern void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata);
#endif /* _SDL_cocoamousetap_h */
diff --git a/src/video/cocoa/SDL_cocoamousetap.m b/src/video/cocoa/SDL_cocoamousetap.m
index 48abbca..a36e423 100644
--- a/src/video/cocoa/SDL_cocoamousetap.m
+++ b/src/video/cocoa/SDL_cocoamousetap.m
@@ -142,15 +142,12 @@ Cocoa_MouseTapThread(void *data)
{
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)data;
- /* Create a tap. */
- CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
- kCGEventTapOptionDefault, allGrabbedEventsMask,
- &Cocoa_MouseTapCallback, tapdata);
+ /* Tap was created on main thread but we own it now. */
+ CFMachPortRef eventTap = tapdata->tap;
if (eventTap) {
/* Try to create a runloop source we can schedule. */
CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
if (runloopSource) {
- tapdata->tap = eventTap;
tapdata->runloopSource = runloopSource;
} else {
CFRelease(eventTap);
@@ -202,15 +199,30 @@ Cocoa_InitMouseEventTap(SDL_MouseData* driverdata)
tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
if (tapdata->runloopStartedSemaphore) {
- tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
- if (!tapdata->thread) {
- SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
+ tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
+ kCGEventTapOptionDefault, allGrabbedEventsMask,
+ &Cocoa_MouseTapCallback, tapdata);
+ if (tapdata->tap) {
+ tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
+ if (tapdata->thread) {
+ /* Success - early out. Ownership transferred to thread. */
+ return;
+ }
+ CFRelease(tapdata->tap);
}
+ SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
}
+ SDL_free(driverdata->tapdata);
+ driverdata->tapdata = NULL;
+}
- if (!tapdata->thread) {
- SDL_free(driverdata->tapdata);
- driverdata->tapdata = NULL;
+void
+Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
+{
+ SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
+ if (tapdata && tapdata->tap)
+ {
+ CGEventTapEnable(tapdata->tap, enabled);
}
}
@@ -246,6 +258,11 @@ Cocoa_InitMouseEventTap(SDL_MouseData *unused)
}
void
+Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
+{
+}
+
+void
Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
{
}
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index cfad548..f705a6c 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -38,6 +38,7 @@
#include "SDL_cocoavideo.h"
#include "SDL_cocoashape.h"
#include "SDL_cocoamouse.h"
+#include "SDL_cocoamousetap.h"
#include "SDL_cocoaopengl.h"
#include "SDL_assert.h"
@@ -1634,8 +1635,13 @@ Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
void
Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
- /* Move the cursor to the nearest point in the window */
+ SDL_Mouse *mouse = SDL_GetMouse();
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ /* Enable or disable the event tap as necessary */
+ Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed);
+
+ /* Move the cursor to the nearest point in the window */
if (grabbed && data && ![data->listener isMoving]) {
int x, y;
CGPoint cgpoint;