diff options
Diffstat (limited to 'opensuse/tdebase/select-wm-gui.diff')
-rw-r--r-- | opensuse/tdebase/select-wm-gui.diff | 635 |
1 files changed, 635 insertions, 0 deletions
diff --git a/opensuse/tdebase/select-wm-gui.diff b/opensuse/tdebase/select-wm-gui.diff new file mode 100644 index 000000000..823262962 --- /dev/null +++ b/opensuse/tdebase/select-wm-gui.diff @@ -0,0 +1,635 @@ +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 + + }; + |