Fix screen sometimes not being hidden on power management action or desktop switch

Handle kdesktop_lock termination in a more sane manner by simply relaunching it if possible
pull/2/head
Timothy Pearson 11 years ago
parent e990ea9964
commit 51a20070fd

@ -218,6 +218,7 @@ LockProcess::LockProcess()
m_mousePrevY(0), m_mousePrevY(0),
m_dialogPrevX(0), m_dialogPrevX(0),
m_dialogPrevY(0), m_dialogPrevY(0),
m_notifyReadyRequested(false),
m_maskWidget(NULL), m_maskWidget(NULL),
m_saverRootWindow(0) m_saverRootWindow(0)
{ {
@ -604,6 +605,7 @@ void LockProcess::startSecureDialog()
} }
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
saverReadyIfNeeded();
int ret; int ret;
SecureDlg inDlg( this ); SecureDlg inDlg( this );
@ -941,6 +943,7 @@ void LockProcess::createSaverWindow()
// setBackgroundMode(TQWidget::NoBackground); // setBackgroundMode(TQWidget::NoBackground);
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
saverReadyIfNeeded();
// HACK // HACK
// Hide all tooltips and notification windows // Hide all tooltips and notification windows
@ -1004,6 +1007,7 @@ void LockProcess::desktopResized()
m_maskWidget->show(); m_maskWidget->show();
} }
XSync(tqt_xdisplay(), False); XSync(tqt_xdisplay(), False);
saverReadyIfNeeded();
if (mEnsureScreenHiddenTimer) { if (mEnsureScreenHiddenTimer) {
mEnsureScreenHiddenTimer->stop(); mEnsureScreenHiddenTimer->stop();
@ -1018,6 +1022,7 @@ void LockProcess::desktopResized()
// Resize the background widget // Resize the background widget
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
XSync(tqt_xdisplay(), False); XSync(tqt_xdisplay(), False);
saverReadyIfNeeded();
// Black out the background widget to hide ugly resize tiling artifacts // Black out the background widget to hide ugly resize tiling artifacts
if (argb_visual) { if (argb_visual) {
@ -1293,6 +1298,15 @@ void LockProcess::setTransparentBackgroundARGB()
setBackgroundPixmap( m_root ); setBackgroundPixmap( m_root );
} }
void LockProcess::saverReadyIfNeeded()
{
if (m_notifyReadyRequested) {
// Make sure the desktop is hidden before notifying the desktop that the saver is running
m_notifyReadyRequested = false;
saverReady();
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// Start the screen saver. // Start the screen saver.
@ -1343,10 +1357,16 @@ bool LockProcess::startSaver(bool notify_ready)
} }
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
erase(); erase();
}
if (notify_ready) { if (notify_ready) {
saverReady(); m_notifyReadyRequested = false;
saverReady();
}
}
else {
if (notify_ready) {
m_notifyReadyRequested = true;
}
} }
if (trinity_desktop_lock_in_sec_dlg == FALSE) { if (trinity_desktop_lock_in_sec_dlg == FALSE) {
@ -1520,6 +1540,7 @@ void LockProcess::repaintRootWindowIfNeeded()
if (currentDialog == NULL) { if (currentDialog == NULL) {
raise(); raise();
} }
saverReadyIfNeeded();
} }
} }
@ -1545,6 +1566,7 @@ bool LockProcess::startHack()
} }
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
erase(); erase();
saverReadyIfNeeded();
return false; return false;
} }
@ -1606,6 +1628,7 @@ bool LockProcess::startHack()
} }
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
erase(); erase();
saverReadyIfNeeded();
mSuspended = false; mSuspended = false;
} }
@ -1662,6 +1685,7 @@ bool LockProcess::startHack()
ENABLE_CONTINUOUS_LOCKDLG_DISPLAY ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
} }
saverReadyIfNeeded();
} }
} }
if (m_startupStatusDialog) { m_startupStatusDialog->closeSMDialog(); m_startupStatusDialog=NULL; } if (m_startupStatusDialog) { m_startupStatusDialog->closeSMDialog(); m_startupStatusDialog=NULL; }
@ -1729,12 +1753,14 @@ void LockProcess::hackExited(TDEProcess *)
if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
} }
} }
saverReadyIfNeeded();
} }
void LockProcess::displayLockDialogIfNeeded() void LockProcess::displayLockDialogIfNeeded()
{ {
if (m_startupStatusDialog) { if (m_startupStatusDialog) {
m_startupStatusDialog->closeSMDialog(); m_startupStatusDialog=NULL; m_startupStatusDialog->closeSMDialog();
m_startupStatusDialog = NULL;
} }
if (!trinity_desktop_lock_in_sec_dlg) { if (!trinity_desktop_lock_in_sec_dlg) {
if (trinity_desktop_lock_use_system_modal_dialogs) { if (trinity_desktop_lock_use_system_modal_dialogs) {
@ -1816,6 +1842,7 @@ void LockProcess::resume( bool force )
else { else {
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
} }
saverReadyIfNeeded();
return; return;
} }
if ((mSuspended) && (mHackProc.isRunning())) if ((mSuspended) && (mHackProc.isRunning()))
@ -1949,6 +1976,7 @@ int LockProcess::execDialog( TQDialog *dlg )
bitBlt(this, 0, 0, &backingPixmap); bitBlt(this, 0, 0, &backingPixmap);
} }
} }
saverReadyIfNeeded();
// dlg->exec may generate BadMatch errors, so make sure they are silently ignored // dlg->exec may generate BadMatch errors, so make sure they are silently ignored
int (*oldHandler)(Display *, XErrorEvent *); int (*oldHandler)(Display *, XErrorEvent *);
oldHandler = XSetErrorHandler(ignoreXError); oldHandler = XSetErrorHandler(ignoreXError);
@ -2048,6 +2076,7 @@ void LockProcess::slotPaintBackground(const TQPixmap &rpm)
setGeometry(0, 0, mRootWidth, mRootHeight); setGeometry(0, 0, mRootWidth, mRootHeight);
erase(); erase();
} }
saverReadyIfNeeded();
} }
void LockProcess::preparePopup() void LockProcess::preparePopup()

@ -151,6 +151,7 @@ private:
void showVkbd(); void showVkbd();
void hideVkbd(); void hideVkbd();
void saverReady(); void saverReady();
void saverReadyIfNeeded();
bool forwardVkbdEvent( XEvent* event ); bool forwardVkbdEvent( XEvent* event );
void sendVkbdFocusInOut( WId window, Time t ); void sendVkbdFocusInOut( WId window, Time t );
void windowAdded( WId window, bool managed ); void windowAdded( WId window, bool managed );
@ -238,6 +239,8 @@ private:
int m_dialogPrevX; int m_dialogPrevX;
int m_dialogPrevY; int m_dialogPrevY;
bool m_notifyReadyRequested;
TQWidget* m_maskWidget; TQWidget* m_maskWidget;
Window m_saverRootWindow; Window m_saverRootWindow;

@ -416,6 +416,12 @@ int main( int argc, char **argv )
sigdelset(&new_mask,SIGTTIN); sigdelset(&new_mask,SIGTTIN);
sigdelset(&new_mask,SIGTTOU); sigdelset(&new_mask,SIGTTOU);
// let kdesktop know the saver process is ready
if (kill(kdesktop_pid, SIGTTIN) < 0) {
// The controlling kdesktop process probably died. Commit suicide...
return 12;
}
// wait for SIGUSR1, SIGUSR2, SIGWINCH, SIGTTIN, or SIGTTOU // wait for SIGUSR1, SIGUSR2, SIGWINCH, SIGTTIN, or SIGTTOU
sigsuspend(&new_mask); sigsuspend(&new_mask);
} }

@ -43,6 +43,12 @@ static void sigusr2_handler(int)
m_masterSaverEngine->slotLockProcessFullyActivated(); m_masterSaverEngine->slotLockProcessFullyActivated();
} }
} }
static void sigttin_handler(int)
{
if (m_masterSaverEngine) {
m_masterSaverEngine->slotLockProcessReady();
}
}
//=========================================================================== //===========================================================================
// //
@ -55,7 +61,8 @@ SaverEngine::SaverEngine()
KScreensaverIface(), KScreensaverIface(),
mBlankOnly(false), mBlankOnly(false),
mSAKProcess(NULL), mSAKProcess(NULL),
mTerminationRequested(false) mTerminationRequested(false),
mSaverProcessReady(false)
{ {
struct sigaction act; struct sigaction act;
@ -75,6 +82,14 @@ SaverEngine::SaverEngine()
act.sa_flags = 0; act.sa_flags = 0;
sigaction(SIGUSR2, &act, 0L); sigaction(SIGUSR2, &act, 0L);
// handle SIGTTIN
m_masterSaverEngine = this;
act.sa_handler= sigttin_handler;
sigemptyset(&(act.sa_mask));
sigaddset(&(act.sa_mask), SIGTTIN);
act.sa_flags = 0;
sigaction(SIGTTIN, &act, 0L);
// Save X screensaver parameters // Save X screensaver parameters
XGetScreenSaver(tqt_xdisplay(), &mXTimeout, &mXInterval, XGetScreenSaver(tqt_xdisplay(), &mXTimeout, &mXInterval,
&mXBlanking, &mXExposures); &mXBlanking, &mXExposures);
@ -341,25 +356,14 @@ void SaverEngine::configure()
void SaverEngine::setBlankOnly( bool blankOnly ) void SaverEngine::setBlankOnly( bool blankOnly )
{ {
mBlankOnly = blankOnly; mBlankOnly = blankOnly;
// FIXME: if running, stop and restart? What about security // FIXME: if running, stop and restart? What about security
// implications of this? // implications of this?
} }
//--------------------------------------------------------------------------- bool SaverEngine::restartDesktopLockProcess()
//
// Start the screen saver.
//
bool SaverEngine::startLockProcess( LockType lock_type )
{ {
if (mState == Saving)
return true;
enableExports();
kdDebug(1204) << "SaverEngine: starting saver" << endl;
emitDCOPSignal("KDE_start_screensaver()", TQByteArray());
if (!mLockProcess.isRunning()) { if (!mLockProcess.isRunning()) {
mSaverProcessReady = false;
mLockProcess.clearArguments(); mLockProcess.clearArguments();
TQString path = TDEStandardDirs::findExe( "kdesktop_lock" ); TQString path = TDEStandardDirs::findExe( "kdesktop_lock" );
if( path.isEmpty()) if( path.isEmpty())
@ -374,6 +378,36 @@ bool SaverEngine::startLockProcess( LockType lock_type )
kdDebug( 1204 ) << "Failed to start kdesktop_lock!" << endl; kdDebug( 1204 ) << "Failed to start kdesktop_lock!" << endl;
return false; return false;
} }
// Wait for the saver process to signal ready...
int count = 0;
while (!mSaverProcessReady) {
count++;
usleep(100);
if (count > 100) {
return false;
}
}
}
return true;
}
//---------------------------------------------------------------------------
//
// Start the screen saver.
//
bool SaverEngine::startLockProcess( LockType lock_type )
{
if (mState == Saving) {
return true;
}
enableExports();
kdDebug(1204) << "SaverEngine: starting saver" << endl;
emitDCOPSignal("KDE_start_screensaver()", TQByteArray());
if (!restartDesktopLockProcess()) {
return false;
} }
switch( lock_type ) switch( lock_type )
@ -435,6 +469,23 @@ void SaverEngine::stopLockProcess()
mState = Waiting; mState = Waiting;
} }
void SaverEngine::recoverFromHackingAttempt()
{
// Try to relaunch saver with forcelock
if (!startLockProcess( ForceLock )) {
// Terminate the TDE session ASAP!
// Values are explained at http://lists.kde.org/?l=kde-linux&m=115770988603387
TQByteArray data;
TQDataStream arg(data, IO_WriteOnly);
arg << (int)0 << (int)0 << (int)2;
if ( ! kapp->dcopClient()->send("ksmserver", "default", "logout(int,int,int)", data) ) {
// Someone got to DCOP before we did
// Try an emergency system logout
system("logout");
}
}
}
void SaverEngine::lockProcessExited() void SaverEngine::lockProcessExited()
{ {
bool abnormalExit = false; bool abnormalExit = false;
@ -452,33 +503,13 @@ void SaverEngine::lockProcessExited()
} }
if (abnormalExit == true) { if (abnormalExit == true) {
// PROBABLE HACKING ATTEMPT DETECTED // PROBABLE HACKING ATTEMPT DETECTED
// Terminate the TDE session ASAP! restartDesktopLockProcess();
// Values are explained at http://lists.kde.org/?l=kde-linux&m=115770988603387 mState = Waiting;
TQByteArray data; TQTimer::singleShot( 100, this, SLOT(recoverFromHackingAttempt()) );
TQDataStream arg(data, IO_WriteOnly);
arg << (int)0 << (int)0 << (int)2;
if ( ! kapp->dcopClient()->send("ksmserver", "default", "logout(int,int,int)", data) ) {
// Someone got to DCOP before we did
// Try an emergency system logout
system("logout");
}
} }
else { else {
// Restart the lock process // Restart the lock process
if (!mLockProcess.isRunning()) { restartDesktopLockProcess();
mLockProcess.clearArguments();
TQString path = TDEStandardDirs::findExe( "kdesktop_lock" );
if( path.isEmpty())
{
kdDebug( 1204 ) << "Can't find kdesktop_lock!" << endl;
}
mLockProcess << path;
mLockProcess << TQString( "--internal" ) << TQString( "%1" ).arg(getpid());
if (mLockProcess.start() == false )
{
kdDebug( 1204 ) << "Failed to start kdesktop_lock!" << endl;
}
}
} }
} }
@ -494,6 +525,11 @@ void SaverEngine::slotLockProcessFullyActivated()
mState = Saving; mState = Saving;
} }
void SaverEngine::slotLockProcessReady()
{
mSaverProcessReady = true;
}
void SaverEngine::lockProcessWaiting() void SaverEngine::lockProcessWaiting()
{ {
kdDebug(1204) << "SaverEngine: lock exited" << endl; kdDebug(1204) << "SaverEngine: lock exited" << endl;

@ -81,6 +81,7 @@ public:
public slots: public slots:
void slotLockProcessWaiting(); void slotLockProcessWaiting();
void slotLockProcessFullyActivated(); void slotLockProcessFullyActivated();
void slotLockProcessReady();
protected slots: protected slots:
void idleTimeout(); void idleTimeout();
@ -95,6 +96,10 @@ private slots:
* Enable wallpaper exports * Enable wallpaper exports
*/ */
void enableExports(); void enableExports();
void recoverFromHackingAttempt();
private:
bool restartDesktopLockProcess();
protected: protected:
enum LockType { DontLock, DefaultLock, ForceLock, SecureDialog }; enum LockType { DontLock, DefaultLock, ForceLock, SecureDialog };
@ -125,6 +130,7 @@ protected:
private: private:
TDEProcess* mSAKProcess; TDEProcess* mSAKProcess;
bool mTerminationRequested; bool mTerminationRequested;
bool mSaverProcessReady;
}; };
#endif #endif

@ -237,7 +237,7 @@ void KSMServer::shutdownInternal( TDEApplication::ShutdownConfirm confirm,
TQByteArray replyData; TQByteArray replyData;
// Block here until lock is complete // Block here until lock is complete
// If this is not done the desktop of the locked session will be shown after suspend/hibernate until the lock fully engages! // If this is not done the desktop of the locked session will be shown after suspend/hibernate until the lock fully engages!
DCOPRef("kdesktop", "KScreensaverIface").call("lock()"); kapp->dcopClient()->call("kdesktop", "KScreensaverIface", "lock()", TQCString(""), replyType, replyData);
} }
TDERootSystemDevice* rootDevice = hwDevices->rootSystemDevice(); TDERootSystemDevice* rootDevice = hwDevices->rootSystemDevice();
if (rootDevice) { if (rootDevice) {

Loading…
Cancel
Save