summaryrefslogtreecommitdiffstats
path: root/ksmserver/shutdown.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <[email protected]>2013-07-21 18:02:15 -0500
committerTimothy Pearson <[email protected]>2013-07-21 18:02:15 -0500
commit08390bda6cc11917a625253a98e48da9b0aac8e6 (patch)
tree1eb1a63da7a0b43619576ff850c2331552f01461 /ksmserver/shutdown.cpp
parent1eb5bc816598318458e3a6459663af103a46094b (diff)
downloadtdebase-08390bda6cc11917a625253a98e48da9b0aac8e6.tar.gz
tdebase-08390bda6cc11917a625253a98e48da9b0aac8e6.zip
Allow the user to manually abort a stalled SaveYourself process
This partially resolves Bug 760
Diffstat (limited to 'ksmserver/shutdown.cpp')
-rw-r--r--ksmserver/shutdown.cpp80
1 files changed, 74 insertions, 6 deletions
diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp
index 5809cd295..41556dcf2 100644
--- a/ksmserver/shutdown.cpp
+++ b/ksmserver/shutdown.cpp
@@ -102,6 +102,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// If set too high running applications may be ungracefully terminated on slow machines
#define KSMSERVER_SHUTDOWN_CLIENT_UNRESPONSIVE_TIMEOUT 60000
+// Time to wait before showing manual termination options
+// If set too low the user may be confused by buttons briefly flashing up on the screen during an otherwise normal logout process
+#define KSMSERVER_NOTIFICATION_MANUAL_OPTIONS_TIMEOUT 1000
+
void KSMServer::logout( int confirm, int sdtype, int sdmode )
{
shutdown( (TDEApplication::ShutdownConfirm)confirm,
@@ -253,6 +257,11 @@ void KSMServer::shutdownInternal( TDEApplication::ShutdownConfirm confirm,
shutdownMode = sdmode;
bootOption = bopt;
shutdownNotifierIPDlg = 0;
+ shutdownNotifierIPDlg = KSMShutdownIPDlg::showShutdownIP();
+ if (shutdownNotifierIPDlg) {
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->setStatusMessage(i18n("Notifying applications of logout request..."));
+ notificationTimer.start( KSMSERVER_NOTIFICATION_MANUAL_OPTIONS_TIMEOUT, true );
+ }
// shall we save the session on logout?
saveSession = ( config->readEntry( "loginMode", "restorePreviousLogout" ) == "restorePreviousLogout" );
@@ -489,11 +498,13 @@ void KSMServer::handlePendingInteractions()
}
}
-
-void KSMServer::cancelShutdown( KSMClient* c )
+void KSMServer::cancelShutdown( TQString cancellationText )
{
- kdDebug( 1218 ) << "Client " << c->program() << " (" << c->clientId() << ") canceled shutdown." << endl;
- KNotifyClient::event( 0, "cancellogout", i18n( "Logout canceled by '%1'" ).arg( c->program()));
+ if (shutdownNotifierIPDlg) {
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->closeSMDialog();
+ shutdownNotifierIPDlg=0;
+ }
+ KNotifyClient::event( 0, "cancellogout", cancellationText);
clientInteracting = 0;
for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
SmsShutdownCancelled( c->connection() );
@@ -507,6 +518,18 @@ void KSMServer::cancelShutdown( KSMClient* c )
state = Idle;
}
+void KSMServer::cancelShutdown( KSMClient* c )
+{
+ kdDebug( 1218 ) << "Client " << c->program() << " (" << c->clientId() << ") canceled shutdown." << endl;
+ cancelShutdown(i18n( "Logout canceled by '%1'" ).arg( c->program()));
+}
+
+void KSMServer::cancelShutdown()
+{
+ kdDebug( 1218 ) << "User canceled shutdown." << endl;
+ cancelShutdown(i18n( "Logout canceled by user" ));
+}
+
void KSMServer::startProtection()
{
protectionTimer.start( KSMSERVER_SHUTDOWN_CLIENT_UNRESPONSIVE_TIMEOUT, true );
@@ -526,6 +549,30 @@ void KSMServer::protectionTimeout()
if ( ( state != Shutdown && state != Checkpoint ) || clientInteracting )
return;
+ handleProtectionTimeout();
+
+ startProtection();
+}
+
+void KSMServer::forceSkipSaveYourself()
+{
+ SHUTDOWN_MARKER("forceSkipSaveYourself");
+
+ handleProtectionTimeout();
+
+ startProtection();
+}
+
+void KSMServer::handleProtectionTimeout()
+{
+ SHUTDOWN_MARKER("handleProtectionTimeout");
+
+ notificationTimer.stop();
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->hideNotificationActionButtons();
+ disconnect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown()));
+ disconnect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself()));
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->setStatusMessage(i18n("Forcing interacting application termination").append("..."));
+
for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
if ( !c->saveYourselfDone && !c->waitForPhase2 ) {
kdDebug( 1218 ) << "protectionTimeout: client " << c->program() << "(" << c->clientId() << ")" << endl;
@@ -533,18 +580,27 @@ void KSMServer::protectionTimeout()
}
}
completeShutdownOrCheckpoint();
- startProtection();
+}
+
+void KSMServer::notificationTimeout()
+{
+ // Display the buttons in the logout dialog
+ connect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown()));
+ connect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself()));
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->showNotificationActionButtons();
}
void KSMServer::completeShutdownOrCheckpoint()
{
SHUTDOWN_MARKER("completeShutdownOrCheckpoint");
if ( state != Shutdown && state != Checkpoint ) {
+ SHUTDOWN_MARKER("completeShutdownOrCheckpoint state not Shutdown or Checkpoint");
return;
}
for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
if ( !c->saveYourselfDone && !c->waitForPhase2 ) {
+ SHUTDOWN_MARKER("completeShutdownOrCheckpoint state not done yet");
return; // not done yet
}
}
@@ -559,6 +615,11 @@ void KSMServer::completeShutdownOrCheckpoint()
}
}
if ( waitForPhase2 ) {
+ SHUTDOWN_MARKER("completeShutdownOrCheckpoint state still waiting for Phase 2");
+ if (shutdownNotifierIPDlg) {
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->setStatusMessage(i18n("Notifying remaining applications of logout request..."));
+ notificationTimer.start( KSMSERVER_NOTIFICATION_MANUAL_OPTIONS_TIMEOUT, true );
+ }
return;
}
SHUTDOWN_MARKER("Phase 2 complete");
@@ -566,12 +627,19 @@ void KSMServer::completeShutdownOrCheckpoint()
bool showLogoutStatusDlg = TDEConfigGroup(TDEGlobal::config(), "Logout").readBoolEntry("showLogoutStatusDlg", true);
if (showLogoutStatusDlg && state != Checkpoint) {
KSMShutdownIPFeedback::showit(); // hide the UGLY logout process from the user
- shutdownNotifierIPDlg = KSMShutdownIPDlg::showShutdownIP();
+ if (!shutdownNotifierIPDlg) {
+ shutdownNotifierIPDlg = KSMShutdownIPDlg::showShutdownIP();
+ }
while (!KSMShutdownIPFeedback::ispainted()) {
tqApp->processEvents();
}
}
+ notificationTimer.stop();
+ static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->hideNotificationActionButtons();
+ disconnect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown()));
+ disconnect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself()));
+
// synchronize any folders that were requested for shutdown sync
if (shutdownNotifierIPDlg) {
static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->setStatusMessage(i18n("Synchronizing remote folders").append("..."));