diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a2cda57f..3faf24867 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,6 +305,15 @@ endif (ENABLE_KDE) find_package(ZLIB REQUIRED) +if (APPLE) + find_package(IOKit) + if (IOKIT_FOUND) + set(CANTATA_LIBS ${CANTATA_LIBS} ${IOKIT_LIBRARY}) + set(CANTATA_SRCS ${CANTATA_SRCS} mac/powermanagement.cpp) + set(CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} mac/powermanagement.h) + endif (IOKIT_FOUND) +endif (APPLE) + # For Qt5, we use Qt's own QJSonDocument class, so no need to find libqjson if (NOT ENABLE_QT5 AND NOT WIN32 AND NOT APPLE) find_package(QJSON) diff --git a/cmake/FindIOKit.cmake b/cmake/FindIOKit.cmake new file mode 100644 index 000000000..f3e3ecb2e --- /dev/null +++ b/cmake/FindIOKit.cmake @@ -0,0 +1,23 @@ +# - Find IOKit on Mac +# +# IOKIT_LIBRARY - the library to use IOKit +# IOKIT_FOUND - true if IOKit has been found + +# Copyright (c) 2009, Harald Fernengel +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +include(CMakeFindFrameworks) + +cmake_find_frameworks(IOKit) +cmake_find_frameworks(CoreFoundation) + +if (IOKit_FRAMEWORKS) + set(IOKIT_LIBRARY "-framework IOKit -framework CoreFoundation" CACHE FILEPATH "IOKit framework" FORCE) + set(IOKIT_FOUND 1) +endif (IOKit_FRAMEWORKS) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(IOKit DEFAULT_MSG IOKIT_LIBRARY) + diff --git a/config.h.cmake b/config.h.cmake index 8aec093fb..d63f26303 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -44,6 +44,7 @@ #cmakedefine ENABLE_MODEL_TEST 1 #cmakedefine USE_SYSTEM_MENU_ICON 1 #cmakedefine ENABLE_UBUNTU 1 +#cmakedefine IOKIT_FOUND 1 #ifdef ENABLE_UBUNTU #define CANTATA_REV_URL "com.ubuntu.developer.nikwen.cantata-touch-reboot" //Sadly, it requires the com.ubuntu.developer.nikwen prefix to be published to the click store diff --git a/gui/application_mac.cpp b/gui/application_mac.cpp index 4ae2e68f4..136cbfb40 100644 --- a/gui/application_mac.cpp +++ b/gui/application_mac.cpp @@ -45,4 +45,3 @@ Application::Application(int &argc, char **argv) QIcon::setThemeName(QLatin1String("oxygen")); } - diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index db200111d..3a6ca229c 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -84,14 +84,19 @@ #ifdef QT_QTDBUS_FOUND #include "dbus/mpris.h" #include "cantataadaptor.h" +#ifdef Q_OS_LINUX #include "dbus/powermanagement.h" #endif +#endif #if !defined Q_OS_WIN && !defined Q_OS_MAC #include "devices/mountpoints.h" #endif #ifdef Q_OS_MAC #include "support/windowmanager.h" #include "support/osxstyle.h" +#ifdef IOKIT_FOUND +#include "mac/powermanagement.h" +#endif #endif #ifdef ENABLE_DYNAMIC #include "dynamic/dynamicpage.h" @@ -1398,7 +1403,7 @@ void MainWindow::readSettings() autoScrollPlayQueue=Settings::self()->playQueueScroll(); updateWindowTitle(); TreeView::setForceSingleClick(Settings::self()->forceSingleClick()); - #ifdef QT_QTDBUS_FOUND + #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) PowerManagement::self()->setInhibitSuspend(Settings::self()->inhibitSuspend()); #endif #ifndef ENABLE_KDE_SUPPORT diff --git a/gui/playbacksettings.cpp b/gui/playbacksettings.cpp index 840b04535..d48c0b9f2 100644 --- a/gui/playbacksettings.cpp +++ b/gui/playbacksettings.cpp @@ -61,7 +61,7 @@ PlaybackSettings::PlaybackSettings(QWidget *p) messageIcon->setMinimumSize(iconSize, iconSize); messageIcon->setMaximumSize(iconSize, iconSize); mpdConnectionStateChanged(MPDConnection::self()->isConnected()); - #if defined Q_OS_WIN || defined Q_OS_MAC + #if defined Q_OS_WIN || (defined Q_OS_MAC && !defined IOKIT_FOUND) REMOVE(inhibitSuspend) #endif outputsView->setVisible(outputsView->count()>1); @@ -72,7 +72,7 @@ void PlaybackSettings::load() { stopOnExit->setChecked(Settings::self()->stopOnExit()); stopFadeDuration->setValue(Settings::self()->stopFadeDuration()); - #if !defined Q_OS_WIN && !defined Q_OS_MAC + #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) inhibitSuspend->setChecked(Settings::self()->inhibitSuspend()); #endif @@ -86,8 +86,7 @@ void PlaybackSettings::load() void PlaybackSettings::save() { Settings::self()->saveStopOnExit(stopOnExit->isChecked()); - Settings::self()->saveStopFadeDuration(stopFadeDuration->value()); - #if !defined Q_OS_WIN && !defined Q_OS_MAC + #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) Settings::self()->saveInhibitSuspend(inhibitSuspend->isChecked()); #endif diff --git a/gui/settings.cpp b/gui/settings.cpp index 77b619b92..0ad96903c 100644 --- a/gui/settings.cpp +++ b/gui/settings.cpp @@ -711,7 +711,7 @@ QStringList Settings::hiddenOnlineProviders() return cfg.get("hiddenOnlineProviders", QStringList()); } -#if !defined Q_OS_WIN && !defined Q_OS_MAC +#if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) bool Settings::inhibitSuspend() { return cfg.get("inhibitSuspend", false); @@ -1318,7 +1318,7 @@ void Settings::saveHiddenOnlineProviders(const QStringList &v) cfg.set("hiddenOnlineProviders", v); } -#if !defined Q_OS_WIN && !defined Q_OS_MAC +#if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) void Settings::saveInhibitSuspend(bool v) { cfg.set("inhibitSuspend", v); diff --git a/gui/settings.h b/gui/settings.h index 1077fe6a2..50d64633d 100644 --- a/gui/settings.h +++ b/gui/settings.h @@ -151,7 +151,7 @@ public: bool showTimeRemaining(); QStringList hiddenStreamCategories(); QStringList hiddenOnlineProviders(); - #if !defined Q_OS_WIN && !defined Q_OS_MAC + #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) bool inhibitSuspend(); #endif int rssUpdate(); @@ -277,7 +277,7 @@ public: void saveShowTimeRemaining(bool v); void saveHiddenStreamCategories(const QStringList &v); void saveHiddenOnlineProviders(const QStringList &v); - #if !defined Q_OS_WIN && !defined Q_OS_MAC + #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) void saveInhibitSuspend(bool v); #endif void saveRssUpdate(int v); diff --git a/mac/powermanagement.cpp b/mac/powermanagement.cpp new file mode 100644 index 000000000..80864bcfe --- /dev/null +++ b/mac/powermanagement.cpp @@ -0,0 +1,70 @@ +/* + * Cantata + * + * Copyright (c) 2011-2014 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "powermanagement.h" +#include "support/globalstatic.h" +#include "mpd/mpdstatus.h" +#include +#include +#include + +GLOBAL_STATIC(PowerManagement, instance) + +static void powerEventCallback(void *rootPort, io_service_t, natural_t msg, void *arg) +{ + switch (msg) { + case kIOMessageSystemWillSleep: + IOAllowPowerChange(*(io_connect_t *) rootPort, (long)arg); + break; + case kIOMessageSystemHasPoweredOn: + PowerManagement::self()->emitResuming(); + break; + case kIOMessageCanSystemSleep: + if (PowerManagement::self()->inhibitSuspend() && MPDState_Playing==MPDStatus::self()->state()) { + IOCancelPowerChange(*(io_connect_t *) rootPort, (long)arg); + } else { + IOAllowPowerChange(*(io_connect_t *) rootPort, (long)arg); + } + break; + default: + break; + } +} + +PowerManagement::PowerManagement() + : inhibitSuspendWhilstPlaying(false) +{ + static io_connect_t rootPort; + IONotificationPortRef notificationPort; + io_object_t notifier; + + rootPort = IORegisterForSystemPower(&rootPort, ¬ificationPort, powerEventCallback, ¬ifier); + if (rootPort) { + CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notificationPort), kCFRunLoopDefaultMode); + } +} + +void PowerManagement::emitResuming() +{ + emit resuming(); +} diff --git a/mac/powermanagement.h b/mac/powermanagement.h new file mode 100644 index 000000000..e255be3cc --- /dev/null +++ b/mac/powermanagement.h @@ -0,0 +1,48 @@ +/* + * Cantata + * + * Copyright (c) 2011-2014 Craig Drummond + * + * ---- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef POWERMANAGEMENT_H +#define POWERMANAGEMENT_H + +#include + +class PowerManagement : public QObject +{ + Q_OBJECT + +public: + static PowerManagement * self(); + PowerManagement(); + + void setInhibitSuspend(bool i) { inhibitSuspendWhilstPlaying=i; } + bool inhibitSuspend() const { return inhibitSuspendWhilstPlaying; } + void emitResuming(); + +Q_SIGNALS: + void resuming(); + +private: + bool inhibitSuspendWhilstPlaying; +}; + +#endif diff --git a/mpd/mpdconnection.cpp b/mpd/mpdconnection.cpp index f8b086346..489826ea8 100644 --- a/mpd/mpdconnection.cpp +++ b/mpd/mpdconnection.cpp @@ -44,8 +44,10 @@ #include "support/thread.h" #include "gui/settings.h" #include "cuefile.h" -#ifdef QT_QTDBUS_FOUND +#if defined Q_OS_LINUX && defined QT_QTDBUS_FOUND #include "dbus/powermanagement.h" +#elif defined Q_OS_MAC && defined IOKIT_FOUND +#include "mac/powermanagement.h" #endif #include static bool debugEnabled=false; @@ -241,7 +243,7 @@ MPDConnection::MPDConnection() qRegisterMetaType("MPDConnectionDetails"); qRegisterMetaType("Stream"); qRegisterMetaType >("QList"); - #ifdef QT_QTDBUS_FOUND + #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND) connect(PowerManagement::self(), SIGNAL(resuming()), this, SLOT(reconnect())); #endif #ifndef ENABLE_UBUNTU