I'm attempting to add the new OS X 10.9 (Mavericks) method beginActivityWithOptions
method to the NSProcessInfo
interface (TNSProcessInfo
) in FireMonkey (Delphi XE2).
The function seems to work. It returns an object, however, it's not disabling App Nap for the application. I'm using the Energy tab of Activity Monitor to monitor the App Nap state.
I've added the following code to Macapi.Foundation.pas
:
const
NSActivityBackground = 255;
NSActivityIdleSystemSleepDisabled = 1048576;
NSActivityUserInitiated = NSActivityIdleSystemSleepDisabled or 16777215;
NSActivityLatencyCritical = 1095216660480;
type
NSActivityOptions = UInt64;
NSProcessInfo = interface(NSObject)
['{B96935F6-3809-4A49-AD4F-CBBAB0F2C961}']
...
// Added following
function beginActivityWithOptions(options: NSActivityOptions; reason: NSString): NSObject; cdecl;
...
end;
I'm calling it like this:
var
obj: NSObject;
reason: NSString;
options: NSActivityOptions;
begin
reason := NSSTR('...');
options := NSActivityUserInitiated or NSActivityLatencyCritical;
obj := TNSProcessInfo.Wrap(TNSProcessInfo.OCClass.processInfo).beginActivityWithOptions(options, reason);
end;
I've tried various combinations of the options flag, and it's not disabling App Nap. Any ideas? Do you see anything wrong with my implementation?
Thanks! I've been working on this same App Nap related problem but was using the NSProcessInfo disableAutomaticTermination and enableAutomaticTermination with no success. I tried your idea of using beginActivityWithOptions and now it works fine. I believe your only mistake is that you need to create an instance of NSProcessInfo that is assigned to field in the class. The way you are doing it, when TNSProcessInfo.Wrap(TNSProcessInfo.OCClass.processInfo) goes out of scope the modification you made to the activity is lost.
In my test, I created a form with
TForm46 = class(TForm)
procedure FormCreate(Sender: TObject);
private
ProcessInfo: NSProcessInfo;
public
end;
then in the FormCreate
procedure TForm46.FormCreate(Sender: TObject);
begin
ProcessInfo := TNSProcessInfo.Wrap(TNSProcessInfo.OCClass.processInfo);
ProcessInfo.beginActivityWithOptions(NSActivityUserInitiated or NSActivityLatencyCritical, NSSTR('Good Reason'));
end;
Then I deployed it to my mac and ran it, and monitored it with Activity Monitor. It seems to work as expected with the app staying in the App Nap No state for hours at a time.
BTW the whole App Nap thing seems to get fooled by running the app through PAServer. I had to deploy and then run locally on the Mac.