mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
549 lines
19 KiB
C++
549 lines
19 KiB
C++
![]() |
/********************************************************************
|
||
|
KSld - the KDE Screenlocker Daemon
|
||
|
This file is part of the KDE project.
|
||
|
|
||
|
Copyright (C) 1999 Martin R. Jones <mjones@kde.org>
|
||
|
Copyright (C) 2002 Luboš Luňák <l.lunak@kde.org>
|
||
|
Copyright (C) 2003 Oswald Buddenhagen <ossi@kde.org>
|
||
|
Copyright (C) 2008 Chani Armitage <chanika@gmail.com>
|
||
|
Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*********************************************************************/
|
||
|
#include "lockwindow.h"
|
||
|
#include "autologout.h"
|
||
|
#include "ksldapp.h"
|
||
|
// KDE
|
||
|
#include <KDE/KApplication>
|
||
|
#include <KDE/KDebug>
|
||
|
#include <KDE/KXErrorHandler>
|
||
|
// Qt
|
||
|
#include <QtCore/QTimer>
|
||
|
#include <QtCore/QPointer>
|
||
|
#include <QtGui/QDesktopWidget>
|
||
|
#include <QtGui/QPainter>
|
||
|
#include <QtGui/QX11Info>
|
||
|
// X11
|
||
|
#include <X11/Xatom.h>
|
||
|
#include <fixx11h.h>
|
||
|
|
||
|
static Window gVRoot = 0;
|
||
|
static Window gVRootData = 0;
|
||
|
static Atom gXA_VROOT;
|
||
|
static Atom gXA_SCREENSAVER_VERSION;
|
||
|
|
||
|
//#define CHECK_XSELECTINPUT
|
||
|
#ifdef CHECK_XSELECTINPUT
|
||
|
#include <dlfcn.h>
|
||
|
static bool check_xselectinput = false;
|
||
|
extern "C"
|
||
|
int XSelectInput( Display* dpy, Window w, long e )
|
||
|
{
|
||
|
typedef int (*ptr)(Display*, Window, long);
|
||
|
static ptr fun = NULL;
|
||
|
if( fun == NULL )
|
||
|
fun = (ptr)dlsym( RTLD_NEXT, "XSelectInput" );
|
||
|
if( check_xselectinput && w == DefaultRootWindow( dpy ))
|
||
|
kDebug() << kBacktrace();
|
||
|
return fun( dpy, w, e );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
namespace ScreenLocker
|
||
|
{
|
||
|
|
||
|
LockWindow::LockWindow()
|
||
|
: QWidget()
|
||
|
, m_autoLogoutTimer(new QTimer(this))
|
||
|
{
|
||
|
initialize();
|
||
|
}
|
||
|
|
||
|
LockWindow::~LockWindow()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void LockWindow::initialize()
|
||
|
{
|
||
|
kapp->installX11EventFilter(this);
|
||
|
|
||
|
XWindowAttributes rootAttr;
|
||
|
QX11Info info;
|
||
|
XGetWindowAttributes(QX11Info::display(), RootWindow(QX11Info::display(),
|
||
|
info.screen()), &rootAttr);
|
||
|
QApplication::desktop(); // make Qt set its event mask on the root window first
|
||
|
#ifdef CHECK_XSELECTINPUT
|
||
|
check_xselectinput = true;
|
||
|
#endif
|
||
|
XSelectInput( QX11Info::display(), QX11Info::appRootWindow(),
|
||
|
SubstructureNotifyMask | rootAttr.your_event_mask );
|
||
|
// Get root window size
|
||
|
updateGeometry();
|
||
|
|
||
|
// virtual root property
|
||
|
gXA_VROOT = XInternAtom (QX11Info::display(), "__SWM_VROOT", False);
|
||
|
gXA_SCREENSAVER_VERSION = XInternAtom (QX11Info::display(), "_SCREENSAVER_VERSION", False);
|
||
|
|
||
|
// read the initial information about all toplevel windows
|
||
|
Window r, p;
|
||
|
Window* real;
|
||
|
unsigned nreal;
|
||
|
if( XQueryTree( x11Info().display(), x11Info().appRootWindow(), &r, &p, &real, &nreal )
|
||
|
&& real != NULL ) {
|
||
|
KXErrorHandler err; // ignore X errors here
|
||
|
for( unsigned i = 0; i < nreal; ++i ) {
|
||
|
XWindowAttributes winAttr;
|
||
|
if (XGetWindowAttributes(QX11Info::display(), real[ i ], &winAttr)) {
|
||
|
WindowInfo info;
|
||
|
info.window = real[ i ];
|
||
|
info.viewable = ( winAttr.map_state == IsViewable );
|
||
|
m_windowInfo.append( info ); // ordered bottom to top
|
||
|
}
|
||
|
}
|
||
|
XFree( real );
|
||
|
}
|
||
|
m_autoLogoutTimer->setSingleShot(true);
|
||
|
connect(m_autoLogoutTimer, SIGNAL(timeout()), SLOT(autoLogoutTimeout()));
|
||
|
connect(QApplication::desktop(), SIGNAL(resized(int)), SLOT(updateGeometry()));
|
||
|
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), SLOT(updateGeometry()));
|
||
|
}
|
||
|
|
||
|
void LockWindow::showLockWindow()
|
||
|
{
|
||
|
Visual* visual = CopyFromParent;
|
||
|
int depth = CopyFromParent;
|
||
|
XSetWindowAttributes attrs;
|
||
|
int flags = CWOverrideRedirect;
|
||
|
attrs.override_redirect = 1;
|
||
|
hide();
|
||
|
Window w = XCreateWindow( x11Info().display(), RootWindow( x11Info().display(), x11Info().screen()),
|
||
|
x(), y(), width(), height(), 0, depth, InputOutput, visual, flags, &attrs );
|
||
|
|
||
|
create( w, false, true );
|
||
|
|
||
|
// Some xscreensaver hacks check for this property
|
||
|
const char *version = "KDE 4.0";
|
||
|
|
||
|
XChangeProperty (QX11Info::display(), winId(),
|
||
|
gXA_SCREENSAVER_VERSION, XA_STRING, 8, PropModeReplace,
|
||
|
(unsigned char *) version, strlen(version));
|
||
|
|
||
|
|
||
|
XSetWindowAttributes attr;
|
||
|
attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask |
|
||
|
VisibilityChangeMask | ExposureMask;
|
||
|
XChangeWindowAttributes(QX11Info::display(), winId(),
|
||
|
CWEventMask, &attr);
|
||
|
|
||
|
QPalette p = palette();
|
||
|
p.setColor(backgroundRole(), Qt::black);
|
||
|
setPalette(p);
|
||
|
setAttribute(Qt::WA_PaintOnScreen, true);
|
||
|
setAttribute(Qt::WA_NoSystemBackground, false);
|
||
|
|
||
|
kDebug() << "Lock window Id: " << winId();
|
||
|
|
||
|
move(0, 0);
|
||
|
XSync(QX11Info::display(), False);
|
||
|
|
||
|
setVRoot( winId(), winId() );
|
||
|
if (KSldApp::self()->autoLogoutTimeout()) {
|
||
|
m_autoLogoutTimer->start(KSldApp::self()->autoLogoutTimeout());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Hide the screen locker window
|
||
|
//
|
||
|
void LockWindow::hideLockWindow()
|
||
|
{
|
||
|
if (m_autoLogoutTimer->isActive()) {
|
||
|
m_autoLogoutTimer->stop();
|
||
|
}
|
||
|
emit userActivity();
|
||
|
hide();
|
||
|
lower();
|
||
|
removeVRoot(winId());
|
||
|
XDeleteProperty(QX11Info::display(), winId(), gXA_SCREENSAVER_VERSION);
|
||
|
if ( gVRoot ) {
|
||
|
unsigned long vroot_data[1] = { gVRootData };
|
||
|
XChangeProperty(QX11Info::display(), gVRoot, gXA_VROOT, XA_WINDOW, 32,
|
||
|
PropModeReplace, (unsigned char *)vroot_data, 1);
|
||
|
gVRoot = 0;
|
||
|
}
|
||
|
XSync(QX11Info::display(), False);
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
static int ignoreXError(Display *, XErrorEvent *)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Save the current virtual root window
|
||
|
//
|
||
|
void LockWindow::saveVRoot()
|
||
|
{
|
||
|
Window rootReturn, parentReturn, *children;
|
||
|
unsigned int numChildren;
|
||
|
QX11Info info;
|
||
|
Window root = RootWindowOfScreen(ScreenOfDisplay(QX11Info::display(), info.screen()));
|
||
|
|
||
|
gVRoot = 0;
|
||
|
gVRootData = 0;
|
||
|
|
||
|
int (*oldHandler)(Display *, XErrorEvent *);
|
||
|
oldHandler = XSetErrorHandler(ignoreXError);
|
||
|
|
||
|
if (XQueryTree(QX11Info::display(), root, &rootReturn, &parentReturn,
|
||
|
&children, &numChildren))
|
||
|
{
|
||
|
for (unsigned int i = 0; i < numChildren; i++)
|
||
|
{
|
||
|
Atom actual_type;
|
||
|
int actual_format;
|
||
|
unsigned long nitems, bytesafter;
|
||
|
unsigned char *newRoot = 0;
|
||
|
|
||
|
if ((XGetWindowProperty(QX11Info::display(), children[i], gXA_VROOT, 0, 1,
|
||
|
False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter,
|
||
|
&newRoot) == Success) && newRoot)
|
||
|
{
|
||
|
gVRoot = children[i];
|
||
|
Window *dummy = (Window*)newRoot;
|
||
|
gVRootData = *dummy;
|
||
|
XFree ((char*) newRoot);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (children)
|
||
|
{
|
||
|
XFree((char *)children);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
XSetErrorHandler(oldHandler);
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Set the virtual root property
|
||
|
//
|
||
|
void LockWindow::setVRoot(Window win, Window vr)
|
||
|
{
|
||
|
if (gVRoot)
|
||
|
removeVRoot(gVRoot);
|
||
|
|
||
|
QX11Info info;
|
||
|
unsigned long rw = RootWindowOfScreen(ScreenOfDisplay(QX11Info::display(), info.screen()));
|
||
|
unsigned long vroot_data[1] = { vr };
|
||
|
|
||
|
Window rootReturn, parentReturn, *children;
|
||
|
unsigned int numChildren;
|
||
|
Window top = win;
|
||
|
while (1) {
|
||
|
if (!XQueryTree(QX11Info::display(), top , &rootReturn, &parentReturn,
|
||
|
&children, &numChildren))
|
||
|
return;
|
||
|
if (children)
|
||
|
XFree((char *)children);
|
||
|
if (parentReturn == rw) {
|
||
|
break;
|
||
|
} else
|
||
|
top = parentReturn;
|
||
|
}
|
||
|
|
||
|
XChangeProperty(QX11Info::display(), top, gXA_VROOT, XA_WINDOW, 32,
|
||
|
PropModeReplace, (unsigned char *)vroot_data, 1);
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Remove the virtual root property
|
||
|
//
|
||
|
void LockWindow::removeVRoot(Window win)
|
||
|
{
|
||
|
XDeleteProperty (QX11Info::display(), win, gXA_VROOT);
|
||
|
}
|
||
|
|
||
|
static void fakeFocusIn( WId window )
|
||
|
{
|
||
|
// We have keyboard grab, so this application will
|
||
|
// get keyboard events even without having focus.
|
||
|
// Fake FocusIn to make Qt realize it has the active
|
||
|
// window, so that it will correctly show cursor in the dialog.
|
||
|
XEvent ev;
|
||
|
memset(&ev, 0, sizeof(ev));
|
||
|
ev.xfocus.display = QX11Info::display();
|
||
|
ev.xfocus.type = FocusIn;
|
||
|
ev.xfocus.window = window;
|
||
|
ev.xfocus.mode = NotifyNormal;
|
||
|
ev.xfocus.detail = NotifyAncestor;
|
||
|
XSendEvent( QX11Info::display(), window, False, NoEventMask, &ev );
|
||
|
}
|
||
|
|
||
|
// Event filter
|
||
|
bool LockWindow::x11Event(XEvent* event)
|
||
|
{
|
||
|
bool ret = false;
|
||
|
switch (event->type) {
|
||
|
case ButtonPress:
|
||
|
case ButtonRelease:
|
||
|
case KeyPress:
|
||
|
case KeyRelease:
|
||
|
case MotionNotify:
|
||
|
if (KSldApp::self()->isGraceTime()) {
|
||
|
KSldApp::self()->unlock();
|
||
|
return true;
|
||
|
}
|
||
|
if (m_autoLogoutTimer->isActive()) {
|
||
|
m_autoLogoutTimer->start(KSldApp::self()->autoLogoutTimeout());
|
||
|
}
|
||
|
emit userActivity();
|
||
|
if (!m_lockWindows.isEmpty()) {
|
||
|
XEvent ev2 = *event;
|
||
|
Window root_return;
|
||
|
int x_return, y_return;
|
||
|
unsigned int width_return, height_return, border_width_return, depth_return;
|
||
|
WId targetWindow = 0;
|
||
|
KXErrorHandler err; // ignore X errors
|
||
|
foreach (WId window, m_lockWindows) {
|
||
|
if (XGetGeometry(QX11Info::display(), window, &root_return,
|
||
|
&x_return, &y_return,
|
||
|
&width_return, &height_return,
|
||
|
&border_width_return, &depth_return)
|
||
|
&&
|
||
|
(event->xkey.x>=x_return && event->xkey.x<=x_return+(int)width_return)
|
||
|
&&
|
||
|
(event->xkey.y>=y_return && event->xkey.y<=y_return+(int)height_return) ) {
|
||
|
targetWindow = window;
|
||
|
ev2.xkey.window = ev2.xkey.subwindow = targetWindow;
|
||
|
ev2.xkey.x = event->xkey.x - x_return;
|
||
|
ev2.xkey.y = event->xkey.y - y_return;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
XSendEvent(QX11Info::display(), targetWindow, False, NoEventMask, &ev2);
|
||
|
ret = true;
|
||
|
}
|
||
|
break;
|
||
|
case ConfigureNotify: // from SubstructureNotifyMask on the root window
|
||
|
if(event->xconfigure.event == QX11Info::appRootWindow()) {
|
||
|
int index = findWindowInfo( event->xconfigure.window );
|
||
|
if( index >= 0 ) {
|
||
|
int index2 = event->xconfigure.above ? findWindowInfo( event->xconfigure.above ) : 0;
|
||
|
if( index2 < 0 )
|
||
|
kDebug(1204) << "Unknown above for ConfigureNotify";
|
||
|
else { // move just above the other window
|
||
|
if( index2 < index )
|
||
|
++index2;
|
||
|
m_windowInfo.move( index, index2 );
|
||
|
}
|
||
|
} else
|
||
|
kDebug(1204) << "Unknown toplevel for ConfigureNotify";
|
||
|
//kDebug() << "ConfigureNotify:";
|
||
|
//the stacking order changed, so let's change the stacking order again to what we want
|
||
|
stayOnTop();
|
||
|
}
|
||
|
break;
|
||
|
case MapNotify: // from SubstructureNotifyMask on the root window
|
||
|
if( event->xmap.event == QX11Info::appRootWindow()) {
|
||
|
kDebug(1204) << "MapNotify:" << event->xmap.window;
|
||
|
int index = findWindowInfo( event->xmap.window );
|
||
|
if( index >= 0 )
|
||
|
m_windowInfo[ index ].viewable = true;
|
||
|
else
|
||
|
kDebug(1204) << "Unknown toplevel for MapNotify";
|
||
|
KXErrorHandler err; // ignore X errors here
|
||
|
if (isLockWindow(event->xmap.window)) {
|
||
|
if (m_lockWindows.contains(event->xmap.window)) {
|
||
|
kDebug() << "uhoh! duplicate!";
|
||
|
} else {
|
||
|
if (!isVisible()) {
|
||
|
// not yet shown and we have a lock window, so we show our own window
|
||
|
show();
|
||
|
setCursor(Qt::ArrowCursor);
|
||
|
}
|
||
|
m_lockWindows.prepend(event->xmap.window);
|
||
|
fakeFocusIn(event->xmap.window);
|
||
|
}
|
||
|
}
|
||
|
stayOnTop();
|
||
|
}
|
||
|
break;
|
||
|
case UnmapNotify:
|
||
|
if (event->xunmap.event == QX11Info::appRootWindow()) {
|
||
|
kDebug(1204) << "UnmapNotify:" << event->xunmap.window;
|
||
|
int index = findWindowInfo( event->xunmap.window );
|
||
|
if( index >= 0 )
|
||
|
m_windowInfo[ index ].viewable = false;
|
||
|
else
|
||
|
kDebug(1204) << "Unknown toplevel for MapNotify";
|
||
|
m_lockWindows.removeAll(event->xunmap.window);
|
||
|
}
|
||
|
break;
|
||
|
case CreateNotify:
|
||
|
if (event->xcreatewindow.parent == QX11Info::appRootWindow()) {
|
||
|
kDebug() << "CreateNotify:" << event->xcreatewindow.window;
|
||
|
int index = findWindowInfo( event->xcreatewindow.window );
|
||
|
if( index >= 0 )
|
||
|
kDebug() << "Already existing toplevel for CreateNotify";
|
||
|
else {
|
||
|
WindowInfo info;
|
||
|
info.window = event->xcreatewindow.window;
|
||
|
info.viewable = false;
|
||
|
m_windowInfo.append( info );
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case DestroyNotify:
|
||
|
if (event->xdestroywindow.event == QX11Info::appRootWindow()) {
|
||
|
int index = findWindowInfo( event->xdestroywindow.window );
|
||
|
if( index >= 0 )
|
||
|
m_windowInfo.removeAt( index );
|
||
|
else
|
||
|
kDebug() << "Unknown toplevel for DestroyNotify";
|
||
|
}
|
||
|
break;
|
||
|
case ReparentNotify:
|
||
|
if (event->xreparent.event == QX11Info::appRootWindow() && event->xreparent.parent != QX11Info::appRootWindow()) {
|
||
|
int index = findWindowInfo( event->xreparent.window );
|
||
|
if( index >= 0 )
|
||
|
m_windowInfo.removeAt( index );
|
||
|
else
|
||
|
kDebug() << "Unknown toplevel for ReparentNotify away";
|
||
|
} else if (event->xreparent.parent == QX11Info::appRootWindow()) {
|
||
|
int index = findWindowInfo( event->xreparent.window );
|
||
|
if( index >= 0 )
|
||
|
kDebug() << "Already existing toplevel for ReparentNotify";
|
||
|
else {
|
||
|
WindowInfo info;
|
||
|
info.window = event->xreparent.window;
|
||
|
info.viewable = false;
|
||
|
m_windowInfo.append( info );
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case CirculateNotify:
|
||
|
if (event->xcirculate.event == QX11Info::appRootWindow()) {
|
||
|
int index = findWindowInfo( event->xcirculate.window );
|
||
|
if( index >= 0 ) {
|
||
|
m_windowInfo.move( index, event->xcirculate.place == PlaceOnTop ? m_windowInfo.size() - 1 : 0 );
|
||
|
} else
|
||
|
kDebug() << "Unknown toplevel for CirculateNotify";
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int LockWindow::findWindowInfo(Window w)
|
||
|
{
|
||
|
for( int i = 0;
|
||
|
i < m_windowInfo.size();
|
||
|
++i )
|
||
|
if( m_windowInfo[ i ].window == w )
|
||
|
return i;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
void LockWindow::stayOnTop()
|
||
|
{
|
||
|
|
||
|
// this restacking is written in a way so that
|
||
|
// if the stacking positions actually don't change,
|
||
|
// all restacking operations will be no-op,
|
||
|
// and no ConfigureNotify will be generated,
|
||
|
// thus avoiding possible infinite loops
|
||
|
QVector< Window > stack( m_lockWindows.count() + 1 );
|
||
|
int count = 0;
|
||
|
foreach( WId w, m_lockWindows )
|
||
|
stack[ count++ ] = w;
|
||
|
// finally, the lock window
|
||
|
stack[ count++ ] = winId();
|
||
|
// do the actual restacking if needed
|
||
|
XRaiseWindow( x11Info().display(), stack[ 0 ] );
|
||
|
if( count > 1 )
|
||
|
XRestackWindows( x11Info().display(), stack.data(), count );
|
||
|
}
|
||
|
|
||
|
bool LockWindow::isLockWindow(Window id)
|
||
|
{
|
||
|
Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False);
|
||
|
Atom actualType;
|
||
|
int actualFormat;
|
||
|
unsigned long nitems, remaining;
|
||
|
unsigned char *data = 0;
|
||
|
Display *display = QX11Info::display();
|
||
|
|
||
|
int result = XGetWindowProperty(display, id, tag, 0, 1, False, tag, &actualType,
|
||
|
&actualFormat, &nitems, &remaining, &data);
|
||
|
|
||
|
bool lockWindow = false;
|
||
|
if (result == Success && actualType == tag) {
|
||
|
lockWindow = true;
|
||
|
}
|
||
|
if (data) {
|
||
|
XFree(data);
|
||
|
}
|
||
|
return lockWindow;
|
||
|
}
|
||
|
|
||
|
void LockWindow::autoLogoutTimeout()
|
||
|
{
|
||
|
QDesktopWidget *desktop = QApplication::desktop();
|
||
|
QRect screenRect;
|
||
|
if (desktop->screenCount() > 1) {
|
||
|
screenRect = desktop->screenGeometry(desktop->screenNumber(QCursor::pos()));
|
||
|
} else {
|
||
|
screenRect = desktop->screenGeometry();
|
||
|
}
|
||
|
|
||
|
QPointer<AutoLogout> dlg = new AutoLogout(this);
|
||
|
dlg->adjustSize();
|
||
|
|
||
|
QRect rect = dlg->geometry();
|
||
|
rect.moveCenter(screenRect.center());
|
||
|
dlg->move(rect.topLeft());
|
||
|
|
||
|
Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False);
|
||
|
XChangeProperty(QX11Info::display(), dlg->winId(), tag, tag, 32, PropModeReplace, 0, 0);
|
||
|
|
||
|
dlg->exec();
|
||
|
delete dlg;
|
||
|
|
||
|
// start the timer again - only if the window is still shown
|
||
|
if (isVisible()) {
|
||
|
m_autoLogoutTimer->start(KSldApp::self()->autoLogoutTimeout());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void LockWindow::updateGeometry()
|
||
|
{
|
||
|
QDesktopWidget *desktop = QApplication::desktop();
|
||
|
setGeometry(desktop->geometry());
|
||
|
}
|
||
|
|
||
|
void LockWindow::paintEvent(QPaintEvent* )
|
||
|
{
|
||
|
QPainter p(this);
|
||
|
p.setBrush(QBrush(Qt::black));
|
||
|
p.drawRect(geometry());
|
||
|
}
|
||
|
|
||
|
}
|