From 51a20070fd51c4ce4eca550fd458b7223bee662a Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 8 Jan 2014 03:21:58 -0600 Subject: 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 --- kdesktop/lock/lockprocess.cc | 37 ++++++++++++-- kdesktop/lock/lockprocess.h | 3 ++ kdesktop/lock/main.cc | 6 +++ kdesktop/lockeng.cc | 114 ++++++++++++++++++++++++++++--------------- kdesktop/lockeng.h | 6 +++ 5 files changed, 123 insertions(+), 43 deletions(-) (limited to 'kdesktop') diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc index 812f2a6d6..71ce93175 100644 --- a/kdesktop/lock/lockprocess.cc +++ b/kdesktop/lock/lockprocess.cc @@ -218,6 +218,7 @@ LockProcess::LockProcess() m_mousePrevY(0), m_dialogPrevX(0), m_dialogPrevY(0), + m_notifyReadyRequested(false), m_maskWidget(NULL), m_saverRootWindow(0) { @@ -604,6 +605,7 @@ void LockProcess::startSecureDialog() } setGeometry(0, 0, mRootWidth, mRootHeight); + saverReadyIfNeeded(); int ret; SecureDlg inDlg( this ); @@ -941,6 +943,7 @@ void LockProcess::createSaverWindow() // setBackgroundMode(TQWidget::NoBackground); setGeometry(0, 0, mRootWidth, mRootHeight); + saverReadyIfNeeded(); // HACK // Hide all tooltips and notification windows @@ -1004,6 +1007,7 @@ void LockProcess::desktopResized() m_maskWidget->show(); } XSync(tqt_xdisplay(), False); + saverReadyIfNeeded(); if (mEnsureScreenHiddenTimer) { mEnsureScreenHiddenTimer->stop(); @@ -1018,6 +1022,7 @@ void LockProcess::desktopResized() // Resize the background widget setGeometry(0, 0, mRootWidth, mRootHeight); XSync(tqt_xdisplay(), False); + saverReadyIfNeeded(); // Black out the background widget to hide ugly resize tiling artifacts if (argb_visual) { @@ -1293,6 +1298,15 @@ void LockProcess::setTransparentBackgroundARGB() 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. @@ -1343,10 +1357,16 @@ bool LockProcess::startSaver(bool notify_ready) } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); - } - if (notify_ready) { - saverReady(); + if (notify_ready) { + m_notifyReadyRequested = false; + saverReady(); + } + } + else { + if (notify_ready) { + m_notifyReadyRequested = true; + } } if (trinity_desktop_lock_in_sec_dlg == FALSE) { @@ -1520,6 +1540,7 @@ void LockProcess::repaintRootWindowIfNeeded() if (currentDialog == NULL) { raise(); } + saverReadyIfNeeded(); } } @@ -1545,6 +1566,7 @@ bool LockProcess::startHack() } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); + saverReadyIfNeeded(); return false; } @@ -1606,6 +1628,7 @@ bool LockProcess::startHack() } setGeometry(0, 0, mRootWidth, mRootHeight); erase(); + saverReadyIfNeeded(); mSuspended = false; } @@ -1662,6 +1685,7 @@ bool LockProcess::startHack() ENABLE_CONTINUOUS_LOCKDLG_DISPLAY if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); } + saverReadyIfNeeded(); } } if (m_startupStatusDialog) { m_startupStatusDialog->closeSMDialog(); m_startupStatusDialog=NULL; } @@ -1729,12 +1753,14 @@ void LockProcess::hackExited(TDEProcess *) if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); } } + saverReadyIfNeeded(); } void LockProcess::displayLockDialogIfNeeded() { 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_use_system_modal_dialogs) { @@ -1816,6 +1842,7 @@ void LockProcess::resume( bool force ) else { setGeometry(0, 0, mRootWidth, mRootHeight); } + saverReadyIfNeeded(); return; } if ((mSuspended) && (mHackProc.isRunning())) @@ -1949,6 +1976,7 @@ int LockProcess::execDialog( TQDialog *dlg ) bitBlt(this, 0, 0, &backingPixmap); } } + saverReadyIfNeeded(); // dlg->exec may generate BadMatch errors, so make sure they are silently ignored int (*oldHandler)(Display *, XErrorEvent *); oldHandler = XSetErrorHandler(ignoreXError); @@ -2048,6 +2076,7 @@ void LockProcess::slotPaintBackground(const TQPixmap &rpm) setGeometry(0, 0, mRootWidth, mRootHeight); erase(); } + saverReadyIfNeeded(); } void LockProcess::preparePopup() diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h index 50fd447bc..dc14aa676 100644 --- a/kdesktop/lock/lockprocess.h +++ b/kdesktop/lock/lockprocess.h @@ -151,6 +151,7 @@ private: void showVkbd(); void hideVkbd(); void saverReady(); + void saverReadyIfNeeded(); bool forwardVkbdEvent( XEvent* event ); void sendVkbdFocusInOut( WId window, Time t ); void windowAdded( WId window, bool managed ); @@ -238,6 +239,8 @@ private: int m_dialogPrevX; int m_dialogPrevY; + bool m_notifyReadyRequested; + TQWidget* m_maskWidget; Window m_saverRootWindow; diff --git a/kdesktop/lock/main.cc b/kdesktop/lock/main.cc index ba42318c0..43534c255 100644 --- a/kdesktop/lock/main.cc +++ b/kdesktop/lock/main.cc @@ -416,6 +416,12 @@ int main( int argc, char **argv ) sigdelset(&new_mask,SIGTTIN); 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 sigsuspend(&new_mask); } diff --git a/kdesktop/lockeng.cc b/kdesktop/lockeng.cc index 4f13dfa14..79d3e6771 100644 --- a/kdesktop/lockeng.cc +++ b/kdesktop/lockeng.cc @@ -43,6 +43,12 @@ static void sigusr2_handler(int) m_masterSaverEngine->slotLockProcessFullyActivated(); } } +static void sigttin_handler(int) +{ + if (m_masterSaverEngine) { + m_masterSaverEngine->slotLockProcessReady(); + } +} //=========================================================================== // @@ -55,7 +61,8 @@ SaverEngine::SaverEngine() KScreensaverIface(), mBlankOnly(false), mSAKProcess(NULL), - mTerminationRequested(false) + mTerminationRequested(false), + mSaverProcessReady(false) { struct sigaction act; @@ -75,6 +82,14 @@ SaverEngine::SaverEngine() act.sa_flags = 0; 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 XGetScreenSaver(tqt_xdisplay(), &mXTimeout, &mXInterval, &mXBlanking, &mXExposures); @@ -341,25 +356,14 @@ void SaverEngine::configure() void SaverEngine::setBlankOnly( bool blankOnly ) { mBlankOnly = blankOnly; - // FIXME: if running, stop and restart? What about security + // FIXME: if running, stop and restart? What about security // implications of this? } -//--------------------------------------------------------------------------- -// -// Start the screen saver. -// -bool SaverEngine::startLockProcess( LockType lock_type ) +bool SaverEngine::restartDesktopLockProcess() { - if (mState == Saving) - return true; - - enableExports(); - - kdDebug(1204) << "SaverEngine: starting saver" << endl; - emitDCOPSignal("KDE_start_screensaver()", TQByteArray()); - if (!mLockProcess.isRunning()) { + mSaverProcessReady = false; mLockProcess.clearArguments(); TQString path = TDEStandardDirs::findExe( "kdesktop_lock" ); if( path.isEmpty()) @@ -374,6 +378,36 @@ bool SaverEngine::startLockProcess( LockType lock_type ) kdDebug( 1204 ) << "Failed to start kdesktop_lock!" << endl; 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 ) @@ -435,6 +469,23 @@ void SaverEngine::stopLockProcess() 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() { bool abnormalExit = false; @@ -452,33 +503,13 @@ void SaverEngine::lockProcessExited() } if (abnormalExit == true) { // PROBABLE HACKING ATTEMPT DETECTED - // 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"); - } + restartDesktopLockProcess(); + mState = Waiting; + TQTimer::singleShot( 100, this, SLOT(recoverFromHackingAttempt()) ); } else { // Restart the lock process - if (!mLockProcess.isRunning()) { - 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; - } - } + restartDesktopLockProcess(); } } @@ -494,6 +525,11 @@ void SaverEngine::slotLockProcessFullyActivated() mState = Saving; } +void SaverEngine::slotLockProcessReady() +{ + mSaverProcessReady = true; +} + void SaverEngine::lockProcessWaiting() { kdDebug(1204) << "SaverEngine: lock exited" << endl; diff --git a/kdesktop/lockeng.h b/kdesktop/lockeng.h index ec0a7bf52..b211c73e9 100644 --- a/kdesktop/lockeng.h +++ b/kdesktop/lockeng.h @@ -81,6 +81,7 @@ public: public slots: void slotLockProcessWaiting(); void slotLockProcessFullyActivated(); + void slotLockProcessReady(); protected slots: void idleTimeout(); @@ -95,6 +96,10 @@ private slots: * Enable wallpaper exports */ void enableExports(); + void recoverFromHackingAttempt(); + +private: + bool restartDesktopLockProcess(); protected: enum LockType { DontLock, DefaultLock, ForceLock, SecureDialog }; @@ -125,6 +130,7 @@ protected: private: TDEProcess* mSAKProcess; bool mTerminationRequested; + bool mSaverProcessReady; }; #endif -- cgit v1.2.3