[SOLVED] QTimer and AppNap on OS X 10.9 Mavericks with Qt 4.8.5
-
You're welcome !
Now that your application doesn't go to sleep anymore, please update the thread title prepending [solved] so other forum users may know a solution has been found :)
-
Hi, after fighting this for days, I finally stumbled on the very helpful info from #SGaist, which appears to work great. One detail that baffled me: for some reason, NSAppSleepDisabled gets removed from my app's plist every time it quits. So, as he describes, you must re-set it each time you launch. A mystery to me.
-
-
How were you able to get the "defaults write <app domain name> NSAppSleepDisabled -bool YES" to work with QProcess on the Mac? I have tried setting up a QProcess object using arguments and just the entire command as one string and it doesn't seem to set this properly. Yet when I run the same command from a Terminal, it sets it correctly.
-
[quote author="janfaroe" date="1405541281"]Adding the following entry in the Info.plist file solved the problem for me:
@<key>LSAppNapIsDisabled</key>
<true/>@[/quote]I've also tried this. Placing these entries in my .app plist file, restarting the app and after a time, the "App Nap" value changes to "Yes" in Activity Monitor.
The only way I can get App Nap to turn off is to use this command from the Terminal:
defaults -write _domain appname_NSAppSleepDisabled -bool YES
-
Anything you set in the Info.plist is read into the application's Info Dictionary, from where it is then used (or not...). I'm a bit surprised that calling
defaults
works from the application itself, but that probably means that the corresponding key/value pair is not read before entering the main function.All that to say that there might be another solution which doesn't even involve ObjC (if could, but many ObjC classes are "toll-free bridged" with regular C types available through the CoreFoundation framework ;)).
Here's a bit of code I use to turn an application into an "agent" (i.e. something that can present widgets, like a systray icon+menu", but doesn't appear in the Dock or App Switcher, and doesn't get a global menubar).
(Replace Q_OS_MAC with Q_OS_OSX in Qt5)@
#ifdef Q_OS_MAC
#include <CoreFoundation/CoreFoundation.h>
#endif
@and then before creating the QApplication instance:
@
#ifdef Q_OS_MAC
CFBundleRef mainBundle = CFBundleGetMainBundle();
if( mainBundle ){
// get the application's Info Dictionary. For app bundles this would live in the bundle's Info.plist,
// for regular executables it is obtained in another way.
CFMutableDictionaryRef infoDict = (CFMutableDictionaryRef) CFBundleGetInfoDictionary(mainBundle);
if( infoDict ){
// Add or set the "LSUIElement" key with/to value "1". This can simply be a CFString.
CFDictionarySetValue(infoDict, CFSTR("LSUIElement"), CFSTR("1"));
// That's it. We're now considered as an "agent" by the window server, and thus will have
// neither menubar nor presence in the Dock or App Switcher.
}
}
#endif
@ -
Anything you set in the Info.plist is read into the application's Info Dictionary, from where it is then used (or not...). I'm a bit surprised that calling
defaults
works from the application itself, but that probably means that the corresponding key/value pair is not read before entering the main function.All that to say that there might be another solution which doesn't even involve ObjC (if could, but many ObjC classes are "toll-free bridged" with regular C types available through the CoreFoundation framework ;)).
Here's a bit of code I use to turn an application into an "agent" (i.e. something that can present widgets, like a systray icon+menu", but doesn't appear in the Dock or App Switcher, and doesn't get a global menubar).
(Replace Q_OS_MAC with Q_OS_OSX in Qt5)@
#ifdef Q_OS_MAC
#include <CoreFoundation/CoreFoundation.h>
#endif
@and then before creating the QApplication instance:
@
#ifdef Q_OS_MAC
CFBundleRef mainBundle = CFBundleGetMainBundle();
if( mainBundle ){
// get the application's Info Dictionary. For app bundles this would live in the bundle's Info.plist,
// for regular executables it is obtained in another way.
CFMutableDictionaryRef infoDict = (CFMutableDictionaryRef) CFBundleGetInfoDictionary(mainBundle);
if( infoDict ){
// Add or set the "LSUIElement" key with/to value "1". This can simply be a CFString.
CFDictionarySetValue(infoDict, CFSTR("LSUIElement"), CFSTR("1"));
// That's it. We're now considered as an "agent" by the window server, and thus will have
// neither menubar nor presence in the Dock or App Switcher.
}
}
#endif
@