changeset 27621:39fac14ab25a

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.
author Andrew Janke <andrew@apjanke.net>
date Sun, 03 Nov 2019 10:09:15 -0500
parents 45bb5bbaf291
children df8942d19b7b
files libgui/src/octave-qobject.cc
diffstat 1 files changed, 54 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- 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 <objc/runtime.h>
 #  include <objc/message.h>
 #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<Class> (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<id> (process_info_class),
+                                 process_info_selector);
+    if (process_info == nil)
+      return;
+
+    reason_string = objc_msgSend (reinterpret_cast<id> (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<Class> (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<id> (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)