Mac OS X: replace some deprecated APIs with modern equivalents (thanks, Alex!). Fixes Bugzilla #2858.
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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
diff --git a/src/video/cocoa/SDL_cocoaevents.h b/src/video/cocoa/SDL_cocoaevents.h
index 687cf64..1d27bbf 100644
--- a/src/video/cocoa/SDL_cocoaevents.h
+++ b/src/video/cocoa/SDL_cocoaevents.h
@@ -25,6 +25,7 @@
extern void Cocoa_RegisterApp(void);
extern void Cocoa_PumpEvents(_THIS);
+extern void Cocoa_SuspendScreenSaver(_THIS);
#endif /* _SDL_cocoaevents_h */
diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m
index 13aeb45..5102034 100644
--- a/src/video/cocoa/SDL_cocoaevents.m
+++ b/src/video/cocoa/SDL_cocoaevents.m
@@ -27,6 +27,11 @@
#include "../../events/SDL_events_c.h"
#include "SDL_assert.h"
+/* This define was added in the 10.9 SDK. */
+#ifndef kIOPMAssertPreventUserIdleDisplaySleep
+#define kIOPMAssertPreventUserIdleDisplaySleep kIOPMAssertionTypePreventUserIdleDisplaySleep
+#endif
+
@interface SDLApplication : NSApplication
- (void)terminate:(id)sender;
@@ -251,17 +256,24 @@ Cocoa_RegisterApp(void)
{ @autoreleasepool
{
/* This can get called more than once! Be careful what you initialize! */
- ProcessSerialNumber psn;
-
- if (!GetCurrentProcess(&psn)) {
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- SetFrontProcess(&psn);
- }
if (NSApp == nil) {
[SDLApplication sharedApplication];
SDL_assert(NSApp != nil);
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
+ if ([NSApp respondsToSelector:@selector(setActivationPolicy:)]) {
+#endif
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
+ } else {
+ ProcessSerialNumber psn = {0, kCurrentProcess};
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ }
+#endif
+
+ [NSApp activateIgnoringOtherApps:YES];
+
if ([NSApp mainMenu] == nil) {
CreateApplicationMenus();
}
@@ -293,8 +305,8 @@ Cocoa_PumpEvents(_THIS)
{ @autoreleasepool
{
/* Update activity every 30 seconds to prevent screensaver */
- if (_this->suspend_screensaver) {
- SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
+ SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
+ if (_this->suspend_screensaver && !data->screensaver_use_iopm) {
Uint32 now = SDL_GetTicks();
if (!data->screensaver_activity ||
SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
@@ -336,6 +348,35 @@ Cocoa_PumpEvents(_THIS)
}
}}
+void
+Cocoa_SuspendScreenSaver(_THIS)
+{ @autoreleasepool
+{
+ SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
+
+ if (!data->screensaver_use_iopm) {
+ return;
+ }
+
+ if (data->screensaver_assertion) {
+ IOPMAssertionRelease(data->screensaver_assertion);
+ data->screensaver_assertion = 0;
+ }
+
+ if (_this->suspend_screensaver) {
+ /* FIXME: this should ideally describe the real reason why the game
+ * called SDL_DisableScreenSaver. Note that the name is only meant to be
+ * seen by OS X power users. there's an additional optional human-readable
+ * (localized) reason parameter which we don't set.
+ */
+ NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"];
+ IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep,
+ (CFStringRef) name,
+ NULL, NULL, NULL, 0, NULL,
+ &data->screensaver_assertion);
+ }
+}}
+
#endif /* SDL_VIDEO_DRIVER_COCOA */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h
index 288c41f..cf254db 100644
--- a/src/video/cocoa/SDL_cocoavideo.h
+++ b/src/video/cocoa/SDL_cocoavideo.h
@@ -26,6 +26,7 @@
#include "SDL_opengl.h"
#include <ApplicationServices/ApplicationServices.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
#include <Cocoa/Cocoa.h>
#include "SDL_keycode.h"
@@ -51,6 +52,9 @@ typedef struct SDL_VideoData
SDLTranslatorResponder *fieldEdit;
NSInteger clipboard_count;
Uint32 screensaver_activity;
+ BOOL screensaver_use_iopm;
+ IOPMAssertionID screensaver_assertion;
+
} SDL_VideoData;
/* Utility functions */
diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m
index ad4f14c..f31218b 100644
--- a/src/video/cocoa/SDL_cocoavideo.m
+++ b/src/video/cocoa/SDL_cocoavideo.m
@@ -76,6 +76,7 @@ Cocoa_CreateDevice(int devindex)
device->GetDisplayModes = Cocoa_GetDisplayModes;
device->SetDisplayMode = Cocoa_SetDisplayMode;
device->PumpEvents = Cocoa_PumpEvents;
+ device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
device->CreateWindow = Cocoa_CreateWindow;
device->CreateWindowFrom = Cocoa_CreateWindowFrom;
@@ -148,6 +149,9 @@ Cocoa_VideoInit(_THIS)
const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
data->allow_spaces = ( (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && (!hint || (*hint != '0')) );
+ /* The IOPM assertion API can disable the screensaver as of 10.7. */
+ data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
+
return 0;
}