kwin Library API Documentation

sm.cpp

00001 /***************************************************************** 00002 KWin - the KDE window manager 00003 This file is part of the KDE project. 00004 00005 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org> 00006 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org> 00007 00008 You can Freely distribute this program under the GNU General Public 00009 License. See the file "COPYING" for the exact licensing terms. 00010 ******************************************************************/ 00011 00012 #include "sm.h" 00013 00014 #include <qsocketnotifier.h> 00015 #include <qsessionmanager.h> 00016 #include <kdebug.h> 00017 #include <unistd.h> 00018 #include <stdlib.h> 00019 #include <pwd.h> 00020 #include <fixx11h.h> 00021 #include <kconfig.h> 00022 #include <kglobal.h> 00023 00024 #include "workspace.h" 00025 #include "client.h" 00026 00027 namespace KWinInternal 00028 { 00029 00030 bool SessionManaged::saveState( QSessionManager& sm ) 00031 { 00032 // If the session manager is ksmserver, save stacking 00033 // order, active window, active desktop etc. in phase 1, 00034 // as ksmserver assures no interaction will be done 00035 // before the WM finishes phase 1. Saving in phase 2 is 00036 // too late, as possible user interaction may change some things. 00037 // Phase2 is still needed though (ICCCM 5.2) 00038 char* sm_vendor = SmcVendor( static_cast< SmcConn >( sm.handle())); 00039 bool ksmserver = qstrcmp( sm_vendor, "KDE" ) == 0; 00040 free( sm_vendor ); 00041 if ( !sm.isPhase2() ) 00042 { 00043 Workspace::self()->sessionSaveStarted(); 00044 if( ksmserver ) // save stacking order etc. before "save file?" etc. dialogs change it 00045 Workspace::self()->storeSession( kapp->sessionConfig(), SMSavePhase0 ); 00046 sm.release(); // Qt doesn't automatically release in this case (bug?) 00047 sm.requestPhase2(); 00048 return true; 00049 } 00050 Workspace::self()->storeSession( kapp->sessionConfig(), ksmserver ? SMSavePhase2 : SMSavePhase2Full ); 00051 kapp->sessionConfig()->sync(); 00052 return true; 00053 } 00054 00055 // I bet this is broken, just like everywhere else in KDE 00056 bool SessionManaged::commitData( QSessionManager& sm ) 00057 { 00058 if ( !sm.isPhase2() ) 00059 Workspace::self()->sessionSaveStarted(); 00060 return true; 00061 } 00062 00063 // Workspace 00064 00070 void Workspace::storeSession( KConfig* config, SMSavePhase phase ) 00071 { 00072 config->setGroup("Session" ); 00073 int count = 0; 00074 int active_client = -1; 00075 for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) 00076 { 00077 Client* c = (*it); 00078 QCString sessionId = c->sessionId(); 00079 QCString wmCommand = c->wmCommand(); 00080 if ( sessionId.isEmpty() ) 00081 // remember also applications that are not XSMP capable 00082 // and use the obsolete WM_COMMAND / WM_SAVE_YOURSELF 00083 if ( wmCommand.isEmpty() ) 00084 continue; 00085 count++; 00086 if( c->isActive()) 00087 active_client = count; 00088 QString n = QString::number(count); 00089 if( phase == SMSavePhase2 || phase == SMSavePhase2Full ) 00090 { 00091 config->writeEntry( QString("sessionId")+n, sessionId.data() ); 00092 config->writeEntry( QString("windowRole")+n, c->windowRole().data() ); 00093 config->writeEntry( QString("wmCommand")+n, wmCommand.data() ); 00094 config->writeEntry( QString("wmClientMachine")+n, c->wmClientMachine().data() ); 00095 config->writeEntry( QString("resourceName")+n, c->resourceName().data() ); 00096 config->writeEntry( QString("resourceClass")+n, c->resourceClass().data() ); 00097 config->writeEntry( QString("geometry")+n, QRect( c->calculateGravitation(TRUE), c->clientSize() ) ); // FRAME 00098 config->writeEntry( QString("restore")+n, c->geometryRestore() ); 00099 config->writeEntry( QString("fsrestore")+n, c->geometryFSRestore() ); 00100 config->writeEntry( QString("maximize")+n, (int) c->maximizeMode() ); 00101 config->writeEntry( QString("fullscreen")+n, (int) c->fullScreenMode() ); 00102 config->writeEntry( QString("desktop")+n, c->desktop() ); 00103 // the config entry is called "iconified" for back. comp. reasons 00104 // (kconf_update script for updating session files would be too complicated) 00105 config->writeEntry( QString("iconified")+n, c->isMinimized() ); 00106 // the config entry is called "sticky" for back. comp. reasons 00107 config->writeEntry( QString("sticky")+n, c->isOnAllDesktops() ); 00108 config->writeEntry( QString("shaded")+n, c->isShade() ); 00109 // the config entry is called "staysOnTop" for back. comp. reasons 00110 config->writeEntry( QString("staysOnTop")+n, c->keepAbove() ); 00111 config->writeEntry( QString("keepBelow")+n, c->keepBelow() ); 00112 config->writeEntry( QString("skipTaskbar")+n, c->skipTaskbar( true ) ); 00113 config->writeEntry( QString("skipPager")+n, c->skipPager() ); 00114 config->writeEntry( QString("userNoBorder")+n, c->isUserNoBorder() ); 00115 config->writeEntry( QString("windowType")+n, windowTypeToTxt( c->windowType())); 00116 } 00117 } 00118 // TODO store also stacking order 00119 if( phase == SMSavePhase0 ) 00120 { 00121 // it would be much simpler to save these values to the config file, 00122 // but both Qt and KDE treat phase1 and phase2 separately, 00123 // which results in different sessionkey and different config file :( 00124 session_active_client = active_client; 00125 session_desktop = currentDesktop(); 00126 } 00127 else if( phase == SMSavePhase2 ) 00128 { 00129 config->writeEntry( "count", count ); 00130 config->writeEntry( "active", session_active_client ); 00131 config->writeEntry( "desktop", session_desktop ); 00132 } 00133 else // SMSavePhase2Full 00134 { 00135 config->writeEntry( "count", count ); 00136 config->writeEntry( "active", session_active_client ); 00137 config->writeEntry( "desktop", currentDesktop()); 00138 } 00139 } 00140 00141 00147 void Workspace::loadSessionInfo() 00148 { 00149 session.clear(); 00150 KConfig* config = kapp->sessionConfig(); 00151 config->setGroup("Session" ); 00152 int count = config->readNumEntry( "count" ); 00153 int active_client = config->readNumEntry( "active" ); 00154 for ( int i = 1; i <= count; i++ ) 00155 { 00156 QString n = QString::number(i); 00157 SessionInfo* info = new SessionInfo; 00158 session.append( info ); 00159 info->sessionId = config->readEntry( QString("sessionId")+n ).latin1(); 00160 info->windowRole = config->readEntry( QString("windowRole")+n ).latin1(); 00161 info->wmCommand = config->readEntry( QString("wmCommand")+n ).latin1(); 00162 info->wmClientMachine = config->readEntry( QString("wmClientMachine")+n ).latin1(); 00163 info->resourceName = config->readEntry( QString("resourceName")+n ).latin1(); 00164 info->resourceClass = config->readEntry( QString("resourceClass")+n ).lower().latin1(); 00165 info->geometry = config->readRectEntry( QString("geometry")+n ); 00166 info->restore = config->readRectEntry( QString("restore")+n ); 00167 info->fsrestore = config->readRectEntry( QString("fsrestore")+n ); 00168 info->maximized = config->readNumEntry( QString("maximize")+n, 0 ); 00169 info->fullscreen = config->readNumEntry( QString("fullscreen")+n, 0 ); 00170 info->desktop = config->readNumEntry( QString("desktop")+n, 0 ); 00171 info->minimized = config->readBoolEntry( QString("iconified")+n, FALSE ); 00172 info->onAllDesktops = config->readBoolEntry( QString("sticky")+n, FALSE ); 00173 info->shaded = config->readBoolEntry( QString("shaded")+n, FALSE ); 00174 info->keepAbove = config->readBoolEntry( QString("staysOnTop")+n, FALSE ); 00175 info->keepBelow = config->readBoolEntry( QString("keepBelow")+n, FALSE ); 00176 info->skipTaskbar = config->readBoolEntry( QString("skipTaskbar")+n, FALSE ); 00177 info->skipPager = config->readBoolEntry( QString("skipPager")+n, FALSE ); 00178 info->userNoBorder = config->readBoolEntry( QString("userNoBorder")+n, FALSE ); 00179 info->windowType = txtToWindowType( config->readEntry( QString("windowType")+n ).latin1()); 00180 info->active = ( active_client == i ); 00181 info->fake = false; 00182 } 00183 } 00184 00185 void Workspace::loadFakeSessionInfo() 00186 { 00187 fakeSession.clear(); 00188 KConfig *config = KGlobal::config(); 00189 config->setGroup("FakeSession" ); 00190 int count = config->readNumEntry( "count" ); 00191 for ( int i = 1; i <= count; i++ ) 00192 { 00193 QString n = QString::number(i); 00194 SessionInfo* info = new SessionInfo; 00195 fakeSession.append( info ); 00196 info->windowRole = config->readEntry( QString("windowRole")+n ).latin1(); 00197 info->resourceName = config->readEntry( QString("resourceName")+n ).latin1(); 00198 info->resourceClass = config->readEntry( QString("resourceClass")+n ).lower().latin1(); 00199 info->wmClientMachine = config->readEntry( QString("clientMachine")+n ).latin1(); 00200 info->geometry = config->readRectEntry( QString("geometry")+n ); 00201 info->restore = config->readRectEntry( QString("restore")+n ); 00202 info->fsrestore = config->readRectEntry( QString("fsrestore")+n ); 00203 info->maximized = config->readNumEntry( QString("maximize")+n, 0 ); 00204 info->fullscreen = config->readNumEntry( QString("fullscreen")+n, 0 ); 00205 info->desktop = config->readNumEntry( QString("desktop")+n, 0 ); 00206 info->minimized = config->readBoolEntry( QString("iconified")+n, FALSE ); 00207 info->onAllDesktops = config->readBoolEntry( QString("sticky")+n, FALSE ); 00208 info->shaded = config->readBoolEntry( QString("shaded")+n, FALSE ); 00209 info->keepAbove = config->readBoolEntry( QString("staysOnTop")+n, FALSE ); 00210 info->keepBelow = config->readBoolEntry( QString("keepBelow")+n, FALSE ); 00211 info->skipTaskbar = config->readBoolEntry( QString("skipTaskbar")+n, FALSE ); 00212 info->skipPager = config->readBoolEntry( QString("skipPager")+n, FALSE ); 00213 info->userNoBorder = config->readBoolEntry( QString("userNoBorder")+n, FALSE ); 00214 info->windowType = txtToWindowType( config->readEntry( QString("windowType")+n ).latin1()); 00215 info->active = false; 00216 info->fake = true; 00217 } 00218 } 00219 00220 void Workspace::storeFakeSessionInfo( Client* c ) 00221 { 00222 if ( !c->storeSettings() ) 00223 return; 00224 SessionInfo* info = new SessionInfo; 00225 fakeSession.append( info ); 00226 info->windowRole = c->windowRole(); 00227 info->resourceName = c->resourceName(); 00228 info->resourceClass = c->resourceClass(); 00229 info->wmClientMachine = c->wmClientMachine(); 00230 info->geometry = QRect( c->calculateGravitation(TRUE), c->clientSize() ) ; // FRAME 00231 info->restore = c->geometryRestore(); 00232 info->fsrestore = c->geometryFSRestore(); 00233 info->maximized = (int)c->maximizeMode(); 00234 info->fullscreen = (int)c->fullScreenMode(); 00235 info->desktop = c->desktop(); 00236 info->minimized = c->isMinimized(); 00237 info->onAllDesktops = c->isOnAllDesktops(); 00238 info->shaded = c->isShade(); 00239 info->keepAbove = c->keepAbove(); 00240 info->keepBelow = c->keepBelow(); 00241 info->skipTaskbar = c->skipTaskbar( true ); 00242 info->skipPager = c->skipPager(); 00243 info->userNoBorder = c->isUserNoBorder(); 00244 info->windowType = c->windowType(); 00245 info->active = false; 00246 info->fake = true; 00247 } 00248 00249 void Workspace::writeFakeSessionInfo() 00250 { 00251 KConfig *config = KGlobal::config(); 00252 config->setGroup("FakeSession" ); 00253 int count = 0; 00254 for ( SessionInfo* info = fakeSession.first(); info; info = fakeSession.next() ) 00255 { 00256 count++; 00257 QString n = QString::number(count); 00258 config->writeEntry( QString("windowRole")+n, info->windowRole.data() ); 00259 config->writeEntry( QString("resourceName")+n, info->resourceName.data() ); 00260 config->writeEntry( QString("resourceClass")+n, info->resourceClass.data() ); 00261 config->writeEntry( QString("clientMachine")+n, info->wmClientMachine.data() ); 00262 config->writeEntry( QString("geometry")+n, info->geometry ); 00263 config->writeEntry( QString("restore")+n, info->restore ); 00264 config->writeEntry( QString("fsrestore")+n, info->fsrestore ); 00265 config->writeEntry( QString("maximize")+n, info->maximized ); 00266 config->writeEntry( QString("fullscreen")+n, info->fullscreen ); 00267 config->writeEntry( QString("desktop")+n, info->desktop ); 00268 config->writeEntry( QString("iconified")+n, info->minimized ); 00269 config->writeEntry( QString("onAllDesktops")+n, info->onAllDesktops ); 00270 config->writeEntry( QString("shaded")+n, info->shaded ); 00271 config->writeEntry( QString("staysOnTop")+n, info->keepAbove ); 00272 config->writeEntry( QString("keepBelow")+n, info->keepBelow ); 00273 config->writeEntry( QString("skipTaskbar")+n, info->skipTaskbar ); 00274 config->writeEntry( QString("skipPager")+n, info->skipPager ); 00275 config->writeEntry( QString("userNoBorder")+n, info->userNoBorder ); 00276 config->writeEntry( QString("windowType")+n, windowTypeToTxt( info->windowType )); 00277 } 00278 config->writeEntry( "count", count ); 00279 } 00280 00292 SessionInfo* Workspace::takeSessionInfo( Client* c ) 00293 { 00294 SessionInfo *realInfo = 0; 00295 SessionInfo *fakeInfo = 0; 00296 QCString sessionId = c->sessionId(); 00297 QCString windowRole = c->windowRole(); 00298 QCString wmCommand = c->wmCommand(); 00299 QCString wmClientMachine = c->wmClientMachine(); 00300 QCString resourceName = c->resourceName(); 00301 QCString resourceClass = c->resourceClass(); 00302 00303 // First search ``session'' 00304 if (! sessionId.isEmpty() ) 00305 { 00306 // look for a real session managed client (algorithm suggested by ICCCM) 00307 for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() ) 00308 if ( info->sessionId == sessionId && sessionInfoWindowTypeMatch( c, info )) 00309 { 00310 if ( ! windowRole.isEmpty() ) 00311 { 00312 if ( info->windowRole == windowRole ) 00313 realInfo = session.take(); 00314 } 00315 else 00316 { 00317 if ( info->windowRole.isEmpty() && 00318 info->resourceName == resourceName && 00319 info->resourceClass == resourceClass ) 00320 realInfo = session.take(); 00321 } 00322 } 00323 } 00324 else 00325 { 00326 // look for a sessioninfo with matching features. 00327 for (SessionInfo* info = session.first(); info && !realInfo; info = session.next() ) 00328 if ( info->resourceName == resourceName && 00329 info->resourceClass == resourceClass && 00330 info->wmClientMachine == wmClientMachine && 00331 sessionInfoWindowTypeMatch( c, info )) 00332 if ( wmCommand.isEmpty() || info->wmCommand == wmCommand ) 00333 realInfo = session.take(); 00334 } 00335 00336 // Now search ``fakeSession'' 00337 for (SessionInfo* info = fakeSession.first(); info && !fakeInfo; info = fakeSession.next() ) 00338 if ( info->resourceName == resourceName && 00339 info->resourceClass == resourceClass && 00340 ( windowRole.isEmpty() || windowRole == info->windowRole ) && 00341 sessionInfoWindowTypeMatch( c, info )) 00342 fakeInfo = fakeSession.take(); 00343 00344 // Reconciliate 00345 if (fakeInfo) 00346 c->setStoreSettings( TRUE ); 00347 if (fakeInfo && realInfo) 00348 delete fakeInfo; 00349 if (realInfo) 00350 return realInfo; 00351 if (fakeInfo) 00352 return fakeInfo; 00353 return 0; 00354 } 00355 00356 bool Workspace::sessionInfoWindowTypeMatch( Client* c, SessionInfo* info ) 00357 { 00358 if( info->windowType == -2 ) 00359 { // undefined (not really part of NET::WindowType) 00360 return !c->isSpecialWindow() || c->isOverride(); 00361 } 00362 return info->windowType == c->windowType(); 00363 } 00364 00365 // maybe needed later 00366 #if 0 00367 // KMainWindow's without name() given have WM_WINDOW_ROLE in the form 00368 // of <appname>-mainwindow#<number> 00369 // when comparing them for fake session info, it's probably better to check 00370 // them without the trailing number 00371 bool Workspace::windowRoleMatch( const QCString& role1, const QCString& role2 ) 00372 { 00373 if( role1.isEmpty() && role2.isEmpty()) 00374 return true; 00375 int pos1 = role1.find( '#' ); 00376 int pos2 = role2.find( '#' ); 00377 bool ret; 00378 if( pos1 < 0 || pos2 < 0 || pos1 != pos2 ) 00379 ret = role1 == role2; 00380 else 00381 ret = qstrncmp( role1, role2, pos1 ) == 0; 00382 kdDebug() << "WR:" << role1 << ":" << pos1 << ":" << role2 << ":" << pos2 << ":::" << ret << endl; 00383 return ret; 00384 } 00385 #endif 00386 00387 static const char* const window_type_names[] = 00388 { 00389 "Unknown", "Normal" , "Desktop", "Dock", "Toolbar", "Menu", "Dialog", 00390 "Override", "TopMenu", "Utility", "Splash" 00391 }; 00392 // change also the two functions below when adding new entries 00393 00394 const char* Workspace::windowTypeToTxt( NET::WindowType type ) 00395 { 00396 if( type >= NET::Unknown && type <= NET::Splash ) 00397 return window_type_names[ type + 1 ]; // +1 (unknown==-1) 00398 if( type == -2 ) // undefined (not really part of NET::WindowType) 00399 return "Undefined"; 00400 kdFatal() << "Unknown Window Type" << endl; 00401 return NULL; 00402 } 00403 00404 NET::WindowType Workspace::txtToWindowType( const char* txt ) 00405 { 00406 for( int i = NET::Unknown; 00407 i <= NET::Splash; 00408 ++i ) 00409 if( qstrcmp( txt, window_type_names[ i + 1 ] ) == 0 ) // +1 00410 return static_cast< NET::WindowType >( i ); 00411 return static_cast< NET::WindowType >( -2 ); // undefined 00412 } 00413 00414 00415 00416 00417 // KWin's focus stealing prevention causes problems with user interaction 00418 // during session save, as it prevents possible dialogs from getting focus. 00419 // Therefore it's temporarily disabled during session saving. Start of 00420 // session saving can be detected in SessionManaged::saveState() above, 00421 // but Qt doesn't have API for saying when session saved finished (either 00422 // successfully, or was cancelled). Therefore, create another connection 00423 // to session manager, that will provide this information. 00424 static void save_yourself( SmcConn conn_P, SmPointer ptr, int, Bool, int, Bool ) 00425 { 00426 SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >( ptr ); 00427 if( conn_P != session->connection()) 00428 return; 00429 SmcSaveYourselfDone( conn_P, True ); 00430 } 00431 00432 static void die( SmcConn conn_P, SmPointer ptr ) 00433 { 00434 SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >( ptr ); 00435 if( conn_P != session->connection()) 00436 return; 00437 // session->saveDone(); we will quit anyway 00438 session->close(); 00439 } 00440 00441 static void save_complete( SmcConn conn_P, SmPointer ptr ) 00442 { 00443 SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >( ptr ); 00444 if( conn_P != session->connection()) 00445 return; 00446 session->saveDone(); 00447 } 00448 00449 static void shutdown_cancelled( SmcConn conn_P, SmPointer ptr ) 00450 { 00451 SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >( ptr ); 00452 if( conn_P != session->connection()) 00453 return; 00454 // no need to differentiate between successful finish and cancel 00455 session->saveDone(); 00456 } 00457 00458 void SessionSaveDoneHelper::saveDone() 00459 { 00460 Workspace::self()->sessionSaveDone(); 00461 } 00462 00463 SessionSaveDoneHelper::SessionSaveDoneHelper() 00464 { 00465 SmcCallbacks calls; 00466 calls.save_yourself.callback = save_yourself; 00467 calls.save_yourself.client_data = reinterpret_cast< SmPointer >(this); 00468 calls.die.callback = die; 00469 calls.die.client_data = reinterpret_cast< SmPointer >(this); 00470 calls.save_complete.callback = save_complete; 00471 calls.save_complete.client_data = reinterpret_cast< SmPointer >(this); 00472 calls.shutdown_cancelled.callback = shutdown_cancelled; 00473 calls.shutdown_cancelled.client_data = reinterpret_cast< SmPointer >(this); 00474 char* id = NULL; 00475 char err[ 11 ]; 00476 conn = SmcOpenConnection( NULL, 0, 1, 0, 00477 SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask 00478 | SmcShutdownCancelledProcMask, &calls, NULL, &id, 10, err ); 00479 if( id != NULL ) 00480 free( id ); 00481 if( conn == NULL ) 00482 return; // no SM 00483 // set the required properties, mostly dummy values 00484 SmPropValue propvalue[ 5 ]; 00485 SmProp props[ 5 ]; 00486 propvalue[ 0 ].length = sizeof( int ); 00487 int value0 = SmRestartNever; // so that this extra SM connection doesn't interfere 00488 propvalue[ 0 ].value = &value0; 00489 props[ 0 ].name = const_cast< char* >( SmRestartStyleHint ); 00490 props[ 0 ].type = const_cast< char* >( SmCARD8 ); 00491 props[ 0 ].num_vals = 1; 00492 props[ 0 ].vals = &propvalue[ 0 ]; 00493 struct passwd* entry = getpwuid( geteuid() ); 00494 propvalue[ 1 ].length = entry != NULL ? strlen( entry->pw_name ) : 0; 00495 propvalue[ 1 ].value = (SmPointer)( entry != NULL ? entry->pw_name : "" ); 00496 props[ 1 ].name = const_cast< char* >( SmUserID ); 00497 props[ 1 ].type = const_cast< char* >( SmARRAY8 ); 00498 props[ 1 ].num_vals = 1; 00499 props[ 1 ].vals = &propvalue[ 1 ]; 00500 propvalue[ 2 ].length = 0; 00501 propvalue[ 2 ].value = (SmPointer)( "" ); 00502 props[ 2 ].name = const_cast< char* >( SmRestartCommand ); 00503 props[ 2 ].type = const_cast< char* >( SmLISTofARRAY8 ); 00504 props[ 2 ].num_vals = 1; 00505 props[ 2 ].vals = &propvalue[ 2 ]; 00506 propvalue[ 3 ].length = 0; 00507 propvalue[ 3 ].value = qApp->argv()[ 0 ]; 00508 props[ 3 ].name = const_cast< char* >( SmProgram ); 00509 props[ 3 ].type = const_cast< char* >( SmARRAY8 ); 00510 props[ 3 ].num_vals = 1; 00511 props[ 3 ].vals = &propvalue[ 3 ]; 00512 propvalue[ 4 ].length = 0; 00513 propvalue[ 4 ].value = (SmPointer)( "" ); 00514 props[ 4 ].name = const_cast< char* >( SmCloneCommand ); 00515 props[ 4 ].type = const_cast< char* >( SmLISTofARRAY8 ); 00516 props[ 4 ].num_vals = 1; 00517 props[ 4 ].vals = &propvalue[ 4 ]; 00518 SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] }; 00519 SmcSetProperties( conn, 5, p ); 00520 notifier = new QSocketNotifier( IceConnectionNumber( SmcGetIceConnection( conn )), 00521 QSocketNotifier::Read, this ); 00522 connect( notifier, SIGNAL( activated( int )), SLOT( processData())); 00523 } 00524 00525 SessionSaveDoneHelper::~SessionSaveDoneHelper() 00526 { 00527 close(); 00528 } 00529 00530 void SessionSaveDoneHelper::close() 00531 { 00532 if( conn != NULL ) 00533 { 00534 delete notifier; 00535 SmcCloseConnection( conn, 0, NULL ); 00536 } 00537 conn = NULL; 00538 } 00539 00540 void SessionSaveDoneHelper::processData() 00541 { 00542 if( conn != NULL ) 00543 IceProcessMessages( SmcGetIceConnection( conn ), 0, 0 ); 00544 } 00545 00546 } // namespace 00547 00548 #include "sm.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Dec 16 19:08:42 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003