[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-bugs-dist
Subject: Bug#9394: PATCH] legacy session management in kwin
From: Leon Bottou <leonb () research ! att ! com>
Date: 2001-03-10 6:20:17
[Download RAW message or body]
Matthias,
This is my first working code for solution #2.
The attached patch gives kwin the following capabilities:
- ability to track WM_CLIENT_LEADER
- for finding the modern sessionID
(e.g. seamless management of gnome apps)
- in legacy session management
(e.g. motif apps, netscape, xemacs, etc.)
- ability to safely perform the WM_SAVE_YOURSELF protocol
(e.g. emacs, netscape, motif apps)
- ability to restart remote legacy application
(assuming that the proper .Xauthority file is accessible)
- ability to match windows with session saved windows on the
basis of sessionId + windowRole
or sessionId + resName + resClass (suggested by ICCCM6)
or resName + resClass + clientMachine + Command
or resName + resClass + clientMachine
or resName + resClass
- ability to properly handle window description that
appear both in [Session] and [fakeSession].
I added a new section in the sessionConfig file.
This new section is named [LegacySession] and contains
the list of applications to start.
This version behaves quite well in all my tests.
Please let me know what you think.
- Leon Bottou
P.S. - Moritz, you are welcome to try and report whatever
problems you observe. Thanks
It is late. Good night.
["2001-03-10.diff" (text/plain)]
? 2001-03-10.diff
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/10 06:03:58
@@ -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/10 06:03:58
@@ -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.226
diff -u -3 -p -r1.226 client.cpp
--- client.cpp 2001/03/06 09:17:43 1.226
+++ client.cpp 2001/03/10 06:03:58
@@ -516,6 +516,7 @@ Client::Client( Workspace *ws, WId w, QW
getWMHints();
getWindowProtocols();
getWmNormalHints(); // get xSizeHint
+ getWmClientLeader();
fetchName();
if ( mainClient()->isSticky() )
@@ -1145,6 +1146,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;
@@ -2589,79 +2592,172 @@ void Client::keyPressEvent( QKeyEvent *
QCursor::setPos( pos );
}
-
-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,
+ unsigned long nitems = 0;
+ unsigned long extra = 0;
+ unsigned char *data = 0;
+ QCString result = "";
+ if ( XGetWindowProperty( qt_xdisplay(), w, prop, 0, 10000,
FALSE, XA_STRING, &type, &format,
- &length, &after, &data ) == Success ) {
- if ( data )
- result = (const char*) data;
- XFree( data );
+ &nitems, &extra, &data ) == 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 );
+ unsigned long nitems = 0;
+ unsigned long extra = 0;
+ unsigned char *data = 0;
+ Window result = w;
+ if ( XGetWindowProperty( qt_xdisplay(), w, atoms->wm_client_leader, 0, 10000,
+ FALSE, XA_WINDOW, &type, &format,
+ &nitems, &extra, &data ) == Success ) {
+ if (data && nitems > 0)
+ result = *((Window*) data);
+ XFree(data);
}
return result;
}
-
-static int getprop(Window w, Atom a, Atom type, long len, unsigned char **p)
+void Client::getWmClientLeader()
{
- Atom real_type;
- int format;
- unsigned long n, extra;
- int status;
+ wmClientLeaderWin = staticWmClientLeader(win);
+}
- 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;
+/*!
+ Returns WINDOW_ROLE for this client
+ */
+QCString Client::windowRole()
+{
+ 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.64
diff -u -3 -p -r1.64 client.h
--- client.h 2001/02/20 01:20:36 1.64
+++ client.h 2001/03/10 06:03:58
@@ -178,9 +178,11 @@ public:
QCString windowRole();
QCString sessionId();
- QCString wmCommand();
QCString resourceName();
QCString resourceClass();
+ QCString wmCommand();
+ QCString wmClientMachine();
+ Window wmClientLeader();
QRect adjustedClientArea( const QRect& area ) const;
@@ -314,6 +316,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.217
diff -u -3 -p -r1.217 workspace.cpp
--- workspace.cpp 2001/03/02 10:35:25 1.217
+++ workspace.cpp 2001/03/10 06:03:59
@@ -280,11 +280,20 @@ 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() ) {
+ if ( restore ) {
+ // legacy session management
+ KConfig* config = kapp->sessionConfig();
+ 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;
- proc << QString::fromLatin1( info->wmCommand );
+ if ( wmClientMachine != "localhost" )
+ proc << "xon" << wmClientMachine;
+ proc << QString::fromLatin1( wmCommand );
proc.start(KShellProcess::DontCare);
}
}
@@ -2888,6 +2897,160 @@ void Workspace::slotResetAllClients()
requestFocus( active );
}
+
+/*
+ * Legacy session management
+ */
+
+#ifndef NO_LEGACY_SESSION_MANAGEMENT
+#define WM_SAVE_YOURSELF_TIMEOUT 2000
+
+#ifndef X_GETTIMEOFDAY // normally defined in Xos.h
+#define X_GETTIMEOFDAY(t) gettimeofday(t, 0)
+#endif
+
+enum WinState { W_INVALID, W_VALID, W_SAVE_YOURSELF, W_SAVE_YOURSELF_OK };
+typedef QMap<WId,WinState> WinMap;
+
+static WinMap *winsPtr = 0;
+
+static int winsErrorHandler(Display *, XErrorEvent *ev)
+{
+ if (winsPtr) {
+ WinMap::Iterator it = winsPtr->find(ev->resourceid);
+ if (it != winsPtr->end())
+ it.data() = W_INVALID;
+ }
+ return 0;
+}
+
+/*!
+ Stores legacy session management data
+*/
+void Workspace::storeLegacySession( KConfig* config )
+{
+ // Compute set of leader windows that
+ // might require legacy session management
+ WinMap wins;
+ for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) {
+ Client* c = (*it);
+ WId leader = c->wmClientLeader();
+ if (!wins.contains(leader) && c->sessionId().isEmpty())
+ wins.insert(leader, W_VALID);
+ }
+
+ // Open a new display for safely doing the WM_SAVE_YOURSELF protocol
+ 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);
+ winsPtr = &wins;
+ XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler);
+
+ // Send WM_SAVE_YOURSELF messages to relevant windows
+ XEvent ev;
+ int awaiting_replies = 0;
+ for (WinMap::Iterator it = wins.begin(); it != wins.end(); ++it) {
+ if ( atoms->wm_protocols == None || atoms->wm_save_yourself == None)
+ break;
+ if ( it.data() == W_VALID ) {
+ WId w = it.key();
+ Atom *protocols = 0;
+ int nprotocols = 0;
+ XGetWMProtocols(newdisplay, w, &protocols, &nprotocols);
+ for (int i=0; i<nprotocols; i++)
+ if (protocols[i] == atoms->wm_save_yourself) {
+ it.data() = W_SAVE_YOURSELF;
+ break;
+ }
+ XFree((void*) protocols);
+ }
+ if ( it.data() == W_SAVE_YOURSELF ) {
+ 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);
+ int msecs = WM_SAVE_YOURSELF_TIMEOUT;
+ while (awaiting_replies > 0 && msecs > 0) {
+ if (XPending(newdisplay)) {
+ /* Process pending event */
+ XNextEvent(newdisplay, &ev);
+ WinMap::Iterator it = wins.find( ev.xany.window );
+ if (it == wins.end() || it.data() == W_SAVE_YOURSELF_OK)
+ continue;
+ if ( ev.type == UnmapNotify ||
+ ( ev.xany.type == PropertyNotify
+ && ev.xproperty.atom == XA_WM_COMMAND ) ) {
+ awaiting_replies -= 1;
+ it.data() = W_SAVE_YOURSELF_OK;
+ }
+ } else {
+ /* Wait for more events */
+ int fd = ConnectionNumber(newdisplay);
+ struct timeval tmwait, tmbefore, tmafter;
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ tmwait.tv_sec = msecs / 1000;
+ tmwait.tv_usec = 1000 * (msecs % 1000);
+ X_GETTIMEOFDAY(&tmbefore);
+ select(fd+1, &fds, NULL, &fds, &tmwait);
+ X_GETTIMEOFDAY(&tmafter);
+ msecs -= (tmafter.tv_sec - tmbefore.tv_sec) * 1000;
+ msecs -= (tmafter.tv_usec - tmbefore.tv_usec) / 1000;
+ msecs -= 1;
+ }
+ }
+
+ // 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 (WinMap::Iterator it = wins.begin(); it != wins.end(); ++it) {
+ if (it.data() != W_INVALID) {
+ 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.
+ kapp->processEvents(200);
+}
+#endif
+
/*!
Stores the current session in the config file
@@ -2895,28 +3058,36 @@ void Workspace::slotResetAllClients()
*/
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() ) {
- count++;
- QString n = QString::number(count);
- config->writeEntry( QString("sessionId")+n, sessionId.data() );
- config->writeEntry( QString("windowRole")+n, windowRole.data() );
- config->writeEntry( QString("wmCommand")+n, wmCommand.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() );
- config->writeEntry( QString("desktop")+n, c->desktop() );
- config->writeEntry( QString("iconified")+n, c->isIconified() );
- config->writeEntry( QString("sticky")+n, c->isSticky() );
- config->writeEntry( QString("shaded")+n, c->isShade() );
- config->writeEntry( QString("staysOnTop")+n, c->staysOnTop() );
- }
+ if ( sessionId.isEmpty() )
+#ifndef NO_LEGACY_SESSION_MANAGEMENT
+ if ( wmCommand.isEmpty() )
+#endif
+ continue;
+ count++;
+ QString n = QString::number(count);
+ config->writeEntry( QString("sessionId")+n, sessionId.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() ); + \
config->writeEntry( QString("desktop")+n, c->desktop() ); + \
config->writeEntry( QString("iconified")+n, c->isIconified() ); + \
config->writeEntry( QString("sticky")+n, c->isSticky() ); + \
config->writeEntry( QString("shaded")+n, c->isShade() ); + config->writeEntry( \
QString("staysOnTop")+n, c->staysOnTop() ); }
config->writeEntry( "count", count );
}
@@ -2940,6 +3111,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 );
@@ -2963,6 +3137,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 );
@@ -2982,6 +3157,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();
@@ -3002,6 +3178,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 );
@@ -3015,47 +3192,74 @@ 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
+ for (SessionInfo* info = session.first(); info && !realInfo; info = \
session.next() ) + if ( info->sessionId == sessionId &&
+ info->windowRole.isEmpty() && windowRole.isEmpty() &&
+ info->resourceName == resourceName && info->resourceClass == \
resourceClass ) + realInfo = session.take();
+ for (SessionInfo* info = session.first(); info && !realInfo; info = \
session.next() ) + if ( info->sessionId == sessionId &&
+ ( info->windowRole == windowRole ||
+ ( info->windowRole.isEmpty() && windowRole.isEmpty() ) ) )
+ realInfo = session.take();
+ } else {
+ // look for a window with matching class hints,
+ // and preferably matching command and client machine.
+ for (SessionInfo* info = session.first(); info && !realInfo; info = \
session.next() ) + if ( info->resourceName == resourceName && \
info->resourceClass == resourceClass && + info->wmCommand == \
wmCommand && info->wmClientMachine == wmClientMachine ) + realInfo = \
session.take(); + for (SessionInfo* info = session.first(); info && !realInfo; \
info = session.next() ) + if ( info->resourceName == resourceName && \
info->resourceClass == resourceClass && + info->wmClientMachine == \
wmClientMachine ) + realInfo = session.take();
+ for (SessionInfo* info = session.first(); info && !realInfo; info = \
session.next() ) + if ( info->resourceName == resourceName && \
info->resourceClass == resourceClass ) + 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();
+ for (SessionInfo* info = fakeSession.first(); info && !fakeInfo; info = \
fakeSession.next() ) + if ( info->resourceName == resourceName && \
info->resourceClass == resourceClass ) + 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.69
diff -u -3 -p -r1.69 workspace.h
--- workspace.h 2001/03/08 14:28:07 1.69
+++ workspace.h 2001/03/10 06:03:59
@@ -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;
@@ -177,6 +176,7 @@ public:
void performWindowOperation( Client* c, Options::WindowOperation op );
+ void storeLegacySession( KConfig* config );
void storeSession( KConfig* config );
SessionInfo* takeSessionInfo( Client* );
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic