diff --git a/CMakeLists.txt b/CMakeLists.txt index aab753da..a141da7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,74 +1,74 @@ project(PowerDevil) set(PROJECT_VERSION "5.9.90") set(PROJECT_VERSION_MAJOR 5) cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) set(QT_MIN_VERSION "5.4.0") find_package(ECM 1.2.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(FeatureSummary) include(WriteBasicConfigVersionFile) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) # require at least gcc 4.8 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.8") message(SEND_ERROR "Version ${CMAKE_CXX_COMPILER_VERSION} of the ${CMAKE_CXX_COMPILER_ID} C++ compiler is not supported. Please use version 4.8 or later.") endif() endif() find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Widgets DBus X11Extras) -find_package(KF5 REQUIRED COMPONENTS Activities Auth IdleTime Config DBusAddons Solid I18n GlobalAccel KIO NotifyConfig Screen KDELibs4Support Wayland) +find_package(KF5 REQUIRED COMPONENTS Activities Auth IdleTime Config DBusAddons Solid I18n GlobalAccel KIO NotifyConfig Screen Wayland DocTools Crash Notifications) find_package(LibKWorkspace CONFIG REQUIRED) find_package(KF5BluezQt) set_package_properties(KF5BluezQt PROPERTIES DESCRIPTION "Qt wrapper for BlueZ 5 DBus API" TYPE OPTIONAL PURPOSE "Support for wireless energy saving actions" ) find_package(KF5NetworkManagerQt) set_package_properties(KF5NetworkManagerQt PROPERTIES DESCRIPTION "Qt wrapper for NetworkManager API" TYPE OPTIONAL PURPOSE "Support for wireless energy saving actions" ) set(HAVE_WIRELESS_SUPPORT FALSE) if(KF5NetworkManagerQt_FOUND AND KF5BluezQt_FOUND) set(HAVE_WIRELESS_SUPPORT TRUE) endif() add_feature_info( "Wireless power saving" HAVE_WIRELESS_SUPPORT "Support turning off signal-transmitting devices to save energy" ) find_package(UDev REQUIRED) find_package(XCB REQUIRED COMPONENTS XCB RANDR DPMS) include_directories ( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/daemon ) configure_file(config-workspace.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-workspace.h) add_definitions(-DQT_NO_KEYWORDS) add_definitions(-DQT_NO_KEYWORDS) add_subdirectory(daemon) add_subdirectory(kcmodule) add_subdirectory(doc) install( FILES powerdevil.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR} ) if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) endif() diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index fcc9c07f..4416387d 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -1,158 +1,159 @@ add_definitions(-DTRANSLATION_DOMAIN=\"powerdevil\" -DQT_USE_QSTRINGBUILDER) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) add_subdirectory(actions) set(POWERDEVIL_CORE_VERSION_MAJOR 2) set(POWERDEVIL_CORE_VERSION_MINOR 0) set(POWERDEVIL_CORE_VERSION_MICRO 0) set(POWERDEVIL_CORE_VERSION_STRING ${POWERDEVIL_CORE_VERSION_MAJOR}.${POWERDEVIL_CORE_VERSION_MINOR}.${POWERDEVIL_CORE_VERSION_MICRO}) # Add bundled actions set(powerdevil_bundled_actions_SRCS powerdevil_debug.cpp actions/bundled/suspendsession.cpp actions/bundled/brightnesscontrol.cpp actions/bundled/keyboardbrightnesscontrol.cpp actions/bundled/dimdisplay.cpp actions/bundled/runscript.cpp actions/bundled/handlebuttonevents.cpp ) if(HAVE_WIRELESS_SUPPORT) set(powerdevil_bundled_actions_SRCS ${powerdevil_bundled_actions_SRCS} actions/bundled/wirelesspowersaving.cpp ) endif() # target no.1 - powerdevil core library set(powerdevilcore_SRCS powerdevil_debug.cpp powerdevilaction.cpp powerdevilactionpool.cpp powerdevilbackendinterface.cpp powerdevilcore.cpp powerdevilpolicyagent.cpp powerdevilprofilegenerator.cpp powerdevilbrightnesslogic.cpp powerdevilscreenbrightnesslogic.cpp powerdevilkeyboardbrightnesslogic.cpp + powerdevilpowermanagement.cpp brightnessosdwidget.cpp kwinkscreenhelpereffect.cpp ) kconfig_add_kcfg_files(powerdevilcore_SRCS ../PowerDevilSettings.kcfgc) # Action DBus Adaptors qt5_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml actions/bundled/brightnesscontrol.h PowerDevil::BundledActions::BrightnessControl) qt5_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl.xml actions/bundled/keyboardbrightnesscontrol.h PowerDevil::BundledActions::KeyboardBrightnessControl) qt5_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.HandleButtonEvents.xml actions/bundled/handlebuttonevents.h PowerDevil::BundledActions::HandleButtonEvents) qt5_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.SuspendSession.xml actions/bundled/suspendsession.h PowerDevil::BundledActions::SuspendSession) if(HAVE_WIRELESS_SUPPORT) qt5_add_dbus_adaptor(powerdevilcore_SRCS actions/bundled/org.kde.Solid.PowerManagement.Actions.WirelessPowerSaving.xml actions/bundled/wirelesspowersaving.h PowerDevil::BundledActions::WirelessPowerSaving) endif() qt5_add_dbus_interface(powerdevilcore_SRCS org.freedesktop.ScreenSaver.xml screenlocker_interface) add_library(powerdevilcore SHARED ${powerdevilcore_SRCS} ${powerdevil_bundled_actions_SRCS}) set_target_properties(powerdevilcore PROPERTIES VERSION ${POWERDEVIL_CORE_VERSION_STRING} SOVERSION ${POWERDEVIL_CORE_VERSION_MAJOR}) # not exported, so just make the deps public target_link_libraries(powerdevilcore KF5::Activities KF5::ConfigCore KF5::ConfigGui KF5::DBusAddons KF5::I18n KF5::Solid KF5::IdleTime KF5::GlobalAccel KF5::Screen KF5::Service KF5::WidgetsAddons KF5::Notifications KF5::XmlGui PW::KWorkspace ) if(HAVE_WIRELESS_SUPPORT) target_link_libraries(powerdevilcore KF5::NetworkManagerQt KF5::BluezQt ) endif() if (XCB_FOUND) # kwin kscreen helper effect target_link_libraries(powerdevilcore Qt5::X11Extras XCB::XCB) endif () # target no.2 - powerdevil kded module set(powerdevil_SRCS powerdevil_debug.cpp powerdevilapp.cpp powerdevilfdoconnector.cpp ) # DBus Adaptors qt5_add_dbus_adaptor(powerdevil_SRCS org.kde.Solid.PowerManagement.xml powerdevilcore.h PowerDevil::Core) qt5_add_dbus_adaptor(powerdevil_SRCS org.kde.Solid.PowerManagement.PolicyAgent.xml powerdevilpolicyagent.h PowerDevil::PolicyAgent powermanagementpolicyagentadaptor PowerManagementPolicyAgentAdaptor) -qt5_add_dbus_adaptor(powerdevil_SRCS ${KDE4_DBUS_INTERFACES_DIR}/kf5_org.freedesktop.PowerManagement.xml powerdevilfdoconnector.h PowerDevil::FdoConnector powermanagementfdoadaptor PowerManagementFdoAdaptor) -qt5_add_dbus_adaptor(powerdevil_SRCS ${KDE4_DBUS_INTERFACES_DIR}/kf5_org.freedesktop.PowerManagement.Inhibit.xml powerdevilfdoconnector.h PowerDevil::FdoConnector powermanagementinhibitadaptor PowerManagementInhibitAdaptor) +qt5_add_dbus_adaptor(powerdevil_SRCS org.freedesktop.PowerManagement.xml powerdevilfdoconnector.h PowerDevil::FdoConnector powermanagementfdoadaptor PowerManagementFdoAdaptor) +qt5_add_dbus_adaptor(powerdevil_SRCS org.freedesktop.PowerManagement.Inhibit.xml powerdevilfdoconnector.h PowerDevil::FdoConnector powermanagementinhibitadaptor PowerManagementInhibitAdaptor) # Backends add_subdirectory(backends) add_executable(powerdevil ${powerdevil_SRCS}) set_target_properties(powerdevil PROPERTIES OUTPUT_NAME org_kde_powerdevil) configure_file(powerdevil.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/powerdevil.desktop) target_link_libraries(powerdevil KF5::Crash KF5::ConfigCore KF5::CoreAddons KF5::I18n KF5::DBusAddons powerdevilcore ) if (XCB_FOUND) target_link_libraries(powerdevil Qt5::X11Extras) endif () target_link_libraries(powerdevil ${UDEV_LIBS}) install(TARGETS powerdevil DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/powerdevil.desktop DESTINATION ${KDE_INSTALL_AUTOSTARTDIR}) install(TARGETS powerdevilcore ${INSTALL_TARGETS_DEFAULT_ARGS}) # target no.3 - powerdevil ui library set(powerdevilui_SRCS powerdevilactionconfig.cpp ) add_library(powerdevilui ${powerdevilui_SRCS}) set_target_properties(powerdevilui PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) # not exported, so just make the deps public target_link_libraries(powerdevilui PUBLIC Qt5::Widgets KF5::ConfigCore ) set(HAVE_XCB ${XCB_FOUND}) configure_file(config-powerdevil.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-powerdevil.h ) install(TARGETS powerdevilui ${INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/daemon/actions/bundled/CMakeLists.txt b/daemon/actions/bundled/CMakeLists.txt index 9623b57c..c0269c6b 100644 --- a/daemon/actions/bundled/CMakeLists.txt +++ b/daemon/actions/bundled/CMakeLists.txt @@ -1,43 +1,43 @@ function(add_powerdevil_bundled_action _name) set(actionconfig_SRCS ${_name}config.cpp) add_library(powerdevil${_name}action_config MODULE ${actionconfig_SRCS}) target_link_libraries(powerdevil${_name}action_config + powerdevilcore powerdevilui Qt5::Widgets KF5::CoreAddons KF5::I18n KF5::ConfigGui KF5::XmlGui ${ARGN}) install(TARGETS powerdevil${_name}action_config DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES powerdevil${_name}action.desktop DESTINATION ${SERVICES_INSTALL_DIR}) endfunction(add_powerdevil_bundled_action _name) add_powerdevil_bundled_action(brightnesscontrol KF5::GlobalAccel) add_powerdevil_bundled_action(keyboardbrightnesscontrol) add_powerdevil_bundled_action(dimdisplay) add_powerdevil_bundled_action(runscript KF5::KIOCore KF5::KIOWidgets) -add_powerdevil_bundled_action(suspendsession KF5::KIOCore KF5::KIOWidgets KF5::Solid KF5::KDELibs4Support) +add_powerdevil_bundled_action(suspendsession KF5::KIOCore KF5::KIOWidgets) if(HAVE_WIRELESS_SUPPORT) add_powerdevil_bundled_action(wirelesspowersaving KF5::NetworkManagerQt KF5::BluezQt) endif() set(actionconfig_SRCS handlebuttoneventsconfig.cpp) qt5_add_dbus_interface(actionconfig_SRCS ${CMAKE_SOURCE_DIR}/daemon/backends/upower/dbus/org.freedesktop.UPower.xml upower_interface) add_library(powerdevilhandlebuttoneventsaction_config MODULE ${actionconfig_SRCS}) target_link_libraries(powerdevilhandlebuttoneventsaction_config + powerdevilcore powerdevilui Qt5::Widgets KF5::CoreAddons KF5::I18n KF5::ConfigGui - KF5::Solid KF5::XmlGui - KF5::KDELibs4Support ) install(TARGETS powerdevilhandlebuttoneventsaction_config DESTINATION ${PLUGIN_INSTALL_DIR}) install(FILES powerdevilhandlebuttoneventsaction.desktop DESTINATION ${SERVICES_INSTALL_DIR}) diff --git a/daemon/actions/bundled/handlebuttoneventsconfig.cpp b/daemon/actions/bundled/handlebuttoneventsconfig.cpp index 8ca5f4c4..08368b87 100644 --- a/daemon/actions/bundled/handlebuttoneventsconfig.cpp +++ b/daemon/actions/bundled/handlebuttoneventsconfig.cpp @@ -1,181 +1,178 @@ /*************************************************************************** * Copyright (C) 2010 by Dario Freddi * * Copyright (C) 2015 by Kai Uwe Broulik * * * * 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; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "handlebuttoneventsconfig.h" #include "suspendsession.h" #include "upower_interface.h" -#include -#include +#include "powerdevilpowermanagement.h" #include #include #include #include #include #include K_PLUGIN_FACTORY(PowerDevilSuspendSessionConfigFactory, registerPlugin(); ) namespace PowerDevil { namespace BundledActions { HandleButtonEventsConfig::HandleButtonEventsConfig(QObject* parent, const QVariantList& ) : ActionConfig(parent) { } HandleButtonEventsConfig::~HandleButtonEventsConfig() { } void HandleButtonEventsConfig::save() { if (m_lidCloseCombo) { configGroup().writeEntry("lidAction", m_lidCloseCombo->itemData(m_lidCloseCombo->currentIndex()).toUInt()); } if (m_triggerLidActionWhenExternalMonitorPresent) { configGroup().writeEntry("triggerLidActionWhenExternalMonitorPresent", m_triggerLidActionWhenExternalMonitorPresent->isChecked()); } if (m_powerButtonCombo) { configGroup().writeEntry("powerButtonAction", m_powerButtonCombo->itemData(m_powerButtonCombo->currentIndex()).toUInt()); } configGroup().sync(); } void HandleButtonEventsConfig::load() { configGroup().config()->reparseConfiguration(); if (m_lidCloseCombo) { m_lidCloseCombo->setCurrentIndex(m_lidCloseCombo->findData(QVariant::fromValue(configGroup().readEntry("lidAction", 0)))); } if (m_triggerLidActionWhenExternalMonitorPresent) { m_triggerLidActionWhenExternalMonitorPresent->setChecked(configGroup().readEntry("triggerLidActionWhenExternalMonitorPresent", false)); } if (m_powerButtonCombo) { m_powerButtonCombo->setCurrentIndex(m_powerButtonCombo->findData(QVariant::fromValue(configGroup().readEntry("powerButtonAction", 0)))); } } QList< QPair< QString, QWidget* > > HandleButtonEventsConfig::buildUi() { // Create the boxes m_lidCloseCombo = new QComboBox; m_triggerLidActionWhenExternalMonitorPresent = new QCheckBox( i18nc("Execute action on lid close even when external monitor is connected", "Even when an external monitor is connected") ); m_powerButtonCombo = new QComboBox; // Fill the boxes with options! { QList boxes; boxes << m_lidCloseCombo << m_powerButtonCombo; - QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); - Q_FOREACH (QComboBox *box, boxes) { box->addItem(QIcon::fromTheme("dialog-cancel"), i18n("Do nothing"), (uint)SuspendSession::None); - if (methods.contains(Solid::PowerManagement::SuspendState)) { + if (PowerManagement::instance()->canSuspend()) { box->addItem(QIcon::fromTheme("system-suspend"), i18n("Suspend"), (uint)SuspendSession::ToRamMode); } - if (methods.contains(Solid::PowerManagement::HibernateState)) { + if (PowerManagement::instance()->canHibernate()) { box->addItem(QIcon::fromTheme("system-suspend-hibernate"), i18n("Hibernate"), (uint)SuspendSession::ToDiskMode); } - if (methods.contains(Solid::PowerManagement::HybridSuspendState)) { + if (PowerManagement::instance()->canHybridSuspend()) { box->addItem(QIcon::fromTheme("system-suspend-hybrid"), i18n("Hybrid suspend"), (uint)SuspendSession::SuspendHybridMode); } box->addItem(QIcon::fromTheme("system-shutdown"), i18n("Shut down"), (uint)SuspendSession::ShutdownMode); box->addItem(QIcon::fromTheme("system-lock-screen"), i18n("Lock screen"), (uint)SuspendSession::LockScreenMode); if (box != m_lidCloseCombo) { box->addItem(QIcon::fromTheme("system-log-out"), i18n("Prompt log out dialog"), (uint)SuspendSession::LogoutDialogMode); } box->addItem(QIcon::fromTheme("preferences-desktop-screensaver"), i18n("Turn off screen"), (uint)SuspendSession::TurnOffScreenMode); } } connect(m_lidCloseCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); connect(m_triggerLidActionWhenExternalMonitorPresent, SIGNAL(stateChanged(int)), this, SLOT(setChanged())); connect(m_powerButtonCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); bool lidFound = false; bool powerFound = true; // HACK This needs proper API!! // get a list of all devices that are Buttons /* Q_FOREACH (Solid::Device device, Solid::Device::listFromType(Solid::DeviceInterface::Button, QString())) { Solid::Button *button = device.as(); if (button->type() == Solid::Button::LidButton) { lidFound = true; } else if (button->type() == Solid::Button::PowerButton) { powerFound = true; } }*/ auto m_upowerInterface = new OrgFreedesktopUPowerInterface("org.freedesktop.UPower", "/org/freedesktop/UPower", QDBusConnection::systemBus(), this); lidFound = m_upowerInterface->lidIsPresent(); QList< QPair< QString, QWidget* > > retlist; if (lidFound) { retlist.append(qMakePair(i18n("When laptop lid closed"), m_lidCloseCombo)); // an empty label will make it treat the widget as title checkbox and left-align it retlist.append(qMakePair(QLatin1Literal("NONE"), m_triggerLidActionWhenExternalMonitorPresent)); } else { m_lidCloseCombo->deleteLater(); m_lidCloseCombo = nullptr; m_triggerLidActionWhenExternalMonitorPresent->deleteLater(); m_triggerLidActionWhenExternalMonitorPresent = nullptr; } if (powerFound) { retlist.append(qMakePair< QString, QWidget* >(i18n("When power button pressed"), m_powerButtonCombo)); } else { m_powerButtonCombo->deleteLater(); m_powerButtonCombo = nullptr; } // unified width for the comboboxes int comboBoxMaxWidth = 300; if (m_lidCloseCombo) { comboBoxMaxWidth = qMax(comboBoxMaxWidth, m_lidCloseCombo->sizeHint().width()); } if (m_powerButtonCombo) { comboBoxMaxWidth = qMax(comboBoxMaxWidth, m_powerButtonCombo->sizeHint().width()); } if (m_lidCloseCombo) { m_lidCloseCombo->setMinimumWidth(300); m_lidCloseCombo->setMaximumWidth(comboBoxMaxWidth); } if (m_powerButtonCombo) { m_powerButtonCombo->setMinimumWidth(300); m_powerButtonCombo->setMaximumWidth(comboBoxMaxWidth); } return retlist; } } } #include "handlebuttoneventsconfig.moc" diff --git a/daemon/actions/bundled/suspendsessionconfig.cpp b/daemon/actions/bundled/suspendsessionconfig.cpp index b9e88294..e2f540ea 100644 --- a/daemon/actions/bundled/suspendsessionconfig.cpp +++ b/daemon/actions/bundled/suspendsessionconfig.cpp @@ -1,113 +1,111 @@ /*************************************************************************** * Copyright (C) 2010 by Dario Freddi * * * * 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; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "suspendsessionconfig.h" +#include "powerdevilpowermanagement.h" + #include #include -#include - #include #include #include #include #include #include #include "suspendsession.h" K_PLUGIN_FACTORY(PowerDevilSuspendSessionConfigFactory, registerPlugin(); ) namespace PowerDevil { namespace BundledActions { SuspendSessionConfig::SuspendSessionConfig(QObject* parent, const QVariantList&) : ActionConfig(parent) { } SuspendSessionConfig::~SuspendSessionConfig() { } void SuspendSessionConfig::save() { configGroup().writeEntry< uint >("suspendType", m_comboBox->itemData(m_comboBox->currentIndex()).toUInt()); configGroup().writeEntry("idleTime", m_idleTime->value() * 60 * 1000); configGroup().sync(); } void SuspendSessionConfig::load() { configGroup().config()->reparseConfiguration(); uint suspendType = configGroup().readEntry< uint >("suspendType", 0); m_comboBox->setCurrentIndex(m_comboBox->findData(suspendType)); m_idleTime->setValue((configGroup().readEntry("idleTime", 600000) / 60) / 1000); } QList< QPair< QString, QWidget* > > SuspendSessionConfig::buildUi() { QWidget *tempWidget = new QWidget; QHBoxLayout *hlay = new QHBoxLayout; m_comboBox = new KComboBox; m_idleTime = new QSpinBox; m_idleTime->setMaximumWidth(150); m_idleTime->setMinimum(1); m_idleTime->setMaximum(360); m_idleTime->setValue(0); m_idleTime->setSuffix(i18n(" min")); - QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); - - if (methods.contains(Solid::PowerManagement::SuspendState)) { + if (PowerManagement::instance()->canSuspend()) { m_comboBox->addItem(QIcon::fromTheme("system-suspend"), i18n("Suspend"), (uint)SuspendSession::ToRamMode); } - if (methods.contains(Solid::PowerManagement::HibernateState)) { + if (PowerManagement::instance()->canHibernate()) { m_comboBox->addItem(QIcon::fromTheme("system-suspend-hibernate"), i18n("Hibernate"), (uint)SuspendSession::ToDiskMode); } - if (methods.contains(Solid::PowerManagement::HybridSuspendState)) { + if (PowerManagement::instance()->canHybridSuspend()) { m_comboBox->addItem(QIcon::fromTheme("system-suspend-hybrid"), i18n("Hybrid suspend"), (uint)SuspendSession::SuspendHybridMode); } m_comboBox->addItem(QIcon::fromTheme("system-shutdown"), i18n("Shut down"), (uint)SuspendSession::ShutdownMode); m_comboBox->addItem(QIcon::fromTheme("system-lock-screen"), i18n("Lock screen"), (uint)SuspendSession::LockScreenMode); hlay->addWidget(m_idleTime); hlay->addWidget(m_comboBox); hlay->addStretch(); tempWidget->setLayout(hlay); QList< QPair< QString, QWidget* > > retlist; retlist.append(qMakePair< QString, QWidget* >(i18n("After"), tempWidget)); connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); connect(m_idleTime, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); return retlist; } } } #include "suspendsessionconfig.moc" diff --git a/daemon/org.freedesktop.PowerManagement.Inhibit.xml b/daemon/org.freedesktop.PowerManagement.Inhibit.xml new file mode 100644 index 00000000..d5be190b --- /dev/null +++ b/daemon/org.freedesktop.PowerManagement.Inhibit.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/daemon/org.freedesktop.PowerManagement.xml b/daemon/org.freedesktop.PowerManagement.xml new file mode 100644 index 00000000..35b45c1a --- /dev/null +++ b/daemon/org.freedesktop.PowerManagement.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/daemon/powerdevilpowermanagement.cpp b/daemon/powerdevilpowermanagement.cpp new file mode 100644 index 00000000..71f8ee5f --- /dev/null +++ b/daemon/powerdevilpowermanagement.cpp @@ -0,0 +1,222 @@ +/******************************************************************** +Copyright 2016 Martin Gräßlin + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#include "powerdevilpowermanagement.h" + +#include +#include +#include + +namespace PowerDevil { + +static const QString s_fdoPowerService = QStringLiteral("org.freedesktop.PowerManagement"); +static const QString s_fdoPowerPath = QStringLiteral("/org/freedesktop/PowerManagement"); + +class PowerManagementInstance : public PowerManagement +{ + Q_OBJECT +public: + explicit PowerManagementInstance() : PowerManagement() {} +}; +Q_GLOBAL_STATIC(PowerManagementInstance, s_instance) + +class PowerManagement::Private +{ +public: + Private(PowerManagement *q); + void update(); + void setCanSuspend(bool set); + void setCanHibernate(bool set); + void setCanHybridSuspend(bool set); + + bool serviceRegistered; + bool canSuspend; + bool canHibernate; + bool canHybridSuspend; + QScopedPointer fdoPowerServiceWatcher; + +private: + void updateProperty(const QString &dbusName, void (Private::*setter)(bool)); + PowerManagement *q; +}; + +PowerManagement::Private::Private(PowerManagement *q) + : serviceRegistered(false) + , canSuspend(false) + , canHibernate(false) + , canHybridSuspend(false) + , fdoPowerServiceWatcher(new QDBusServiceWatcher(s_fdoPowerService, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForUnregistration | QDBusServiceWatcher::WatchForRegistration)) + , q(q) +{ +} + +void PowerManagement::Private::update() +{ + serviceRegistered = true; + updateProperty(QStringLiteral("CanSuspend"), &Private::setCanSuspend); + updateProperty(QStringLiteral("CanHibernate"), &Private::setCanHibernate); + updateProperty(QStringLiteral("CanHybridSuspend"), &Private::setCanHybridSuspend); +} + +void PowerManagement::Private::updateProperty(const QString &dbusName, void (Private::*setter)(bool)) +{ + QDBusMessage message = QDBusMessage::createMethodCall(s_fdoPowerService, + s_fdoPowerPath, + s_fdoPowerService, + dbusName); + QDBusPendingReply reply = QDBusConnection::sessionBus().asyncCall(message); + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(reply, q); + QObject::connect(callWatcher, &QDBusPendingCallWatcher::finished, q, + [this, setter](QDBusPendingCallWatcher *self) { + QDBusPendingReply reply = *self; + self->deleteLater(); + if (!reply.isValid()) { + return; + } + ((this)->*setter)(reply.value()); + } + ); + +} + +void PowerManagement::Private::setCanHibernate(bool set) +{ + if (canHibernate == set) { + return; + } + canHibernate = set; + q->canHibernateChanged(); +} + +void PowerManagement::Private::setCanSuspend(bool set) +{ + if (canSuspend == set) { + return; + } + canSuspend = set; + q->canSuspendChanged(); +} + +void PowerManagement::Private::setCanHybridSuspend(bool set) +{ + if (canHybridSuspend == set) { + return; + } + canHybridSuspend = set; + q->canHybridSuspendChanged(); +} + +PowerManagement *PowerManagement::instance() +{ + return s_instance; +} + +PowerManagement::PowerManagement() + : QObject() + , d(new Private(this)) +{ + connect(d->fdoPowerServiceWatcher.data(), &QDBusServiceWatcher::serviceRegistered, this, [this] { d->update(); }); + connect(d->fdoPowerServiceWatcher.data(), &QDBusServiceWatcher::serviceUnregistered, this, + [this] { + d->serviceRegistered = false; + d->setCanSuspend(false); + d->setCanHibernate(false); + d->setCanHybridSuspend(false); + } + ); + + // check whether the service is registered + QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"), + QStringLiteral("/"), + QStringLiteral("org.freedesktop.DBus"), + QStringLiteral("ListNames")); + QDBusPendingReply async = QDBusConnection::sessionBus().asyncCall(message); + QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(async, this); + connect(callWatcher, &QDBusPendingCallWatcher::finished, this, + [this](QDBusPendingCallWatcher *self) { + QDBusPendingReply reply = *self; + self->deleteLater(); + if (!reply.isValid()) { + return; + } + if (reply.value().contains(s_fdoPowerService)) { + d->update(); + } + } + ); +} + +PowerManagement::~PowerManagement() +{ +} + +void PowerManagement::suspend() +{ + if (!d->serviceRegistered) { + return; + } + if (!d->canSuspend) { + return; + } + QDBusMessage message = QDBusMessage::createMethodCall(s_fdoPowerService, + s_fdoPowerPath, + s_fdoPowerService, + QStringLiteral("Suspend")); + QDBusConnection::sessionBus().asyncCall(message); +} + +void PowerManagement::hibernate() +{ + if (!d->serviceRegistered) { + return; + } + if (!d->canHibernate) { + return; + } + QDBusMessage message = QDBusMessage::createMethodCall(s_fdoPowerService, + s_fdoPowerPath, + s_fdoPowerService, + QStringLiteral("Hibernate")); + QDBusConnection::sessionBus().asyncCall(message); +} + +void PowerManagement::hybridSuspend() +{ + // FIXME: Whether there is a support of this mode? +} + +bool PowerManagement::canSuspend() const +{ + return d->canSuspend; +} + +bool PowerManagement::canHibernate() const +{ + return d->canHibernate; +} + +bool PowerManagement::canHybridSuspend() const +{ + return d->canHybridSuspend; +} + +} // namespace PowerDevil + +#include "powerdevilpowermanagement.moc" diff --git a/daemon/powerdevilpowermanagement.h b/daemon/powerdevilpowermanagement.h new file mode 100644 index 00000000..06f65bf1 --- /dev/null +++ b/daemon/powerdevilpowermanagement.h @@ -0,0 +1,63 @@ +/******************************************************************** +Copyright 2016 Martin Gräßlin + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +*********************************************************************/ + +#ifndef POWERDEVIL_POWERMANAGEMENT_H +#define POWERDEVIL_POWERMANAGEMENT_H + +#include + +namespace PowerDevil { + +class Q_DECL_EXPORT PowerManagement : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool canSuspend READ canSuspend NOTIFY canSuspendChanged) + Q_PROPERTY(bool canHibernate READ canHibernate NOTIFY canHibernateChanged) + Q_PROPERTY(bool canHybridSuspend READ canHybridSuspend NOTIFY canHybridSuspendChanged) +public: + virtual ~PowerManagement(); + + bool canSuspend() const; + bool canHibernate() const; + bool canHybridSuspend() const; + + static PowerManagement *instance(); + +public Q_SLOTS: + void suspend(); + void hibernate(); + void hybridSuspend(); + +Q_SIGNALS: + void canSuspendChanged(); + void canHibernateChanged(); + void canHybridSuspendChanged(); + +protected: + explicit PowerManagement(); + +private: + class Private; + QScopedPointer d; +}; + +} // namespace PowerDevil + +#endif // POWERDEVIL_POWERMANAGEMENT_H diff --git a/kcmodule/activities/CMakeLists.txt b/kcmodule/activities/CMakeLists.txt index 0e3c9792..243184ae 100644 --- a/kcmodule/activities/CMakeLists.txt +++ b/kcmodule/activities/CMakeLists.txt @@ -1,25 +1,23 @@ add_definitions(-DTRANSLATION_DOMAIN=\"powerdevilactivitiesconfig\") set( kcm_powerdevil_activities_SRCS ${PowerDevil_SOURCE_DIR}/daemon/powerdevil_debug.cpp activitypage.cpp activitywidget.cpp ../common/ErrorOverlay.cpp ) ki18n_wrap_ui(kcm_powerdevil_activities_SRCS activityWidget.ui) kconfig_add_kcfg_files(kcm_powerdevil_activities_SRCS ../../PowerDevilSettings.kcfgc) add_library(kcm_powerdevilactivitiesconfig MODULE ${kcm_powerdevil_activities_SRCS}) target_link_libraries(kcm_powerdevilactivitiesconfig - KF5::Solid KF5::Activities - KF5::KDELibs4Support powerdevilconfigcommonprivate ) install(TARGETS kcm_powerdevilactivitiesconfig DESTINATION ${PLUGIN_INSTALL_DIR} ) install( FILES powerdevilactivitiesconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcmodule/activities/activitywidget.cpp b/kcmodule/activities/activitywidget.cpp index cabcf167..64651c9b 100644 --- a/kcmodule/activities/activitywidget.cpp +++ b/kcmodule/activities/activitywidget.cpp @@ -1,204 +1,203 @@ /*************************************************************************** * Copyright (C) 2011 by Dario Freddi * * * * 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; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "activitywidget.h" #include "ui_activityWidget.h" #include "../daemon/actions/bundled/suspendsession.h" +#include "powerdevilpowermanagement.h" + #include #include -#include #include #include #include #include ActivityWidget::ActivityWidget(const QString& activity, QWidget* parent) : QWidget(parent) , m_ui(new Ui::ActivityWidget) , m_profilesConfig(KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig | KConfig::CascadeConfig)) , m_activity(activity) , m_activityConsumer(new KActivities::Consumer(this)) , m_actionEditWidget(new ActionEditWidget(QString("Activities/%1/SeparateSettings").arg(activity))) { m_ui->setupUi(this); m_ui->separateSettingsLayout->addWidget(m_actionEditWidget); for (int i = 0; i < m_ui->specialBehaviorLayout->count(); ++i) { QWidget *widget = m_ui->specialBehaviorLayout->itemAt(i)->widget(); if (widget) { widget->setVisible(false); connect(m_ui->specialBehaviorRadio, SIGNAL(toggled(bool)), widget, SLOT(setVisible(bool))); } else { QLayout *layout = m_ui->specialBehaviorLayout->itemAt(i)->layout(); if (layout) { for (int j = 0; j < layout->count(); ++j) { QWidget *widget = layout->itemAt(j)->widget(); if (widget) { widget->setVisible(false); connect(m_ui->specialBehaviorRadio, SIGNAL(toggled(bool)), widget, SLOT(setVisible(bool))); } } } } } m_actionEditWidget->setVisible(false); m_actionEditWidget->load(); connect(m_ui->separateSettingsRadio, SIGNAL(toggled(bool)), m_actionEditWidget, SLOT(setVisible(bool))); connect(m_ui->actLikeRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); connect(m_ui->noSettingsRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); connect(m_ui->separateSettingsRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); connect(m_ui->specialBehaviorRadio, SIGNAL(toggled(bool)), this, SLOT(setChanged())); connect(m_ui->actLikeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); connect(m_ui->alwaysActionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChanged())); connect(m_ui->alwaysAfterSpin, SIGNAL(valueChanged(int)), this, SLOT(setChanged())); connect(m_actionEditWidget, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); } ActivityWidget::~ActivityWidget() { } void ActivityWidget::load() { KConfigGroup activitiesGroup(m_profilesConfig, "Activities"); KConfigGroup config = activitiesGroup.group(m_activity); using namespace PowerDevil::BundledActions; - QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); - - if (methods.contains(Solid::PowerManagement::SuspendState)) { + if (PowerDevil::PowerManagement::instance()->canSuspend()) { m_ui->alwaysActionBox->addItem(QIcon::fromTheme("system-suspend"), i18n("Suspend"), (uint)SuspendSession::ToRamMode); } - if (methods.contains(Solid::PowerManagement::HibernateState)) { + if (PowerDevil::PowerManagement::instance()->canHibernate()) { m_ui->alwaysActionBox->addItem(QIcon::fromTheme("system-suspend-hibernate"), i18n("Hibernate"), (uint)SuspendSession::ToDiskMode); } m_ui->alwaysActionBox->addItem(QIcon::fromTheme("system-shutdown"), i18n("Shut down"), (uint)SuspendSession::ShutdownMode); m_ui->actLikeComboBox->clear(); m_ui->actLikeComboBox->addItem(QIcon::fromTheme("battery-charging"), i18n("PC running on AC power"), "AC"); m_ui->actLikeComboBox->addItem(QIcon::fromTheme("battery-060"), i18n("PC running on battery power"), "Battery"); m_ui->actLikeComboBox->addItem(QIcon::fromTheme("battery-low"), i18n("PC running on low battery"), "LowBattery"); bool hasBattery = false; Q_FOREACH (const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString())) { const Solid::Battery *b = qobject_cast (device.asDeviceInterface(Solid::DeviceInterface::Battery)); if (b->type() == Solid::Battery::PrimaryBattery || b->type() == Solid::Battery::UpsBattery) { hasBattery = false; break; } } m_ui->actLikeRadio->setVisible(hasBattery); m_ui->actLikeComboBox->setVisible(hasBattery); Q_FOREACH (const QString &activity, m_activityConsumer->activities()) { if (activity == m_activity) { continue; } if (activitiesGroup.group(activity).readEntry("mode", "None") == "None" || activitiesGroup.group(activity).readEntry("mode", "None") == "ActLike") { continue; } KActivities::Info *info = new KActivities::Info(activity, this); QString icon = info->icon(); QString name = i18nc("This is meant to be: Act like activity %1", "Activity \"%1\"", info->name()); m_ui->actLikeComboBox->addItem(QIcon::fromTheme(icon), name, activity); } // Proper loading routine if (config.readEntry("mode", QString()) == "ActLike") { m_ui->actLikeRadio->setChecked(true); m_ui->actLikeComboBox->setCurrentIndex(m_ui->actLikeComboBox->findData(config.readEntry("actLike", QString()))); } else if (config.readEntry("mode", QString()) == "SpecialBehavior") { m_ui->specialBehaviorRadio->setChecked(true); KConfigGroup behaviorGroup = config.group("SpecialBehavior"); m_ui->noShutdownPCBox->setChecked(behaviorGroup.readEntry("noSuspend", false)); m_ui->noShutdownScreenBox->setChecked(behaviorGroup.readEntry("noScreenManagement", false)); m_ui->alwaysBox->setChecked(behaviorGroup.readEntry("performAction", false)); KConfigGroup actionConfig = behaviorGroup.group("ActionConfig"); m_ui->alwaysActionBox->setCurrentIndex(m_ui->alwaysActionBox->findData(actionConfig.readEntry("suspendType", 0))); m_ui->alwaysAfterSpin->setValue(actionConfig.readEntry("idleTime", 600000) / 60 / 1000); } else if (config.readEntry("mode", QString()) == "SeparateSettings") { m_ui->separateSettingsRadio->setChecked(true); m_actionEditWidget->load(); } } void ActivityWidget::save() { KConfigGroup activitiesGroup(m_profilesConfig, "Activities"); KConfigGroup config = activitiesGroup.group(m_activity); if (m_ui->actLikeRadio->isChecked()) { config.writeEntry("mode", "ActLike"); config.writeEntry("actLike", m_ui->actLikeComboBox->itemData(m_ui->actLikeComboBox->currentIndex()).toString()); } else if (m_ui->specialBehaviorRadio->isChecked()) { config.writeEntry("mode", "SpecialBehavior"); KConfigGroup behaviorGroup = config.group("SpecialBehavior"); behaviorGroup.writeEntry("noSuspend", m_ui->noShutdownPCBox->isChecked()); behaviorGroup.writeEntry("noScreenManagement", m_ui->noShutdownScreenBox->isChecked()); behaviorGroup.writeEntry("performAction", m_ui->alwaysBox->isChecked()); KConfigGroup actionConfig = behaviorGroup.group("ActionConfig"); actionConfig.writeEntry("suspendType", m_ui->alwaysActionBox->itemData(m_ui->alwaysActionBox->currentIndex())); actionConfig.writeEntry("idleTime", m_ui->alwaysAfterSpin->value() * 60 * 1000); actionConfig.sync(); behaviorGroup.sync(); } else if (m_ui->separateSettingsRadio->isChecked()) { config.writeEntry("mode", "SeparateSettings"); m_actionEditWidget->save(); } else { config.writeEntry("mode", "None"); } config.sync(); } void ActivityWidget::setChanged() { Q_EMIT changed(true); } #include "activitywidget.moc" diff --git a/kcmodule/global/CMakeLists.txt b/kcmodule/global/CMakeLists.txt index 93246da7..2e9fac31 100644 --- a/kcmodule/global/CMakeLists.txt +++ b/kcmodule/global/CMakeLists.txt @@ -1,24 +1,22 @@ add_definitions(-DTRANSLATION_DOMAIN=\"powerdevilglobalconfig\") set( kcm_powerdevil_global_SRCS GeneralPage.cpp ) ki18n_wrap_ui(kcm_powerdevil_global_SRCS generalPage.ui) kconfig_add_kcfg_files(kcm_powerdevil_global_SRCS ../../PowerDevilSettings.kcfgc) add_library(kcm_powerdevilglobalconfig MODULE ${kcm_powerdevil_global_SRCS}) target_link_libraries(kcm_powerdevilglobalconfig KF5::ConfigWidgets KF5::KIOWidgets - KF5::Solid KF5::NotifyConfig - KF5::KDELibs4Support powerdevilconfigcommonprivate ) install(TARGETS kcm_powerdevilglobalconfig DESTINATION ${PLUGIN_INSTALL_DIR} ) install( FILES powerdevilglobalconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcmodule/global/GeneralPage.cpp b/kcmodule/global/GeneralPage.cpp index 78a6fe20..e429bb06 100644 --- a/kcmodule/global/GeneralPage.cpp +++ b/kcmodule/global/GeneralPage.cpp @@ -1,209 +1,208 @@ /*************************************************************************** * Copyright (C) 2008 by Dario Freddi * * * * 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; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "GeneralPage.h" #include "ErrorOverlay.h" #include "PowerDevilSettings.h" #include "actions/bundled/suspendsession.h" +#include "powerdevilpowermanagement.h" + #include #include #include -#include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY(PowerDevilGeneralKCMFactory, registerPlugin(); ) GeneralPage::GeneralPage(QWidget *parent, const QVariantList &args) : KCModule(0, parent, args) { setButtons(Apply | Help); // KAboutData *about = // new KAboutData("powerdevilglobalconfig", "powerdevilglobalconfig", ki18n("Global Power Management Configuration"), // "", ki18n("A global power management configurator for KDE Power Management System"), // KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), // ki18n("From this module, you can configure the main Power Management daemon, assign profiles to " // "states, and do some advanced fine tuning on battery handling")); // // about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", // "http://drfav.wordpress.com"); // // setAboutData(about); setupUi(this); fillUi(); QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this); connect(watcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onServiceRegistered(QString))); connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onServiceUnregistered(QString))); if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { onServiceRegistered("org.kde.Solid.PowerManagement"); } else { onServiceUnregistered("org.kde.Solid.PowerManagement"); } } GeneralPage::~GeneralPage() { } void GeneralPage::fillUi() { bool hasPowerSupplyBattery = false; bool hasPeripheralBattery = false; Q_FOREACH (const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString())) { const Solid::Battery *b = qobject_cast (device.asDeviceInterface(Solid::DeviceInterface::Battery)); if (b->isPowerSupply()) { hasPowerSupplyBattery = true; } else { hasPeripheralBattery = true; } } - QSet< Solid::PowerManagement::SleepState > methods = Solid::PowerManagement::supportedSleepStates(); - BatteryCriticalCombo->addItem(QIcon::fromTheme("dialog-cancel"), i18n("Do nothing"), PowerDevil::BundledActions::SuspendSession::None); - if (methods.contains(Solid::PowerManagement::SuspendState)) { + if (PowerDevil::PowerManagement::instance()->canSuspend()) { BatteryCriticalCombo->addItem(QIcon::fromTheme("system-suspend"), i18n("Suspend"), PowerDevil::BundledActions::SuspendSession::ToRamMode); } - if (methods.contains(Solid::PowerManagement::HibernateState)) { + if (PowerDevil::PowerManagement::instance()->canHibernate()) { BatteryCriticalCombo->addItem(QIcon::fromTheme("system-suspend-hibernate"), i18n("Hibernate"), PowerDevil::BundledActions::SuspendSession::ToDiskMode); } BatteryCriticalCombo->addItem(QIcon::fromTheme("system-shutdown"), i18n("Shut down"), PowerDevil::BundledActions::SuspendSession::ShutdownMode); notificationsButton->setIcon(QIcon::fromTheme("preferences-desktop-notification")); // modified fields... connect(notificationsButton, SIGNAL(clicked()), SLOT(configureNotifications())); connect(lowSpin, SIGNAL(valueChanged(int)), SLOT(changed())); connect(criticalSpin, SIGNAL(valueChanged(int)), SLOT(changed())); connect(lowPeripheralSpin, SIGNAL(valueChanged(int)), SLOT(changed())); connect(BatteryCriticalCombo, SIGNAL(currentIndexChanged(int)), SLOT(changed())); if (!hasPowerSupplyBattery) { BatteryCriticalLabel->hide(); BatteryCriticalCombo->hide(); lowLabel->hide(); lowSpin->hide(); criticalLabel->hide(); criticalSpin->hide(); } if (!hasPeripheralBattery) { lowPeripheralLabel->hide(); lowPeripheralSpin->hide(); } if (!hasPeripheralBattery && !hasPeripheralBattery) { batteryLevelsLabel->hide(); } } void GeneralPage::load() { lowSpin->setValue(PowerDevilSettings::batteryLowLevel()); criticalSpin->setValue(PowerDevilSettings::batteryCriticalLevel()); lowPeripheralSpin->setValue(PowerDevilSettings::peripheralBatteryLowLevel()); BatteryCriticalCombo->setCurrentIndex(BatteryCriticalCombo->findData(PowerDevilSettings::batteryCriticalAction())); } void GeneralPage::configureNotifications() { KNotifyConfigWidget::configure(this, "powerdevil"); } void GeneralPage::save() { PowerDevilSettings::setBatteryLowLevel(lowSpin->value()); PowerDevilSettings::setBatteryCriticalLevel(criticalSpin->value()); PowerDevilSettings::setPeripheralBatteryLowLevel(lowPeripheralSpin->value()); PowerDevilSettings::setBatteryCriticalAction(BatteryCriticalCombo->itemData(BatteryCriticalCombo->currentIndex()).toInt()); PowerDevilSettings::self()->save(); // Notify Daemon QDBusMessage call = QDBusMessage::createMethodCall("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", "org.kde.Solid.PowerManagement", "refreshStatus"); // Perform call QDBusConnection::sessionBus().asyncCall(call); // And now we are set with no change Q_EMIT changed(false); } void GeneralPage::defaults() { KCModule::defaults(); } void GeneralPage::onServiceRegistered(const QString& service) { Q_UNUSED(service); if (m_errorOverlay) { m_errorOverlay->deleteLater(); m_errorOverlay = nullptr; } } void GeneralPage::onServiceUnregistered(const QString& service) { Q_UNUSED(service); if (m_errorOverlay) { m_errorOverlay->deleteLater(); } m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running.\n" "This can be solved by starting or scheduling it inside \"Startup and Shutdown\""), this); } #include "GeneralPage.moc" diff --git a/kcmodule/profiles/CMakeLists.txt b/kcmodule/profiles/CMakeLists.txt index 7c4b1252..0074a5fb 100644 --- a/kcmodule/profiles/CMakeLists.txt +++ b/kcmodule/profiles/CMakeLists.txt @@ -1,27 +1,25 @@ add_definitions(-DTRANSLATION_DOMAIN=\"powerdevilprofilesconfig\") set( kcm_powerdevil_profiles_SRCS ${PowerDevil_SOURCE_DIR}/daemon/powerdevil_debug.cpp EditPage.cpp ${PowerDevil_SOURCE_DIR}/daemon/powerdevilprofilegenerator.cpp ) ki18n_wrap_ui(kcm_powerdevil_profiles_SRCS profileEditPage.ui) kconfig_add_kcfg_files(kcm_powerdevil_profiles_SRCS ../../PowerDevilSettings.kcfgc) add_library(kcm_powerdevilprofilesconfig MODULE ${kcm_powerdevil_profiles_SRCS}) target_link_libraries(kcm_powerdevilprofilesconfig KF5::KIOWidgets - KF5::Solid KF5::ConfigGui KF5::ConfigWidgets - KF5::KDELibs4Support powerdevilui powerdevilconfigcommonprivate ) install(TARGETS kcm_powerdevilprofilesconfig DESTINATION ${PLUGIN_INSTALL_DIR} ) install( FILES powerdevilprofilesconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) diff --git a/kcmodule/profiles/EditPage.cpp b/kcmodule/profiles/EditPage.cpp index 135365bf..083b13ad 100644 --- a/kcmodule/profiles/EditPage.cpp +++ b/kcmodule/profiles/EditPage.cpp @@ -1,280 +1,278 @@ /*************************************************************************** * Copyright (C) 2008-2010 by Dario Freddi * * * * 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; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ #include "EditPage.h" #include "actioneditwidget.h" #include "ErrorOverlay.h" #include #include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include K_PLUGIN_FACTORY(PowerDevilProfilesKCMFactory, registerPlugin(); ) EditPage::EditPage(QWidget *parent, const QVariantList &args) : KCModule(0, parent, args) { setButtons(Apply | Help | Default); // KAboutData *about = // new KAboutData("powerdevilprofilesconfig", "powerdevilprofilesconfig", ki18n("Power Profiles Configuration"), // "", ki18n("A profile configurator for KDE Power Management System"), // KAboutData::License_GPL, ki18n("(c), 2010 Dario Freddi"), // ki18n("From this module, you can manage KDE Power Management System's power profiles, by tweaking " // "existing ones or creating new ones.")); // // about->addAuthor(ki18n("Dario Freddi"), ki18n("Maintainer") , "drf@kde.org", // "http://drfav.wordpress.com"); // // setAboutData(about); setupUi(this); m_profilesConfig = KSharedConfig::openConfig("powermanagementprofilesrc", KConfig::SimpleConfig | KConfig::CascadeConfig); if (m_profilesConfig->groupList().isEmpty()) { // Use the generator - QSet methods = Solid::PowerManagement::supportedSleepStates(); PowerDevil::ProfileGenerator::generateProfiles( - methods.contains(Solid::PowerManagement::SuspendState), - methods.contains(Solid::PowerManagement::HibernateState) + PowerDevil::PowerManagement::instance()->canSuspend(), + PowerDevil::PowerManagement::instance()->canHibernate() ); m_profilesConfig->reparseConfiguration(); } qCDebug(POWERDEVIL) << m_profilesConfig.data()->groupList() << m_profilesConfig.data()->entryMap().keys(); // Create widgets for each profile ActionEditWidget *editWidget = new ActionEditWidget("AC", tabWidget); m_editWidgets.insert("AC", editWidget); acWidgetLayout->addWidget(editWidget); connect(editWidget, SIGNAL(changed(bool)), this, SLOT(onChanged(bool))); editWidget = new ActionEditWidget("Battery", tabWidget); m_editWidgets.insert("Battery", editWidget); batteryWidgetLayout->addWidget(editWidget); connect(editWidget, SIGNAL(changed(bool)), this, SLOT(onChanged(bool))); editWidget = new ActionEditWidget("LowBattery", tabWidget); m_editWidgets.insert("LowBattery", editWidget); lowBatteryWidgetLayout->addWidget(editWidget); connect(editWidget, SIGNAL(changed(bool)), this, SLOT(onChanged(bool))); QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.Solid.PowerManagement", QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this); connect(watcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onServiceRegistered(QString))); connect(watcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onServiceUnregistered(QString))); bool hasBattery = false; Q_FOREACH(const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::Battery, QString())) { const Solid::Battery *b = qobject_cast (device.asDeviceInterface(Solid::DeviceInterface::Battery)); if (b->isPowerSupply() && (b->type() == Solid::Battery::PrimaryBattery || b->type() == Solid::Battery::UpsBattery)) { hasBattery = true; break; } } if (!hasBattery) { tabWidget->setTabEnabled(1, false); tabWidget->setTabEnabled(2, false); tabWidget->tabBar()->hide(); } if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.Solid.PowerManagement")) { onServiceRegistered("org.kde.Solid.PowerManagement"); } else { onServiceUnregistered("org.kde.Solid.PowerManagement"); } } void EditPage::onChanged(bool value) { ActionEditWidget *editWidget = qobject_cast< ActionEditWidget* >(sender()); if (!editWidget) { return; } m_profileEdited[editWidget->configName()] = value; if (value) { Q_EMIT changed(true); } checkAndEmitChanged(); } void EditPage::load() { qCDebug(POWERDEVIL) << "Loading routine called"; for (QHash< QString, ActionEditWidget* >::const_iterator i = m_editWidgets.constBegin(); i != m_editWidgets.constEnd(); ++i) { i.value()->load(); m_profileEdited[i.value()->configName()] = false; } } void EditPage::save() { for (auto it = m_editWidgets.constBegin(); it != m_editWidgets.constEnd(); ++it) { (*it)->save(); } notifyDaemon(); Q_EMIT changed(false); } void EditPage::notifyDaemon() { QDBusConnection::sessionBus().asyncCall( QDBusMessage::createMethodCall( QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement"), QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("refreshStatus") ) ); } void EditPage::restoreDefaultProfiles() { // Confirm int ret = KMessageBox::warningContinueCancel(this, i18n("The KDE Power Management System will now generate a set of defaults " "based on your computer's capabilities. This will also erase " "all existing modifications you made. " "Are you sure you want to continue?"), i18n("Restore Default Profiles")); if (ret == KMessageBox::Continue) { qCDebug(POWERDEVIL) << "Restoring defaults."; - QSet methods = Solid::PowerManagement::supportedSleepStates(); PowerDevil::ProfileGenerator::generateProfiles( - methods.contains(Solid::PowerManagement::SuspendState), - methods.contains(Solid::PowerManagement::HibernateState) + PowerDevil::PowerManagement::instance()->canSuspend(), + PowerDevil::PowerManagement::instance()->canHibernate() ); load(); notifyDaemon(); } } void EditPage::openUrl(const QString &url) { new KRun(QUrl(url), this); } void EditPage::defaults() { restoreDefaultProfiles(); } void EditPage::checkAndEmitChanged() { bool value = false; for (QHash< QString, bool >::const_iterator i = m_profileEdited.constBegin(); i != m_profileEdited.constEnd(); ++i) { if (i.value()) { value = i.value(); } } Q_EMIT changed(value); } void EditPage::onServiceRegistered(const QString& service) { Q_UNUSED(service); QDBusPendingCallWatcher *currentProfileWatcher = new QDBusPendingCallWatcher(QDBusConnection::sessionBus().asyncCall( QDBusMessage::createMethodCall( QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("/org/kde/Solid/PowerManagement"), QStringLiteral("org.kde.Solid.PowerManagement"), QStringLiteral("currentProfile") ) ), this); QObject::connect(currentProfileWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; if (!reply.isError()) { const QString ¤tProfile = reply.value(); if (currentProfile == QLatin1String("Battery")) { tabWidget->setCurrentIndex(1); } else if (currentProfile == QLatin1String("LowBattery")) { tabWidget->setCurrentIndex(2); } } watcher->deleteLater(); }); if (m_errorOverlay) { m_errorOverlay->deleteLater(); m_errorOverlay = nullptr; } } void EditPage::onServiceUnregistered(const QString& service) { Q_UNUSED(service); if (m_errorOverlay) { m_errorOverlay->deleteLater(); } m_errorOverlay = new ErrorOverlay(this, i18n("The Power Management Service appears not to be running.\n" "This can be solved by starting or scheduling it inside \"Startup and Shutdown\""), this); } #include "EditPage.moc"