diff --git a/src/mumble/AppNap.h b/src/mumble/AppNap.h new file mode 100644 index 00000000000..767d4cfe047 --- /dev/null +++ b/src/mumble/AppNap.h @@ -0,0 +1,37 @@ +/* Copyright (C) 2015, Mikkel Krautz + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Mumble Developers nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MUMBLE_MUMBLE_APPNAP_H_ +#define MUMBLE_MUMBLE_APPNAP_H_ + +/// MUSuppressAppNap suppresses OS X's App Nap feature. +void MUSuppressAppNap(bool suppress); + +#endif diff --git a/src/mumble/AppNap.mm b/src/mumble/AppNap.mm new file mode 100644 index 00000000000..aa9c0f5d41d --- /dev/null +++ b/src/mumble/AppNap.mm @@ -0,0 +1,60 @@ +/* Copyright (C) 2015, Mikkel Krautz + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Mumble Developers nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "mumble_pch.hpp" + +static bool appNapSuppressed = false; + +void MUSuppressAppNap(bool suppress) { + NSProcessInfo *processInfo = [NSProcessInfo processInfo]; + if (![processInfo respondsToSelector:@selector(disableAutomaticTermination:)]) { + return; + } + + if (suppress == appNapSuppressed) { + qWarning("AppNap: attempt to set AppNap suppression state to %s while already in that state.", suppress ? "true" : "false"); + return; + } + + QString translatedReason = QApplication::tr("Mumble is currently connected to a server"); + NSString *reason = const_cast(reinterpret_cast(CFStringCreateWithCharacters(kCFAllocatorDefault, reinterpret_cast(translatedReason.unicode()), translatedReason.length()))); + + if (suppress) { + [[NSProcessInfo processInfo] disableAutomaticTermination:reason]; + qWarning("AppNap: suppressed with reason: '%s'", qPrintable(translatedReason)); + } else { + [[NSProcessInfo processInfo] enableAutomaticTermination:reason]; + qWarning("AppNap: re-enabled, was suppressed with reason: '%s'", qPrintable(translatedReason)); + } + + appNapSuppressed = suppress; + + [reason release]; +} diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp index fe4f5678cfb..e6bb2661efd 100644 --- a/src/mumble/MainWindow.cpp +++ b/src/mumble/MainWindow.cpp @@ -75,6 +75,10 @@ #include "TaskList.h" #endif +#ifdef Q_OS_MAC +#include "AppNap.h" +#endif + #ifdef USE_COCOA #include "ConfigDialog_macx.h" #endif @@ -2662,6 +2666,11 @@ void MainWindow::serverConnected() { #endif g.iCodecBeta = 0; +#ifdef Q_OS_MAC + // Suppress AppNap while we're connected to a server. + MUSuppressAppNap(true); +#endif + g.l->clearIgnore(); g.l->setIgnore(Log::UserJoin); g.l->setIgnore(Log::OtherSelfMute); @@ -2712,6 +2721,11 @@ void MainWindow::serverDisconnected(QAbstractSocket::SocketError err, QString re qteChat->setEnabled(false); updateTrayIcon(); +#ifdef Q_OS_MAC + // Remove App Nap suppression now that we're disconnected. + MUSuppressAppNap(false); +#endif + QString uname, pw, host; unsigned short port; g.sh->getConnectionInfo(host, port, uname, pw); diff --git a/src/mumble/mumble.pro b/src/mumble/mumble.pro index 2f8d4c2b7ba..3ba2b5412b9 100644 --- a/src/mumble/mumble.pro +++ b/src/mumble/mumble.pro @@ -452,9 +452,9 @@ unix { LIBS += -framework Security -framework SecurityInterface -framework ApplicationServices - HEADERS *= GlobalShortcut_macx.h ConfigDialogDelegate.h + HEADERS *= GlobalShortcut_macx.h ConfigDialogDelegate.h AppNap.h SOURCES *= SharedMemory_unix.cpp - OBJECTIVE_SOURCES *= TextToSpeech_macx.mm GlobalShortcut_macx.mm os_macx.mm Log_macx.mm + OBJECTIVE_SOURCES *= TextToSpeech_macx.mm GlobalShortcut_macx.mm os_macx.mm Log_macx.mm AppNap.mm !CONFIG(no-cocoa) { DEFINES *= USE_COCOA