From e972ff07d575958a22b952bcc957e5bac1863965 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 24 Apr 2016 19:34:38 +1000 Subject: ksmserver: Added support for hybrid suspend (aka suspend to RAM + suspend to disk). This relates to bug 2601. Signed-off-by: Michele Calgaro --- ksmserver/shutdown.cpp | 23 +++++++----- ksmserver/shutdowndlg.cpp | 90 +++++++++++++++++++++++++++++++++++++---------- ksmserver/shutdowndlg.h | 13 ++++++- 3 files changed, 98 insertions(+), 28 deletions(-) (limited to 'ksmserver') diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp index a40bffc3b..753703289 100644 --- a/ksmserver/shutdown.cpp +++ b/ksmserver/shutdown.cpp @@ -229,7 +229,7 @@ void KSMServer::shutdownInternal( TDEApplication::ShutdownConfirm confirm, // TODO: turn the feedback widget into a list of apps to be closed, // with an indicator of the current status for each. KSMShutdownFeedback::stop(); // make the screen become normal again - if (selection != 0) { + if (selection != SuspendType::NotSpecified) { // respect lock on resume & disable suspend/hibernate settings // from power-manager TDEConfig config("power-managerrc"); @@ -244,14 +244,19 @@ void KSMServer::shutdownInternal( TDEApplication::ShutdownConfirm confirm, #ifdef __TDE_HAVE_TDEHWLIB TDERootSystemDevice* rootDevice = hwDevices->rootSystemDevice(); if (rootDevice) { - if (selection == 1) { // Suspend - rootDevice->setPowerState(TDESystemPowerState::Suspend); - } - if (selection == 2) { // Hibernate - rootDevice->setPowerState(TDESystemPowerState::Hibernate); - } - if (selection == 3) { // Freeze - rootDevice->setPowerState(TDESystemPowerState::Freeze); + switch (selection) { + case SuspendType::Freeze: + rootDevice->setPowerState(TDESystemPowerState::Freeze); + break; + case SuspendType::Suspend: + rootDevice->setPowerState(TDESystemPowerState::Suspend); + break; + case SuspendType::Hibernate: + rootDevice->setPowerState(TDESystemPowerState::Hibernate); + break; + case SuspendType::HybridSuspend: + rootDevice->setPowerState(TDESystemPowerState::HybridSuspend); + break; } } #endif diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp index 6ff1d6cf2..7106aa6fb 100644 --- a/ksmserver/shutdowndlg.cpp +++ b/ksmserver/shutdowndlg.cpp @@ -707,7 +707,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, TQVBoxLayout* vbox = new TQVBoxLayout( this ); if (m_selection) { - *m_selection = 0; + *m_selection = SuspendType::NotSpecified; } TQFrame* frame = new TQFrame( this ); @@ -766,7 +766,6 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, } else { - // konqy lfrm = new TQFrame( frame ); lfrm->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); @@ -810,6 +809,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, bool canFreeze = false; bool canSuspend = false; bool canHibernate = false; + bool canHybridSuspend = false; #if defined(COMPILE_HALBACKEND) // Query HAL for suspend/resume support @@ -865,6 +865,14 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, { canHibernate = true; } + + if (libhal_device_get_property_bool(m_halCtx, + "/org/freedesktop/Hal/devices/computer", + "power_management.can_suspend_hybrid", + NULL)) + { + canHybridSuspend = true; + } } #elif defined(__TDE_HAVE_TDEHWLIB) // COMPILE_HALBACKEND TDERootSystemDevice* rootDevice = TDEGlobal::hardwareDevices()->rootSystemDevice(); @@ -872,11 +880,13 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, canFreeze = rootDevice->canFreeze(); canSuspend = rootDevice->canSuspend(); canHibernate = rootDevice->canHibernate(); + canHybridSuspend = rootDevice->canHybridSuspend(); } else { canFreeze = false; canSuspend = false; canHibernate = false; + canHybridSuspend = false; } #endif // COMPILE_HALBACKEND @@ -890,7 +900,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, btnFreeze->setPixmap( DesktopIcon( "suspend") ); int i = btnFreeze->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 btnFreeze->setAccel( "ALT+" + btnFreeze->textLabel().lower()[i+1] ) ; - hbuttonbox->addWidget ( btnFreeze); + hbuttonbox->addWidget ( btnFreeze ); connect(btnFreeze, TQT_SIGNAL(clicked()), TQT_SLOT(slotFreeze())); } @@ -902,7 +912,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, btnSuspend->setPixmap( DesktopIcon( "suspend") ); int i = btnSuspend->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 btnSuspend->setAccel( "ALT+" + btnSuspend->textLabel().lower()[i+1] ) ; - hbuttonbox->addWidget ( btnSuspend); + hbuttonbox->addWidget ( btnSuspend ); connect(btnSuspend, TQT_SIGNAL(clicked()), TQT_SLOT(slotSuspend())); } @@ -914,10 +924,22 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, btnHibernate->setPixmap( DesktopIcon( "hibernate") ); int i = btnHibernate->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 btnHibernate->setAccel( "ALT+" + btnHibernate->textLabel().lower()[i+1] ) ; - hbuttonbox->addWidget ( btnHibernate); + hbuttonbox->addWidget ( btnHibernate ); connect(btnHibernate, TQT_SIGNAL(clicked()), TQT_SLOT(slotHibernate())); } + if (canHybridSuspend && !disableSuspend && !disableHibernate) + { + // Hybrid suspend + FlatButton* btnHybridSuspend = new FlatButton( frame ); + btnHybridSuspend->setTextLabel( i18n("H&ybrid Suspend"), false ); + btnHybridSuspend->setPixmap( DesktopIcon( "hibernate") ); + int i = btnHybridSuspend->textLabel().find( TQRegExp("\\&"), 0 ); // i == 1 + btnHybridSuspend->setAccel( "ALT+" + btnHybridSuspend->textLabel().lower()[i+1] ) ; + hbuttonbox->addWidget ( btnHybridSuspend ); + connect(btnHybridSuspend, TQT_SIGNAL(clicked()), TQT_SLOT(slotHybridSuspend())); + } + // Separator (within buttonlay) vbox->addWidget( new KSeparator( frame ) ); @@ -1043,7 +1065,9 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, if (canFreeze && !disableSuspend) { KPushButton* btnFreeze = new KPushButton( KGuiItem( i18n("&Freeze Computer"), "suspend"), frame ); - TQToolTip::add(btnFreeze, i18n("

Freeze Computer

Put the computer in software sleep mode, allowing for some powersaving. The system can be reactivated in a really short time, almost instantly.

")); + TQToolTip::add(btnFreeze, i18n("

Freeze Computer

Put the computer in software sleep mode," + " allowing for some powersaving. The system can be reactivated in a really short time, almost" + " instantly.

")); btnFreeze->setFont( btnFont ); buttonlay->addWidget( btnFreeze ); connect(btnFreeze, TQT_SIGNAL(clicked()), TQT_SLOT(slotFreeze())); @@ -1052,7 +1076,9 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, if (canSuspend && !disableSuspend) { KPushButton* btnSuspend = new KPushButton( KGuiItem( i18n("&Suspend Computer"), "suspend"), frame ); - TQToolTip::add(btnSuspend, i18n("

Suspend Computer

Put the computer in a suspend-to-memory mode. The system is stopped and its state saved to memory.

This allows more powersaving than 'Freeze Computer' but requires longer time to reactivate the system.

")); + TQToolTip::add(btnSuspend, i18n("

Suspend Computer

Put the computer in a suspend-to-memory mode." + " The system is stopped and its state saved to memory.

This allows more powersaving than 'Freeze" + " Computer' but requires longer time to reactivate the system.

")); btnSuspend->setFont( btnFont ); buttonlay->addWidget( btnSuspend ); connect(btnSuspend, TQT_SIGNAL(clicked()), TQT_SLOT(slotSuspend())); @@ -1061,12 +1087,25 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, if (canHibernate && !disableHibernate) { KPushButton* btnHibernate = new KPushButton( KGuiItem( i18n("&Hibernate Computer"), "hibernate"), frame ); - TQToolTip::add(btnHibernate, i18n("

Hibernate Computer

Put the computer in a suspend-to-disk mode. The system is stopped and its state saved to disk.

This offers the greatest powersaving but considerable time is required to reactivate the system again.

")); + TQToolTip::add(btnHibernate, i18n("

Hibernate Computer

Put the computer in a suspend-to-disk" + " mode. The system is stopped and its state saved to disk.

This offers the greatest powersaving but" + " considerable time is required to reactivate the system again.

")); btnHibernate->setFont( btnFont ); buttonlay->addWidget( btnHibernate ); connect(btnHibernate, TQT_SIGNAL(clicked()), TQT_SLOT(slotHibernate())); } + if (canHybridSuspend && !disableSuspend && !disableHibernate) + { + KPushButton* btnHybridSuspend = new KPushButton( KGuiItem( i18n("&Hybrid Suspend"), "hibernate"), frame ); + TQToolTip::add(btnHybridSuspend, i18n("

Hybrid Suspend

Put the computer in both suspend-to-memory" " and suspend-to-disk mode. The system is stopped and its state saved to memory and to disk.

This offers" " the best of both 'Suspend' and 'Hibernate' combined together. The system is de facto in 'Suspend' mode but if" + " power is lost, work can still be resumed as if the system had been hibernated, preventing any data" + " loss.

")); + btnHybridSuspend->setFont( btnFont ); + buttonlay->addWidget( btnHybridSuspend ); + connect(btnHybridSuspend, TQT_SIGNAL(clicked()), TQT_SLOT(slotHybridSuspend())); + } + buttonlay->addStretch( 1 ); // Separator @@ -1076,9 +1115,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, KPushButton* btnBack = new KPushButton( KStdGuiItem::cancel(), frame ); buttonlay->addWidget( btnBack ); connect(btnBack, TQT_SIGNAL(clicked()), TQT_SLOT(reject())); - } - } else { // finish the dialog correctly @@ -1105,11 +1142,7 @@ KSMShutdownDlg::KSMShutdownDlg( TQWidget* parent, connect(btnBack, TQT_SIGNAL(clicked()), TQT_SLOT(reject())); } - - } - - } @@ -1161,7 +1194,7 @@ void KSMShutdownDlg::slotHalt() void KSMShutdownDlg::slotSuspend() { #ifndef COMPILE_HALBACKEND - *m_selection = 1; // Suspend + *m_selection = SuspendType::Suspend; #else if (m_dbusConn) { @@ -1185,7 +1218,7 @@ void KSMShutdownDlg::slotSuspend() void KSMShutdownDlg::slotHibernate() { #ifndef COMPILE_HALBACKEND - *m_selection = 2; // Hibernate + *m_selection = SuspendType::Hibernate; #else if (m_dbusConn) { @@ -1205,8 +1238,29 @@ void KSMShutdownDlg::slotHibernate() void KSMShutdownDlg::slotFreeze() { - *m_selection = 3; // Freeze - reject(); + *m_selection = SuspendType::Freeze; + reject(); // continue on resume +} + +void KSMShutdownDlg::slotHybridSuspend() +{ +#ifndef COMPILE_HALBACKEND + *m_selection = SuspendType::HybridSuspend; +#else + if (m_dbusConn) + { + DBusMessage *msg = dbus_message_new_method_call( + "org.freedesktop.Hal", + "/org/freedesktop/Hal/devices/computer", + "org.freedesktop.Hal.Device.SystemPowerManagement", + "SuspendHybrid"); + + dbus_connection_send(m_dbusConn, msg, NULL); + + dbus_message_unref(msg); + } +#endif + reject(); // continue on resume } bool KSMShutdownDlg::confirmShutdown( bool maysd, bool mayrb, TDEApplication::ShutdownType& sdtype, TQString& bootOption, int* selection ) diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h index a3864e616..25ee60f77 100644 --- a/ksmserver/shutdowndlg.h +++ b/ksmserver/shutdowndlg.h @@ -44,6 +44,17 @@ class TDEAction; #include #endif // COMPILE_HALBACKEND +namespace SuspendType { +enum SuspendType { + NotSpecified = 0, + Freeze, + Standby, + Suspend, + Hibernate, + HybridSuspend +}; +}; + // The (singleton) widget that makes/fades the desktop gray. class KSMShutdownFeedback : public TQWidget { @@ -76,7 +87,6 @@ private: int m_rowsDone; KPixmapIO m_pmio; bool m_greyImageCreated; - }; // The (singleton) widget that shows either pretty pictures or a black screen during logout @@ -138,6 +148,7 @@ public slots: void slotSuspend(); void slotHibernate(); void slotFreeze(); + void slotHybridSuspend(); protected: ~KSMShutdownDlg(); -- cgit v1.2.3