diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in
index 41f37eb43c..ff1f26cdd9 100644
--- a/share/qt/Info.plist.in
+++ b/share/qt/Info.plist.in
@@ -97,9 +97,6 @@
NSHighResolutionCapable
True
- LSAppNapIsDisabled
- True
-
NSRequiresAquaSystemAppearance
True
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 56a6dca189..26eb4dfc85 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -103,7 +103,8 @@ QT_MOC_CPP = \
BITCOIN_MM = \
qt/macdockiconhandler.mm \
- qt/macnotificationhandler.mm
+ qt/macnotificationhandler.mm \
+ qt/macos_appnap.mm
QT_MOC = \
qt/dash.moc \
@@ -142,6 +143,7 @@ BITCOIN_QT_H = \
qt/intro.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
+ qt/macos_appnap.h \
qt/modaloverlay.h \
qt/masternodelist.h \
qt/networkstyle.h \
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index cc90e89d64..b6c4ca816a 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -24,6 +24,7 @@
#include "utilitydialog.h"
#ifdef ENABLE_WALLET
+#include "privatesend/privatesend-client.h"
#include "walletframe.h"
#include "walletmodel.h"
#endif // ENABLE_WALLET
@@ -266,6 +267,10 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
connect(progressBar, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay()));
}
#endif
+
+#ifdef Q_OS_MAC
+ m_app_nap_inhibitor = new CAppNapInhibitor;
+#endif
}
BitcoinGUI::~BitcoinGUI()
@@ -277,6 +282,7 @@ BitcoinGUI::~BitcoinGUI()
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
trayIcon->hide();
#ifdef Q_OS_MAC
+ delete m_app_nap_inhibitor;
delete appMenuBar;
MacDockIconHandler::cleanup();
#endif
@@ -950,6 +956,19 @@ void BitcoinGUI::updateHeadersSyncProgressLabel()
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header)
{
+#ifdef Q_OS_MAC
+ // Disabling macOS App Nap on initial sync, disk, reindex operations and mixing.
+ bool disableAppNap = !masternodeSync.IsSynced();
+#ifdef ENABLE_WALLET
+ disableAppNap |= privateSendClient.fPrivateSendRunning;
+#endif // ENABLE_WALLET
+ if (disableAppNap) {
+ m_app_nap_inhibitor->disableAppNap();
+ } else {
+ m_app_nap_inhibitor->enableAppNap();
+ }
+#endif // Q_OS_MAC
+
if (modalOverlay)
{
if (header)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index df1fd19933..ef08389982 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -19,6 +19,10 @@
#include
#include
+#ifdef Q_OS_MAC
+#include
+#endif
+
class ClientModel;
class NetworkStyle;
class Notificator;
@@ -131,6 +135,10 @@ private:
HelpMessageDialog *helpMessageDialog;
ModalOverlay *modalOverlay;
+#ifdef Q_OS_MAC
+ CAppNapInhibitor* m_app_nap_inhibitor = nullptr;
+#endif
+
/** Keep track of previous number of blocks, to detect progress */
int prevBlocks;
int spinnerFrame;
diff --git a/src/qt/macos_appnap.h b/src/qt/macos_appnap.h
new file mode 100644
index 0000000000..8c2cd840b0
--- /dev/null
+++ b/src/qt/macos_appnap.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_MACOS_APPNAP_H
+#define BITCOIN_QT_MACOS_APPNAP_H
+
+#include
+
+class CAppNapInhibitor final
+{
+public:
+ explicit CAppNapInhibitor();
+ ~CAppNapInhibitor();
+
+ void disableAppNap();
+ void enableAppNap();
+
+private:
+ class CAppNapImpl;
+ std::unique_ptr impl;
+};
+
+#endif // BITCOIN_QT_MACOS_APPNAP_H
diff --git a/src/qt/macos_appnap.mm b/src/qt/macos_appnap.mm
new file mode 100644
index 0000000000..363c60091f
--- /dev/null
+++ b/src/qt/macos_appnap.mm
@@ -0,0 +1,71 @@
+// Copyright (c) 2011-2018 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "macos_appnap.h"
+
+#include
+#include
+#include
+
+class CAppNapInhibitor::CAppNapImpl
+{
+public:
+ ~CAppNapImpl()
+ {
+ if(activityId)
+ enableAppNap();
+ }
+
+ void disableAppNap()
+ {
+ if (!activityId)
+ {
+ @autoreleasepool {
+ const NSActivityOptions activityOptions =
+ NSActivityUserInitiatedAllowingIdleSystemSleep &
+ ~(NSActivitySuddenTerminationDisabled |
+ NSActivityAutomaticTerminationDisabled);
+
+ id processInfo = [NSProcessInfo processInfo];
+ if ([processInfo respondsToSelector:@selector(beginActivityWithOptions:reason:)])
+ {
+ activityId = [processInfo beginActivityWithOptions: activityOptions reason:@"Temporarily disable App Nap for dash-qt."];
+ [activityId retain];
+ }
+ }
+ }
+ }
+
+ void enableAppNap()
+ {
+ if(activityId)
+ {
+ @autoreleasepool {
+ id processInfo = [NSProcessInfo processInfo];
+ if ([processInfo respondsToSelector:@selector(endActivity:)])
+ [processInfo endActivity:activityId];
+
+ [activityId release];
+ activityId = nil;
+ }
+ }
+ }
+
+private:
+ NSObject* activityId;
+};
+
+CAppNapInhibitor::CAppNapInhibitor() : impl(new CAppNapImpl()) {}
+
+CAppNapInhibitor::~CAppNapInhibitor() = default;
+
+void CAppNapInhibitor::disableAppNap()
+{
+ impl->disableAppNap();
+}
+
+void CAppNapInhibitor::enableAppNap()
+{
+ impl->enableAppNap();
+}