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.

This commit is contained in:
Sam Lantinga 2016-11-26 10:26:22 -08:00
parent ff56c7b300
commit 354a8f276e
3 changed files with 36 additions and 12 deletions

View File

@ -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 */

View File

@ -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);
}
}
@ -245,6 +257,11 @@ Cocoa_InitMouseEventTap(SDL_MouseData *unused)
{
}
void
Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
{
}
void
Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
{

View File

@ -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;