# HG changeset patch # User Andrew Janke # Date 1572793755 18000 # Node ID 39fac14ab25ad9616ad9724e1c4cb1aa7826e64b # Parent 45bb5bbaf2913e4a52190d45e542618eb20f74df Enable App Nap disabling on macOS (bug #55490). * octave-qobject.cc: Remove #if 0 / #endif blocks disabling fix. User reinterpret_cast to correctly prepare inputs for objc_msgSend. Use C++ comparison to nullptr rather than C comparison to NULL. diff -r 45bb5bbaf291 -r 39fac14ab25a libgui/src/octave-qobject.cc --- a/libgui/src/octave-qobject.cc Fri Nov 01 18:16:49 2019 -0400 +++ b/libgui/src/octave-qobject.cc Sun Nov 03 10:09:15 2019 -0500 @@ -42,19 +42,70 @@ #include "resource-manager.h" // Bug #55940 (Disable App Nap on Mac) -#if 0 #if defined (Q_OS_MAC) - // ObjC interface is needed for App Nap control # include # include #endif -#endif #include "oct-env.h" #include "version.h" #include "ovl.h" + +// Bug #55940 (Disable App Nap on Mac) +#if defined (Q_OS_MAC) + static void disable_app_nap (void) + { + Class process_info_class; + SEL process_info_selector; + SEL begin_activity_with_options_selector; + id process_info; + id reason_string; + id osx_latencycritical_activity; + + // Option codes found at https://stackoverflow.com/questions/22784886/what-can-make-nanosleep-drift-with-exactly-10-sec-on-mac-os-x-10-9/32729281#32729281 + unsigned long long NSActivityUserInitiatedAllowingIdleSystemSleep = 0x00FFFFFFULL; + unsigned long long NSActivityLatencyCritical = 0xFF00000000ULL; + + // Avoid errors on older versions of OS X + process_info_class = static_cast (objc_getClass ("NSProcessInfo")); + if (process_info_class == nil) + return; + + process_info_selector = sel_getUid ("processInfo"); + if (class_getClassMethod (process_info_class, process_info_selector) + == nullptr) + return; + + begin_activity_with_options_selector = sel_getUid ("beginActivityWithOptions:reason:"); + if (class_getInstanceMethod (process_info_class, + begin_activity_with_options_selector) + == nullptr) + return; + + process_info = objc_msgSend (reinterpret_cast (process_info_class), + process_info_selector); + if (process_info == nil) + return; + + reason_string = objc_msgSend (reinterpret_cast (objc_getClass ("NSString")), + sel_getUid ("alloc")); + reason_string = objc_msgSend (reason_string, + sel_getUid ("initWithUTF8String:"), + "App Nap causes pause() malfunction"); + + // Start an Activity that suppresses App Nap. This Activity will run for + // the entire duration of the Octave process. This is intentional, + // not a leak. + osx_latencycritical_activity = objc_msgSend (process_info, + begin_activity_with_options_selector, + NSActivityUserInitiatedAllowingIdleSystemSleep + | NSActivityLatencyCritical, + reason_string); + } +#endif + namespace octave { // Disable all Qt messages by default. @@ -153,13 +204,11 @@ // Bug #55940 (Disable App Nap on Mac) -#if 0 #if defined (Q_OS_MAC) // Mac App Nap feature causes pause() and sleep() to misbehave. // Disable it for the entire program run. disable_app_nap (); #endif -#endif // Force left-to-right alignment (see bug #46204) m_qapplication->setLayoutDirection (Qt::LeftToRight); @@ -199,57 +248,6 @@ string_vector::delete_c_str_vec (m_argv); } -// Bug #55940 (Disable App Nap on Mac) -#if 0 -#if defined (Q_OS_MAC) - // FIXME: Does this need to be a private member function of base_qobject? - // Or should it be a file local static function? - void disable_app_nap (void) - { - Class process_info_class; - SEL process_info_selector; - SEL begin_activity_with_options_selector; - id process_info; - id reason_string; - - // Option codes found at https://stackoverflow.com/questions/22784886/what-can-make-nanosleep-drift-with-exactly-10-sec-on-mac-os-x-10-9/32729281#32729281 - unsigned long long NSActivityUserInitiatedAllowingIdleSystemSleep = 0x00FFFFFFULL; - unsigned long long NSActivityLatencyCritical = 0xFF00000000ULL; - - // Avoid errors on older versions of OS X - process_info_class = static_cast (objc_getClass ("NSProcessInfo")); - if (process_info_class == nil) - return; - - process_info_selector = sel_getUid ("processInfo"); - if (class_getClassMethod (process_info_class, process_info_selector) == NULL) - return; - - begin_activity_with_options_selector = sel_getUid ("beginActivityWithOptions:reason:"); - if (class_getInstanceMethod (process_info_class, - begin_activity_with_options_selector) == NULL) - return; - - if ((process_info = objc_msgSend (static_cast (process_info_class), process_info_selector)) == nil) - return; - - reason_string = objc_msgSend (objc_getClass ("NSString"), - sel_getUid ("alloc")); - reason_string = objc_msgSend (reason_string, - sel_getUid ("initWithUTF8String:"), - "App Nap causes pause() malfunction"); - - // Start an Activity that suppresses App Nap. This Activity will run for - // the entire duration of the Octave process. This is intentional, - // not a leak. - osx_latencycritical_activity = objc_msgSend (process_info, - begin_activity_with_options_selector, - NSActivityUserInitiatedAllowingIdleSystemSleep | NSActivityLatencyCritical, - reason_string); - } -#endif -#endif - void base_qobject::config_translators (void) { if (m_translators_installed)