summaryrefslogtreecommitdiffstats
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
parent1eb5bc816598318458e3a6459663af103a46094b (diff)
downloadtdebase-08390bda6cc11917a625253a98e48da9b0aac8e6.tar.gz
tdebase-08390bda6cc11917a625253a98e48da9b0aac8e6.zip
Allow the user to manually abort a stalled SaveYourself process
This partially resolves Bug 760
-rw-r--r--ksmserver/server.cpp1
-rw-r--r--ksmserver/server.h7
-rw-r--r--ksmserver/shutdown.cpp80
-rw-r--r--ksmserver/shutdowndlg.cpp25
-rw-r--r--ksmserver/shutdowndlg.h7
5 files changed, 114 insertions, 6 deletions
diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp
index 6e3ed44a3..3adcbbade 100644
--- a/ksmserver/server.cpp
+++ b/ksmserver/server.cpp
@@ -681,6 +681,7 @@ KSMServer::KSMServer( const TQString& windowManager, const TQString& windowManag
signal(SIGINT, sighandler);
signal(SIGPIPE, SIG_IGN);
+ connect( &notificationTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( notificationTimeout() ) );
connect( &protectionTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( protectionTimeout() ) );
connect( &restoreTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( tryRestoreNext() ) );
connect( &shutdownTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( timeoutQuit() ) );
diff --git a/ksmserver/server.h b/ksmserver/server.h
index f850c747c..5dd97ba7c 100644
--- a/ksmserver/server.h
+++ b/ksmserver/server.h
@@ -109,6 +109,7 @@ private slots:
void restoreSessionInternal();
void restoreSessionDoneInternal();
+ void notificationTimeout();
void protectionTimeout();
void timeoutQuit();
void timeoutWMQuit();
@@ -123,6 +124,9 @@ private slots:
void tryRestoreNext();
void startupSuspendTimeout();
+ void cancelShutdown();
+ void forceSkipSaveYourself();
+
private:
void handlePendingInteractions();
void completeShutdownOrCheckpoint();
@@ -131,6 +135,7 @@ private:
void completeKilling();
void killWM();
void completeKillingWM();
+ void cancelShutdown( TQString cancellationText );
void cancelShutdown( KSMClient* c );
void killingCompleted();
@@ -139,6 +144,7 @@ private:
void startProtection();
void endProtection();
+ void handleProtectionTimeout();
void startApplication( TQStringList command,
const TQString& clientMachine = TQString::null,
@@ -214,6 +220,7 @@ private:
TQString sessionName;
TQCString launcher;
TQTimer protectionTimer;
+ TQTimer notificationTimer;
TQTimer restoreTimer;
TQTimer shutdownTimer;
TQString xonCommand;
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("..."));
diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp
index b30e6ec2e..6526bc4b8 100644
--- a/ksmserver/shutdowndlg.cpp
+++ b/ksmserver/shutdowndlg.cpp
@@ -1201,14 +1201,39 @@ TQWidget* KSMShutdownIPDlg::showShutdownIP()
return l;
}
+void KSMShutdownIPDlg::showNotificationActionButtons()
+{
+ m_button1->show();
+ m_button2->show();
+ m_buttonframe->show();
+
+ m_gridlayout->invalidate();
+}
+
+void KSMShutdownIPDlg::hideNotificationActionButtons()
+{
+ m_button1->hide();
+ m_button2->hide();
+ m_buttonframe->hide();
+
+ m_gridlayout->invalidate();
+}
+
KSMShutdownIPDlg::KSMShutdownIPDlg(TQWidget* parent)
: KSMModalDialog( parent )
{
setStatusMessage(i18n("Saving your settings..."));
+ m_button1->setText(i18n("Skip Notification"));
+ m_button2->setText(i18n("Abort Logout"));
+ connect(m_button1, SIGNAL(clicked()), this, SIGNAL(skipNotificationClicked()));
+ connect(m_button2, SIGNAL(clicked()), this, SIGNAL(abortLogoutClicked()));
+
show();
setActiveWindow();
+
+// KWin::setOnAllDesktops( winId(), true );
}
KSMShutdownIPDlg::~KSMShutdownIPDlg()
diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h
index 3ce851244..5ab9d7c3e 100644
--- a/ksmserver/shutdowndlg.h
+++ b/ksmserver/shutdowndlg.h
@@ -171,6 +171,13 @@ class KSMShutdownIPDlg : public KSMModalDialog
public:
static TQWidget* showShutdownIP();
+ void showNotificationActionButtons();
+ void hideNotificationActionButtons();
+
+signals:
+ void abortLogoutClicked();
+ void skipNotificationClicked();
+
protected:
~KSMShutdownIPDlg();