14

Possible Duplicate:
How to programmatically prevent a Mac from going to sleep?

What is the correct method on the current version of OS X (10.7) for preventing sleep while an application or process is running?

In particular, is IOCancelPowerChange still (or did it ever) serve this purpose? I call IOCancelPowerChange in response to kIOMessageCanSystemSleep, but that doesn't do the trick.


Essentially the same question as the first part of this one has been asked before, but the documentation it points to is quite old and the answer was never accepted.

Community
  • 1
  • 1
orome
  • 45,163
  • 57
  • 202
  • 418
  • 2
    There's a [new Apple Q&A](http://developer.apple.com/library/mac/#qa/qa1340/_index.html) on this. – jscs Dec 10 '11 at 21:36
  • @Michael: And I'd like to do the same. Is there a way I can amend the question? – orome Dec 10 '11 at 21:36
  • Posting a bounty will raise that question's visibility, and may prompt more answers. Click the `start a bounty` link on that question, and provide the resulting dialog with your reasons for wanting a more current answer. Add a comment if you want to provide more detail. – Michael Petrotta Dec 10 '11 at 21:37
  • @rax: Anybody can propose an edit to a post. Your specific query about `IOCancelPowerChange` could probably stand on its own, if you want it to. – jscs Dec 10 '11 at 21:39

2 Answers2

17

IOCancelPowerChange continues to work but only for idle triggered sleep; it will not work for sleep triggered by the Finder's Sleep menu item, programmatically requested, or from a push of the power button.

Apple's Q&A1340 answers the question "Q: How can my application get notified when the computer is going to sleep or waking from sleep? How do I prevent sleep?"

Listing 2 of Q&A1340:

#import <IOKit/pwr_mgt/IOPMLib.h>

// kIOPMAssertionTypeNoDisplaySleep prevents display sleep,
// kIOPMAssertionTypeNoIdleSleep prevents idle sleep

//reasonForActivity is a descriptive string used by the system whenever it needs 
//  to tell the user why the system is not sleeping. For example, 
//  "Mail Compacting Mailboxes" would be a useful string.

//  NOTE: IOPMAssertionCreateWithName limits the string to 128 characters. 
CFStringRef* reasonForActivity= CFSTR("Describe Activity Type");

IOPMAssertionID assertionID;
IOReturn success = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, 
                                    kIOPMAssertionLevelOn, reasonForActivity, &assertionID); 
if (success == kIOReturnSuccess)
{

    //Add the work you need to do without 
    //  the system sleeping here.

    success = IOPMAssertionRelease(assertionID);
    //The system will be able to sleep again. 
}

Note that you can only stop idle time sleep, not sleep triggered by the user.

For applications supporting Mac OS X 10.6 and later, use the new IOPMAssertion family of functions. These functions allow other applications and utilities to see your application's desire not to sleep; this is critical to working seamlessly with third party power management software.

Graham Miln
  • 2,724
  • 3
  • 33
  • 33
-2

You could call updatesystemActivity(OverallAct) every 30 seconds to prevent the display from sleeping.

lbrndnr
  • 3,361
  • 2
  • 24
  • 34
  • 5
    Please avoid this trick. Instead use the Apple endorsed techniques documented in Q&A1340. – Graham Miln Dec 11 '11 at 01:44
  • 2
    How come? Apple advises this method in a document too. – lbrndnr Dec 12 '11 at 00:21
  • 4
    Apple's latest recommendation in Q&A1340 is to use the new IOPMAssertionCreateWithName interface. This interface avoids your application needing to demand CPU cycles every 30 seconds, it provides a simplified way for Mac OS X – and other tools – to check for assertions, and better indicates your applications real intention. Telling the system to mimic user activity every 30 seconds is a trick that worked but has now been superseded by a formal API. – Graham Miln Dec 12 '11 at 03:31