diff --git a/kdesktop/kdesktop.kcfg b/kdesktop/kdesktop.kcfg index 3d20778af..e83face76 100644 --- a/kdesktop/kdesktop.kcfg +++ b/kdesktop/kdesktop.kcfg @@ -323,7 +323,14 @@ When disabled the screensaver starts immediately when locking the desktop. - + + + + true + + When enabled all active windows are hidden from the screensaver, showing only the desktop background as a result. + + diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc index db92c0018..1a58d4e52 100644 --- a/kdesktop/lock/lockprocess.cc +++ b/kdesktop/lock/lockprocess.cc @@ -111,6 +111,8 @@ Status DPMSInfo ( Display *, CARD16 *, BOOL * ); #define LOCK_GRACE_DEFAULT 5000 #define AUTOLOGOUT_DEFAULT 600 +#define DESKTOP_WALLPAPER_OBTAIN_TIMEOUT_MS 3000 + // Setting this define is INSECURE // Use it for debugging purposes ONLY // #define KEEP_MOUSE_UNGRABBED 1 @@ -136,6 +138,7 @@ extern Atom tqt_wm_state; extern bool trinity_desktop_lock_use_system_modal_dialogs; extern bool trinity_desktop_lock_delay_screensaver_start; extern bool trinity_desktop_lock_use_sak; +extern bool trinity_desktop_lock_hide_active_windows; extern bool trinity_desktop_lock_forced; extern TQXLibWindowList trinity_desktop_lock_hidden_window_list; @@ -218,8 +221,8 @@ LockProcess::LockProcess() // Try to get the root pixmap if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this); - m_rootPixmap->setCustomPainting(true); connect(m_rootPixmap, TQT_SIGNAL(backgroundUpdated(const TQPixmap &)), this, TQT_SLOT(slotPaintBackground(const TQPixmap &))); + m_rootPixmap->setCustomPainting(true); m_rootPixmap->start(); // Get root window size @@ -1286,6 +1289,27 @@ bool LockProcess::startSaver() raise(); XSync(tqt_xdisplay(), False); setVRoot( winId(), winId() ); + + if (!trinity_desktop_lock_hide_active_windows) { + if (m_rootPixmap) m_rootPixmap->stop(); + TQPixmap rootWinSnapShot = TQPixmap::grabWindow(TQApplication::desktop()->winId()); + slotPaintBackground(rootWinSnapShot); + } + else { + // Sometimes KRootPixmap fails...make sure the desktop is hidden regardless + if (backingPixmap.isNull()) { + if (!mEnsureScreenHiddenTimer) { + mEnsureScreenHiddenTimer = new TQTimer( this ); + connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) ); + mEnsureScreenHiddenTimer->start(DESKTOP_WALLPAPER_OBTAIN_TIMEOUT_MS, true); + } + + while ((backingPixmap.isNull()) && (mEnsureScreenHiddenTimer->isActive())) { + kapp->processEvents(); + } + } + } + if (((!(trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced)) && (!trinity_desktop_lock_in_sec_dlg)) && mHackStartupEnabled) { if (backingPixmap.isNull()) { setBackgroundColor(black); @@ -1296,18 +1320,6 @@ bool LockProcess::startSaver() setGeometry(0, 0, mRootWidth, mRootHeight); erase(); } - if (trinity_desktop_lock_use_system_modal_dialogs) { - // Try to get the root pixmap - if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this); - m_rootPixmap->setCustomPainting(true); - m_rootPixmap->start(); - // Sometimes KRootPixmap fails...make sure the desktop is hidden regardless - if (!mEnsureScreenHiddenTimer) { - mEnsureScreenHiddenTimer = new TQTimer( this ); - connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) ); - mEnsureScreenHiddenTimer->start(2000, true); - } - } if (trinity_desktop_lock_in_sec_dlg == FALSE) { if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced && trinity_desktop_lock_use_system_modal_dialogs) { @@ -1433,6 +1445,9 @@ void LockProcess::closeDialogAndStartHack() if (closeCurrentWindow()) { TQTimer::singleShot( 0, this, SLOT(closeDialogAndStartHack()) ); } + else { + resume(true); + } } void LockProcess::repaintRootWindowIfNeeded() @@ -1512,7 +1527,6 @@ bool LockProcess::startHack() if (!mForbidden) { - if (trinity_desktop_lock_use_system_modal_dialogs) { // Make sure we have a nice clean display to start with! if (backingPixmap.isNull()) { @@ -1686,14 +1700,19 @@ void LockProcess::resume( bool force ) } if( !force && (!mDialogs.isEmpty() || !mVisibility )) { // no resuming with dialog visible or when not visible - if (backingPixmap.isNull()) { - setBackgroundColor(black); + if (trinity_desktop_lock_use_system_modal_dialogs) { + if (backingPixmap.isNull()) { + setBackgroundColor(black); + } + else { + setBackgroundPixmap(backingPixmap); + } + setGeometry(0, 0, mRootWidth, mRootHeight); + erase(); } else { - setBackgroundPixmap(backingPixmap); + setGeometry(0, 0, mRootWidth, mRootHeight); } - setGeometry(0, 0, mRootWidth, mRootHeight); - erase(); return; } if ((mSuspended) && (mHackProc.isRunning())) @@ -1810,11 +1829,15 @@ int LockProcess::execDialog( TQDialog *dlg ) } mDialogs.prepend( dlg ); fakeFocusIn( dlg->winId()); - if (backingPixmap.isNull() && trinity_desktop_lock_use_system_modal_dialogs) { - setGeometry(0, 0, mRootWidth, mRootHeight); - erase(); + if (trinity_desktop_lock_use_system_modal_dialogs) { + if (backingPixmap.isNull()) { + setGeometry(0, 0, mRootWidth, mRootHeight); + erase(); + } + else { + bitBlt(this, 0, 0, &backingPixmap); + } } - else bitBlt(this, 0, 0, &backingPixmap); // dlg->exec may generate BadMatch errors, so make sure they are silently ignored int (*oldHandler)(Display *, XErrorEvent *); oldHandler = XSetErrorHandler(ignoreXError); @@ -2011,15 +2034,15 @@ bool LockProcess::x11Event(XEvent *event) { // mVisibility == false means the screensaver is not visible at all // e.g. when switched to text console mVisibility = !(event->xvisibility.state == VisibilityFullyObscured); - if(!mVisibility) + if(!mVisibility) { mSuspendTimer.start(2000, true); + } else { mSuspendTimer.stop(); if (mResizingDesktopLock == false) { if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced && trinity_desktop_lock_use_system_modal_dialogs) { - ENABLE_CONTINUOUS_LOCKDLG_DISPLAY - if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE); + // Do nothing } else { if (mHackStartupEnabled == true) { @@ -2037,8 +2060,9 @@ bool LockProcess::x11Event(XEvent *event) } } } - if (event->xvisibility.state != VisibilityUnobscured) + if (event->xvisibility.state != VisibilityUnobscured) { stayOnTop(); + } } break; diff --git a/kdesktop/lock/main.cc b/kdesktop/lock/main.cc index 7235776fb..5ac0a588a 100644 --- a/kdesktop/lock/main.cc +++ b/kdesktop/lock/main.cc @@ -53,6 +53,7 @@ TQXLibWindowList trinity_desktop_lock_hidden_window_list; bool trinity_desktop_lock_use_system_modal_dialogs = FALSE; bool trinity_desktop_lock_delay_screensaver_start = FALSE; bool trinity_desktop_lock_use_sak = FALSE; +bool trinity_desktop_lock_hide_active_windows = FALSE; bool trinity_desktop_lock_forced = FALSE; @@ -195,6 +196,11 @@ static void sigusr5_handler(int) signalled_run = TRUE; } +static int trapXErrors(Display *, XErrorEvent *) +{ + return 0; +} + // ----------------------------------------------------------------------------- int main( int argc, char **argv ) @@ -209,6 +215,8 @@ int main( int argc, char **argv ) KApplication::disableAutoDcopRegistration(); // not needed + XSetErrorHandler(trapXErrors); + while (1 == 1) { signalled_forcelock = FALSE; signalled_dontlock = FALSE; @@ -365,6 +373,7 @@ int main( int argc, char **argv ) trinity_desktop_lock_use_sak = false; // If SAK is enabled with unmanaged windows, the SAK dialog will never close and will "burn in" the screen trinity_desktop_lock_delay_screensaver_start = false; // If trinity_desktop_lock_delay_screensaver_start is true with unmanaged windows, the lock dialog may never appear } + trinity_desktop_lock_hide_active_windows = KDesktopSettings::hideActiveWindowsFromSaver(); delete tdmconfig;