14 #include <tqsocketnotifier.h>
15 #include <tqsessionmanager.h>
21 #include <tdeconfig.h>
22 #include <tdeglobal.h>
24 #include "workspace.h"
27 namespace KWinInternal
30 bool SessionManaged::saveState( TQSessionManager& sm )
38 char* sm_vendor = SmcVendor(
static_cast< SmcConn
>( sm.handle()));
39 bool ksmserver = qstrcmp( sm_vendor,
"KDE" ) == 0;
43 Workspace::self()->sessionSaveStarted();
45 Workspace::self()->storeSession( kapp->sessionConfig(), SMSavePhase0 );
50 Workspace::self()->storeSession( kapp->sessionConfig(), ksmserver ? SMSavePhase2 : SMSavePhase2Full );
51 kapp->sessionConfig()->sync();
56 bool SessionManaged::commitData( TQSessionManager& sm )
59 Workspace::self()->sessionSaveStarted();
70 void Workspace::storeSession( TDEConfig* config, SMSavePhase phase )
72 config->setGroup(
"Session" );
74 int active_client = -1;
75 for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it)
78 TQCString sessionId = c->sessionId();
79 TQCString wmCommand = c->wmCommand();
80 if ( sessionId.isEmpty() )
83 if ( wmCommand.isEmpty() )
87 active_client = count;
88 TQString n = TQString::number(count);
89 if( phase == SMSavePhase2 || phase == SMSavePhase2Full )
91 config->writeEntry( TQString(
"sessionId")+n, sessionId.data() );
92 config->writeEntry( TQString(
"windowRole")+n, c->windowRole().data() );
93 config->writeEntry( TQString(
"wmCommand")+n, wmCommand.data() );
94 config->writeEntry( TQString(
"wmClientMachine")+n, c->wmClientMachine(
true ).data() );
95 config->writeEntry( TQString(
"resourceName")+n, c->resourceName().data() );
96 config->writeEntry( TQString(
"resourceClass")+n, c->resourceClass().data() );
97 config->writeEntry( TQString(
"geometry")+n, TQRect( c->calculateGravitation(TRUE), c->clientSize() ) );
98 config->writeEntry( TQString(
"restore")+n, c->geometryRestore() );
99 config->writeEntry( TQString(
"fsrestore")+n, c->geometryFSRestore() );
100 config->writeEntry( TQString(
"maximize")+n, (
int) c->maximizeMode() );
101 config->writeEntry( TQString(
"fullscreen")+n, (
int) c->fullScreenMode() );
102 config->writeEntry( TQString(
"desktop")+n, c->desktop() );
105 config->writeEntry( TQString(
"iconified")+n, c->isMinimized() );
107 config->writeEntry( TQString(
"sticky")+n, c->isOnAllDesktops() );
108 config->writeEntry( TQString(
"shaded")+n, c->isShade() );
109 config->writeEntry( TQString(
"shadowed")+n, c->isShadowed() );
111 config->writeEntry( TQString(
"staysOnTop")+n, c->keepAbove() );
112 config->writeEntry( TQString(
"keepBelow")+n, c->keepBelow() );
113 config->writeEntry( TQString(
"skipTaskbar")+n, c->skipTaskbar(
true ) );
114 config->writeEntry( TQString(
"skipPager")+n, c->skipPager() );
115 config->writeEntry( TQString(
"userNoBorder")+n, c->isUserNoBorder() );
116 config->writeEntry( TQString(
"windowType")+n, windowTypeToTxt( c->windowType()));
117 config->writeEntry( TQString(
"shortcut")+n, c->shortcut().toStringInternal());
121 if( phase == SMSavePhase0 )
126 session_active_client = active_client;
127 session_desktop = currentDesktop();
129 else if( phase == SMSavePhase2 )
131 config->writeEntry(
"count", count );
132 config->writeEntry(
"active", session_active_client );
133 config->writeEntry(
"desktop", session_desktop );
137 config->writeEntry(
"count", count );
138 config->writeEntry(
"active", session_active_client );
139 config->writeEntry(
"desktop", currentDesktop());
149 void Workspace::loadSessionInfo()
152 TDEConfig* config = kapp->sessionConfig();
153 config->setGroup(
"Session" );
154 int count = config->readNumEntry(
"count" );
155 int active_client = config->readNumEntry(
"active" );
156 for (
int i = 1; i <= count; i++ )
158 TQString n = TQString::number(i);
159 SessionInfo* info =
new SessionInfo;
160 session.append( info );
161 info->sessionId = config->readEntry( TQString(
"sessionId")+n ).latin1();
162 info->windowRole = config->readEntry( TQString(
"windowRole")+n ).latin1();
163 info->wmCommand = config->readEntry( TQString(
"wmCommand")+n ).latin1();
164 info->wmClientMachine = config->readEntry( TQString(
"wmClientMachine")+n ).latin1();
165 info->resourceName = config->readEntry( TQString(
"resourceName")+n ).latin1();
166 info->resourceClass = config->readEntry( TQString(
"resourceClass")+n ).lower().latin1();
167 info->geometry = config->readRectEntry( TQString(
"geometry")+n );
168 info->restore = config->readRectEntry( TQString(
"restore")+n );
169 info->fsrestore = config->readRectEntry( TQString(
"fsrestore")+n );
170 info->maximized = config->readNumEntry( TQString(
"maximize")+n, 0 );
171 info->fullscreen = config->readNumEntry( TQString(
"fullscreen")+n, 0 );
172 info->desktop = config->readNumEntry( TQString(
"desktop")+n, 0 );
173 info->minimized = config->readBoolEntry( TQString(
"iconified")+n, FALSE );
174 info->onAllDesktops = config->readBoolEntry( TQString(
"sticky")+n, FALSE );
175 info->shaded = config->readBoolEntry( TQString(
"shaded")+n, FALSE );
176 info->shadowed = config->readBoolEntry( TQString(
"shadowed")+n, TRUE );
177 info->keepAbove = config->readBoolEntry( TQString(
"staysOnTop")+n, FALSE );
178 info->keepBelow = config->readBoolEntry( TQString(
"keepBelow")+n, FALSE );
179 info->skipTaskbar = config->readBoolEntry( TQString(
"skipTaskbar")+n, FALSE );
180 info->skipPager = config->readBoolEntry( TQString(
"skipPager")+n, FALSE );
181 info->userNoBorder = config->readBoolEntry( TQString(
"userNoBorder")+n, FALSE );
182 info->windowType = txtToWindowType( config->readEntry( TQString(
"windowType")+n ).latin1());
183 info->shortcut = config->readEntry( TQString(
"shortcut")+n );
184 info->active = ( active_client == i );
197 SessionInfo* Workspace::takeSessionInfo( Client* c )
199 SessionInfo *realInfo = 0;
200 TQCString sessionId = c->sessionId();
201 TQCString windowRole = c->windowRole();
202 TQCString wmCommand = c->wmCommand();
203 TQCString wmClientMachine = c->wmClientMachine(
true );
204 TQCString resourceName = c->resourceName();
205 TQCString resourceClass = c->resourceClass();
208 if (! sessionId.isEmpty() )
211 for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() )
212 if ( info->sessionId == sessionId && sessionInfoWindowTypeMatch( c, info ))
214 if ( ! windowRole.isEmpty() )
216 if ( info->windowRole == windowRole )
217 realInfo = session.take();
221 if ( info->windowRole.isEmpty() &&
222 info->resourceName == resourceName &&
223 info->resourceClass == resourceClass )
224 realInfo = session.take();
231 for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() )
232 if ( info->resourceName == resourceName &&
233 info->resourceClass == resourceClass &&
234 info->wmClientMachine == wmClientMachine &&
235 sessionInfoWindowTypeMatch( c, info ))
236 if ( wmCommand.isEmpty() || info->wmCommand == wmCommand )
237 realInfo = session.take();
243 bool Workspace::sessionInfoWindowTypeMatch( Client* c, SessionInfo* info )
245 if( info->windowType == -2 )
247 return !c->isSpecialWindow();
249 return info->windowType == c->windowType();
258 bool Workspace::windowRoleMatch(
const TQCString& role1,
const TQCString& role2 )
260 if( role1.isEmpty() && role2.isEmpty())
262 int pos1 = role1.find(
'#' );
263 int pos2 = role2.find(
'#' );
265 if( pos1 < 0 || pos2 < 0 || pos1 != pos2 )
266 ret = role1 == role2;
268 ret = tqstrncmp( role1, role2, pos1 ) == 0;
269 kdDebug() <<
"WR:" << role1 <<
":" << pos1 <<
":" << role2 <<
":" << pos2 <<
":::" << ret << endl;
274 static const char*
const window_type_names[] =
276 "Unknown",
"Normal" ,
"Desktop",
"Dock",
"Toolbar",
"Menu",
"Dialog",
277 "Override",
"TopMenu",
"Utility",
"Splash"
281 const char* Workspace::windowTypeToTxt( NET::WindowType type )
283 if( type >= NET::Unknown && type <= NET::Splash )
284 return window_type_names[ type + 1 ];
287 kdFatal() <<
"Unknown Window Type" << endl;
291 NET::WindowType Workspace::txtToWindowType(
const char* txt )
293 for(
int i = NET::Unknown;
296 if( qstrcmp( txt, window_type_names[ i + 1 ] ) == 0 )
297 return static_cast< NET::WindowType
>( i );
298 return static_cast< NET::WindowType
>( -2 );
319 static void save_yourself( SmcConn conn_P, SmPointer ptr,
int, Bool shutdown,
int, Bool )
321 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
322 if( conn_P != session->connection())
325 Workspace::self()->disableRulesUpdates(
true );
326 SmcSaveYourselfDone( conn_P, True );
329 static void die( SmcConn conn_P, SmPointer ptr )
331 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
332 if( conn_P != session->connection())
338 static void save_complete( SmcConn conn_P, SmPointer ptr )
340 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
341 if( conn_P != session->connection())
346 static void shutdown_cancelled( SmcConn conn_P, SmPointer ptr )
348 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
349 if( conn_P != session->connection())
351 Workspace::self()->disableRulesUpdates(
false );
356 void SessionSaveDoneHelper::saveDone()
358 Workspace::self()->sessionSaveDone();
361 SessionSaveDoneHelper::SessionSaveDoneHelper()
364 calls.save_yourself.callback = save_yourself;
365 calls.save_yourself.client_data =
reinterpret_cast< SmPointer
>(
this);
366 calls.die.callback = die;
367 calls.die.client_data =
reinterpret_cast< SmPointer
>(
this);
368 calls.save_complete.callback = save_complete;
369 calls.save_complete.client_data =
reinterpret_cast< SmPointer
>(
this);
370 calls.shutdown_cancelled.callback = shutdown_cancelled;
371 calls.shutdown_cancelled.client_data =
reinterpret_cast< SmPointer
>(
this);
374 conn = SmcOpenConnection( NULL, 0, 1, 0,
375 SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
376 | SmcShutdownCancelledProcMask, &calls, NULL, &
id, 10, err );
382 SmPropValue propvalue[ 5 ];
384 propvalue[ 0 ].length =
sizeof( int );
385 int value0 = SmRestartNever;
386 propvalue[ 0 ].value = &value0;
387 props[ 0 ].name =
const_cast< char*
>( SmRestartStyleHint );
388 props[ 0 ].type =
const_cast< char*
>( SmCARD8 );
389 props[ 0 ].num_vals = 1;
390 props[ 0 ].vals = &propvalue[ 0 ];
391 struct passwd* entry = getpwuid( geteuid() );
392 propvalue[ 1 ].length = entry != NULL ? strlen( entry->pw_name ) : 0;
393 propvalue[ 1 ].value = (SmPointer)( entry != NULL ? entry->pw_name :
"" );
394 props[ 1 ].name =
const_cast< char*
>( SmUserID );
395 props[ 1 ].type =
const_cast< char*
>( SmARRAY8 );
396 props[ 1 ].num_vals = 1;
397 props[ 1 ].vals = &propvalue[ 1 ];
398 propvalue[ 2 ].length = 0;
399 propvalue[ 2 ].value = (SmPointer)(
"" );
400 props[ 2 ].name =
const_cast< char*
>( SmRestartCommand );
401 props[ 2 ].type =
const_cast< char*
>( SmLISTofARRAY8 );
402 props[ 2 ].num_vals = 1;
403 props[ 2 ].vals = &propvalue[ 2 ];
404 propvalue[ 3 ].length = 0;
405 propvalue[ 3 ].value = tqApp->argv()[ 0 ];
406 props[ 3 ].name =
const_cast< char*
>( SmProgram );
407 props[ 3 ].type =
const_cast< char*
>( SmARRAY8 );
408 props[ 3 ].num_vals = 1;
409 props[ 3 ].vals = &propvalue[ 3 ];
410 propvalue[ 4 ].length = 0;
411 propvalue[ 4 ].value = (SmPointer)(
"" );
412 props[ 4 ].name =
const_cast< char*
>( SmCloneCommand );
413 props[ 4 ].type =
const_cast< char*
>( SmLISTofARRAY8 );
414 props[ 4 ].num_vals = 1;
415 props[ 4 ].vals = &propvalue[ 4 ];
416 SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
417 SmcSetProperties( conn, 5, p );
418 notifier =
new TQSocketNotifier( IceConnectionNumber( SmcGetIceConnection( conn )),
419 TQSocketNotifier::Read,
this );
420 connect( notifier, TQ_SIGNAL( activated(
int )), TQ_SLOT( processData()));
423 SessionSaveDoneHelper::~SessionSaveDoneHelper()
428 void SessionSaveDoneHelper::close()
433 SmcCloseConnection( conn, 0, NULL );
438 void SessionSaveDoneHelper::processData()
441 IceProcessMessages( SmcGetIceConnection( conn ), 0, 0 );