[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    [PATCH] - Multiple session support for ksmserver
From:       Ravikiran Rajagopal <ravi () ee ! eng ! ohio-state ! edu>
Date:       2002-02-01 14:49:56
[Download RAW message or body]

Hello all,
  The following patch implements multiple session support for KSMServer. 
Please test and let me know if it does not work for you. Every user is 
allowed to have 100 stored sessions; it can be trivially extended to the 
maximum value supported by uint.

Please note that it modifies the public API of KSMServer by adding a default 
argument to KSMServer::restoreSession. However, it does not seem as if any 
other apps use this function; even if they do, the default value of the 
argument should take care of any problems. Further, string naming of sessions 
is simple (but tedious) to add. The 0-th session is called "Session" rather 
than "Session0" to maintain compatibility with KDE 2.x.

It adds 3 new i18n() strings; so it may be preferable to add it after the 
freeze is over, or perhaps for 3.1. If anyone is interested (though I suspect 
not), I can write a KControl module for a session editor.

I have two questions for the current maintainer of KSMServer:
1. What does the config value discardCommand do?
2. Do we allow restoring apps not restored by the window manager?

Ravi

NB: The patch is essentially trivial. My biggest concern is whether I have 
done stuff in KSMServer::restoreSession() in the right order.

["patch" (text/x-diff)]

--- kdebase/ksmserver/main.cpp	Thu Jan 24 10:59:07 2002
+++ kdebase/ksmserver/main.cpp	Fri Feb  1 09:18:51 2002
@@ -33,6 +33,8 @@
 {
    { "r", 0, 0 },
    { "restore", I18N_NOOP("Restores the previous session if available"), 0},
+   { "s", 0, 0 },
+   { "session", I18N_NOOP("Session number to activate"), "0"},
    { "w", 0, 0 },
    { "windowmanager <wm>", I18N_NOOP("Starts 'wm' in case no other window manager is \
\nparticipating in the session. Default is 'kwin'"), 0},  { "nolocal", \
I18N_NOOP("Also allow remote connections."), 0}, @@ -206,13 +208,18 @@
 
     KConfig *config = KGlobal::config();
     config->setGroup( "General" );
+    
+    // Which session do we want to restore?
+    uint sess = config->readUnsignedNumEntry( "DefaultSession", 0 );
+    if ( args->isSet("session") )
+      sess = (args->getOption("session")).toUInt(); // Perhaps we need check for \
invalid value ...  
     int realScreenCount = ScreenCount( qt_xdisplay() );
     bool screenCountChanged =
          ( config->readNumEntry( "screenCount", realScreenCount ) != realScreenCount \
);  
     if ( args->isSet("restore") && ! screenCountChanged )
-	server->restoreSession();
+	server->restoreSession( sess );
     else
 	server->startDefaultSession();
 
--- kdebase/ksmserver/shutdown.h	Fri Jan  4 17:44:59 2002
+++ kdebase/ksmserver/shutdown.h	Thu Jan 31 19:28:37 2002
@@ -12,6 +12,7 @@
 class QCheckBox;
 class QRadioButton;
 class QVButtonGroup;
+class QSpinBox;
 
 #include <kapplication.h>
 
@@ -51,7 +52,7 @@
     KSMShutdownDlg( QWidget* parent, bool saveSession, bool maysd, bool maynuke, \
KApplication::ShutdownType sdtype, KApplication::ShutdownMode sdmode );  \
~KSMShutdownDlg() {}  
-    static bool confirmShutdown( bool& saveSession, bool maysd, bool maynuke, \
KApplication::ShutdownType& sdtype, KApplication::ShutdownMode& sdmode ); +    static \
bool confirmShutdown( bool& saveSession, bool maysd, bool maynuke, \
KApplication::ShutdownType& sdtype, KApplication::ShutdownMode& sdmode, bool& \
saveDefault, uint &sess, uint &def );  
     const QPixmap & pixmap() { return pm; }
 
@@ -64,7 +65,8 @@
 private:
     virtual void mousePressEvent( QMouseEvent * ){}
     virtual void showEvent( QShowEvent * e );
-    QCheckBox* checkbox;
+    QCheckBox *checkbox, *defaultbox;
+    QSpinBox *savespin, *defaultspin;
     QRadioButton *rLogout, *rHalt, *rReboot, *rSched, *rTry, *rForce;
     QVButtonGroup *mgrp;
     QPixmap pm;
--- kdebase/ksmserver/shutdown.cpp	Fri Jan  4 17:44:59 2002
+++ kdebase/ksmserver/shutdown.cpp	Thu Jan 31 19:59:21 2002
@@ -20,6 +20,7 @@
 #include <qtimer.h>
 #include <qstyle.h>
 #include <qcursor.h>
+#include <qspinbox.h>
 
 #include <klocale.h>
 #include <kapplication.h>
@@ -107,8 +108,18 @@
     else
         vbox->addStretch();
 
-    checkbox = new QCheckBox( i18n("&Save session for future logins"), frame );
-    vbox->addWidget( checkbox, 0, AlignLeft  );
+    QHBoxLayout* firstbox = new QHBoxLayout( vbox );
+    checkbox = new QCheckBox( i18n("&Save session for future logins as session :"), \
frame ); +    firstbox->addWidget( checkbox, 0, AlignLeft  );
+    savespin = new QSpinBox( 0, 99, 1, frame );
+    firstbox->addWidget( savespin, 0, AlignRight  );
+    firstbox->addStretch();
+    QHBoxLayout* secondbox = new QHBoxLayout( vbox );    
+    defaultbox = new QCheckBox( i18n("S&et default session for future logins :"), \
frame ); +    secondbox->addWidget( defaultbox, 2, AlignLeft  );
+    defaultspin = new QSpinBox( 0, 99, 1, frame );
+    secondbox->addWidget( defaultspin, 0, AlignRight  );
+    secondbox->addStretch();
     vbox->addStretch();
 
     QHBoxLayout* hbox = new QHBoxLayout( vbox );
@@ -126,6 +137,7 @@
     QTimer::singleShot( 0, this, SLOT( requestFocus() ) );
     checkbox->setFocus();
 
+    defaultbox->setChecked( FALSE );
     checkbox->setChecked( saveSession );
     if (maysd)
     {
@@ -158,7 +170,8 @@
 
 bool KSMShutdownDlg::confirmShutdown( bool& saveSession, 
   bool maysd, bool maynuke,
-  KApplication::ShutdownType& sdtype, KApplication::ShutdownMode& sdmode )
+  KApplication::ShutdownType& sdtype, KApplication::ShutdownMode& sdmode,
+  bool &saveDefault, uint& sess, uint& def )
 {
     kapp->enableStyles();
     KSMShutdownDlg* l = new KSMShutdownDlg( KSMShutdownFeedback::self(), 
@@ -191,6 +204,11 @@
                                           KApplication::ShutdownModeForceNow;
     }
     saveSession = l->checkbox->isChecked();
+    if ( saveSession )
+      sess = l->savespin->value();
+    saveDefault = l->defaultbox->isChecked();
+    if ( saveDefault )
+      def = l->defaultspin->value();
 
     delete l;
 
--- kdebase/ksmserver/server.cpp	Sat Jan 26 15:13:30 2002
+++ kdebase/ksmserver/server.cpp	Thu Jan 31 20:41:13 2002
@@ -55,6 +55,7 @@
 #include <vfork.h>
 #endif
 
+#include <qstring.h>
 #include <qfile.h>
 #include <qtextstream.h>
 #include <qdatastream.h>
@@ -1048,13 +1049,15 @@
     if (!maynuke && sdmode == KApplication::ShutdownModeForceNow)
 	sdmode = KApplication::ShutdownModeSchedule;
 
+    unsigned int sess, def;
+    bool saveDefault;
     if ( !logoutConfirmed ) {
 	KSMShutdownFeedback::start(); // make the screen gray
 	connect( KSMShutdownFeedback::self(), SIGNAL( aborted() ),
 		 SLOT( cancelShutdown() ) );
 	logoutConfirmed =
 	    KSMShutdownDlg::confirmShutdown( saveSession,
-					     maysd, maynuke, sdtype, sdmode );
+					     maysd, maynuke, sdtype, sdmode, saveDefault, sess, def );
 	// ###### We can't make the screen remain gray while talking to the apps,
 	// because this prevents interaction ("do you want to save", etc.)
 	// TODO: turn the feedback widget into a list of apps to be closed,
@@ -1062,6 +1065,9 @@
 	KSMShutdownFeedback::stop(); // make the screen become normal again
     }
 
+    // HACK : to get around modifying completeShutdown()
+    sessionToSave = sess;
+
     if ( logoutConfirmed ) {
 	// Set the real desktop background to black so that exit looks
 	// clean regardless of what was on "our" desktop.
@@ -1076,8 +1082,13 @@
 	    config->writeEntry( "shutdownMode", (int)sdmode);
 	}
 	if ( saveSession )
-	    discardStoredSession();
-	state = Shutdown;
+	    discardStoredSession( sess );
+        if ( saveDefault ) {
+	    KConfig* config = KGlobal::config();
+	    config->setGroup("General" );
+            config->writeEntry( "DefaultSession", (uint)def );
+        }		    
+        state = Shutdown;
 	startProtection();
 	for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
 	    c->resetState();
@@ -1236,7 +1247,7 @@
 	return;
 
     if ( saveSession )
-	storeSession();
+	storeSession( sessionToSave );
     else
 	discardSession();
 
@@ -1284,16 +1295,19 @@
     qApp->quit();
 }
 
-void KSMServer::discardStoredSession()
+// Ravi: adding support for multiple sessions
+void KSMServer::discardStoredSession( uint sess )
 {
+    QString sessName = (sess==0) ? (QString::QString("Session")) :
+           (QString::QString("Session%1").arg(QString::number(sess)));
     KConfig* config = KGlobal::config();
-    config->setGroup("Session" );
+    config->setGroup( sessName.latin1() );
     int count =  config->readNumEntry( "count" );
     for ( int i = 1; i <= count; i++ ) {
 	QString n = QString::number(i);
 	executeCommand( config->readListEntry( QString("discardCommand")+n ) );
     }
-    config->deleteGroup("Session");
+    config->deleteGroup( sessName.latin1() );
 }
 
 void KSMServer::discardSession()
@@ -1306,10 +1320,12 @@
     }
 }
 
-void KSMServer::storeSession()
+void KSMServer::storeSession( uint sess )
 {
+    QString sessName = (sess==0) ? (QString::QString("Session")) :
+           (QString::QString("Session%1").arg(QString::number(sess)));
     KConfig* config = KGlobal::config();
-    config->setGroup("Session" );
+    config->setGroup( sessName.latin1() );
     int count =  0;
     for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
         int restartHint = c->restartStyleHint();
@@ -1340,12 +1356,14 @@
 /*!  Restores the previous session. Ensures the window manager is
   running (if specified).
  */
-void KSMServer::restoreSession()
+void KSMServer::restoreSession( uint sess )
 {
-    kdDebug(0) << "KSMServer::restoreSession" << endl;
+    kdDebug(0) << "KSMServer::restoreSession : " << sess << endl;
     upAndRunning( "restore session");
     KConfig* config = KGlobal::config();
-    config->setGroup("Session" );
+    QString sessName = (sess==0) ? (QString::QString("Session")) :
+           (QString::QString("Session%1").arg(QString::number(sess)));
+    config->setGroup( sessName.latin1() );
     int count =  config->readNumEntry( "count" );
     appsToStart = count;
 
@@ -1353,6 +1371,7 @@
     if ( !wm.isEmpty() ) {
 	for ( int i = 1; i <= count; i++ ) {
 	    QString n = QString::number(i);
+            config->setGroup( sessName.latin1() );
 	    if ( wm == config->readEntry( QString("program")+n ) ) {
 		appsToStart--;
 		wmCommand << config->readEntry( QString("restartCommand")+n );
@@ -1474,13 +1493,15 @@
 }
 
 
-void KSMServer::restoreSessionInternal()
+void KSMServer::restoreSessionInternal( uint sess )
 {
     disconnectDCOPSignal( "klauncher", "klauncher", "autoStartDone()",
                           "restoreSessionInternal()");
     progress = appsToStart;
+    QString sessName = (sess==0) ? (QString::QString("Session")) :
+           (QString::QString("Session%s").arg(QString::number(sess)));
     KConfig* config = KGlobal::config();
-    config->setGroup("Session" );
+    config->setGroup( sessName.latin1() );
     int count =  config->readNumEntry( "count" );
     for ( int i = 1; i <= count; i++ ) {
 	QString n = QString::number(i);
--- kdebase/ksmserver/server.h	Thu Jan 24 10:59:07 2002
+++ kdebase/ksmserver/server.h	Thu Jan 31 19:28:37 2002
@@ -98,7 +98,7 @@
     void clientSetProgram( KSMClient* client );
 
     // public API
-    void restoreSession();
+    void restoreSession( uint sess=0 );
     void startDefaultSession();
     void shutdown( KApplication::ShutdownConfirm confirm,
                    KApplication::ShutdownType sdtype,
@@ -111,7 +111,7 @@
     void newConnection( int socket );
     void processData( int socket );
     void timeoutQuit();
-    void restoreSessionInternal();
+    void restoreSessionInternal( uint sess=0 );
     void restoreSessionDone();
 
     void protectionTimeout();
@@ -125,8 +125,8 @@
     void completeKilling();
 
     void discardSession();
-    void storeSession();
-    void discardStoredSession();
+    void storeSession( uint sess=0 );
+    void discardStoredSession( uint sess=0 );
 
     void startProtection();
     void endProtection();
@@ -157,6 +157,9 @@
 
     int progress;
     int appsToStart;
+
+    // HACK: Need to modify completeShutdown and all the routines that call it.
+    uint sessionToSave;
 };
 
 #endif


>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic