summaryrefslogtreecommitdiffstats
path: root/kdesktop/lock/lockprocess.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kdesktop/lock/lockprocess.cc')
-rw-r--r--kdesktop/lock/lockprocess.cc205
1 files changed, 191 insertions, 14 deletions
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc
index c11314bb8..519646f1e 100644
--- a/kdesktop/lock/lockprocess.cc
+++ b/kdesktop/lock/lockprocess.cc
@@ -51,6 +51,7 @@
#include <tqsocketnotifier.h>
#include <tqvaluevector.h>
#include <tqtooltip.h>
+#include <tqimage.h>
#include <tqdatetime.h>
@@ -122,6 +123,18 @@ static void segv_handler(int)
}
extern Atom qt_wm_state;
+extern bool trinity_desktop_lock_use_system_modal_dialogs;
+extern bool trinity_desktop_lock_delay_screensaver_start;
+
+bool trinity_desktop_lock_autohide_lockdlg = TRUE;
+
+#define ENABLE_CONTINUOUS_LOCKDLG_DISPLAY \
+mForceContinualLockDisplayTimer->start(100, FALSE); \
+trinity_desktop_lock_autohide_lockdlg = FALSE;
+
+#define DISABLE_CONTINUOUS_LOCKDLG_DISPLAY \
+mForceContinualLockDisplayTimer->stop(); \
+trinity_desktop_lock_autohide_lockdlg = TRUE;
//===========================================================================
//
@@ -129,7 +142,7 @@ extern Atom qt_wm_state;
// starting screensaver hacks, and password entry.f
//
LockProcess::LockProcess(bool child, bool useBlankOnly)
- : TQWidget(0L, "saver window", WX11BypassWM),
+ : TQWidget(0L, "saver window", (trinity_desktop_lock_use_system_modal_dialogs?((WFlags)(WStyle_StaysOnTop|WStyle_Customize | WStyle_NoBorder)):((WFlags)WX11BypassWM))),
mOpenGLVisual(0),
child_saver(child),
mParent(0),
@@ -147,13 +160,26 @@ LockProcess::LockProcess(bool child, bool useBlankOnly)
mForceReject(false),
mDialogControlLock(false),
currentDialog(NULL),
- resizeTimer(NULL)
+ resizeTimer(NULL),
+ hackResumeTimer(NULL),
+ mForceContinualLockDisplayTimer(NULL),
+ mHackDelayStartupTimer(NULL),
+ mHackDelayStartupTimeout(0)
{
setupSignals();
setupPipe();
kapp->installX11EventFilter(this);
+ mForceContinualLockDisplayTimer = new TQTimer( this );
+ connect( mForceContinualLockDisplayTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(displayLockDialogIfNeeded()) );
+
+ mHackDelayStartupTimer = new TQTimer( this );
+ connect( mHackDelayStartupTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(startHack()) );
+
+ // [FIXME] This interval should be taken from the screensaver start delay of kdesktop
+ mHackDelayStartupTimeout = 10*1000;
+
// Get root window size
XWindowAttributes rootAttr;
XGetWindowAttributes(qt_xdisplay(), RootWindow(qt_xdisplay(),
@@ -232,6 +258,23 @@ LockProcess::LockProcess(bool child, bool useBlankOnly)
//
LockProcess::~LockProcess()
{
+ if (resizeTimer != NULL) {
+ resizeTimer->stop();
+ delete resizeTimer;
+ }
+ if (hackResumeTimer != NULL) {
+ hackResumeTimer->stop();
+ delete hackResumeTimer;
+ }
+ if (mForceContinualLockDisplayTimer != NULL) {
+ mForceContinualLockDisplayTimer->stop();
+ delete mForceContinualLockDisplayTimer;
+ }
+ if (mHackDelayStartupTimer != NULL) {
+ mHackDelayStartupTimer->stop();
+ delete mHackDelayStartupTimer;
+ }
+
if (greetPlugin.library) {
if (greetPlugin.info->done)
greetPlugin.info->done();
@@ -575,10 +618,19 @@ void LockProcess::readSaver()
kdDebug(1204) << "mForbidden: " << (mForbidden ? "true" : "false") << endl;
- if (config.hasActionGroup("Root"))
- {
- config.setActionGroup("Root");
- mSaverExec = config.readPathEntry("Exec");
+ if (trinity_desktop_lock_use_system_modal_dialogs) {
+ if (config.hasActionGroup("InWindow"))
+ {
+ config.setActionGroup("InWindow");
+ mSaverExec = config.readPathEntry("Exec");
+ }
+ }
+ else {
+ if (config.hasActionGroup("Root"))
+ {
+ config.setActionGroup("Root");
+ mSaverExec = config.readPathEntry("Exec");
+ }
}
}
}
@@ -591,7 +643,7 @@ void LockProcess::createSaverWindow()
{
Visual* visual = CopyFromParent;
XSetWindowAttributes attrs;
- int flags = CWOverrideRedirect;
+ int flags = trinity_desktop_lock_use_system_modal_dialogs?0:CWOverrideRedirect;
#ifdef HAVE_GLXCHOOSEVISUAL
if( mOpenGLVisual )
{
@@ -658,7 +710,8 @@ void LockProcess::createSaverWindow()
// set NoBackground so that the saver can capture the current
// screen state if necessary
- setBackgroundMode(TQWidget::NoBackground);
+ // this is a security risk and has been deactivated--welcome to the 21st century folks!
+ // setBackgroundMode(TQWidget::NoBackground);
setCursor( tqblankCursor );
setGeometry(0, 0, mRootWidth, mRootHeight);
@@ -915,7 +968,27 @@ bool LockProcess::startSaver()
raise();
XSync(qt_xdisplay(), False);
setVRoot( winId(), winId() );
- startHack();
+ if (!trinity_desktop_lock_delay_screensaver_start) {
+ setBackgroundColor(black);
+ erase();
+ }
+ if (trinity_desktop_lock_use_system_modal_dialogs) {
+ // Try to get the root pixmap
+ TQString filename = getenv("USER");
+ filename.prepend("/tmp/kde-");
+ filename.append("/krootbacking.png");
+ remove(filename.ascii());
+ system("krootbacking &");
+ TQTimer::singleShot( 0, this, SLOT(slotPaintBackground()) );
+ }
+
+ if (trinity_desktop_lock_delay_screensaver_start) {
+ ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
+ mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
+ }
+ else {
+ startHack();
+ }
return true;
}
@@ -926,8 +999,9 @@ bool LockProcess::startSaver()
void LockProcess::stopSaver()
{
kdDebug(1204) << "LockProcess: stopping saver" << endl;
- resume( true );
+ mHackProc.kill(SIGCONT);
stopHack();
+ mSuspended = false;
hideSaverWindow();
mVisibility = false;
if (!child_saver) {
@@ -1048,12 +1122,27 @@ bool LockProcess::startHack()
if (!mForbidden)
{
+ if (trinity_desktop_lock_delay_screensaver_start) {
+ // Make sure we have a nice clean display to start with!
+ setBackgroundColor(black);
+ erase();
+ mSuspended = false;
+ }
+
if (mHackProc.start() == true)
{
#ifdef HAVE_SETPRIORITY
setpriority(PRIO_PROCESS, mHackProc.pid(), mPriority);
#endif
//bitBlt(this, 0, 0, &mOriginal);
+ DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
+ if (trinity_desktop_lock_delay_screensaver_start) {
+ // Close any active dialogs
+ if (currentDialog != NULL) {
+ mForceReject = true;
+ currentDialog->close();
+ }
+ }
return true;
}
}
@@ -1061,7 +1150,12 @@ bool LockProcess::startHack()
// we aren't allowed to start the specified screensaver either because it didn't run for some reason
// according to the kiosk restrictions forbid it
{
- setBackgroundColor(black);
+ usleep(100);
+ TQApplication::syncX();
+ if (!trinity_desktop_lock_use_system_modal_dialogs) setBackgroundColor(black);
+ if (backingPixmap.isNull()) erase();
+ else bitBlt(this, 0, 0, &backingPixmap);
+ ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
}
}
return false;
@@ -1087,7 +1181,28 @@ void LockProcess::hackExited(KProcess *)
{
// Hack exited while we're supposed to be saving the screen.
// Make sure the saver window is black.
- setBackgroundColor(black);
+ usleep(100);
+ TQApplication::syncX();
+ if (!trinity_desktop_lock_use_system_modal_dialogs) setBackgroundColor(black);
+ if (backingPixmap.isNull()) erase();
+ else bitBlt(this, 0, 0, &backingPixmap);
+ ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
+}
+
+void LockProcess::displayLockDialogIfNeeded()
+{
+ if (trinity_desktop_lock_use_system_modal_dialogs) {
+ if (!mBusy) {
+ mBusy = true;
+ if (mLocked) {
+ if (checkPass()) {
+ stopSaver();
+ kapp->quit();
+ }
+ }
+ mBusy = false;
+ }
+ }
}
void LockProcess::suspend()
@@ -1096,6 +1211,8 @@ void LockProcess::suspend()
{
mHackProc.kill(SIGSTOP);
TQApplication::syncX();
+ usleep(100); // Let the stop signal get through
+ TQApplication::syncX();
mSavedScreen = TQPixmap::grabWindow( winId());
}
mSuspended = true;
@@ -1105,7 +1222,7 @@ void LockProcess::resume( bool force )
{
if( !force && (!mDialogs.isEmpty() || !mVisibility ))
return; // no resuming with dialog visible or when not visible
- if(mSuspended)
+ if ((mSuspended) && (mHackProc.isRunning()))
{
XForceScreenSaver(qt_xdisplay(), ScreenSaverReset );
bitBlt( this, 0, 0, &mSavedScreen );
@@ -1169,6 +1286,11 @@ static void fakeFocusIn( WId window )
XSendEvent( qt_xdisplay(), window, False, NoEventMask, &ev );
}
+void LockProcess::resumeUnforced()
+{
+ resume( false );
+}
+
int LockProcess::execDialog( TQDialog *dlg )
{
currentDialog=dlg;
@@ -1186,6 +1308,8 @@ int LockProcess::execDialog( TQDialog *dlg )
}
mDialogs.prepend( dlg );
fakeFocusIn( dlg->winId());
+ if (backingPixmap.isNull() && trinity_desktop_lock_use_system_modal_dialogs) erase();
+ else bitBlt(this, 0, 0, &backingPixmap);
int rt = dlg->exec();
while (mDialogControlLock == true) sleep(1);
currentDialog = NULL;
@@ -1193,12 +1317,63 @@ int LockProcess::execDialog( TQDialog *dlg )
if( mDialogs.isEmpty() ) {
XChangeActivePointerGrab( qt_xdisplay(), GRABEVENTS,
TQCursor(tqblankCursor).handle(), CurrentTime);
- resume( false );
+ if (trinity_desktop_lock_use_system_modal_dialogs) {
+ // Slight delay before screensaver resume to allow the dialog window to fully disappear
+ if (hackResumeTimer == NULL) {
+ hackResumeTimer = new TQTimer( this );
+ connect( hackResumeTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(resumeUnforced()) );
+ }
+ hackResumeTimer->start( 10, TRUE );
+ }
+ else {
+ resume( false );
+ }
} else
fakeFocusIn( mDialogs.first()->winId());
return rt;
}
+void LockProcess::slotPaintBackground()
+{
+ TQPixmap pm;
+ TQString filename = getenv("USER");
+ filename.prepend("/tmp/kde-");
+ filename.append("/krootbacking.png");
+ bool success = pm.load(filename, "PNG");
+ if (!success) {
+ sleep(1);
+ success = pm.load(filename, "PNG");
+ if (!success) {
+ pm = TQPixmap(kapp->desktop()->width(), kapp->desktop()->height());
+ pm.fill(Qt::black);
+ }
+ }
+
+ if (TQPaintDevice::x11AppDepth() == 32) {
+ // Remove the alpha components from the image
+ TQImage correctedImage = pm.convertToImage();
+ correctedImage = correctedImage.convertDepth(32);
+ correctedImage.setAlphaBuffer(true);
+ int w = correctedImage.width();
+ int h = correctedImage.height();
+ for (int y = 0; y < h; ++y) {
+ TQRgb *ls = (TQRgb *)correctedImage.scanLine( y );
+ for (int x = 0; x < w; ++x) {
+ TQRgb l = ls[x];
+ int r = int( tqRed( l ) );
+ int g = int( tqGreen( l ) );
+ int b = int( tqBlue( l ) );
+ int a = int( 255 );
+ ls[x] = tqRgba( r, g, b, a );
+ }
+ }
+ pm.convertFromImage(correctedImage);
+ }
+
+ backingPixmap = pm;
+ if (trinity_desktop_lock_delay_screensaver_start) erase();
+}
+
void LockProcess::preparePopup()
{
TQWidget *dlg = (TQWidget *)sender();
@@ -1266,6 +1441,8 @@ bool LockProcess::x11Event(XEvent *event)
return true; // filter out
// fall through
case KeyPress:
+ if ((mHackDelayStartupTimer) && ((trinity_desktop_lock_autohide_lockdlg == FALSE) && (mHackDelayStartupTimer->isActive())))
+ mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
if (mBusy || !mDialogs.isEmpty())
break;
mBusy = true;