[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Mixing KDE3 and KDE4
From: Lubos Lunak <l.lunak () suse ! cz>
Date: 2008-03-16 18:00:10
Message-ID: 200803161900.10394.l.lunak () suse ! cz
[Download RAW message or body]
Hello,
the 'mixing' in the subject refers to being able to run things from KDE3 and
KDE4 at the same time, not just install them alongside. Currently, I'm aware
of these issues:
- session management doesn't work - ksmserver restores "its" version (i.e. run
KWrite from KDE3 in KDE4, you get the KDE4 version after next login)
- launching apps using .desktop files has a similar problem of launching
the "native" version
- logout is delayed by waiting for the "other" kdeinit etc. to exit after a
timeout
I'd expect the list to be longer and therefore I'd like to collect all such
problems. Some of these possibly don't exist with distros that install
everything in /usr (I can't see how they want to install KWrite both from
KDE3 and KDE4), but even there people e.g. may be interested in running other
version they built from sources.
To solve some of the above things I suggest the attached patches:
- there are scripts 'kde3' and 'kde4', to be used as wrappers when
launching "foreign" KDE apps. They may need to be patched by specific
distributions to run them from the proper prefix, set up some env. variables
or whatever. They may also be extended to try to run the apps using kdeinit
if possible for better performance.
Does this look ok, or does somebody have a better idea?
- kdelibs is patched to make apps explicitly tell ksmserver their KDE version,
ksmserver then will use kde3/kde4 if appropriate to launch such apps
- startkde is patched to immediatelly shut down "other" kdeinit (need some
commits I did recently to be really fast)
(CC-ing packagers as they're most likely to know, but please keep the
discussion on kde-core-devel, thanks)
--
Lubos Lunak
KDE developer
--------------------------------------------------------------
SUSE LINUX, s.r.o. e-mail: l.lunak@suse.cz , l.lunak@kde.org
Lihovarska 1060/12 tel: +420 284 028 972
190 00 Prague 9 fax: +420 284 028 951
Czech Republic http://www.suse.cz
["kdebase3.patch" (text/x-diff)]
--- kdebase/ksmserver/client.h.sav 2008-03-08 17:16:24.000000000 +0100
+++ kdebase/ksmserver/client.h 2008-03-14 15:47:01.000000000 +0100
@@ -51,6 +51,7 @@ public:
int restartStyleHint() const;
QString userId() const;
const char* clientId() { return id ? id : ""; }
+ int specialKdeVersion() const;
private:
const char* id;
--- kdebase/ksmserver/startup.cpp.sav 2008-03-08 17:16:24.000000000 +0100
+++ kdebase/ksmserver/startup.cpp 2008-03-14 15:52:01.000000000 +0100
@@ -105,11 +105,13 @@ void KSMServer::restoreSession( QString
appsToStart = count;
QValueList<QStringList> wmCommands;
+ int wmSpecialKdeVersion = 0;
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 );
+ wmSpecialKdeVersion = config->readNumEntry( QString( "specialKdeVersion")+n, 0 );
}
}
}
@@ -130,7 +132,7 @@ void KSMServer::restoreSession( QString
// 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] );
+ startApplication( wmCommands[i], QString(), QString(), wmSpecialKdeVersion );
QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
} else {
autoStart0();
@@ -268,7 +270,8 @@ void KSMServer::tryRestoreNext()
continue;
startApplication( restartCommand,
config->readEntry( QString("clientMachine")+n ),
- config->readEntry( QString("userId")+n ));
+ config->readEntry( QString("userId")+n ),
+ config->readNumEntry( QString("specialKdeVersion")+n, 0 ));
lastIdStarted = config->readEntry( QString("clientId")+n );
if ( !lastIdStarted.isEmpty() ) {
restoreTimer.start( 2000, TRUE );
--- kdebase/ksmserver/server.h.sav 2008-03-08 17:16:24.000000000 +0100
+++ kdebase/ksmserver/server.h 2008-03-14 15:49:14.000000000 +0100
@@ -134,7 +134,8 @@ private:
void startApplication( QStringList command,
const QString& clientMachine = QString::null,
- const QString& userId = QString::null );
+ const QString& userId = QString::null,
+ int specialKdeVersion = 0 );
void executeCommand( const QStringList& command );
bool isWM( const KSMClient* client ) const;
--- kdebase/ksmserver/server.cpp.sav 2008-03-08 17:16:24.000000000 +0100
+++ kdebase/ksmserver/server.cpp 2008-03-14 15:51:41.000000000 +0100
@@ -99,10 +99,15 @@ KSMServer* KSMServer::self()
* to restart applications.
*/
void KSMServer::startApplication( QStringList command, const QString& clientMachine,
- const QString& userId )
+ const QString& userId, int specialKdeVersion )
{
if ( command.isEmpty() )
return;
+ if( specialKdeVersion != KDE_VERSION_MAJOR ) {
+ QString wrapper = "kde" + QString::number( specialKdeVersion );
+ if( !KStandardDirs::findExe( wrapper ).isEmpty())
+ command.prepend( wrapper );
+ }
if ( !userId.isEmpty()) {
struct passwd* pw = getpwuid( getuid());
if( pw != NULL && userId != QString::fromLocal8Bit( pw->pw_name )) {
@@ -879,6 +884,9 @@ void KSMServer::storeSession()
config->writePathEntry( QString("discardCommand")+n, c->discardCommand() );
config->writeEntry( QString("restartStyleHint")+n, restartHint );
config->writeEntry( QString("userId")+n, c->userId() );
+ int specialVersion = c->specialKdeVersion();
+ if( specialVersion != 0 && specialVersion != KDE_VERSION_MAJOR )
+ config->writeEntry( QString("specialKdeVersion")+n, specialVersion );
}
config->writeEntry( "count", count );
--- kdebase/ksmserver/client.cpp.sav 2008-03-08 17:16:24.000000000 +0100
+++ kdebase/ksmserver/client.cpp 2008-03-14 15:47:46.000000000 +0100
@@ -187,4 +187,10 @@ QString KSMClient::userId() const
return QString::fromLatin1( (const char*) p->vals[0].value );
}
-
+int KSMClient::specialKdeVersion() const
+{
+ SmProp* p = property( "_KDE_VERSION" );
+ if( !p || qstrcmp( p->type, SmARRAY8 ) != 0 || p->num_vals != 1 )
+ return 0;
+ return atoi( (const char*) p->vals[0].value );
+}
--- kdebase/Makefile.am.in.sav 2008-03-08 17:23:21.000000000 +0100
+++ kdebase/Makefile.am.in 2008-03-14 20:10:08.000000000 +0100
@@ -9,7 +9,7 @@ COMPILE_AFTER_kcontrol = kdm kdesktop
AUTOMAKE_OPTIONS = foreign 1.6.1
-bin_SCRIPTS = startkde
+bin_SCRIPTS = startkde kde3
EXTRA_DIST = admin bsd-port debian kdebase.spec.in README.pam kde.pamd kscreensaver.pamd mkpamserv
--- kdebase/startkde.sav 2008-03-08 17:23:21.000000000 +0100
+++ kdebase/startkde 2008-03-14 20:09:38.000000000 +0100
@@ -387,6 +387,8 @@ echo 'startkde: Shutting down...' 1>&2
kdeinit_shutdown
dcopserver_shutdown --wait
artsshell -q terminate
+# KDE4 support
+kde4 kdeinit4_shutdown 2>/dev/null
echo 'startkde: Running shutdown scripts...' 1>&2
--- kdebase/kde3.sav 2008-03-14 20:09:51.000000000 +0100
+++ kdebase/kde3 2008-03-14 20:15:08.000000000 +0100
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Script for launching KDE3 applications from outside of the KDE3 desktop
+#
+# Modify this to match your specific needs, such as setting up needed env. variables,
+# and make sure this script is in $PATH (e.g. make a symlink if necessary).
+#
+
+exec "$@"
["kdelibs3.patch" (text/x-diff)]
--- kdelibs/kdecore/kapplication.cpp.sav 2008-03-08 17:26:49.000000000 +0100
+++ kdelibs/kdecore/kapplication.cpp 2008-03-14 15:33:14.000000000 +0100
@@ -1200,9 +1200,25 @@ void KApplication::propagateSessionManag
#endif
}
+// QSessionManager::setManagerProperty() is broken in Qt3
+static void setVersionSmProperty( QSessionManager& sm )
+{
+ SmProp prop;
+ prop.name = (char*)"_KDE_VERSION";
+ prop.type = (char*)SmARRAY8;
+ prop.num_vals = 1;
+ SmPropValue val;
+ prop.vals = &val;
+ val.length = 1;
+ val.value = (SmPointer)"3";
+ SmProp* p[ 1 ] = { &prop };
+ SmcSetProperties( (SmcConn)sm.handle(), 1, p );
+}
+
void KApplication::commitData( QSessionManager& sm )
{
d->session_save = true;
+ setVersionSmProperty( sm );
bool canceled = false;
for (KSessionManaged* it = sessionClients()->first();
it && !canceled;
@@ -1247,6 +1263,7 @@ void KApplication::commitData( QSessionM
void KApplication::saveState( QSessionManager& sm )
{
d->session_save = true;
+ setVersionSmProperty( sm );
#ifdef Q_WS_X11
static bool firstTime = true;
mySmcConnection = (SmcConn) sm.handle();
["kdelibs4.patch" (text/x-diff)]
--- kdelibs/kdeui/kernel/kapplication.cpp.sav 2008-03-11 19:15:21.000000000 +0100
+++ kdelibs/kdeui/kernel/kapplication.cpp 2008-03-14 15:06:24.000000000 +0100
@@ -683,6 +683,7 @@ void KApplication::enableSessionManageme
void KApplication::commitData( QSessionManager& sm )
{
d->session_save = true;
+ sm.setManagerProperty( "_KDE_VERSION", QString::number( KDE_VERSION_MAJOR ));
bool canceled = false;
foreach (KSessionManager *it, KSessionManager::sessionClients()) {
@@ -732,6 +733,7 @@ commitDataRestart:
void KApplication::saveState( QSessionManager& sm )
{
d->session_save = true;
+ sm.setManagerProperty( "_KDE_VERSION", QString::number( KDE_VERSION_MAJOR ));
#ifdef Q_WS_X11
static bool firstTime = true;
mySmcConnection = (SmcConn) sm.handle();
["kdebase4.patch" (text/x-diff)]
--- kdebase/runtime/kde4.sav 2008-03-14 20:09:51.000000000 +0100
+++ kdebase/runtime/kde4 2008-03-14 20:15:29.000000000 +0100
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# Script for launching KDE4 applications from outside of the KDE4 desktop
+#
+# Modify this to match your specific needs, such as setting up needed env. \
variables, +# and make sure this script is in $PATH (e.g. make a symlink if \
necessary). +#
+
+exec "$@"
--- kdebase/runtime/CMakeLists.txt.sav 2008-02-09 15:13:25.000000000 +0100
+++ kdebase/runtime/CMakeLists.txt 2008-03-14 20:14:44.000000000 +0100
@@ -80,3 +80,5 @@ if(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CU
macro_display_feature_log()
endif(CMAKE_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
+########### install files ###############
+install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/kde4 DESTINATION ${BIN_INSTALL_DIR})
--- kdebase/workspace/ksmserver/client.h.sav 2008-01-19 18:39:05.000000000 +0100
+++ kdebase/workspace/ksmserver/client.h 2008-03-14 12:58:51.000000000 +0100
@@ -58,6 +58,7 @@ public:
int restartStyleHint() const;
QString userId() const;
const char* clientId() { return id ? id : ""; }
+ int specialKdeVersion() const;
private:
const char* id;
--- kdebase/workspace/ksmserver/startup.cpp.sav 2008-01-19 18:39:05.000000000 +0100
+++ kdebase/workspace/ksmserver/startup.cpp 2008-03-14 15:35:41.000000000 +0100
@@ -100,11 +100,13 @@ void KSMServer::restoreSession( const QS
appsToStart = count;
QList<QStringList> wmCommands;
+ int wmSpecialKdeVersion = 0;
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() ); + wmSpecialKdeVersion = configSessionGroup.readEntry( \
QString( "specialKdeVersion")+n, 0 ); }
}
}
@@ -122,7 +124,7 @@ void KSMServer::restoreSession( const QS
// 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] );
+ startApplication( wmCommands[i], QString(), QString(), \
wmSpecialKdeVersion ); QTimer::singleShot( 4000, this, SLOT( autoStart0() ) );
} else {
autoStart0();
@@ -258,7 +260,8 @@ void KSMServer::tryRestoreNext()
continue;
startApplication( restartCommand,
config.readEntry( QString("clientMachine")+n, QString() ),
- config.readEntry( QString("userId")+n, QString() ));
+ config.readEntry( QString("userId")+n, QString() ),
+ config.readEntry( QString("specialKdeVersion")+n, 0 ));
lastIdStarted = config.readEntry( QString("clientId")+n, QString() );
if ( !lastIdStarted.isEmpty() ) {
restoreTimer.setSingleShot( true );
--- kdebase/workspace/ksmserver/server.h.sav 2008-03-03 22:05:03.000000000 +0100
+++ kdebase/workspace/ksmserver/server.h 2008-03-14 13:04:42.000000000 +0100
@@ -144,7 +144,8 @@ private:
void startApplication( QStringList& command,
const QString& clientMachine = QString(),
- const QString& userId = QString() );
+ const QString& userId = QString(),
+ int specialKdeVersion = 0 );
void executeCommand( const QStringList& command );
bool isWM( const KSMClient* client ) const;
--- kdebase/workspace/ksmserver/server.cpp.sav 2008-03-03 22:05:00.000000000 +0100
+++ kdebase/workspace/ksmserver/server.cpp 2008-03-14 15:46:47.000000000 +0100
@@ -94,10 +94,15 @@ KSMServer* KSMServer::self()
* to restart applications.
*/
void KSMServer::startApplication( QStringList& command, const QString& \
clientMachine,
- const QString& userId )
+ const QString& userId, int specialKdeVersion )
{
if ( command.isEmpty() )
return;
+ if( specialKdeVersion != KDE_VERSION_MAJOR ) {
+ QString wrapper = "kde" + QString::number( specialKdeVersion );
+ if( !KStandardDirs::findExe( wrapper ).isEmpty())
+ command.prepend( wrapper );
+ }
if ( !userId.isEmpty()) {
struct passwd* pw = getpwuid( getuid());
if( pw != NULL && userId != QString::fromLocal8Bit( pw->pw_name )) {
@@ -881,6 +886,9 @@ void KSMServer::storeSession()
cg.writePathEntry( QString("discardCommand")+n, c->discardCommand() );
cg.writeEntry( QString("restartStyleHint")+n, restartHint );
cg.writeEntry( QString("userId")+n, c->userId() );
+ int specialVersion = c->specialKdeVersion();
+ if( specialVersion != 0 && specialVersion != KDE_VERSION_MAJOR )
+ cg.writeEntry( QString("specialKdeVersion")+n, specialVersion );
}
cg.writeEntry( "count", count );
--- kdebase/workspace/ksmserver/client.cpp.sav 2008-01-19 18:39:05.000000000 +0100
+++ kdebase/workspace/ksmserver/client.cpp 2008-03-14 15:47:12.000000000 +0100
@@ -183,3 +183,11 @@ QString KSMClient::userId() const
return QString();
return QLatin1String( (const char*) p->vals[0].value );
}
+
+int KSMClient::specialKdeVersion() const
+{
+ SmProp* p = property( "_KDE_VERSION" );
+ if( !p || qstrcmp( p->type, SmARRAY8 ) != 0 || p->num_vals != 1 )
+ return 0;
+ return atoi( (const char*) p->vals[0].value );
+}
--- kdebase/workspace/startkde.cmake.sav 2008-03-11 19:17:44.000000000 +0100
+++ kdebase/workspace/startkde.cmake 2008-03-14 20:17:03.000000000 +0100
@@ -401,6 +401,8 @@ test -n "$ksplash_pid" && kill "$ksplash
# Clean up
kdeinit4_shutdown
+# KDE4 support
+kde4 kdeinit4_shutdown 2>/dev/null
echo 'startkde: Running shutdown scripts...' 1>&2
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic