You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
636 lines
21 KiB
636 lines
21 KiB
13 years ago
|
Subject: GUI configuration for selecting WM
|
||
|
From: Lubos Lunak
|
||
|
Feature: bnc#332079
|
||
|
Patch-upstream: no
|
||
|
|
||
|
Index: ksmserver/startup.cpp
|
||
|
===================================================================
|
||
|
--- ksmserver/startup.cpp.orig
|
||
|
+++ ksmserver/startup.cpp
|
||
|
@@ -103,38 +103,39 @@ void KSMServer::restoreSession( QString
|
||
|
config->setGroup( sessionGroup );
|
||
|
int count = config->readNumEntry( "count" );
|
||
|
appsToStart = count;
|
||
|
-
|
||
|
- QValueList<QStringList> wmCommands;
|
||
|
- if ( !wm.isEmpty() ) {
|
||
|
- for ( int i = 1; i <= count; i++ ) {
|
||
|
- QString n = QString::number(i);
|
||
|
- if ( wm == config->readEntry( QString("program")+n ) ) {
|
||
|
- wmCommands << config->readListEntry( QString("restartCommand")+n );
|
||
|
- }
|
||
|
- }
|
||
|
- }
|
||
|
- if ( wmCommands.isEmpty() )
|
||
|
- wmCommands << ( QStringList() << wm );
|
||
|
-
|
||
|
publishProgress( appsToStart, true );
|
||
|
+ upAndRunning( "ksmserver" );
|
||
|
connectDCOPSignal( launcher, launcher, "autoStart0Done()",
|
||
|
"autoStart0Done()", true);
|
||
|
connectDCOPSignal( launcher, launcher, "autoStart1Done()",
|
||
|
"autoStart1Done()", true);
|
||
|
connectDCOPSignal( launcher, launcher, "autoStart2Done()",
|
||
|
"autoStart2Done()", true);
|
||
|
- 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 (uint i = 0; i < wmCommands.count(); i++)
|
||
|
- startApplication( wmCommands[i] );
|
||
|
- QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
|
||
|
- } else {
|
||
|
- autoStart0();
|
||
|
+ // find all commands to launch the wm in the session
|
||
|
+ QValueList<QStringList> wmStartCommands;
|
||
|
+ if ( !wm.isEmpty() ) {
|
||
|
+ for ( int i = 1; i <= count; i++ ) {
|
||
|
+ QString n = QString::number(i);
|
||
|
+ // special hack for it, both kde3(=native) and kde4 kwin have the same program,
|
||
|
+ // but the command for kde4 kwin starts with the kde4 wrapper
|
||
|
+ if( config->readEntry( QString("program")+n ) == "kwin" ) {
|
||
|
+ QStringList command = config->readListEntry( QString("restartCommand")+n );
|
||
|
+ if( wmCommands.count() > 1 && wmCommands[ 0 ].endsWith( "kde4" )
|
||
|
+ && command.count() > 1 && command[ 0 ].endsWith( "kde4" )) {
|
||
|
+ wmStartCommands << command; // kde4 wanted, kde4 found
|
||
|
+ } else if(!( wmCommands.count() > 1 && wmCommands[ 0 ].endsWith( "kde4" ))
|
||
|
+ && !( command.count() > 1 && command[ 0 ].endsWith( "kde4" ))) {
|
||
|
+ wmStartCommands << command; // native wanted, native found
|
||
|
+ }
|
||
|
+ } else if ( wm == config->readEntry( QString("program")+n ) ) {
|
||
|
+ wmStartCommands << config->readListEntry( QString("restartCommand")+n );
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
+ if( wmStartCommands.isEmpty()) // otherwise use the configured default
|
||
|
+ wmStartCommands << wmCommands;
|
||
|
+ launchWM( wmStartCommands );
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
@@ -157,17 +158,53 @@ void KSMServer::startDefaultSession()
|
||
|
"autoStart1Done()", true);
|
||
|
connectDCOPSignal( launcher, launcher, "autoStart2Done()",
|
||
|
"autoStart2Done()", true);
|
||
|
- startApplication( wm );
|
||
|
+ launchWM( QValueList< QStringList >() << wmCommands );
|
||
|
+}
|
||
|
+
|
||
|
+void KSMServer::launchWM( const QValueList< QStringList >& wmStartCommands )
|
||
|
+{
|
||
|
+ assert( state == LaunchingWM );
|
||
|
+
|
||
|
+ // 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.
|
||
|
+ wmProcess = startApplication( wmStartCommands[ 0 ] );
|
||
|
+ connect( wmProcess, SIGNAL( processExited( KProcess* )), SLOT( wmProcessChange()));
|
||
|
+ // there can be possibly more wm's (because of forking for multihead),
|
||
|
+ // but in such case care only about the process of the first one
|
||
|
+ for (unsigned int i = 1; i < wmStartCommands.count(); i++)
|
||
|
+ startApplication( wmStartCommands[i] );
|
||
|
QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
void KSMServer::clientSetProgram( KSMClient* client )
|
||
|
{
|
||
|
- if ( !wm.isEmpty() && client->program() == wm )
|
||
|
+ if ( client->program() == wm )
|
||
|
autoStart0();
|
||
|
}
|
||
|
|
||
|
+void KSMServer::wmProcessChange()
|
||
|
+{
|
||
|
+ if( state != LaunchingWM )
|
||
|
+ { // don't care about the process when not in the wm-launching state anymore
|
||
|
+ wmProcess = NULL;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ if( !wmProcess->isRunning())
|
||
|
+ { // wm failed to launch for some reason, go with kwin instead
|
||
|
+ kdWarning( 1218 ) << "Window manager '" << wm << "' failed to launch" << endl;
|
||
|
+ if( wm == "kwin" )
|
||
|
+ return; // uhoh, kwin itself failed
|
||
|
+ kdDebug( 1218 ) << "Launching KWin" << endl;
|
||
|
+ wm = "kwin";
|
||
|
+ wmCommands = ( QStringList() << "kwin" );
|
||
|
+ // launch it
|
||
|
+ launchWM( QValueList< QStringList >() << wmCommands );
|
||
|
+ return;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
void KSMServer::autoStart0()
|
||
|
{
|
||
|
if( state != LaunchingWM )
|
||
|
Index: ksmserver/server.h
|
||
|
===================================================================
|
||
|
--- ksmserver/server.h.orig
|
||
|
+++ ksmserver/server.h
|
||
|
@@ -30,6 +30,8 @@ Copyright (C) 2000 Matthias Ettrich <ett
|
||
|
#define SESSION_PREVIOUS_LOGOUT "saved at previous logout"
|
||
|
#define SESSION_BY_USER "saved by user"
|
||
|
|
||
|
+class KProcess;
|
||
|
+
|
||
|
typedef QValueList<QCString> QCStringList;
|
||
|
class KSMListener;
|
||
|
class KSMConnection;
|
||
|
@@ -98,6 +100,8 @@ public:
|
||
|
KApplication::ShutdownType sdtype,
|
||
|
KApplication::ShutdownMode sdmode );
|
||
|
|
||
|
+ void launchWM( const QValueList< QStringList >& wmStartCommands );
|
||
|
+
|
||
|
public slots:
|
||
|
void cleanUp();
|
||
|
|
||
|
@@ -120,6 +124,7 @@ private slots:
|
||
|
void autoStart2();
|
||
|
void tryRestoreNext();
|
||
|
void startupSuspendTimeout();
|
||
|
+ void wmProcessChange();
|
||
|
|
||
|
private:
|
||
|
void handlePendingInteractions();
|
||
|
@@ -138,13 +143,14 @@ private:
|
||
|
void startProtection();
|
||
|
void endProtection();
|
||
|
|
||
|
- void startApplication( QStringList command,
|
||
|
+ KProcess* startApplication( QStringList command,
|
||
|
const QString& clientMachine = QString::null,
|
||
|
const QString& userId = QString::null );
|
||
|
void executeCommand( const QStringList& command );
|
||
|
|
||
|
bool isWM( const KSMClient* client ) const;
|
||
|
bool isWM( const QString& program ) const;
|
||
|
+ void selectWm( const QString& kdewm );
|
||
|
bool defaultSession() const; // empty session
|
||
|
void setupXIOErrorHandler();
|
||
|
|
||
|
@@ -223,6 +229,8 @@ private:
|
||
|
int lastAppStarted;
|
||
|
QString lastIdStarted;
|
||
|
|
||
|
+ QStringList wmCommands;
|
||
|
+ KProcess* wmProcess;
|
||
|
QStringList excludeApps;
|
||
|
|
||
|
WindowMap legacyWindows;
|
||
|
Index: ksmserver/Makefile.am
|
||
|
===================================================================
|
||
|
--- ksmserver/Makefile.am.orig
|
||
|
+++ ksmserver/Makefile.am
|
||
|
@@ -15,7 +15,7 @@
|
||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
-SUBDIRS = .
|
||
|
+SUBDIRS = . windowmanagers
|
||
|
|
||
|
INCLUDES= -I$(top_srcdir)/kdmlib $(all_includes) $(DBUS_INCS)
|
||
|
|
||
|
Index: ksmserver/main.cpp
|
||
|
===================================================================
|
||
|
--- ksmserver/main.cpp.orig
|
||
|
+++ ksmserver/main.cpp
|
||
|
@@ -203,8 +203,6 @@ extern "C" KDE_EXPORT int kdemain( int a
|
||
|
}
|
||
|
|
||
|
QCString wm = args->getOption("windowmanager");
|
||
|
- if ( wm.isEmpty() )
|
||
|
- wm = "kwin";
|
||
|
|
||
|
bool only_local = args->isSet("local");
|
||
|
#ifndef HAVE__ICETRANSNOLISTEN
|
||
|
Index: ksmserver/server.cpp
|
||
|
===================================================================
|
||
|
--- ksmserver/server.cpp.orig
|
||
|
+++ ksmserver/server.cpp
|
||
|
@@ -77,6 +77,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE
|
||
|
#include <kprocess.h>
|
||
|
#include <dcopclient.h>
|
||
|
#include <dcopref.h>
|
||
|
+#include <kdesktopfile.h>
|
||
|
+#include <kshell.h>
|
||
|
|
||
|
#include "server.h"
|
||
|
#include "global.h"
|
||
|
@@ -98,11 +100,11 @@ KSMServer* KSMServer::self()
|
||
|
/*! Utility function to execute a command on the local machine. Used
|
||
|
* to restart applications.
|
||
|
*/
|
||
|
-void KSMServer::startApplication( QStringList command, const QString& clientMachine,
|
||
|
+KProcess* KSMServer::startApplication( QStringList command, const QString& clientMachine,
|
||
|
const QString& userId )
|
||
|
{
|
||
|
if ( command.isEmpty() )
|
||
|
- return;
|
||
|
+ return NULL;
|
||
|
if ( !userId.isEmpty()) {
|
||
|
struct passwd* pw = getpwuid( getuid());
|
||
|
if( pw != NULL && userId != QString::fromLocal8Bit( pw->pw_name )) {
|
||
|
@@ -116,12 +118,12 @@ void KSMServer::startApplication( QStrin
|
||
|
command.prepend( clientMachine );
|
||
|
command.prepend( xonCommand ); // "xon" by default
|
||
|
}
|
||
|
- int n = command.count();
|
||
|
- QCString app = command[0].latin1();
|
||
|
- QValueList<QCString> argList;
|
||
|
- for ( int i=1; i < n; i++)
|
||
|
- argList.append( QCString(command[i].latin1()));
|
||
|
- DCOPRef( launcher ).send( "exec_blind", app, DCOPArg( argList, "QValueList<QCString>" ) );
|
||
|
+ KProcess* process = new KProcess( this );
|
||
|
+ *process << command;
|
||
|
+ // make it auto-delete
|
||
|
+ connect( process, SIGNAL( processExited( KProcess* )), process, SLOT( deleteLater()));
|
||
|
+ process->start();
|
||
|
+ return process;
|
||
|
}
|
||
|
|
||
|
/*! Utility function to execute a command on the local machine. Used
|
||
|
@@ -580,10 +582,10 @@ extern "C" int _IceTransNoListen(const c
|
||
|
|
||
|
KSMServer::KSMServer( const QString& windowManager, bool _only_local )
|
||
|
: DCOPObject("ksmserver"), sessionGroup( "" )
|
||
|
+ , wmProcess( NULL )
|
||
|
{
|
||
|
the_server = this;
|
||
|
clean = false;
|
||
|
- wm = windowManager;
|
||
|
|
||
|
shutdownType = KApplication::ShutdownTypeNone;
|
||
|
|
||
|
@@ -595,6 +597,9 @@ KSMServer::KSMServer( const QString& win
|
||
|
config->setGroup("General" );
|
||
|
clientInteracting = 0;
|
||
|
xonCommand = config->readEntry( "xonCommand", "xon" );
|
||
|
+
|
||
|
+ KGlobal::dirs()->addResourceType( "windowmanagers", "share/apps/ksmserver/windowmanagers" );
|
||
|
+ selectWm( windowManager );
|
||
|
|
||
|
connect( &knotifyTimeoutTimer, SIGNAL( timeout()), SLOT( knotifyTimeout()));
|
||
|
connect( &startupSuspendTimeoutTimer, SIGNAL( timeout()), SLOT( startupSuspendTimeout()));
|
||
|
@@ -851,14 +856,12 @@ void KSMServer::storeSession()
|
||
|
config->setGroup( sessionGroup );
|
||
|
count = 0;
|
||
|
|
||
|
- if ( !wm.isEmpty() ) {
|
||
|
- // put the wm first
|
||
|
- for ( KSMClient* c = clients.first(); c; c = clients.next() )
|
||
|
- if ( c->program() == wm ) {
|
||
|
- clients.prepend( clients.take() );
|
||
|
- break;
|
||
|
- }
|
||
|
- }
|
||
|
+ // put the wm first
|
||
|
+ for ( KSMClient* c = clients.first(); c; c = clients.next() )
|
||
|
+ if ( c->program() == wm ) {
|
||
|
+ clients.prepend( clients.take() );
|
||
|
+ break;
|
||
|
+ }
|
||
|
|
||
|
for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
|
||
|
int restartHint = c->restartStyleHint();
|
||
|
@@ -909,14 +912,65 @@ bool KSMServer::isWM( const KSMClient* c
|
||
|
|
||
|
bool KSMServer::isWM( const QString& program ) 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 program == wm || program == "kwin";
|
||
|
+ return program == wm;
|
||
|
}
|
||
|
|
||
|
bool KSMServer::defaultSession() const
|
||
|
{
|
||
|
return sessionGroup.isEmpty();
|
||
|
}
|
||
|
+
|
||
|
+static bool noDisplay( KDesktopFile& f )
|
||
|
+{
|
||
|
+ KConfigGroup gr( &f, "Desktop Entry" );
|
||
|
+ if (gr.readBoolEntry("NoDisplay", false)) {
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ if (gr.hasKey("OnlyShowIn")) {
|
||
|
+ if (!gr.readListEntry("OnlyShowIn", ';').contains("KDE"))
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ if (gr.hasKey("NotShowIn")) {
|
||
|
+ if (gr.readListEntry("NotShowIn", ';').contains("KDE"))
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ return false;
|
||
|
+}
|
||
|
+
|
||
|
+// 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( cfgwm + ".desktop", true, "windowmanagers" );
|
||
|
+ if( noDisplay( file ))
|
||
|
+ return;
|
||
|
+ if( !file.tryExec())
|
||
|
+ return;
|
||
|
+ file.setDesktopGroup();
|
||
|
+ QString testexec = file.readEntry( "X-KDE-WindowManagerTestExec" );
|
||
|
+ if( !testexec.isEmpty())
|
||
|
+ {
|
||
|
+ int ret = system( QFile::encodeName( testexec ));
|
||
|
+ if( !WIFEXITED( ret ) || WEXITSTATUS( ret ) != 0 )
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ QStringList cfgWmCommands = KShell::splitArgs( file.readEntry( "Exec" ));
|
||
|
+ if( cfgWmCommands.isEmpty())
|
||
|
+ return;
|
||
|
+ QString smname = file.readEntry( "X-KDE-WindowManagerId" );
|
||
|
+ // ok
|
||
|
+ wm = smname.isEmpty() ? cfgwm : smname;
|
||
|
+ wmCommands = cfgWmCommands;
|
||
|
+}
|
||
|
Index: ksmserver/windowmanagers/openbox.desktop
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ksmserver/windowmanagers/openbox.desktop
|
||
|
@@ -0,0 +1,5 @@
|
||
|
+[Desktop Entry]
|
||
|
+Name=Openbox
|
||
|
+Exec=openbox
|
||
|
+TryExec=openbox
|
||
|
+
|
||
|
Index: ksmserver/windowmanagers/Makefile.am
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ksmserver/windowmanagers/Makefile.am
|
||
|
@@ -0,0 +1,2 @@
|
||
|
+windowmanager_DATA = compiz-custom.desktop compiz.desktop kwin4.desktop metacity.desktop openbox.desktop
|
||
|
+windowmanagerdir = $(kde_datadir)/ksmserver/windowmanagers
|
||
|
Index: ksmserver/windowmanagers/compiz.desktop
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ksmserver/windowmanagers/compiz.desktop
|
||
|
@@ -0,0 +1,4 @@
|
||
|
+[Desktop Entry]
|
||
|
+Name=Compiz
|
||
|
+Exec=compiz ccp
|
||
|
+TryExec=compiz
|
||
|
Index: ksmserver/windowmanagers/compiz-custom.desktop
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ksmserver/windowmanagers/compiz-custom.desktop
|
||
|
@@ -0,0 +1,5 @@
|
||
|
+[Desktop Entry]
|
||
|
+Name=Compiz custom (create wrapper script 'compiz-kde-launcher' to launch it)
|
||
|
+Exec=compiz-kde-launcher
|
||
|
+TryExec=compiz
|
||
|
+X-KDE-WindowManagerId=compiz
|
||
|
Index: ksmserver/windowmanagers/kwin4.desktop
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ksmserver/windowmanagers/kwin4.desktop
|
||
|
@@ -0,0 +1,6 @@
|
||
|
+[Desktop Entry]
|
||
|
+Name=KWin (KDE4)
|
||
|
+Exec=kde4 /usr/bin/kwin
|
||
|
+TryExec=/usr/bin/kwin
|
||
|
+X-KDE-WindowManagerId=kwin
|
||
|
+
|
||
|
Index: ksmserver/windowmanagers/metacity.desktop
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ksmserver/windowmanagers/metacity.desktop
|
||
|
@@ -0,0 +1,4 @@
|
||
|
+[Desktop Entry]
|
||
|
+Name=Metacity (GNOME)
|
||
|
+Exec=metacity
|
||
|
+TryExec=metacity
|
||
|
Index: kcontrol/smserver/smserverconfigdlg.ui
|
||
|
===================================================================
|
||
|
--- kcontrol/smserver/smserverconfigdlg.ui.orig
|
||
|
+++ kcontrol/smserver/smserverconfigdlg.ui
|
||
|
@@ -1,4 +1,4 @@
|
||
|
-<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
|
||
|
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
|
||
|
<class>SMServerConfigDlg</class>
|
||
|
<widget class="QWidget">
|
||
|
<property name="name">
|
||
|
@@ -8,8 +8,8 @@
|
||
|
<rect>
|
||
|
<x>0</x>
|
||
|
<y>0</y>
|
||
|
- <width>325</width>
|
||
|
- <height>366</height>
|
||
|
+ <width>334</width>
|
||
|
+ <height>476</height>
|
||
|
</rect>
|
||
|
</property>
|
||
|
<property name="caption">
|
||
|
@@ -148,6 +148,24 @@
|
||
|
</widget>
|
||
|
</vbox>
|
||
|
</widget>
|
||
|
+ <widget class="QGroupBox">
|
||
|
+ <property name="name">
|
||
|
+ <cstring>windowManagerGroup</cstring>
|
||
|
+ </property>
|
||
|
+ <property name="title">
|
||
|
+ <string>Window Manager</string>
|
||
|
+ </property>
|
||
|
+ <hbox>
|
||
|
+ <property name="name">
|
||
|
+ <cstring>unnamed</cstring>
|
||
|
+ </property>
|
||
|
+ <widget class="QComboBox">
|
||
|
+ <property name="name">
|
||
|
+ <cstring>windowManagerCombo</cstring>
|
||
|
+ </property>
|
||
|
+ </widget>
|
||
|
+ </hbox>
|
||
|
+ </widget>
|
||
|
<widget class="QButtonGroup">
|
||
|
<property name="name">
|
||
|
<cstring>advancedGroup</cstring>
|
||
|
@@ -236,6 +254,12 @@
|
||
|
<receiver>SMServerConfigDlg</receiver>
|
||
|
<slot>configChanged()</slot>
|
||
|
</connection>
|
||
|
+ <connection>
|
||
|
+ <sender>windowManagerCombo</sender>
|
||
|
+ <signal>activated(int)</signal>
|
||
|
+ <receiver>SMServerConfigDlg</receiver>
|
||
|
+ <slot>configChanged()</slot>
|
||
|
+ </connection>
|
||
|
</connections>
|
||
|
<includes>
|
||
|
<include location="global" impldecl="in implementation">kdialog.h</include>
|
||
|
Index: kcontrol/smserver/kcmsmserver.cpp
|
||
|
===================================================================
|
||
|
--- kcontrol/smserver/kcmsmserver.cpp.orig
|
||
|
+++ kcontrol/smserver/kcmsmserver.cpp
|
||
|
@@ -22,6 +22,8 @@
|
||
|
#include <qcheckbox.h>
|
||
|
#include <qlayout.h>
|
||
|
#include <qradiobutton.h>
|
||
|
+#include <qcombobox.h>
|
||
|
+#include <qfile.h>
|
||
|
|
||
|
#include <dcopclient.h>
|
||
|
|
||
|
@@ -29,6 +31,12 @@
|
||
|
#include <kconfig.h>
|
||
|
#include <kgenericfactory.h>
|
||
|
#include <klineedit.h>
|
||
|
+#include <kstandarddirs.h>
|
||
|
+#include <qregexp.h>
|
||
|
+#include <kdesktopfile.h>
|
||
|
+#include <kdebug.h>
|
||
|
+#include <kprocess.h>
|
||
|
+#include <kmessagebox.h>
|
||
|
|
||
|
#include "kcmsmserver.h"
|
||
|
#include "smserverconfigimpl.h"
|
||
|
@@ -52,6 +60,7 @@ SMServerConfig::SMServerConfig( QWidget
|
||
|
|
||
|
dialog->show();
|
||
|
topLayout->add(dialog);
|
||
|
+ KGlobal::dirs()->addResourceType( "windowmanagers", "share/apps/ksmserver/windowmanagers" );
|
||
|
load();
|
||
|
|
||
|
}
|
||
|
@@ -90,6 +99,7 @@ void SMServerConfig::load(bool useDefaul
|
||
|
dialog->logoutRadio->setChecked(true);
|
||
|
break;
|
||
|
}
|
||
|
+ loadWMs(c->readEntry("windowManager", "kwin"));
|
||
|
dialog->excludeLineedit->setText( c->readEntry("excludeApps"));
|
||
|
|
||
|
delete c;
|
||
|
@@ -116,6 +126,7 @@ void SMServerConfig::save()
|
||
|
dialog->rebootRadio->isChecked() ?
|
||
|
int(KApplication::ShutdownTypeReboot) :
|
||
|
int(KApplication::ShutdownTypeNone));
|
||
|
+ c->writeEntry("windowManager", currentWM());
|
||
|
c->writeEntry("excludeApps", dialog->excludeLineedit->text());
|
||
|
c->sync();
|
||
|
delete c;
|
||
|
@@ -123,6 +134,12 @@ void SMServerConfig::save()
|
||
|
// update the k menu if necessary
|
||
|
QByteArray data;
|
||
|
kapp->dcopClient()->send( "kicker", "kicker", "configure()", data );
|
||
|
+ 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()
|
||
|
@@ -130,5 +147,72 @@ void SMServerConfig::defaults()
|
||
|
load( true );
|
||
|
}
|
||
|
|
||
|
+static bool noDisplay( KDesktopFile& f )
|
||
|
+{
|
||
|
+ KConfigGroup gr( &f, "Desktop Entry" );
|
||
|
+ if (gr.readBoolEntry("NoDisplay", false)) {
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ if (gr.hasKey("OnlyShowIn")) {
|
||
|
+ if (!gr.readListEntry("OnlyShowIn", ';').contains("KDE"))
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ if (gr.hasKey("NotShowIn")) {
|
||
|
+ if (gr.readListEntry("NotShowIn", ';').contains("KDE"))
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ return false;
|
||
|
+}
|
||
|
+
|
||
|
+void SMServerConfig::loadWMs( const QString& current )
|
||
|
+{
|
||
|
+ QString kwinname = i18n( "KWin (KDE default)" );
|
||
|
+ dialog->windowManagerCombo->insertItem( kwinname );
|
||
|
+ dialog->windowManagerCombo->setCurrentItem( 0 );
|
||
|
+ wms[ kwinname ] = "kwin";
|
||
|
+ oldwm = "kwin";
|
||
|
+ QStringList list = KGlobal::dirs()->findAllResources( "windowmanagers", QString(), false, true );
|
||
|
+ QRegExp reg( ".*/([^/\\.]*)\\.[^/\\.]*" );
|
||
|
+ for( QStringList::ConstIterator it = list.begin();
|
||
|
+ it != list.end();
|
||
|
+ ++it )
|
||
|
+ {
|
||
|
+ QString wmfile = *it;
|
||
|
+ KDesktopFile file( wmfile );
|
||
|
+ if( noDisplay( file ))
|
||
|
+ continue;
|
||
|
+ if( !file.tryExec())
|
||
|
+ continue;
|
||
|
+ file.setDesktopGroup();
|
||
|
+ QString testexec = file.readEntry( "X-KDE-WindowManagerTestExec" );
|
||
|
+ if( !testexec.isEmpty())
|
||
|
+ {
|
||
|
+ int ret = system( QFile::encodeName( testexec ));
|
||
|
+ if( !WIFEXITED( ret ) || WEXITSTATUS( ret ) != 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->insertItem( name );
|
||
|
+ if( wms[ name ] == current ) // make it selected
|
||
|
+ {
|
||
|
+ dialog->windowManagerCombo->setCurrentItem( dialog->windowManagerCombo->count() - 1 );
|
||
|
+ oldwm = wm;
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+QString SMServerConfig::currentWM() const
|
||
|
+{
|
||
|
+ return wms[ dialog->windowManagerCombo->currentText() ];
|
||
|
+}
|
||
|
+
|
||
|
#include "kcmsmserver.moc"
|
||
|
|
||
|
Index: kcontrol/smserver/kcmsmserver.h
|
||
|
===================================================================
|
||
|
--- kcontrol/smserver/kcmsmserver.h.orig
|
||
|
+++ kcontrol/smserver/kcmsmserver.h
|
||
|
@@ -40,6 +40,10 @@ public:
|
||
|
|
||
|
private:
|
||
|
SMServerConfigImpl* dialog;
|
||
|
+ void loadWMs( const QString& current );
|
||
|
+ QString currentWM() const;
|
||
|
+ QMap< QString, QString > wms; // i18n text -> internal name
|
||
|
+ QString oldwm; // the original value
|
||
|
|
||
|
};
|
||
|
|