? 2001-03-16.diff ? 2001-03-12.diff ? 2001-03-10.diff ? 2001-03-14.diff ? 2001-03-19.diff ? workspace.cpp.debug Index: atoms.cpp =================================================================== RCS file: /home/kde/kdebase/kwin/atoms.cpp,v retrieving revision 1.13 diff -u -3 -p -r1.13 atoms.cpp --- atoms.cpp 2000/06/24 17:58:10 1.13 +++ atoms.cpp 2001/03/19 16:31:07 @@ -30,6 +30,12 @@ Atoms::Atoms() atoms[n] = &wm_change_state; names[n++] = (char *) "WM_CHANGE_STATE"; + atoms[n] = &wm_client_leader; + names[n++] = (char *) "WM_CLIENT_LEADER"; + + atoms[n] = &wm_save_yourself; + names[n++] = (char *) "WM_SAVE_YOURSELF"; + atoms[n] = &motif_wm_hints; names[n++] = (char *) "_MOTIF_WM_HINTS"; Index: atoms.h =================================================================== RCS file: /home/kde/kdebase/kwin/atoms.h,v retrieving revision 1.13 diff -u -3 -p -r1.13 atoms.h --- atoms.h 2000/06/24 17:58:10 1.13 +++ atoms.h 2001/03/19 16:31:07 @@ -17,6 +17,8 @@ public: Atom wm_delete_window; Atom wm_take_focus; Atom wm_change_state; + Atom wm_client_leader; + Atom wm_save_yourself; Atom motif_wm_hints; Atom net_wm_context_help; Index: client.cpp =================================================================== RCS file: /home/kde/kdebase/kwin/client.cpp,v retrieving revision 1.228 diff -u -3 -p -r1.228 client.cpp --- client.cpp 2001/03/14 09:21:16 1.228 +++ client.cpp 2001/03/19 16:31:08 @@ -518,6 +518,7 @@ Client::Client( Workspace *ws, WId w, QW getWMHints(); getWindowProtocols(); getWmNormalHints(); // get xSizeHint + getWmClientLeader(); fetchName(); if ( mainClient()->isSticky() ) @@ -1150,6 +1151,8 @@ bool Client::propertyNotify( XPropertyEv default: if ( e.atom == atoms->wm_protocols ) getWindowProtocols(); + else if (e.atom == atoms->wm_client_leader ) + getWmClientLeader(); break; } return TRUE; @@ -2603,79 +2606,183 @@ void Client::keyPressEvent( QKeyEvent * QCursor::setPos( pos ); } +static int nullErrorHandler(Display *, XErrorEvent *) +{ + return 0; +} -QCString Client::windowRole() +static QCString getStringProperty(WId w, Atom prop, char separator=0) { Atom type; - int format; - unsigned long length, after; - unsigned char *data; - QCString result; - if ( XGetWindowProperty( qt_xdisplay(), win, qt_window_role, 0, 1024, - FALSE, XA_STRING, &type, &format, - &length, &after, &data ) == Success ) { - if ( data ) - result = (const char*) data; - XFree( data ); + int format, status; + unsigned long nitems = 0; + unsigned long extra = 0; + unsigned char *data = 0; + QCString result = ""; + XErrorHandler oldHandler = XSetErrorHandler(nullErrorHandler); + status = XGetWindowProperty( qt_xdisplay(), w, prop, 0, 10000, + FALSE, XA_STRING, &type, &format, + &nitems, &extra, &data ); + XSetErrorHandler(oldHandler); + if ( status == Success) { + if (data && separator) { + for (int i=0; i<(int)nitems; i++) + if (!data[i] && i+1<(int)nitems) + data[i] = separator; + } + if (data) + result = (const char*) data; + XFree(data); } return result; } -QCString Client::sessionId() +/*! + Returns WINDOW_ROLE property for a given window. + */ +QCString Client::staticWindowRole(WId w) +{ + return getStringProperty(w, qt_window_role); +} + +/*! + Returns SM_CLIENT_ID property for a given window. + */ +QCString Client::staticSessionId(WId w) +{ + return getStringProperty(w, qt_sm_client_id); +} + +/*! + Returns WM_COMMAND property for a given window. + */ +QCString Client::staticWmCommand(WId w) { + return getStringProperty(w, XA_WM_COMMAND, ' '); +} + +/*! + Returns WM_CLIENT_MACHINE property for a given window. + Local machine is always returned as "localhost". + */ +QCString Client::staticWmClientMachine(WId w) +{ + QCString result = getStringProperty(w, XA_WM_CLIENT_MACHINE); + if (result.isEmpty()) { + result = "localhost"; + } else { + // special name for the local machine (localhost) + char hostnamebuf[80]; + if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0) { + hostnamebuf[sizeof(hostnamebuf)-1] = 0; + if (result == hostnamebuf) + result = "localhost"; + char *dot = strchr(hostnamebuf, '.'); + if (dot && !(*dot = 0) && result == hostnamebuf) + result = "localhost"; + } + } + return result; +} + +/*! + Returns WM_CLIENT_LEADER property for a given window. + */ +Window Client::staticWmClientLeader(WId w) +{ Atom type; - int format; - unsigned long length, after; - unsigned char *data; - QCString result; - if ( XGetWindowProperty( qt_xdisplay(), win, qt_sm_client_id, 0, 1024, - FALSE, XA_STRING, &type, &format, - &length, &after, &data ) == Success ) { - if ( data ) - result = (const char*) data; - XFree( data ); + int format, status; + unsigned long nitems = 0; + unsigned long extra = 0; + unsigned char *data = 0; + Window result = w; + XErrorHandler oldHandler = XSetErrorHandler(nullErrorHandler); + status = XGetWindowProperty( qt_xdisplay(), w, atoms->wm_client_leader, 0, 10000, + FALSE, XA_WINDOW, &type, &format, + &nitems, &extra, &data ); + XSetErrorHandler(oldHandler); + if (status == Success ) { + if (data && nitems > 0) + result = *((Window*) data); + XFree(data); } return result; } +void Client::getWmClientLeader() +{ + wmClientLeaderWin = staticWmClientLeader(win); +} -static int getprop(Window w, Atom a, Atom type, long len, unsigned char **p) +/*! + Returns WINDOW_ROLE for this client + */ +QCString Client::windowRole() { - Atom real_type; - int format; - unsigned long n, extra; - int status; - - status = XGetWindowProperty(qt_xdisplay(), w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p); - if (status != Success || *p == 0) - return -1; - if (n == 0) - XFree((void*) *p); - return n; + return staticWindowRole(win); } -QCString Client::wmCommand() +/*! + Returns sessionId for this client, + taken either from its window or from the leader window. + */ +QCString Client::sessionId() { - QCString result; - char *p; - int i,n; - if ((n = getprop(win, XA_WM_COMMAND, XA_STRING, 100L, (unsigned char **)&p)) > 0){ - result = p; - for ( i = 0; (i += strlen(p+i)+1) < n; result.append(p+i) ) - result.append(" "); - XFree((char *) p); - } - return result; + QCString result = staticSessionId(win); + if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=win) + result = staticSessionId(wmClientLeaderWin); + return result; } +/*! + Returns the classhint resource name for this client, + */ QCString Client::resourceName() { return resource_name; } +/*! + Returns the classhint resource class for this client, + */ QCString Client::resourceClass() { return resource_class; +} + +/*! + Returns command property for this client, + taken either from its window or from the leader window. + */ +QCString Client::wmCommand() +{ + QCString result = staticWmCommand(win); + if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=win) + result = staticWmCommand(wmClientLeaderWin); + return result; +} + +/*! + Returns client machine for this client, + taken either from its window or from the leader window. +*/ +QCString Client::wmClientMachine() +{ + QCString result = staticWmClientMachine(win); + if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=win) + result = staticWmClientMachine(wmClientLeaderWin); + return result; +} + +/*! + Returns client leader window for this client. + Returns the client window itself if no leader window is defined. +*/ +Window Client::wmClientLeader() +{ + if (wmClientLeaderWin) + return wmClientLeaderWin; + return win; } Index: client.h =================================================================== RCS file: /home/kde/kdebase/kwin/client.h,v retrieving revision 1.65 diff -u -3 -p -r1.65 client.h --- client.h 2001/03/12 21:32:13 1.65 +++ client.h 2001/03/19 16:31:08 @@ -181,9 +181,11 @@ public: QCString windowRole(); QCString sessionId(); - QCString wmCommand(); QCString resourceName(); QCString resourceClass(); + QCString wmCommand(); + QCString wmClientMachine(); + Window wmClientLeader(); QRect adjustedClientArea( const QRect& area ) const; @@ -317,6 +319,16 @@ private: void verifyTransientFor(); friend class WindowWrapper; QString cap; + WId wmClientLeaderWin; + void getWmClientLeader(); + + public: + static QCString staticWindowRole(WId); + static QCString staticSessionId(WId); + static QCString staticWmCommand(WId); + static QCString staticWmClientMachine(WId); + static Window staticWmClientLeader(WId); + }; inline WId Client::window() const Index: workspace.cpp =================================================================== RCS file: /home/kde/kdebase/kwin/workspace.cpp,v retrieving revision 1.221 diff -u -3 -p -r1.221 workspace.cpp --- workspace.cpp 2001/03/14 10:16:08 1.221 +++ workspace.cpp 2001/03/19 16:31:08 @@ -3,7 +3,10 @@ kwin - the KDE window manager Copyright (C) 1999, 2000 Matthias Ettrich ******************************************************************/ + //#define QT_CLEAN_NAMESPACE +#define select kwin_hide_select + #include #include #include @@ -42,6 +45,15 @@ const int XIconicState = IconicState; #include #include +// Possible protoypes for select() were hidden as `kwin_hide_select. +// Undo the hiding definition and defines an acceptable prototype. +// This is how QT does this. It should work where QT works. +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#undef select +extern "C" int select(int,void*,void*,void*,struct timeval*); + namespace KWinInternal { // NET WM Protocol handler class @@ -280,15 +292,8 @@ Workspace::Workspace( bool restore ) init(); - if ( restore ) { // pseudo session management with wmCommand - for (SessionInfo* info = session.first(); info; info = session.next() ) { - if ( info->sessionId.isEmpty() && !info->wmCommand.isEmpty() ) { - KShellProcess proc; - proc << QString::fromLatin1( info->wmCommand ); - proc.start(KShellProcess::DontCare); - } - } - } + if ( restore ) + restoreLegacySession(kapp->sessionConfig()); } void Workspace::init() @@ -2924,26 +2929,201 @@ void Workspace::slotResetAllClients() requestFocus( active ); } + +/* + * Legacy session management + */ + +#ifndef NO_LEGACY_SESSION_MANAGEMENT +#define WM_SAVE_YOURSELF_TIMEOUT 4000 + +typedef QMap WindowMap; +#define HAS_ERROR 0 +#define HAS_WMCOMMAND 1 +#define HAS_WMSAVEYOURSELF 2 + +static WindowMap *windowMapPtr = 0; + +static int winsErrorHandler(Display *, XErrorEvent *ev) +{ + if (windowMapPtr) { + WindowMap::Iterator it = windowMapPtr->find(ev->resourceid); + if (it != windowMapPtr->end()) + it.data() = HAS_ERROR; + } + return 0; +} + /*! + Stores legacy session management data +*/ +void Workspace::storeLegacySession( KConfig* config ) +{ + // Setup error handler + WindowMap wins; + windowMapPtr = &wins; + XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler); + // Compute set of leader windows that need legacy session management + // and determine which style (WM_COMMAND or WM_SAVE_YOURSELF) + for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) { + Client* c = (*it); + WId leader = c->wmClientLeader(); + if (!wins.contains(leader) && c->sessionId().isEmpty()) { + int wtype = HAS_WMCOMMAND; + int nprotocols = 0; + Atom *protocols = 0; + XGetWMProtocols(qt_xdisplay(), leader, &protocols, &nprotocols); + for (int i=0; iwm_save_yourself) { + wtype = HAS_WMSAVEYOURSELF; + break; + } + XFree((void*) protocols); + wins.insert(leader, wtype); + } + } + // Open fresh display for sending WM_SAVE_YOURSELF + XSync(qt_xdisplay(), False); + Display *newdisplay = XOpenDisplay(DisplayString(qt_xdisplay())); + if (!newdisplay) return; + WId root = DefaultRootWindow(newdisplay); + XGrabKeyboard(newdisplay, root, False, + GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabPointer(newdisplay, root, False, Button1Mask|Button2Mask|Button3Mask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + // Send WM_SAVE_YOURSELF messages + XEvent ev; + int awaiting_replies = 0; + for (WindowMap::Iterator it = wins.begin(); it != wins.end(); ++it) { + if ( it.data() == HAS_WMSAVEYOURSELF ) { + WId w = it.key(); + awaiting_replies += 1; + memset(&ev, 0, sizeof(ev)); + ev.xclient.type = ClientMessage; + ev.xclient.window = w; + ev.xclient.message_type = atoms->wm_protocols; + ev.xclient.format = 32; + ev.xclient.data.l[0] = atoms->wm_save_yourself; + ev.xclient.data.l[1] = CurrentTime; + XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask); + XSendEvent(newdisplay, w, False, 0, &ev); + } + } + // Wait for change in WM_COMMAND with timeout + XFlush(newdisplay); + QTime start = QTime::currentTime(); + while (awaiting_replies > 0) { + if (XPending(newdisplay)) { + /* Process pending event */ + XNextEvent(newdisplay, &ev); + if ( ( ev.xany.type == UnmapNotify ) || + ( ev.xany.type == PropertyNotify && ev.xproperty.atom == XA_WM_COMMAND ) ) { + WindowMap::Iterator it = wins.find( ev.xany.window ); + if ( it != wins.end() && it.data() != HAS_WMCOMMAND ) { + awaiting_replies -= 1; + if ( it.data() != HAS_ERROR ) + it.data() = HAS_WMCOMMAND; + } + } + } else { + /* Check timeout */ + int msecs = start.elapsed(); + if (msecs >= WM_SAVE_YOURSELF_TIMEOUT) + break; + /* Wait for more events */ + fd_set fds; + FD_ZERO(&fds); + int fd = ConnectionNumber(newdisplay); + FD_SET(fd, &fds); + struct timeval tmwait; + tmwait.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000; + tmwait.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000; + ::select(fd+1, &fds, NULL, &fds, &tmwait); + } + } + // Terminate work in new display + XAllowEvents(newdisplay, ReplayPointer, CurrentTime); + XAllowEvents(newdisplay, ReplayKeyboard, CurrentTime); + XSync(newdisplay, False); + XCloseDisplay(newdisplay); + // Write LegacySession data + config->setGroup("LegacySession" ); + int count = 0; + for (WindowMap::Iterator it = wins.begin(); it != wins.end(); ++it) { + if (it.data() != HAS_ERROR) { + WId w = it.key(); + QCString wmCommand = Client::staticWmCommand(w); + QCString wmClientMachine = Client::staticWmClientMachine(w); + if ( !wmCommand.isEmpty() && !wmClientMachine.isEmpty() ) { + count++; + QString n = QString::number(count); + config->writeEntry( QString("command")+n, wmCommand.data() ); + config->writeEntry( QString("clientMachine")+n, wmClientMachine.data() ); + } + } + } + config->writeEntry( "count", count ); + // Restore old error handler + XSync(qt_xdisplay(), False); + XSetErrorHandler(oldHandler); + // Process a few events to update the client list. + // All events should be there because of the XSync above. + kapp->processEvents(10); +} +#endif + +/*! + Restores legacy session management data (i.e. restart applications) +*/ +void Workspace::restoreLegacySession( KConfig* config ) +{ + if (config) { + config->setGroup("LegacySession" ); + int count = config->readNumEntry( "count" ); + for ( int i = 1; i <= count; i++ ) { + QString n = QString::number(i); + QCString wmCommand = config->readEntry( QString("command")+n ).latin1(); + QCString wmClientMachine = config->readEntry( QString("clientMachine")+n ).latin1(); + if ( !wmCommand.isEmpty() && !wmClientMachine.isEmpty() ) { + KShellProcess proc; + if ( wmClientMachine != "localhost" ) + proc << "xon" << wmClientMachine; + proc << QString::fromLatin1( wmCommand ); + proc.start(KShellProcess::DontCare); + } + } + } +} + +/*! Stores the current session in the config file \sa loadSessionInfo() */ void Workspace::storeSession( KConfig* config ) { +#ifndef NO_LEGACY_SESSION_MANAGEMENT + storeLegacySession(config); +#endif config->setGroup("Session" ); int count = 0; for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) { Client* c = (*it); QCString sessionId = c->sessionId(); - QCString windowRole = c->windowRole(); QCString wmCommand = c->wmCommand(); - if ( !sessionId.isEmpty() || !wmCommand.isEmpty() ) { + if (! sessionId.isEmpty() +#ifndef NO_LEGACY_SESSION_MANAGEMENT + || ! wmCommand.isEmpty() ) +#endif + { count++; QString n = QString::number(count); config->writeEntry( QString("sessionId")+n, sessionId.data() ); - config->writeEntry( QString("windowRole")+n, windowRole.data() ); + config->writeEntry( QString("windowRole")+n, c->windowRole().data() ); config->writeEntry( QString("wmCommand")+n, wmCommand.data() ); + config->writeEntry( QString("wmClientMachine")+n, c->wmClientMachine().data() ); + config->writeEntry( QString("resourceName")+n, c->resourceName().data() ); + config->writeEntry( QString("resourceClass")+n, c->resourceClass().data() ); config->writeEntry( QString("geometry")+n, QRect( c->pos(), c->windowWrapper()->size() ) ); config->writeEntry( QString("restore")+n, c->geometryRestore() ); config->writeEntry( QString("maximize")+n, (int) c->maximizeMode() ); @@ -2952,7 +3132,7 @@ void Workspace::storeSession( KConfig* c config->writeEntry( QString("sticky")+n, c->isSticky() ); config->writeEntry( QString("shaded")+n, c->isShade() ); config->writeEntry( QString("staysOnTop")+n, c->staysOnTop() ); - config->writeEntry( QString("skipTaskbar")+n, c->skipTaskbar() ); + config->writeEntry( QString("skipTaskbar")+n, c->skipTaskbar() ); } } config->writeEntry( "count", count ); @@ -2977,6 +3157,9 @@ void Workspace::loadSessionInfo() info->sessionId = config->readEntry( QString("sessionId")+n ).latin1(); info->windowRole = config->readEntry( QString("windowRole")+n ).latin1(); info->wmCommand = config->readEntry( QString("wmCommand")+n ).latin1(); + info->wmClientMachine = config->readEntry( QString("wmClientMachine")+n ).latin1(); + info->resourceName = config->readEntry( QString("resourceName")+n ).latin1(); + info->resourceClass = config->readEntry( QString("resourceClass")+n ).latin1(); info->geometry = config->readRectEntry( QString("geometry")+n ); info->restore = config->readRectEntry( QString("restore")+n ); info->maximize = config->readNumEntry( QString("maximize")+n, 0 ); @@ -3001,6 +3184,7 @@ void Workspace::loadFakeSessionInfo() fakeSession.append( info ); info->resourceName = config->readEntry( QString("resourceName")+n ).latin1(); info->resourceClass = config->readEntry( QString("resourceClass")+n ).latin1(); + info->wmClientMachine = config->readEntry( QString("clientMachine")+n ).latin1(); info->geometry = config->readRectEntry( QString("geometry")+n ); info->restore = config->readRectEntry( QString("restore")+n ); info->maximize = config->readNumEntry( QString("maximize")+n, 0 ); @@ -3021,6 +3205,7 @@ void Workspace::storeFakeSessionInfo( Cl fakeSession.append( info ); info->resourceName = c->resourceName(); info->resourceClass = c->resourceClass(); + info->wmClientMachine = c->wmClientMachine(); info->geometry = QRect( c->pos(), c->windowWrapper()->size() ) ; info->restore = c->geometryRestore(); info->maximize = (int)c->maximizeMode(); @@ -3042,6 +3227,7 @@ void Workspace::writeFakeSessionInfo() QString n = QString::number(count); config->writeEntry( QString("resourceName")+n, info->resourceName.data() ); config->writeEntry( QString("resourceClass")+n, info->resourceClass.data() ); + config->writeEntry( QString("clientMachine")+n, info->wmClientMachine.data() ); config->writeEntry( QString("geometry")+n, info->geometry ); config->writeEntry( QString("restore")+n, info->restore ); config->writeEntry( QString("maximize")+n, info->maximize ); @@ -3056,47 +3242,68 @@ void Workspace::writeFakeSessionInfo() } /*! - Returns the SessionInfo for client \a c. The returned session + Returns a SessionInfo for client \a c. The returned session info is removed from the storage. It's up to the caller to delete it. + This function is called when a new window is mapped and must be managed. + We try to find a matching entry in the session. We also try to find + a matching entry in the fakeSession to see if the user had seclected the + ``store settings'' menu entry. + May return 0 if there's no session info for the client. */ SessionInfo* Workspace::takeSessionInfo( Client* c ) { - - if ( !session.isEmpty() ) { - QCString sessionId = c->sessionId(); - QCString windowRole = c->windowRole(); - QCString wmCommand = c->wmCommand(); - - for (SessionInfo* info = session.first(); info; info = session.next() ) { - - // a real session managed client - if ( info->sessionId == sessionId && - ( ( info->windowRole.isEmpty() && windowRole.isEmpty() ) - || (info->windowRole == windowRole ) ) ) - return session.take(); - - // pseudo session management - if ( info->sessionId.isEmpty() && !info->wmCommand.isEmpty() && - info->wmCommand == wmCommand && - ( ( info->windowRole.isEmpty() && windowRole.isEmpty() ) - || (info->windowRole == windowRole ) ) ) - return session.take(); - } - } - - // fakeSession, the "Store Settings" option in the window operation popup menu - if ( !fakeSession.isEmpty() ) { - QCString resourceName = c->resourceName(); - QCString resourceClass = c->resourceClass(); - for (SessionInfo* info = fakeSession.first(); info; info = fakeSession.next() ) { - if ( info->resourceName == resourceName && info->resourceClass == resourceClass ) { - c->setStoreSettings( TRUE ); - return fakeSession.take(); + SessionInfo *realInfo = 0; + SessionInfo *fakeInfo = 0; + QCString sessionId = c->sessionId(); + QCString windowRole = c->windowRole(); + QCString wmCommand = c->wmCommand(); + QCString wmClientMachine = c->wmClientMachine(); + QCString resourceName = c->resourceName(); + QCString resourceClass = c->resourceClass(); + + // First search ``session'' + if (! sessionId.isEmpty() ) { + // look for a real session managed client (algorithm suggested by ICCCM) + for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() ) + if ( info->sessionId == sessionId ) { + if ( ! windowRole.isEmpty() ) { + if ( info->windowRole == windowRole ) + realInfo = session.take(); + } else { + if ( info->windowRole.isEmpty() && + info->resourceName == resourceName && + info->resourceClass == resourceClass ) + realInfo = session.take(); + } } - } - } + } else { + // look for a sessioninfo with matching features. + for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() ) + if ( info->resourceName == resourceName && + info->resourceClass == resourceClass && + info->wmClientMachine == wmClientMachine ) + if ( wmCommand.isEmpty() || info->wmCommand == wmCommand ) + realInfo = session.take(); + } + + // Now search ``fakeSession'' + for (SessionInfo* info = fakeSession.first(); info && !fakeInfo; info = fakeSession.next() ) + if ( info->resourceName == resourceName && + info->resourceClass == resourceClass && + info->wmClientMachine == wmClientMachine ) + fakeInfo = fakeSession.take(); + + // Reconciliate + if (fakeInfo) + c->setStoreSettings( TRUE ); + if (fakeInfo && realInfo) + delete fakeInfo; + if (realInfo) + return realInfo; + if (fakeInfo) + return fakeInfo; return 0; } Index: workspace.h =================================================================== RCS file: /home/kde/kdebase/kwin/workspace.h,v retrieving revision 1.72 diff -u -3 -p -r1.72 workspace.h --- workspace.h 2001/03/14 10:16:08 1.72 +++ workspace.h 2001/03/19 16:31:08 @@ -56,10 +56,9 @@ struct SessionInfo { QCString sessionId; QCString windowRole; - - QCString wmCommand; // compatibility - - QCString resourceName; // for faked session info + QCString wmCommand; + QCString wmClientMachine; + QCString resourceName; QCString resourceClass; QRect geometry; @@ -180,6 +179,8 @@ public: void performWindowOperation( Client* c, Options::WindowOperation op ); + void restoreLegacySession( KConfig* config ); + void storeLegacySession( KConfig* config ); void storeSession( KConfig* config ); SessionInfo* takeSessionInfo( Client* );