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

List:       kde-commits
Subject:    KDE/kdebase/workspace [POSSIBLY UNSAFE]
From:       Luboš Luňák <l.lunak () kde ! org>
Date:       2008-04-08 15:58:14
Message-ID: 1207670294.337313.11854.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 794782 by lunakl:

GUI in the session manager module for selecting the window manager
to use with KDE. $KDEWM still overrides.
FEATURE: 130042



 M  +63 -1     kcontrol/smserver/kcmsmserver.cpp   [POSSIBLY UNSAFE: setShellCommand]
 M  +4 -1      kcontrol/smserver/kcmsmserver.h  
 M  +14 -2     kcontrol/smserver/smserverconfigdlg.ui  
 M  +1 -0      kcontrol/smserver/smserverconfigimpl.cpp  
 M  +1 -0      ksmserver/CMakeLists.txt  
 M  +0 -2      ksmserver/main.cpp  
 M  +51 -15    ksmserver/server.cpp   [POSSIBLY UNSAFE: setShellCommand]
 M  +2 -0      ksmserver/server.h  
 M  +13 -16    ksmserver/startup.cpp  
 A             ksmserver/windowmanagers (directory)  
 A             ksmserver/windowmanagers/CMakeLists.txt  
 A             ksmserver/windowmanagers/README  
 A             ksmserver/windowmanagers/compiz-custom.desktop  
 A             ksmserver/windowmanagers/compiz.desktop  
 A             ksmserver/windowmanagers/metacity.desktop  
 A             ksmserver/windowmanagers/openbox.desktop  


--- trunk/KDE/kdebase/workspace/kcontrol/smserver/kcmsmserver.cpp #794781:794782
@@ -28,6 +28,12 @@
 #include <kconfig.h>
 #include <klineedit.h>
 #include <kworkspace.h>
+#include <kstandarddirs.h>
+#include <qregexp.h>
+#include <kdesktopfile.h>
+#include <kdebug.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
 #include <QtDBus/QtDBus>
 
 #include "kcmsmserver.h"
@@ -57,6 +63,8 @@
     connect(dialog, SIGNAL(changed()), SLOT(changed()));
 
     topLayout->addWidget(dialog);
+
+    KGlobal::dirs()->addResourceType( "windowmanagers", "data", \
"ksmserver/windowmanagers" );  }
 
 void SMServerConfig::load()
@@ -86,6 +94,7 @@
     dialog->logoutRadio->setChecked(true);
     break;
   }
+  loadWMs(c.readEntry("windowManager", "kwin"));
   dialog->excludeLineedit->setText( c.readEntry("excludeApps"));
 
   emit changed(false);
@@ -110,6 +119,7 @@
                    dialog->rebootRadio->isChecked() ?
                      int(KWorkSpace::ShutdownTypeReboot) :
                      int(KWorkSpace::ShutdownTypeNone));
+  group.writeEntry("windowManager", currentWM());
   group.writeEntry("excludeApps", dialog->excludeLineedit->text());
   c->sync();
   delete c;
@@ -118,6 +128,12 @@
   QDBusInterface kicker("org.kde.kicker", "/kicker", "org.kde.kicker");
   kicker.call("configure");
 #endif
+  if( oldwm != currentWM())
+  { // TODO switch it already in the session instead and tell ksmserver
+    KMessageBox::information( this,
+        i18n( "The new window manager will be used when KDE is started the next \
time." ), +        i18n( "Window manager change" ), "windowmanagerchange" );
+  }
 }
 
 void SMServerConfig::defaults()
@@ -127,9 +143,55 @@
   dialog->offerShutdownCheck->setChecked(true);
   dialog->sdGroup->setEnabled(true);
   dialog->logoutRadio->setChecked(true);
+  dialog->windowManagerCombo->setCurrentIndex( 0 );
   dialog->excludeLineedit->clear();
+}
 
+void SMServerConfig::loadWMs( const QString& current )
+{
+  QString kwinname = i18n( "KWin (KDE default)" );
+  dialog->windowManagerCombo->addItem( kwinname );
+  dialog->windowManagerCombo->setCurrentIndex( 0 );
+  wms[ kwinname ] = "kwin";
+  oldwm = "kwin";
+  QStringList list = KGlobal::dirs()->findAllResources( "windowmanagers", QString(), \
KStandardDirs::NoDuplicates ); +  QRegExp reg( ".*/([^/\\.]*)\\.[^/\\.]*" );
+  foreach( QString wmfile, list )
+  {
+    KDesktopFile file( wmfile );
+    if( file.noDisplay())
+        continue;
+    if( !file.tryExec())
+        continue;
+    QString testexec = file.desktopGroup().readEntry( "X-KDE-WindowManagerTestExec" \
); +    if( !testexec.isEmpty())
+    {
+        KProcess proc;
+        proc.setShellCommand( testexec );
+        if( proc.execute() != 0 )
+            continue;
+    }
+    QString name = file.readName();
+    if( name.isEmpty())
+        continue;
+    if( !reg.exactMatch( wmfile ))
+        continue;
+    QString wm = reg.cap( 1 );
+    if( wms.values().contains( wm ))
+        continue;
+    wms[ name ] = wm;
+    dialog->windowManagerCombo->addItem( name );
+    if( wms[ name ] == current ) // make it selected
+    {
+        dialog->windowManagerCombo->setCurrentIndex( \
dialog->windowManagerCombo->count() - 1 ); +        oldwm = wm;
+    }
+  }
 }
 
+QString SMServerConfig::currentWM() const
+{
+  return wms[ dialog->windowManagerCombo->currentText() ];
+}
+
 #include "kcmsmserver.moc"
-
--- trunk/KDE/kdebase/workspace/kcontrol/smserver/kcmsmserver.h #794781:794782
@@ -40,8 +40,11 @@
   void defaults();
 
 private:
+  void loadWMs( const QString& current );
+  QString currentWM() const;
+  QHash< QString, QString > wms; // i18n text -> internal name
+  QString oldwm; // the original value
   SMServerConfigImpl* dialog;
-
 };
 
 #endif
--- trunk/KDE/kdebase/workspace/kcontrol/smserver/smserverconfigdlg.ui #794781:794782
@@ -6,7 +6,7 @@
     <x>0</x>
     <y>0</y>
     <width>325</width>
-    <height>473</height>
+    <height>478</height>
    </rect>
   </property>
   <property name="windowTitle" >
@@ -125,6 +125,18 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="windowManagerGroup" >
+     <property name="title" >
+      <string>Window Manager</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout" >
+      <item>
+       <widget class="QComboBox" name="windowManagerCombo" />
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <widget class="QGroupBox" name="advancedGroup" >
      <property name="title" >
       <string>Advanced</string>
@@ -161,7 +173,7 @@
      <property name="sizeType" >
       <enum>QSizePolicy::Expanding</enum>
      </property>
-     <property name="sizeHint" >
+     <property name="sizeHint" stdset="0" >
       <size>
        <width>20</width>
        <height>5</height>
--- trunk/KDE/kdebase/workspace/kcontrol/smserver/smserverconfigimpl.cpp \
#794781:794782 @@ -28,6 +28,7 @@
     connect(rebootRadio,SIGNAL(toggled(bool)), SLOT(configChanged()));
     connect(excludeLineedit,SIGNAL(textChanged(QString)),SLOT(configChanged()));
     connect(offerShutdownCheck,SIGNAL(toggled(bool)),SLOT(configChanged()));
+    connect(windowManagerCombo,SIGNAL(activated(int)),SLOT(configChanged()));
 }
 SMServerConfigImpl::~SMServerConfigImpl(){
 }
--- trunk/KDE/kdebase/workspace/ksmserver/CMakeLists.txt #794781:794782
@@ -1,3 +1,4 @@
+add_subdirectory( windowmanagers )
 add_subdirectory( tests )
 
 include_directories(
--- trunk/KDE/kdebase/workspace/ksmserver/main.cpp #794781:794782
@@ -221,8 +221,6 @@
     }
 
     QString wm = args->getOption("windowmanager");
-    if ( wm.isEmpty() )
-        wm = "kwin";
 
     bool only_local = args->isSet("local");
 #ifndef HAVE__ICETRANSNOLISTEN
--- trunk/KDE/kdebase/workspace/ksmserver/server.cpp #794781:794782
@@ -69,12 +69,14 @@
 #include <klocale.h>
 #include <kglobal.h>
 #include <kconfig.h>
+#include <kdesktopfile.h>
 #include <kstandarddirs.h>
 #include <kapplication.h>
 #include <ktemporaryfile.h>
 #include <kconfiggroup.h>
 #include <kprocess.h>
 #include <kdebug.h>
+#include <kshell.h>
 
 #include "server.moc"
 
@@ -586,7 +588,6 @@
     kcminitSignals = NULL;
     the_server = this;
     clean = false;
-    wm = windowManager;
 
     shutdownType = KWorkSpace::ShutdownTypeNone;
 
@@ -598,6 +599,9 @@
     clientInteracting = 0;
     xonCommand = config.readEntry( "xonCommand", "xon" );
 
+    KGlobal::dirs()->addResourceType( "windowmanagers", "data", \
"ksmserver/windowmanagers" ); +    selectWm( windowManager );
+
     connect( &startupSuspendTimeoutTimer, SIGNAL( timeout()), SLOT( \
                startupSuspendTimeout()));
     connect( &pendingShutdown, SIGNAL( timeout()), SLOT( pendingShutdownTimeout()));
 
@@ -852,15 +856,13 @@
 	KConfigGroup cg( config, sessionGroup);
     count =  0;
 
-    if ( !wm.isEmpty() ) {
-        // put the wm first
-        foreach ( KSMClient *c, clients )
-            if ( c->program() == wm ) {
-                clients.removeAll( c );
-                clients.prepend( c );
-                break;
-            }
-    }
+    // put the wm first
+    foreach ( KSMClient *c, clients )
+        if ( c->program() == wm ) {
+            clients.removeAll( c );
+            clients.prepend( c );
+            break;
+        }
 
     foreach ( KSMClient *c, clients ) {
         int restartHint = c->restartStyleHint();
@@ -910,14 +912,48 @@
 
 bool KSMServer::isWM( const QString& command ) const
 {
-    // KWin relies on ksmserver's special treatment in phase1,
-    // therefore make sure it's recognized even if ksmserver
-    // was initially started with different WM, and kwin replaced
-    // it later
-    return command == wm || command == "kwin";
+    return command == wm;
 }
 
 bool KSMServer::defaultSession() const
 {
     return sessionGroup.isEmpty();
 }
+
+// selection logic:
+// - $KDEWM is set - use that
+// - a wm is selected using the kcm - use that
+// - if that fails, just use KWin
+void KSMServer::selectWm( const QString& kdewm )
+{
+    wm = "kwin"; // defaults
+    wmCommands = ( QStringList() << "kwin" ); 
+    if( !kdewm.isEmpty())
+    {
+        wmCommands = ( QStringList() << kdewm );
+        wm = kdewm;
+        return;
+    }
+    KConfigGroup config(KGlobal::config(), "General");
+    QString cfgwm = config.readEntry( "windowManager", "kwin" );
+    KDesktopFile file( "windowmanagers", cfgwm + ".desktop" );
+    if( file.noDisplay())
+        return;
+    if( !file.tryExec())
+        return;
+    QString testexec = file.desktopGroup().readEntry( "X-KDE-WindowManagerTestExec" \
); +    if( !testexec.isEmpty())
+    {
+        KProcess proc;
+        proc.setShellCommand( testexec );
+        if( proc.execute() != 0 )
+            return;
+    }
+    QStringList cfgWmCommands = KShell::splitArgs( file.desktopGroup().readEntry( \
"Exec" )); +    if( cfgWmCommands.isEmpty())
+        return;
+    QString smname = file.desktopGroup().readEntry( "X-KDE-WindowManagerId" );
+    // ok
+    wm = smname.isEmpty() ? cfgwm : smname;
+    wmCommands = cfgWmCommands;
+}
--- trunk/KDE/kdebase/workspace/ksmserver/server.h #794781:794782
@@ -162,6 +162,7 @@
 
     bool isWM( const KSMClient* client ) const;
     bool isWM( const QString& command ) const;
+    void selectWm( const QString& kdewm );
     bool defaultSession() const; // empty session
     void setupXIOErrorHandler();
 
@@ -210,6 +211,7 @@
     bool clean;
     KSMClient* clientInteracting;
     QString wm;
+    QStringList wmCommands;
     QString sessionGroup;
     QString sessionName;
     QTimer protectionTimer;
--- trunk/KDE/kdebase/workspace/ksmserver/startup.cpp #794781:794782
@@ -99,17 +99,18 @@
     int count =  configSessionGroup.readEntry( "count", 0 );
     appsToStart = count;
 
-    QList<QStringList> wmCommands;
+    // it's a list because of multihead (with one kwin per head)
+    QList<QStringList> wmStartCommands;
     if ( !wm.isEmpty() ) {
 	for ( int i = 1; i <= count; i++ ) {
 	    QString n = QString::number(i);
 	    if ( wm == configSessionGroup.readEntry( QString("program")+n, QString() ) ) {
-		wmCommands << configSessionGroup.readEntry( QString("restartCommand")+n, \
QStringList() ); +		wmStartCommands << configSessionGroup.readEntry( \
QString("restartCommand")+n, QStringList() );  }
 	}
     }
-    if ( wmCommands.isEmpty() )
-        wmCommands << ( QStringList() << wm );
+    if( wmStartCommands.isEmpty())
+        wmStartCommands << wmCommands;
 
     publishProgress( appsToStart, true );
     connect( klauncherSignals, SIGNAL( autoStart0Done()), SLOT( autoStart0Done()));
@@ -117,16 +118,12 @@
     connect( klauncherSignals, SIGNAL( autoStart2Done()), SLOT( autoStart2Done()));
     upAndRunning( "ksmserver" );
 
-    if ( !wmCommands.isEmpty() ) {
-        // when we have a window manager, we start it first and give
-        // it some time before launching other processes. Results in a
-        // visually more appealing startup.
-        for (int i = 0; i < wmCommands.count(); i++)
-            startApplication( wmCommands[i] );
-        QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
-    } else {
-        autoStart0();
-    }
+    // when we have a window manager, we start it first and give
+    // it some time before launching other processes. Results in a
+    // visually more appealing startup.
+    for (int i = 0; i < wmStartCommands.count(); i++)
+        startApplication( wmStartCommands[i] );
+    QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
 }
 
 /*!
@@ -146,13 +143,13 @@
     connect( klauncherSignals, SIGNAL( autoStart0Done()), SLOT( autoStart0Done()));
     connect( klauncherSignals, SIGNAL( autoStart1Done()), SLOT( autoStart1Done()));
     connect( klauncherSignals, SIGNAL( autoStart2Done()), SLOT( autoStart2Done()));
-    startApplication( QStringList() << wm );
+    startApplication( wmCommands );
     QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
 }
 
 void KSMServer::clientSetProgram( KSMClient* client )
 {
-    if ( !wm.isEmpty() && client->program() == wm )
+    if( client->program() == wm )
         autoStart0();
 }
 


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

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