# HG changeset patch
# User Andrew Janke <andrew@apjanke.net>
# Date 1572793755 18000
#      Sun Nov 03 10:09:15 2019 -0500
# Node ID 38ca36e6d39d3e4eb7d073154a4ec619b93a5ecd
# Parent  45bb5bbaf2913e4a52190d45e542618eb20f74df
Fix and enable App Nap disabling on macOS.

This fixes the too-long pause() behavior seen on Macs. See Bug #55490.

diff --git a/libgui/src/octave-qobject.cc b/libgui/src/octave-qobject.cc
--- a/libgui/src/octave-qobject.cc
+++ b/libgui/src/octave-qobject.cc
@@ -37,29 +37,78 @@ along with Octave; see the file COPYING.
 #include "interpreter-qobject.h"
 #include "main-window.h"
 #include "octave-qobject.h"
 #include "qt-application.h"
 #include "qt-interpreter-events.h"
 #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)
+  // FIXME: Does this need to be a private member function of base_qobject?
+  //        Or should it be a file local static function?
+  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) == 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 (reinterpret_cast<id> (process_info_class), process_info_selector)) == 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.
 
   static void
 #if defined (QTMESSAGEHANDLER_ACCEPTS_QMESSAGELOGCONTEXT)
   message_handler (QtMsgType, const QMessageLogContext &, const QString &)
 #else
@@ -148,23 +197,21 @@ namespace octave
     QCoreApplication::setApplicationVersion (OCTAVE_VERSION);
 
     // Register octave_value_list for connecting thread crossing signals.
 
     qRegisterMetaType<octave_value_list> ("octave_value_list");
 
 
 // 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);
 
     connect (m_interpreter_qobj, SIGNAL (octave_finished_signal (int)),
              this, SLOT (handle_octave_finished (int)));
 
     connect (m_main_thread, SIGNAL (finished (void)),
@@ -194,67 +241,16 @@ namespace octave
     delete m_qsci_tr;
     delete m_gui_tr;
     delete m_qt_tr;
     delete m_qapplication;
 
     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)
       return;
 
     m_resource_manager.config_translators (m_qt_tr, m_qsci_tr, m_gui_tr);
 
     m_qapplication->installTranslator (m_qt_tr);
