Index: kdesktop/krootwm.cc =================================================================== RCS file: /home/kde/kdebase/kdesktop/krootwm.cc,v retrieving revision 1.162 diff -u -r1.162 krootwm.cc --- kdesktop/krootwm.cc 2002/09/11 08:57:17 1.162 +++ kdesktop/krootwm.cc 2002/09/20 01:07:18 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ #include #include #include +#include #include "krootwm.h" #include "kdiconview.h" @@ -162,6 +164,17 @@ this, SLOT( slotLogout() ), m_actionCollection, "logout" ); } + QStringList dmopt = + QStringList::split( QChar( ',' ), + QString::fromLatin1( ::getenv( "XDM_MANAGED" ) ) ); + if ( dmopt.findIndex( "rsvd" ) < 0 ) + xdmFifoName = QString::null; + else { + xdmFifoName = dmopt.first(); + new KAction(i18n("Start New Session"), "fork", 0, this, + SLOT( slotNewSession() ), m_actionCollection, "newsession" ); + } + initConfig(); } @@ -267,6 +280,10 @@ if (action) action->plug( file ); + action = m_actionCollection->action("newsession"); + if (action) + action->plug( file ); + desk = new QPopupMenu; if (m_bDesktopEnabled) @@ -371,6 +388,10 @@ if (action) action->plug( desktopMenu ); + action = m_actionCollection->action("newsession"); + if (action) + action->plug( desktopMenu ); + connect( desktopMenu, SIGNAL( aboutToShow() ), this, SLOT( slotFileNewAboutToShow() ) ); if (menuBar) { @@ -604,6 +625,13 @@ m_pDesktop->logout(KApplication::ShutdownConfirmDefault, KApplication::ShutdownTypeDefault); } +void KRootWm::slotNewSession() { + QFile fifo(xdmFifoName); + if (fifo.open(IO_WriteOnly | IO_Raw)) { + fifo.writeBlock( "reserve\n", 8 ); + fifo.close(); + } +} void KRootWm::slotMenuItemActivated(int /* item */ ) { Index: kdesktop/krootwm.h =================================================================== RCS file: /home/kde/kdebase/kdesktop/krootwm.h,v retrieving revision 1.49 diff -u -r1.49 krootwm.h --- kdesktop/krootwm.h 2002/08/02 21:46:48 1.49 +++ kdesktop/krootwm.h 2002/09/20 01:07:18 @@ -104,6 +104,7 @@ void slotWindowList(); void slotLock(); void slotLogout(); + void slotNewSession(); private: KDesktop* m_pDesktop; @@ -141,6 +142,8 @@ KHelpMenu *help; QPixmap defaultPixmap; + + QString xdmFifoName; static KRootWm * s_rootWm; Index: kdesktop/lock/lockdlg.cc =================================================================== RCS file: /home/kde/kdebase/kdesktop/lock/lockdlg.cc,v retrieving revision 1.2 diff -u -r1.2 lockdlg.cc --- kdesktop/lock/lockdlg.cc 2002/04/03 14:28:52 1.2 +++ kdesktop/lock/lockdlg.cc 2002/09/20 01:07:18 @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -17,145 +19,72 @@ #include #include #include +#include #include "lockdlg.h" #include "lockdlg.moc" #include #include -#define MAX_PASSWORD_LENGTH 80 +#define PASSDLG_HIDE_TIMEOUT 10000 //=========================================================================== // // Simple dialog for entering a password. -// It does not handle password validation. // -PasswordDlg::PasswordDlg(QWidget *parent) - : QFrame(parent) +PasswordDlg::PasswordDlg(QWidget *parent, bool nsess) + : QDialog(parent, "password dialog", true, WStyle_Customize | WStyle_NoBorder) { - setFocusPolicy(StrongFocus); - setFrameStyle(QFrame::Panel | QFrame::Raised); - setLineWidth(2); - - KConfig *config = KGlobal::config(); - config->reparseConfiguration(); - KConfigGroupSaver cgs(config, "Passwords"); - QString val = config->readEntry("EchoMode", "x"); - if (val == "OneStar" - || (val == "x" && defEchoMode == KPasswordEdit::OneStar)) - mStars = 1; - else if (val == "ThreeStars" - || (val == "x" && defEchoMode == KPasswordEdit::ThreeStars)) - mStars = 3; - else - mStars = 0; + QFrame *winFrame = new QFrame( this ); + winFrame->setFrameStyle( QFrame::Panel | QFrame::Raised ); + winFrame->setLineWidth( 2 ); - mBlink = false; - mPassword = ""; +// setFocusPolicy(StrongFocus); - QGridLayout *layout = new QGridLayout(this, 2, 3, 20, 10); + QGridLayout *layout = new QGridLayout(winFrame, 2, 3, 20, 10); layout->setResizeMode(QLayout::Minimum); layout->addColSpacing(1, 20); - QLabel *pixlabel= new QLabel(this); + QLabel *pixlabel= new QLabel(winFrame); pixlabel->setPixmap(QPixmap(locate("data", "kdesktop/pics/ksslogo.png"))); layout->addMultiCellWidget(pixlabel, 0, 1, 0, 0, QLayout::AlignTop); QFont font = KGlobalSettings::generalFont(); - font.setPointSize(18); - QString query = passwordQueryMsg(true); - mLabel = new QLabel(query, this); - mLabel->setFont(font); + mLabel = new QLabel(passwordQueryMsg(), winFrame); mLabel->setAlignment(AlignCenter); + font.setPointSize(18); + mLabel->setFont(font); + mLabel->setFixedSize(mLabel->sizeHint()); layout->addWidget(mLabel, 0, 2); + mEntry = new KPasswordEdit( winFrame, "password edit" ); font.setPointSize(16); - mEntry = new QLabel("*********************_", this); mEntry->setFont(font); - mEntry->setMinimumHeight(mEntry->sizeHint().height()+5); - mEntry->setMinimumWidth(mEntry->sizeHint().width()+10); - mEntry->setFrameStyle(QFrame::Panel | QFrame::Sunken); - mEntry->setText(""); + mEntry->installEventFilter(this); layout->addWidget(mEntry, 1, 2); - layout->activate(); - - resize(layout->sizeHint()); - - mFailedTimerId = 0; - mBlinkTimerId = startTimer(300); -} - -//--------------------------------------------------------------------------- -// -// Reset the password to "" -// -void PasswordDlg::resetPassword() -{ - mPassword = ""; - drawStars(); -} -//--------------------------------------------------------------------------- -// -// Show "Failed" in the dialog for 1.5 seconds -// -void PasswordDlg::showFailed() -{ - mLabel->setText(i18n("Failed")); - mFailedTimerId = startTimer(1500); -} - -//--------------------------------------------------------------------------- -// -// Keyboard events should be passed to this function directly. -// We accept key presses this way because the keyboard is grabbed, so we -// don't get any events. There's nicer ways of handling this, but this is -// simplest. -// -void PasswordDlg::keyPressed(XKeyEvent *xKeyEvent) -{ - KeySym keysym = 0; - char buffer[10] = ""; - (void)XLookupString(xKeyEvent, buffer, 10, &keysym, 0); + if (nsess) { + mButton = new QPushButton(i18n("\nStart\n&new\nsession\n"), winFrame, "button"); + layout->addMultiCellWidget(mButton, 0,1, 3,3, AlignCenter); + connect(mButton, SIGNAL(clicked()), SIGNAL(startNewSession())); + mButton->installEventFilter(this); + } else + mButton = 0; - switch (keysym) - { - case XK_BackSpace: - if (mPassword.length()) - { - mPassword.truncate(mPassword.length() - 1); - drawStars(); - } - break; - - default: - if (mPassword.length() < MAX_PASSWORD_LENGTH && !iscntrl(buffer[0])) - { - mPassword += buffer[0]; - drawStars(); - } - break; - } -} + layout->activate(); -//--------------------------------------------------------------------------- -// -// Draws the stars if mStars is true -// -void PasswordDlg::drawStars() -{ - QString s(""); + resize(layout->sizeHint()); - if (mStars) - s.fill('*', mPassword.length() * mStars); + installEventFilter(this); - if (mBlink) - s += "_"; + mFailedTimerId = 0; + mTimeoutTimerId = startTimer(PASSDLG_HIDE_TIMEOUT); - mEntry->setText(s); + connect(&mPassProc, SIGNAL(processExited(KProcess *)), + SLOT(passwordChecked(KProcess *))); } //--------------------------------------------------------------------------- @@ -181,14 +110,9 @@ // // This returns the string to use to ask the user for their password. // -QString PasswordDlg::passwordQueryMsg(bool name) +QString PasswordDlg::passwordQueryMsg() { - QString retval(""); - if (name) - { - retval = currentUser(); - } - return i18n("Enter Password") + "\n" + retval; + return i18n("Enter Password") + "\n" + currentUser(); } //--------------------------------------------------------------------------- @@ -197,19 +121,155 @@ // void PasswordDlg::timerEvent(QTimerEvent *ev) { - if (ev->timerId() == mBlinkTimerId) + if (ev->timerId() == mTimeoutTimerId) { - // Show/hide the password entry cursor. - mBlink = !mBlink; - drawStars(); + reject(); } else if (ev->timerId() == mFailedTimerId) { - // Show the normal password prompt. - mLabel->setText(passwordQueryMsg(true)); - drawStars(); killTimer(mFailedTimerId); mFailedTimerId = 0; + // Show the normal password prompt. + mLabel->setText(passwordQueryMsg()); + mEntry->erase(); + mEntry->setEnabled(true); + if( mButton ) + mButton->setEnabled(true); + } +} + +#undef KeyPress /* i hate X #defines */ + +bool PasswordDlg::eventFilter( QObject *, QEvent *ev ) +{ + if ( ev->type() == QEvent::KeyPress ) { + killTimer(mTimeoutTimerId); + mTimeoutTimerId = startTimer(PASSDLG_HIDE_TIMEOUT); + QKeyEvent *e = (QKeyEvent *)ev; + if ( ( e->state() == 0 && + ( e->key() == Key_Enter || e->key() == Key_Return ) ) || + ( e->state() & Keypad && e->key() == Key_Enter ) ) { + if ( focusWidget() == mButton ) + mButton->animateClick(); + else if ( focusWidget() == mEntry ) + startCheckPassword(); + return true; + } + } else if (ev->type() == QEvent::ContextMenu) + return true; + return false; +} + +//--------------------------------------------------------------------------- +// +// Starts the kcheckpass process to check the user's password. +// +// Serge Droz 10.2000 +// Define ACCEPT_ENV if you want to pass an environment variable to +// kcheckpass. Define ACCEPT_ARGS if you want to pass command line +// arguments to kcheckpass +#define ACCEPT_ENV +//#define ACCEPT_ARGS +void PasswordDlg::startCheckPassword() +{ + const char *passwd = mEntry->password(); + if (passwd && *passwd) + { + if( mButton ) + mButton->setEnabled(false); + mEntry->setEnabled(false); + + QString kcp_binName = KStandardDirs::findExe("kcheckpass"); + + mPassProc.clearArguments(); + mPassProc << kcp_binName; + +#ifdef HAVE_PAM +# ifdef ACCEPT_ENV + setenv("KDE_PAM_ACTION", KSCREENSAVER_PAM_SERVICE, 1); +# elif defined(ACCEPT_ARGS) + mPassProc << "-c" << KSCREENSAVER_PAM_SERVICE; +# endif +#endif + bool ret = mPassProc.start(KProcess::NotifyOnExit, KProcess::Stdin); +#ifdef HAVE_PAM +# ifdef ACCEPT_ENV + unsetenv("KDE_PAM_ACTION"); +# endif +#endif + if (ret == false) + { + kdDebug(1204) << "kcheckpass failed to start" << endl; + mLabel->setText(i18n("Verification failed\nKill kdesktop_lock")); + mFailedTimerId = startTimer(10000); + return; + } + + // write Password to stdin + mPassProc.writeStdin(passwd, strlen(passwd)); + mPassProc.closeStdin(); + } +} + +//--------------------------------------------------------------------------- +// +// The kcheckpass process has exited. +// +void PasswordDlg::passwordChecked(KProcess *proc) +{ + if (proc == &mPassProc) + { + /* the exit codes of kcheckpass: + 0: everything fine + 1: authentification failed + 2: passwd access failed [permissions/misconfig] + */ + if (mPassProc.normalExit() && !mPassProc.exitStatus()) + { +/* +XXX this needs to go into a separate routine at startup time + stopSaver(); + if ( mPassProc.exitStatus() == 2 ) + { + KMessageBox::error(0, + i18n( "

Screen Locking Failed!

" + "Your screen was not locked because the kcheckpass " + "program was not able to check your password. This is " + "usually the result of kcheckpass not being installed " + "correctly. If you installed KDE yourself, reinstall " + "kcheckpass as root. If you are using a pre-compiled " + "package, contact the packager." ), + i18n( "Screen Locking Failed" ) ); + } + kapp->quit(); +*/ + accept(); + } + else + { + mLabel->setText(i18n("Failed")); + mFailedTimerId = startTimer(1500); + } } } +// see the comment at the top of lockprocess.cpp +// with certain unreasonable focus policies (focus under mouse, ehm), +// KWin interferes and doesn't make the dialog focused, so we have +// to focus it manually (moving mouse doesn't help because of mouse grab) +// the right fix is of course override_redirect, so KWin won't get in the way +// and we can call setActiveWindow() and setFocus() without waiting +void PasswordDlg::show() +{ + QDialog::show(); + QApplication::flushX(); + for(;;) + { // wait for the window to get mapped + XWindowAttributes attrs; + if( XGetWindowAttributes( qt_xdisplay(), winId(), &attrs ) + && attrs.map_state != IsUnmapped ) + break; + } + setActiveWindow(); + setFocus(); +} Index: kdesktop/lock/lockdlg.h =================================================================== RCS file: /home/kde/kdebase/kdesktop/lock/lockdlg.h,v retrieving revision 1.1 diff -u -r1.1 lockdlg.h --- kdesktop/lock/lockdlg.h 2002/03/02 22:53:37 1.1 +++ kdesktop/lock/lockdlg.h 2002/09/20 01:07:18 @@ -8,62 +8,48 @@ #ifndef __LOCKDLG_H__ #define __LOCKDLG_H__ -#include -#include +#include +#include +#include #include +class KPasswordEdit; +class QPushButton; + //=========================================================================== // // Simple dialog for entering a password. // It does not handle password validation. // -class PasswordDlg : public QFrame +class PasswordDlg : public QDialog { Q_OBJECT + public: - PasswordDlg(QWidget *parent); + PasswordDlg(QWidget *parent, bool msess); + virtual void show(); - //----------------------------------------------------------------------- - // - // Reset the password to "" - // - void resetPassword(); - - //----------------------------------------------------------------------- - // - // Show "Failed" in the dialog for 1.5 seconds - // - void showFailed(); - - //----------------------------------------------------------------------- - // - // Keyboard events should be passed to this function directly. - // We accept key presses this way because the keyboard is grabbed, so we - // don't get any events. There's nicer ways of handling this, but this - // is simplest. - // - void keyPressed(XKeyEvent *); - - //----------------------------------------------------------------------- - // - // return the password the user entered. - // - QString password() const { return mPassword; } +signals: + void startNewSession(); protected: - void drawStars(); - QString currentUser(); - QString passwordQueryMsg(bool name); virtual void timerEvent(QTimerEvent *); + virtual bool eventFilter(QObject *, QEvent *); +protected slots: + void passwordChecked(KProcess *); + private: + void startCheckPassword(); + QString currentUser(); + QString passwordQueryMsg(); + int mFailedTimerId; - int mBlinkTimerId; + int mTimeoutTimerId; QLabel *mLabel; - QLabel *mEntry; - QString mPassword; - int mStars; - bool mBlink; + KPasswordEdit *mEntry; + QPushButton *mButton; + KProcess mPassProc; }; #endif Index: kdesktop/lock/lockprocess.cc =================================================================== RCS file: /home/kde/kdebase/kdesktop/lock/lockprocess.cc,v retrieving revision 1.6 diff -u -r1.6 lockprocess.cc --- kdesktop/lock/lockprocess.cc 2002/08/07 08:36:17 1.6 +++ kdesktop/lock/lockprocess.cc 2002/09/20 01:07:19 @@ -14,6 +14,14 @@ //crashes (e.g. because it's set to multiple wallpapers and //some image will be corrupted). + +// This stuff should be probably rewritten to use override_redirect +// (WX11BypassWM) windows. This process grabs the mouse and the keyboard, +// and basically pretends there's no WM anyway. If there will be some +// more problems with focus, window showing or whatever related, +// tell KWin developers. +// See also PasswordDlg::show(). + #include #include @@ -36,6 +44,7 @@ #include "lockprocess.h" #include "lockprocess.moc" +#include "lockdlg.h" #ifdef HAVE_SETPRIORITY #include @@ -47,10 +56,8 @@ #include #include -#define PASSDLG_HIDE_TIMEOUT 10000 #define LOCK_GRACE_DEFAULT 5000 -int ignoreXError(Display *, XErrorEvent *); static Window gVRoot = 0; static Window gVRootData = 0; static Atom gXA_VROOT; @@ -95,11 +102,6 @@ KGlobal::dirs()->kde_default("apps") + relPath); - mState = Saving; - mPassDlg = 0; - mHidePassTimerId = 0; - mCheckPassTimerId = 0; - mCheckingPass = false; mLockOnce = false; // virtual root property @@ -110,15 +112,13 @@ XGetWindowAttributes(qt_xdisplay(), winId(), &attrs); mColorMap = attrs.colormap; - connect(&mPassProc, SIGNAL(processExited(KProcess *)), - SLOT(passwordChecked(KProcess *))); connect(&mHackProc, SIGNAL(processExited(KProcess *)), SLOT(hackExited(KProcess *))); QStringList dmopt = QStringList::split( QChar( ',' ), QString::fromLatin1( ::getenv( "XDM_MANAGED" ) ) ); - if ( dmopt.isEmpty() || dmopt.first()[0] != QChar( '/' ) ) + if (dmopt.findIndex( "rsvd" ) < 0) mXdmFifoName = QString::null; else mXdmFifoName = dmopt.first(); @@ -132,7 +132,6 @@ // LockProcess::~LockProcess() { - hidePassDlg(); } static int sigterm_pipe[ 2 ]; @@ -206,10 +205,7 @@ //--------------------------------------------------------------------------- void LockProcess::quitSaver() { - if (mState == Saving) - { - stopSaver(); - } + stopSaver(); kapp->quit(); } @@ -240,10 +236,7 @@ QTimer::singleShot(lockGrace, this, SLOT(actuallySetLock())); } - else - { - mLock = false; - } + mLock = false; mPriority = config.readNumEntry("Priority", 19); if (mPriority < 0) mPriority = 0; @@ -307,7 +300,7 @@ attr.colormap = DefaultColormapOfScreen( ScreenOfDisplay(qt_xdisplay(), qt_xscreen())); } - attr.event_mask = KeyPressMask | ButtonPressMask | MotionNotify | + attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask | VisibilityChangeMask | ExposureMask; XChangeWindowAttributes(qt_xdisplay(), winId(), CWEventMask | CWColormap, &attr); @@ -345,6 +338,12 @@ } //--------------------------------------------------------------------------- +static int ignoreXError(Display *, XErrorEvent *) +{ + return 0; +} + +//--------------------------------------------------------------------------- // // Save the current virtual root window // @@ -441,6 +440,9 @@ return (rv == GrabSuccess); } +#define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ + EnterWindowMask | LeaveWindowMask + //--------------------------------------------------------------------------- // // Grab the mouse. Returns true on success @@ -448,13 +450,8 @@ bool LockProcess::grabMouse() { int rv = XGrabPointer( qt_xdisplay(), QApplication::desktop()->winId(), - True, ButtonPressMask - | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask - | PointerMotionMask | PointerMotionHintMask | Button1MotionMask - | Button2MotionMask | Button3MotionMask | Button4MotionMask - | Button5MotionMask | ButtonMotionMask | KeymapStateMask, - GrabModeAsync, GrabModeAsync, None, blankCursor.handle(), - CurrentTime ); + True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None, + blankCursor.handle(), CurrentTime ); return (rv == GrabSuccess); } @@ -500,19 +497,23 @@ //--------------------------------------------------------------------------- // -// Send KDM (or XDM, if it gets adapted) a command if we lock the screen +// Send KDM (or XDM, if it gets adapted) a command // void LockProcess::xdmFifoCmd(const char *cmd) { - if (!mXdmFifoName.isNull() && (mLock || mLockOnce)) { - QFile fifo(mXdmFifoName); - if (fifo.open(IO_WriteOnly | IO_Raw)) { - fifo.writeBlock( cmd, ::strlen(cmd) ); - fifo.close(); - } + QFile fifo(mXdmFifoName); + if (fifo.open(IO_WriteOnly | IO_Raw)) { + fifo.writeBlock( cmd, ::strlen(cmd) ); + fifo.close(); } } +void LockProcess::xdmFifoLockCmd(const char *cmd) +{ + if (!mXdmFifoName.isNull() && (mLock || mLockOnce)) + xdmFifoCmd(cmd); +} + //--------------------------------------------------------------------------- // // Start the screen saver. @@ -524,15 +525,13 @@ kdWarning(1204) << "LockProcess::startSaver() grabInput() failed!!!!" << endl; return; } - mState = Saving; + mBusy = false; saveVRoot(); if (parent) { QSocketNotifier *notifier = new QSocketNotifier(parent, QSocketNotifier::Read, this, "notifier"); connect(notifier, SIGNAL( activated (int)), SLOT( quitSaver())); - notifier = new QSocketNotifier(parent, QSocketNotifier::Exception, this, "notifier_ex"); - connect(notifier, SIGNAL( activated (int)), SLOT( quitSaver())); } createSaverWindow(); move(0, 0); @@ -542,7 +541,7 @@ raise(); XSync(qt_xdisplay(), False); if (!child_saver) - xdmFifoCmd("lock\n"); + xdmFifoLockCmd("lock\n"); slotStart(); } @@ -568,10 +567,9 @@ { kdDebug(1204) << "LockProcess: stopping saver" << endl; stopHack(); - xdmFifoCmd("unlock\n"); hideSaverWindow(); - hidePassDlg(); if (!child_saver) { + xdmFifoLockCmd("unlock\n"); ungrabInput(); const char *out = "GOAWAY!"; for (QValueList::ConstIterator it = child_sockets.begin(); it != child_sockets.end(); ++it) @@ -580,6 +578,11 @@ mLockOnce = false; } +void LockProcess::actuallySetLock() +{ + mLock = true; +} + //--------------------------------------------------------------------------- // bool LockProcess::startHack() @@ -652,64 +655,25 @@ // // Show the password dialog // -void LockProcess::showPassDlg() +bool LockProcess::checkPass() { - if (mPassDlg) - { - hidePassDlg(); - } - mPassDlg = new PasswordDlg(this); - QDesktopWidget *desktop = KApplication::desktop(); + PasswordDlg passDlg(this, !mXdmFifoName.isNull()); + connect(&passDlg, SIGNAL(startNewSession()), SLOT(startNewSession())); - QRect rect = mPassDlg->geometry(); - if (child_sockets.isEmpty()) { + QDesktopWidget *desktop = KApplication::desktop(); + QRect rect = passDlg.geometry(); + if (child_sockets.isEmpty()) rect.moveCenter( desktop->screenGeometry(desktop->screenNumber(QCursor::pos())).center()); - } else + else rect.moveCenter( desktop->screenGeometry(qt_xscreen()).center()); - mPassDlg->move(rect.topLeft() ); - - mPassDlg->show(); - setPassDlgTimeout(PASSDLG_HIDE_TIMEOUT); -} + passDlg.move(rect.topLeft() ); -//--------------------------------------------------------------------------- -// -// Hide the password dialog -// -void LockProcess::hidePassDlg() -{ - if (mPassDlg) - { - delete mPassDlg; - mPassDlg = 0; - killPassDlgTimeout(); - } -} - -//--------------------------------------------------------------------------- -// -// Hide the password dialog in "t" seconds. -// -void LockProcess::setPassDlgTimeout(int t) -{ - if (mHidePassTimerId) - { - killTimer(mHidePassTimerId); - } - mHidePassTimerId = startTimer(t); -} - -//--------------------------------------------------------------------------- -// -// Kill the password dialog hide timer. -// -void LockProcess::killPassDlgTimeout() -{ - if (mHidePassTimerId) - { - killTimer(mHidePassTimerId); - mHidePassTimerId = 0; - } + XChangeActivePointerGrab( qt_xdisplay(), GRABEVENTS, + arrowCursor.handle(), CurrentTime); + bool rt = passDlg.exec(); + XChangeActivePointerGrab( qt_xdisplay(), GRABEVENTS, + blankCursor.handle(), CurrentTime); + return rt; } //--------------------------------------------------------------------------- @@ -720,25 +684,25 @@ { switch (event->type) { - case KeyPress: - return handleKeyPress((XKeyEvent *)event); + case FocusIn: + case FocusOut: + // Hack to tell dialogs to take focus when the keyboard is grabbed + event->xfocus.mode = NotifyNormal; + break; + case KeyPress: case ButtonPress: case MotionNotify: - if (mState == Saving) + if (mBusy) + break; + mBusy = true; + if (!(mLock || mLockOnce) || checkPass()) { - if (mLock || mLockOnce) - { - showPassDlg(); - mState = Password; - } - else - { - stopSaver(); - kapp->quit(); - } + stopSaver(); + kapp->quit(); } - break; + mBusy = false; + return true; case VisibilityNotify: if (event->xvisibility.state != VisibilityUnobscured && @@ -754,175 +718,16 @@ // if (event->xconfigure.window != event->xconfigure.event) // return true; - if (mState == Saving || mState == Password) - { - raise(); - QApplication::flushX(); - } + raise(); + QApplication::flushX(); break; } return false; } - -//--------------------------------------------------------------------------- -// -// Handle key press event. -// -bool LockProcess::handleKeyPress(XKeyEvent *xke) -{ - switch (mState) - { - case Password: - if (!mCheckingPass) - { - KeySym keysym = XLookupKeysym(xke, 0); - switch (keysym) - { - case XK_Escape: - hidePassDlg(); - mState = Saving; - break; - - case XK_Return: - case XK_KP_Enter: - startCheckPassword(); - break; - - default: - setPassDlgTimeout(PASSDLG_HIDE_TIMEOUT); - mPassDlg->keyPressed(xke); - } - } - break; - - case Saving: - if (mLock || mLockOnce) - { - showPassDlg(); - mState = Password; - } - else - { - stopSaver(); - kapp->quit(); - } - break; - } - return true; -} - -//--------------------------------------------------------------------------- -// -// Starts the kcheckpass process to check the user's password. -// -// Serge Droz 10.2000 -// Define ACCEPT_ENV if you want to pass an environment variable to -// kcheckpass. Define ACCEPT_ARGS if you want to pass command line -// arguments to kcheckpass -#define ACCEPT_ENV -//#define ACCEPT_ARGS -void LockProcess::startCheckPassword() -{ - const char *passwd = mPassDlg->password().ascii(); - if (passwd) - { - QString kcp_binName = KStandardDirs::findExe("kcheckpass"); - - mPassProc.clearArguments(); - mPassProc << kcp_binName; - -#ifdef HAVE_PAM -# ifdef ACCEPT_ENV - setenv("KDE_PAM_ACTION", KSCREENSAVER_PAM_SERVICE, 1); -# elif defined(ACCEPT_ARGS) - mPassProc << "-c" << KSCREENSAVER_PAM_SERVICE; -# endif -#endif - bool ret = mPassProc.start(KProcess::NotifyOnExit, KProcess::Stdin); -#ifdef HAVE_PAM -# ifdef ACCEPT_ENV - unsetenv("KDE_PAM_ACTION"); -# endif -#endif - if (ret == false) - { - kdDebug(1204) << "kcheckpass failed to start" << endl; - return; - } - - // write Password to stdin - mPassProc.writeStdin(passwd, strlen(passwd)); - mPassProc.closeStdin(); - - killPassDlgTimeout(); - - mCheckingPass = true; - } -} - -//--------------------------------------------------------------------------- -// -// The kcheckpass process has exited. -// -void LockProcess::passwordChecked(KProcess *proc) -{ - if (proc == &mPassProc) - { - /* the exit codes of kcheckpass: - 0: everything fine - 1: authentification failed - 2: passwd access failed [permissions/misconfig] - */ - if (mPassProc.normalExit() && (mPassProc.exitStatus() != 1)) - { - stopSaver(); - if ( mPassProc.exitStatus() == 2 ) - { - KMessageBox::error(0, - i18n( "

Screen Locking Failed!

" - "Your screen was not locked because the kcheckpass " - "program was not able to check your password. This is " - "usually the result of kcheckpass not being installed " - "correctly. If you installed KDE yourself, reinstall " - "kcheckpass as root. If you are using a pre-compiled " - "package, contact the packager." ), - i18n( "Screen Locking Failed" ) ); - } - kapp->quit(); - } - else - { - mPassDlg->showFailed(); - mPassDlg->resetPassword(); - setPassDlgTimeout(PASSDLG_HIDE_TIMEOUT); - } - - mCheckingPass = false; - } -} -//--------------------------------------------------------------------------- -// -// Handle our timer events. -// -void LockProcess::timerEvent(QTimerEvent *ev) +void LockProcess::startNewSession() { - if (ev->timerId() == mHidePassTimerId && !mCheckingPass) - { - hidePassDlg(); - mState = Saving; - } -} - -//--------------------------------------------------------------------------- -int ignoreXError(Display *, XErrorEvent *) -{ - return 0; -} - -void LockProcess::actuallySetLock() -{ - mLock = true; + xdmFifoCmd("reserve\n"); } Index: kdesktop/lock/lockprocess.h =================================================================== RCS file: /home/kde/kdebase/kdesktop/lock/lockprocess.h,v retrieving revision 1.4 diff -u -r1.4 lockprocess.h --- kdesktop/lock/lockprocess.h 2002/03/29 07:33:45 1.4 +++ kdesktop/lock/lockprocess.h 2002/09/20 01:07:19 @@ -10,8 +10,9 @@ #include #include -#include "lockdlg.h" +#include + //=========================================================================== // // Screen saver handling process. Handles screensaver window, @@ -34,23 +35,21 @@ void setChildren(QValueList children) { child_sockets = children; } void setParent(int fd) { parent = fd; } -protected: - virtual bool x11Event(XEvent *); - virtual void timerEvent(QTimerEvent *); - public slots: void quitSaver(); -protected slots: - void passwordChecked(KProcess *); +protected: + virtual bool x11Event(XEvent *); + +private slots: void hackExited(KProcess *); void slotStart(); void sigtermPipeSignal(); + void startNewSession(); void actuallySetLock(); -protected: +private: void configure(); - enum State { Saving, Password }; void readSaver(); void createSaverWindow(); void hideSaverWindow(); @@ -62,36 +61,25 @@ bool grabInput(); void ungrabInput(); void xdmFifoCmd(const char *cmd); + void xdmFifoLockCmd(const char *cmd); void startSaver(); void stopSaver(); bool startHack(); void stopHack(); - void showPassDlg(); - void hidePassDlg(); - void setPassDlgTimeout(int t); - void killPassDlgTimeout(); - void startCheckPassword(); - bool handleKeyPress(XKeyEvent *xke); void setupSignals(); + bool checkPass(); -protected: - bool mEnabled; bool mLock; int mPriority; bool mLockOnce; - State mState; - PasswordDlg *mPassDlg; + bool mBusy; Colormap mColorMap; - int mHidePassTimerId; - int mCheckPassTimerId; - KProcess mPassProc; KProcess mHackProc; - bool mCheckingPass; int mRootWidth; int mRootHeight; QString mSaverExec; - QString mSaver; - QString mXdmFifoName; + QString mSaver; + QString mXdmFifoName; bool child_saver; QValueList child_sockets; int parent; Index: kdesktop/lock/main.cc =================================================================== RCS file: /home/kde/kdebase/kdesktop/lock/main.cc,v retrieving revision 1.4 diff -u -r1.4 main.cc --- kdesktop/lock/main.cc 2002/03/07 16:01:39 1.4 +++ kdesktop/lock/main.cc 2002/09/20 01:07:19 @@ -93,7 +93,7 @@ if (putenv(strdup(env.data()))) { fprintf(stderr, - "%s: WARNING: unable to set DISPLAY environment vairable\n", + "%s: WARNING: unable to set DISPLAY environment variable\n", argv[0]); perror("putenv()"); } Index: kicker/ui/k_mnu.cpp =================================================================== RCS file: /home/kde/kdebase/kicker/ui/k_mnu.cpp,v retrieving revision 1.65 diff -u -r1.65 k_mnu.cpp --- kicker/ui/k_mnu.cpp 2002/08/25 06:45:15 1.65 +++ kicker/ui/k_mnu.cpp 2002/09/20 01:07:20 @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -277,10 +278,19 @@ // insertItem(SmallIconSet("panel"), i18n("Configure Panel"), panelOpMenu); // subMenus.append(panelOpMenu); - // lock and logout if (kapp->authorize("lock_screen")) insertItem(SmallIconSet("lock"), i18n("Lock Screen"), this, SLOT(slotLock())); + QStringList dmopt = + QStringList::split( QChar( ',' ), + QString::fromLatin1( ::getenv( "XDM_MANAGED" ) ) ); + if ( dmopt.findIndex( "rsvd" ) < 0 ) + xdmFifoName = QString::null; + else { + xdmFifoName = dmopt.first(); + insertItem(SmallIconSet("fork"), i18n("Start New Session"), this, SLOT(slotNewSession())); + } + char *user = getlogin(); if (user == 0) user = getenv("LOGNAME"); QString username(user); @@ -336,6 +346,15 @@ { QApplication::syncX(); kapp->requestShutDown(); +} + +void PanelKMenu::slotNewSession() +{ + QFile fifo(xdmFifoName); + if (fifo.open(IO_WriteOnly | IO_Raw)) { + fifo.writeBlock( "reserve\n", 8 ); + fifo.close(); + } } void PanelKMenu::slotSaveSession() Index: kicker/ui/k_mnu.h =================================================================== RCS file: /home/kde/kdebase/kicker/ui/k_mnu.h,v retrieving revision 1.21 diff -u -r1.21 k_mnu.h --- kicker/ui/k_mnu.h 2002/05/13 18:00:21 1.21 +++ kicker/ui/k_mnu.h 2002/09/20 01:07:20 @@ -58,6 +58,7 @@ protected slots: void slotLock(); void slotLogout(); + void slotNewSession(); void slotSaveSession(); void slotRunCommand(); void paletteChanged(); @@ -74,6 +75,7 @@ bool loadSidePixmap(); private: + QString xdmFifoName; QPixmap sidePixmap; QPixmap sideTilePixmap; int client_id;