From 9925fc58bcca4faf6f6a356ace24acdf19556560 Mon Sep 17 00:00:00 2001 From: tpearson Date: Mon, 12 Sep 2011 00:34:54 +0000 Subject: Fix system modal dialogs Fix shutdown background Add code to make the desktop locking system use the system window decorations and generally use the same theme and style as the active desktop This code is disabled for now, but can be enabled via the two new static variables in kdesktop/lock/main.cc git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1252900 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kdesktop/lock/lockprocess.cc | 205 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 191 insertions(+), 14 deletions(-) (limited to 'kdesktop/lock/lockprocess.cc') 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 #include #include +#include #include @@ -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; -- cgit v1.2.1