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( tdeApp->sessionConfig(), SMSavePhase0 );
50 Workspace::self()->storeSession( tdeApp->sessionConfig(), ksmserver ? SMSavePhase2 : SMSavePhase2Full );
51 tdeApp->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(
"userNoBorderForced")+n, c->isUserNoBorderForced() );
117 config->writeEntry( TQString(
"windowType")+n, windowTypeToTxt( c->windowType()));
118 config->writeEntry( TQString(
"shortcut")+n, c->shortcut().toStringInternal());
122 if( phase == SMSavePhase0 )
127 session_active_client = active_client;
128 session_desktop = currentDesktop();
130 else if( phase == SMSavePhase2 )
132 config->writeEntry(
"count", count );
133 config->writeEntry(
"active", session_active_client );
134 config->writeEntry(
"desktop", session_desktop );
138 config->writeEntry(
"count", count );
139 config->writeEntry(
"active", session_active_client );
140 config->writeEntry(
"desktop", currentDesktop());
150 void Workspace::loadSessionInfo()
153 TDEConfig* config = tdeApp->sessionConfig();
154 config->setGroup(
"Session" );
155 int count = config->readNumEntry(
"count" );
156 int active_client = config->readNumEntry(
"active" );
157 for (
int i = 1; i <= count; i++ )
159 TQString n = TQString::number(i);
160 SessionInfo* info =
new SessionInfo;
161 session.append( info );
162 info->sessionId = config->readEntry( TQString(
"sessionId")+n ).latin1();
163 info->windowRole = config->readEntry( TQString(
"windowRole")+n ).latin1();
164 info->wmCommand = config->readEntry( TQString(
"wmCommand")+n ).latin1();
165 info->wmClientMachine = config->readEntry( TQString(
"wmClientMachine")+n ).latin1();
166 info->resourceName = config->readEntry( TQString(
"resourceName")+n ).latin1();
167 info->resourceClass = config->readEntry( TQString(
"resourceClass")+n ).lower().latin1();
168 info->geometry = config->readRectEntry( TQString(
"geometry")+n );
169 info->restore = config->readRectEntry( TQString(
"restore")+n );
170 info->fsrestore = config->readRectEntry( TQString(
"fsrestore")+n );
171 info->maximized = config->readNumEntry( TQString(
"maximize")+n, 0 );
172 info->fullscreen = config->readNumEntry( TQString(
"fullscreen")+n, 0 );
173 info->desktop = config->readNumEntry( TQString(
"desktop")+n, 0 );
174 info->minimized = config->readBoolEntry( TQString(
"iconified")+n,
false );
175 info->onAllDesktops = config->readBoolEntry( TQString(
"sticky")+n,
false );
176 info->shaded = config->readBoolEntry( TQString(
"shaded")+n,
false );
177 info->shadowed = config->readBoolEntry( TQString(
"shadowed")+n,
true );
178 info->keepAbove = config->readBoolEntry( TQString(
"staysOnTop")+n,
false );
179 info->keepBelow = config->readBoolEntry( TQString(
"keepBelow")+n,
false );
180 info->skipTaskbar = config->readBoolEntry( TQString(
"skipTaskbar")+n,
false );
181 info->skipPager = config->readBoolEntry( TQString(
"skipPager")+n,
false );
182 info->userNoBorder = config->readBoolEntry( TQString(
"userNoBorder")+n,
false );
183 info->userNoBorderForced = config->readBoolEntry( TQString(
"userNoBorderForced")+n,
false );
184 info->windowType = txtToWindowType( config->readEntry( TQString(
"windowType")+n ).latin1());
185 info->shortcut = config->readEntry( TQString(
"shortcut")+n );
186 info->active = ( active_client == i );
199 SessionInfo* Workspace::takeSessionInfo( Client* c )
201 SessionInfo *realInfo = 0;
202 TQCString sessionId = c->sessionId();
203 TQCString windowRole = c->windowRole();
204 TQCString wmCommand = c->wmCommand();
205 TQCString wmClientMachine = c->wmClientMachine(
true );
206 TQCString resourceName = c->resourceName();
207 TQCString resourceClass = c->resourceClass();
210 if (! sessionId.isEmpty() )
213 for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() )
214 if ( info->sessionId == sessionId && sessionInfoWindowTypeMatch( c, info ))
216 if ( ! windowRole.isEmpty() )
218 if ( info->windowRole == windowRole )
219 realInfo = session.take();
223 if ( info->windowRole.isEmpty() &&
224 info->resourceName == resourceName &&
225 info->resourceClass == resourceClass )
226 realInfo = session.take();
233 for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() )
234 if ( info->resourceName == resourceName &&
235 info->resourceClass == resourceClass &&
236 info->wmClientMachine == wmClientMachine &&
237 sessionInfoWindowTypeMatch( c, info ))
238 if ( wmCommand.isEmpty() || info->wmCommand == wmCommand )
239 realInfo = session.take();
245 bool Workspace::sessionInfoWindowTypeMatch( Client* c, SessionInfo* info )
247 if( info->windowType == -2 )
249 return !c->isSpecialWindow();
251 return info->windowType == c->windowType();
260 bool Workspace::windowRoleMatch(
const TQCString& role1,
const TQCString& role2 )
262 if( role1.isEmpty() && role2.isEmpty())
264 int pos1 = role1.find(
'#' );
265 int pos2 = role2.find(
'#' );
267 if( pos1 < 0 || pos2 < 0 || pos1 != pos2 )
268 ret = role1 == role2;
270 ret = tqstrncmp( role1, role2, pos1 ) == 0;
271 kdDebug() <<
"WR:" << role1 <<
":" << pos1 <<
":" << role2 <<
":" << pos2 <<
":::" << ret << endl;
276 static const char*
const window_type_names[] =
278 "Unknown",
"Normal" ,
"Desktop",
"Dock",
"Toolbar",
"Menu",
"Dialog",
279 "Override",
"TopMenu",
"Utility",
"Splash"
283 const char* Workspace::windowTypeToTxt( NET::WindowType type )
285 if( type >= NET::Unknown && type <= NET::Splash )
286 return window_type_names[ type + 1 ];
289 kdFatal() <<
"Unknown Window Type" << endl;
293 NET::WindowType Workspace::txtToWindowType(
const char* txt )
295 for(
int i = NET::Unknown;
298 if( qstrcmp( txt, window_type_names[ i + 1 ] ) == 0 )
299 return static_cast< NET::WindowType
>( i );
300 return static_cast< NET::WindowType
>( -2 );
321 static void save_yourself( SmcConn conn_P, SmPointer ptr,
int, Bool shutdown,
int, Bool )
323 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
324 if( conn_P != session->connection())
327 Workspace::self()->disableRulesUpdates(
true );
328 SmcSaveYourselfDone( conn_P, True );
331 static void die( SmcConn conn_P, SmPointer ptr )
333 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
334 if( conn_P != session->connection())
340 static void save_complete( SmcConn conn_P, SmPointer ptr )
342 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
343 if( conn_P != session->connection())
348 static void shutdown_cancelled( SmcConn conn_P, SmPointer ptr )
350 SessionSaveDoneHelper* session =
reinterpret_cast< SessionSaveDoneHelper*
>( ptr );
351 if( conn_P != session->connection())
353 Workspace::self()->disableRulesUpdates(
false );
358 void SessionSaveDoneHelper::saveDone()
360 Workspace::self()->sessionSaveDone();
363 SessionSaveDoneHelper::SessionSaveDoneHelper()
366 calls.save_yourself.callback = save_yourself;
367 calls.save_yourself.client_data =
reinterpret_cast< SmPointer
>(
this);
368 calls.die.callback = die;
369 calls.die.client_data =
reinterpret_cast< SmPointer
>(
this);
370 calls.save_complete.callback = save_complete;
371 calls.save_complete.client_data =
reinterpret_cast< SmPointer
>(
this);
372 calls.shutdown_cancelled.callback = shutdown_cancelled;
373 calls.shutdown_cancelled.client_data =
reinterpret_cast< SmPointer
>(
this);
376 conn = SmcOpenConnection( NULL, 0, 1, 0,
377 SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
378 | SmcShutdownCancelledProcMask, &calls, NULL, &
id, 10, err );
384 SmPropValue propvalue[ 5 ];
386 propvalue[ 0 ].length =
sizeof( int );
387 int value0 = SmRestartNever;
388 propvalue[ 0 ].value = &value0;
389 props[ 0 ].name =
const_cast< char*
>( SmRestartStyleHint );
390 props[ 0 ].type =
const_cast< char*
>( SmCARD8 );
391 props[ 0 ].num_vals = 1;
392 props[ 0 ].vals = &propvalue[ 0 ];
393 struct passwd* entry = getpwuid( geteuid() );
394 propvalue[ 1 ].length = entry != NULL ? strlen( entry->pw_name ) : 0;
395 propvalue[ 1 ].value = (SmPointer)( entry != NULL ? entry->pw_name :
"" );
396 props[ 1 ].name =
const_cast< char*
>( SmUserID );
397 props[ 1 ].type =
const_cast< char*
>( SmARRAY8 );
398 props[ 1 ].num_vals = 1;
399 props[ 1 ].vals = &propvalue[ 1 ];
400 propvalue[ 2 ].length = 0;
401 propvalue[ 2 ].value = (SmPointer)(
"" );
402 props[ 2 ].name =
const_cast< char*
>( SmRestartCommand );
403 props[ 2 ].type =
const_cast< char*
>( SmLISTofARRAY8 );
404 props[ 2 ].num_vals = 1;
405 props[ 2 ].vals = &propvalue[ 2 ];
406 propvalue[ 3 ].length = 0;
407 propvalue[ 3 ].value = tqApp->argv()[ 0 ];
408 props[ 3 ].name =
const_cast< char*
>( SmProgram );
409 props[ 3 ].type =
const_cast< char*
>( SmARRAY8 );
410 props[ 3 ].num_vals = 1;
411 props[ 3 ].vals = &propvalue[ 3 ];
412 propvalue[ 4 ].length = 0;
413 propvalue[ 4 ].value = (SmPointer)(
"" );
414 props[ 4 ].name =
const_cast< char*
>( SmCloneCommand );
415 props[ 4 ].type =
const_cast< char*
>( SmLISTofARRAY8 );
416 props[ 4 ].num_vals = 1;
417 props[ 4 ].vals = &propvalue[ 4 ];
418 SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
419 SmcSetProperties( conn, 5, p );
420 notifier =
new TQSocketNotifier( IceConnectionNumber( SmcGetIceConnection( conn )),
421 TQSocketNotifier::Read,
this );
422 connect( notifier, TQ_SIGNAL( activated(
int )), TQ_SLOT( processData()));
425 SessionSaveDoneHelper::~SessionSaveDoneHelper()
430 void SessionSaveDoneHelper::close()
435 SmcCloseConnection( conn, 0, NULL );
440 void SessionSaveDoneHelper::processData()
443 IceProcessMessages( SmcGetIceConnection( conn ), 0, 0 );