summaryrefslogtreecommitdiffstats
path: root/kdesktop
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-03 09:14:57 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-09-03 09:14:57 +0000
commit27856879bf962f178d88e79144e37a47e731b122 (patch)
treea3bd3f489b755cd2941e7c53b90d12d6bfd4fbe3 /kdesktop
parentc5228d52f504d6d2c0fefdd625ec08ebb8e91f85 (diff)
downloadtdebase-27856879bf962f178d88e79144e37a47e731b122.tar.gz
tdebase-27856879bf962f178d88e79144e37a47e731b122.zip
* Massive import of OpenSUSE patches, primarily for bugfixes
* Added some infrastructure created by OpenSUSE to allow for future addition of the Kickoff menu as an option * Minor Slackware compilation fixes git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1171255 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdesktop')
-rw-r--r--kdesktop/KDesktopIface.h29
-rw-r--r--kdesktop/Makefile.am2
-rw-r--r--kdesktop/desktop.cc47
-rw-r--r--kdesktop/desktop.h5
-rw-r--r--kdesktop/kdiconview.cc120
-rw-r--r--kdesktop/kdiconview.h9
-rw-r--r--kdesktop/lock/lockprocess.cc244
-rw-r--r--kdesktop/lock/lockprocess.h30
-rw-r--r--kdesktop/minicli.cpp15
-rw-r--r--kdesktop/minicli.h4
10 files changed, 482 insertions, 23 deletions
diff --git a/kdesktop/KDesktopIface.h b/kdesktop/KDesktopIface.h
index 1aa90e538..b966405e4 100644
--- a/kdesktop/KDesktopIface.h
+++ b/kdesktop/KDesktopIface.h
@@ -107,6 +107,35 @@ k_dcop:
* space for desktop icons
*/
virtual void desktopIconsAreaChanged(const TQRect &area, int screen) = 0;
+
+ /**
+ * Find the next free place for a not yet existing icon, so it fits
+ * in the user arrangement. Basicly prepare for icons to be moved in.
+ * It will try to find a place in the virtual grid near col,row
+ * where no other icon is.
+ *
+ * If you specify -1 for row or column, it will try to find the next
+ * free room where no other icon follows. E.g. if you specify column
+ * = -1 and row = 0, kdesktop will find the next vertical placement
+ * so that the icon appears at the end of the existing icons preferable
+ * in the first column. If the first column is full, it will find the
+ * next free room in the second column.
+ *
+ * If you specify both column and row, kdesktop won't care for aligning,
+ * or surrounding icons, but try to find the free place near the given
+ * grid place (e.g. specify 0,0 to find the nearest place in the left
+ * upper corner).
+ */
+ virtual TQPoint findPlaceForIcon( int column, int row) = 0;
+
+ /// copy the desktop file in the Desktop and place it at x, y
+ virtual void addIcon(const TQString &url, int x, int y) = 0;
+
+ /// same with specific destination
+ virtual void addIcon(const TQString &url, const TQString &dest, int x, int y) = 0;
+
+ /// remove the desktop file (either full path or relative)
+ virtual void removeIcon(const TQString &dest) = 0;
};
#endif
diff --git a/kdesktop/Makefile.am b/kdesktop/Makefile.am
index fecd9e9c4..5035fe77f 100644
--- a/kdesktop/Makefile.am
+++ b/kdesktop/Makefile.am
@@ -6,6 +6,8 @@ kdesktop_la_LIBADD = libkdesktopsettings.la $(top_builddir)/libkonq/libkonq.la
SUBDIRS = . lock pics patterns programs init kwebdesktop
+KDE_OPTIONS = nofinal
+
####### Files
bin_PROGRAMS = kcheckrunning
diff --git a/kdesktop/desktop.cc b/kdesktop/desktop.cc
index 54513e962..a05dfcb99 100644
--- a/kdesktop/desktop.cc
+++ b/kdesktop/desktop.cc
@@ -32,6 +32,9 @@
#include <unistd.h>
#include <kcolordrag.h>
#include <kurldrag.h>
+#include <stdlib.h>
+#include <kio/job.h>
+#include <tqfile.h>
#include <tqdir.h>
#include <tqevent.h>
@@ -58,6 +61,7 @@
#include <kglobalsettings.h>
#include <kpopupmenu.h>
#include <kapplication.h>
+#include <kdirlister.h>
// Create the equivalent of KAccelBase::connectItem
// and then remove this include and fix reconnects in initRoot() -- ellis
//#include <kaccelbase.h>
@@ -986,4 +990,47 @@ bool KDesktop::event(TQEvent * e)
return TQWidget::event(e);
}
+TQPoint KDesktop::findPlaceForIcon( int column, int row )
+{
+ if (m_pIconView)
+ return m_pIconView->findPlaceForIcon(column, row);
+ else
+ return TQPoint(-1, -1);
+}
+
+void KDesktop::addIcon(const TQString & _url, int x, int y)
+{
+ addIcon( _url, KGlobalSettings::desktopPath(), x, y );
+}
+
+void KDesktop::addIcon(const TQString & _url, const TQString & _dest, int x, int y)
+{
+ TQString filename = _url.mid(_url.findRev('/') + 1);
+
+ TQValueList<KIO::CopyInfo> files;
+ KIO::CopyInfo i;
+ i.uSource = KURL::fromPathOrURL( _url );
+ i.uDest = KURL::fromPathOrURL( _dest );
+ i.uDest.addPath( filename );
+ files.append(i);
+ if (!TQFile::exists(i.uDest.prettyURL().replace("file://",TQString::null))) { m_pIconView->slotAboutToCreate( TQPoint( x, y ), files );
+ KIO::copy( i.uSource, i.uDest, false ); }
+
+// m_pIconView->addFuturePosition(filename, x, y);
+ // qDebug("addIcon %s %s %d %d", _url.latin1(), _dest.latin1(), x, y);
+// system(TQString("cp \"%1\" \"%2/%3\"").arg(KURL(_url).path()).arg(KURL(_dest).path()).arg(filename).latin1());
+// m_pIconView->update( _dest );
+}
+
+void KDesktop::removeIcon(const TQString &_url)
+{
+ if (_url.at(0) != '/') {
+ qDebug("removeIcon with relative path not supported for now");
+ return;
+ }
+ unlink(KURL(_url).path().latin1());
+ TQString dest = _url.left(_url.findRev('/') + 1);
+ m_pIconView->update( dest );
+}
+
#include "desktop.moc"
diff --git a/kdesktop/desktop.h b/kdesktop/desktop.h
index d8ec12c69..31928e9d4 100644
--- a/kdesktop/desktop.h
+++ b/kdesktop/desktop.h
@@ -164,6 +164,11 @@ protected:
virtual void setIconsEnabled( bool enable );
virtual bool event ( TQEvent * e );
+ virtual TQPoint findPlaceForIcon( int column, int row);
+ virtual void addIcon(const TQString &url, int x, int y);
+ virtual void addIcon(const TQString &url, const TQString &dest, int x, int y);
+ virtual void removeIcon(const TQString &url);
+
private slots:
void desktopResized();
diff --git a/kdesktop/kdiconview.cc b/kdesktop/kdiconview.cc
index caa68feb9..5762458fd 100644
--- a/kdesktop/kdiconview.cc
+++ b/kdesktop/kdiconview.cc
@@ -962,6 +962,18 @@ void KDIconView::slotNewItems( const KFileItemList & entries )
kdDebug(1214) << "KDIconView::slotNewItems count=" << entries.count() << endl;
KFileItemListIterator it(entries);
KFileIVI* fileIVI = 0L;
+
+ if (m_nextItemPos.isNull() && !m_dotDirectory) {
+ // Not found, we'll need to save the new pos
+ kdDebug(1214)<<"Neither a drop position stored nor m_dotDirectory set"<<endl;
+ m_dotDirectory = new KSimpleConfig( dotDirectoryPath(), true );
+ // recursion
+ slotNewItems( entries );
+ delete m_dotDirectory;
+ m_dotDirectory = 0;
+ return;
+ }
+
for (; it.current(); ++it)
{
KURL url = it.current()->url();
@@ -1026,15 +1038,6 @@ void KDIconView::slotNewItems( const KFileItemList & entries )
kdDebug(1214)<<"Using saved position"<<endl;
}
}
- else
- {
- // Not found, we'll need to save the new pos
- kdDebug(1214)<<"slotNewItems(): New item without position information, try to find a sane location"<<endl;
-
- moveToFreePosition(fileIVI);
-
- m_bNeedSave = true;
- }
}
}
@@ -1638,6 +1641,98 @@ void KDIconView::moveToFreePosition(TQIconViewItem *item )
}
+TQPoint KDIconView::findPlaceForIconCol( int column, int dx, int dy)
+{
+ if (column < 0)
+ return TQPoint();
+
+ TQRect rect;
+ rect.moveTopLeft( TQPoint(column * dx, 0) );
+ rect.setWidth(dx);
+ rect.setHeight(dy);
+
+ if (rect.right() > viewport()->width())
+ return TQPoint();
+
+ while ( rect.bottom() < viewport()->height() - spacing() )
+ {
+ if ( !isFreePosition(0,rect) )
+ rect.moveBy(0, rect.height());
+ else
+ return rect.topLeft();
+ }
+
+ return TQPoint();
+}
+
+TQPoint KDIconView::findPlaceForIconRow( int row, int dx, int dy )
+{
+ if (row < 0)
+ return TQPoint();
+
+ TQRect rect;
+ rect.moveTopLeft(TQPoint(0, row * dy));
+ rect.setWidth(dx);
+ rect.setHeight(dy);
+
+ if (rect.bottom() > viewport()->height())
+ return TQPoint();
+
+ while (rect.right() < viewport()->width() - spacing())
+ {
+ if (!isFreePosition(0,rect))
+ rect.moveBy(rect.width()+spacing(), 0);
+ else
+ return rect.topLeft();
+ }
+
+ return TQPoint();
+}
+
+TQPoint KDIconView::findPlaceForIcon( int column, int row)
+{
+ int dx = gridXValue(), dy = 0;
+ TQIconViewItem *item = firstItem();
+ for ( ; item; item = item->nextItem() ) {
+ dx = QMAX( dx, item->width() );
+ dy = QMAX( dy, item->height() );
+ }
+
+ dx += spacing();
+ dy += spacing();
+
+ if (row == -1) {
+ int max_cols = viewport()->width() / dx;
+ int delta = 0;
+ TQPoint res;
+ do {
+ delta++;
+ res = findPlaceForIconCol(column + (delta / 2) * (-2 * (delta % 2) + 1),
+ dx, dy);
+ if (delta / 2 > QMAX(max_cols - column, column))
+ return res;
+ } while (res.isNull());
+ return res;
+ }
+
+ if (column == -1) {
+ int max_rows = viewport()->height() / dy;
+ int delta = 0;
+ TQPoint res;
+ do {
+ delta++;
+ res = findPlaceForIconRow(row + (delta / 2) * (-2 * (delta % 2) + 1),
+ dx, dy);
+ if (delta / 2 > QMAX(max_rows - row, row))
+ return res;
+ } while (res.isNull());
+ return res;
+ }
+
+ // very unlikely - if I may add that
+ return TQPoint(0, 0);
+}
+
void KDIconView::saveIconPositions()
{
kdDebug(1214) << "KDIconView::saveIconPositions" << endl;
@@ -1665,4 +1760,11 @@ void KDIconView::saveIconPositions()
m_dotDirectory->sync();
}
+void KDIconView::update( const TQString &_url )
+{
+ if (m_dirLister)
+ m_dirLister->updateDirectory( _url );
+}
+
+
#include "kdiconview.moc"
diff --git a/kdesktop/kdiconview.h b/kdesktop/kdiconview.h
index 715a0eb5e..5ef349322 100644
--- a/kdesktop/kdiconview.h
+++ b/kdesktop/kdiconview.h
@@ -73,6 +73,8 @@ public:
TQStringList selectedURLs();
+ void update( const TQString &url );
+
/**
* Save the icon positions
*/
@@ -103,6 +105,10 @@ public:
void startDirLister();
+ TQPoint findPlaceForIconCol( int column, int dx, int dy );
+ TQPoint findPlaceForIconRow( int row, int dx, int dy );
+ TQPoint findPlaceForIcon( int column, int row );
+
protected slots:
// slots connected to the icon view
@@ -112,8 +118,9 @@ protected slots:
void slotMouseButtonClickedKDesktop(int _button, TQIconViewItem* _item, const TQPoint& _global);
void slotContextMenuRequested(TQIconViewItem* _item, const TQPoint& _global);
void slotEnableAction( const char * name, bool enabled );
+public slots:
void slotAboutToCreate(const TQPoint &pos, const TQValueList<KIO::CopyInfo> &files);
-
+protected slots:
void slotItemRenamed(TQIconViewItem*, const TQString &name);
// slots connected to the directory lister
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc
index d589232a1..cdd5581e7 100644
--- a/kdesktop/lock/lockprocess.cc
+++ b/kdesktop/lock/lockprocess.cc
@@ -39,6 +39,8 @@
#include <kstdguiitem.h>
#include <kpixmapeffect.h>
#include <kpixmap.h>
+#include <kwin.h>
+#include <kwinmodule.h>
#include <tqframe.h>
#include <tqlabel.h>
@@ -119,6 +121,8 @@ static void segv_handler(int)
sleep(1);
}
+extern Atom qt_wm_state;
+
//===========================================================================
//
// Screen saver handling process. Handles screensaver window,
@@ -135,6 +139,8 @@ LockProcess::LockProcess(bool child, bool useBlankOnly)
mRestoreXF86Lock(false),
mForbidden(false),
mAutoLogout(false),
+ mVkbdProcess(NULL),
+ mKWinModule(NULL),
mPipeOpen(false),
mPipeOpen_out(false),
mInfoMessageDisplayed(false),
@@ -1120,9 +1126,11 @@ bool LockProcess::checkPass()
if (mAutoLogout)
killTimer(mAutoLogoutTimerId);
+ showVkbd();
PasswordDlg passDlg( this, &greetPlugin);
-
int ret = execDialog( &passDlg );
+ hideVkbd();
+
if (mForceReject == true) {
ret = TQDialog::Rejected;
}
@@ -1251,9 +1259,13 @@ bool LockProcess::x11Event(XEvent *event)
switch (event->type)
{
- case KeyPress:
case ButtonPress:
case MotionNotify:
+ case ButtonRelease:
+ if( forwardVkbdEvent( event ))
+ return true; // filter out
+ // fall through
+ case KeyPress:
if (mBusy || !mDialogs.isEmpty())
break;
mBusy = true;
@@ -1290,11 +1302,30 @@ bool LockProcess::x11Event(XEvent *event)
case ConfigureNotify: // from SubstructureNotifyMask on the root window
if(event->xconfigure.event == qt_xrootwin())
stayOnTop();
+ for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it ) {
+ if( (*it).id == event->xconfigure.window ) {
+ (*it).rect = TQRect( event->xconfigure.x, event->xconfigure.y,
+ event->xconfigure.width, event->xconfigure.height );
+ break;
+ }
+ }
break;
case MapNotify: // from SubstructureNotifyMask on the root window
+ windowAdded( event->xmap.window, false );
if( event->xmap.event == qt_xrootwin())
stayOnTop();
break;
+ case DestroyNotify:
+ for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it )
+ if( (*it).id == event->xdestroywindow.window ) {
+ mVkbdWindows.remove( it );
+ break;
+ }
+ break;
}
// We have grab with the grab window being the root window.
@@ -1319,17 +1350,24 @@ bool LockProcess::x11Event(XEvent *event)
void LockProcess::stayOnTop()
{
- if(!mDialogs.isEmpty())
+ if(!mDialogs.isEmpty() || !mVkbdWindows.isEmpty())
{
// 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
- XRaiseWindow( qt_xdisplay(), mDialogs.first()->winId()); // raise topmost
+ if( !mVkbdWindows.isEmpty())
+ XRaiseWindow( qt_xdisplay(), mVkbdWindows.first().id );
+ else
+ XRaiseWindow( qt_xdisplay(), mDialogs.first()->winId()); // raise topmost
// and stack others below it
- Window* stack = new Window[ mDialogs.count() + 1 ];
+ Window* stack = new Window[ mDialogs.count() + mVkbdWindows.count() + 1 ];
int count = 0;
+ for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it )
+ stack[ count++ ] = (*it).id;
for( TQValueList< TQWidget* >::ConstIterator it = mDialogs.begin();
it != mDialogs.end();
++it )
@@ -1428,4 +1466,200 @@ void LockProcess::msgBox( TQMessageBox::Icon type, const TQString &txt )
execDialog( &box );
}
+static int run_vkbd = -1;
+void LockProcess::showVkbd()
+{
+ if( run_vkbd == - 1 ) {
+ int status = system( "hal-find-by-property --key system.formfactor.subtype --string tabletpc" );
+// status = 0; // enable for testing
+ run_vkbd = ( WIFEXITED( status ) && WEXITSTATUS( status ) == 0
+ && !KStandardDirs::findExe( "xvkbd" ).isEmpty()) ? 1 : 0;
+ }
+ if( run_vkbd ) {
+ mVkbdWindows.clear();
+ mVkbdLastEventWindow = None;
+ mKWinModule = new KWinModule( NULL, KWinModule::INFO_WINDOWS );
+ connect( mKWinModule, TQT_SIGNAL( windowAdded( WId )), TQT_SLOT( windowAdded( WId )));
+ mVkbdProcess = new KProcess;
+ *mVkbdProcess << "xvkbd" << "-compact" << "-geometry" << "-0-0" << "-xdm";
+ mVkbdProcess->start();
+ }
+}
+
+void LockProcess::hideVkbd()
+{
+ if( mVkbdProcess != NULL ) {
+ mVkbdProcess->kill();
+ delete mVkbdProcess;
+ mVkbdProcess = NULL;
+ delete mKWinModule;
+ mKWinModule = NULL;
+ mVkbdWindows.clear();
+ }
+}
+
+void LockProcess::windowAdded( WId w )
+{
+ windowAdded( w, true );
+}
+
+void LockProcess::windowAdded( WId w, bool managed )
+{
+ KWin::WindowInfo info = KWin::windowInfo( w, 0, NET::WM2WindowClass );
+ if( info.windowClassClass().lower() != "xvkbd" )
+ return;
+ // Unmanaged windows (i.e. popups) don't currently work anyway, since they
+ // don't have WM_CLASS set anyway. I could perhaps try tricks with X id
+ // ranges if really needed.
+ if( managed ) {
+ // withdraw the window, wait for it to be withdrawn, reparent it directly
+ // to root at the right position
+ XWithdrawWindow( qt_xdisplay(), w, qt_xscreen());
+ for(;;) {
+ Atom type;
+ int format;
+ unsigned long length, after;
+ unsigned char *data;
+ int r = XGetWindowProperty( qt_xdisplay(), w, qt_wm_state, 0, 2,
+ false, AnyPropertyType, &type, &format,
+ &length, &after, &data );
+ bool withdrawn = true;
+ if ( r == Success && data && format == 32 ) {
+ Q_UINT32 *wstate = (Q_UINT32*)data;
+ withdrawn = (*wstate == WithdrawnState );
+ XFree( (char *)data );
+ }
+ if( withdrawn )
+ break;
+ }
+ }
+ XSelectInput( qt_xdisplay(), w, StructureNotifyMask );
+ XWindowAttributes attr_geom;
+ if( !XGetWindowAttributes( qt_xdisplay(), w, &attr_geom ))
+ return;
+ int x = XDisplayWidth( qt_xdisplay(), qt_xscreen()) - attr_geom.width;
+ int y = XDisplayHeight( qt_xdisplay(), qt_xscreen()) - attr_geom.height;
+ if( managed ) {
+ XSetWindowAttributes attr;
+ attr.override_redirect = True;
+ XChangeWindowAttributes( qt_xdisplay(), w, CWOverrideRedirect, &attr );
+ XReparentWindow( qt_xdisplay(), w, qt_xrootwin(), x, y );
+ XMapWindow( qt_xdisplay(), w );
+ }
+ VkbdWindow data;
+ data.id = w;
+ data.rect = TQRect( x, y, attr_geom.width, attr_geom.height );
+ mVkbdWindows.prepend( data );
+}
+
+bool LockProcess::forwardVkbdEvent( XEvent* event )
+{
+ if( mVkbdProcess == NULL )
+ return false;
+ TQPoint pos;
+ Time time;
+ switch( event->type )
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ pos = TQPoint( event->xbutton.x, event->xbutton.y );
+ time = event->xbutton.time;
+ break;
+ case MotionNotify:
+ pos = TQPoint( event->xmotion.x, event->xmotion.y );
+ time = event->xmotion.time;
+ break;
+ default:
+ return false;
+ }
+ // vkbd windows are kept topmost, so just find the first one in the position
+ for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin();
+ it != mVkbdWindows.end();
+ ++it ) {
+ if( (*it).rect.contains( pos )) {
+ // Find the subwindow where the event should actually go.
+ // Not exactly cheap in the number of X roundtrips but oh well.
+ Window window = (*it).id;
+ Window root, child;
+ int root_x, root_y, x, y;
+ unsigned int mask;
+ for(;;) {
+ if( !XQueryPointer( qt_xdisplay(), window, &root, &child, &root_x, &root_y, &x, &y, &mask ))
+ return false;
+ if( child == None )
+ break;
+ window = child;
+ }
+ switch( event->type )
+ {
+ case ButtonPress:
+ case ButtonRelease:
+ event->xbutton.x = x;
+ event->xbutton.y = y;
+ event->xbutton.subwindow = None;
+ break;
+ case MotionNotify:
+ event->xmotion.x = x;
+ event->xmotion.y = y;
+ event->xmotion.subwindow = None;
+ break;
+ }
+ event->xany.window = window;
+ sendVkbdFocusInOut( window, time );
+ XSendEvent( qt_xdisplay(), window, False, 0, event );
+ return true;
+ }
+ }
+ sendVkbdFocusInOut( None, time );
+ return false;
+}
+
+// Fake EnterNotify/LeaveNotify events as the mouse moves. They're not sent by X
+// because of the grab and having them makes xvkbd highlight the buttons (but
+// not needed otherwise it seems).
+void LockProcess::sendVkbdFocusInOut( WId window, Time t )
+{
+ if( mVkbdLastEventWindow == window )
+ return;
+ if( mVkbdLastEventWindow != None ) {
+ XEvent e;
+ e.xcrossing.type = LeaveNotify;
+ e.xcrossing.display = qt_xdisplay();
+ e.xcrossing.window = mVkbdLastEventWindow;
+ e.xcrossing.root = qt_xrootwin();
+ e.xcrossing.subwindow = None;
+ e.xcrossing.time = t;
+ e.xcrossing.x = 0;
+ e.xcrossing.y = 0;
+ e.xcrossing.x_root = -1;
+ e.xcrossing.y_root = -1;
+ e.xcrossing.mode = NotifyNormal;
+ e.xcrossing.detail = NotifyAncestor;
+ e.xcrossing.same_screen = True;
+ e.xcrossing.focus = False;
+ e.xcrossing.state = 0;
+ XSendEvent( qt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
+ }
+ mVkbdLastEventWindow = window;
+ if( mVkbdLastEventWindow != None ) {
+ XEvent e;
+ e.xcrossing.type = EnterNotify;
+ e.xcrossing.display = qt_xdisplay();
+ e.xcrossing.window = mVkbdLastEventWindow;
+ e.xcrossing.root = qt_xrootwin();
+ e.xcrossing.subwindow = None;
+ e.xcrossing.time = t;
+ e.xcrossing.x = 0;
+ e.xcrossing.y = 0;
+ e.xcrossing.x_root = 0;
+ e.xcrossing.y_root = 0;
+ e.xcrossing.mode = NotifyNormal;
+ e.xcrossing.detail = NotifyAncestor;
+ e.xcrossing.same_screen = True;
+ e.xcrossing.focus = False;
+ e.xcrossing.state = 0;
+ XSendEvent( qt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
+ }
+}
+
#include "lockprocess.moc"
diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h
index cdbeb0da1..76ffb6013 100644
--- a/kdesktop/lock/lockprocess.h
+++ b/kdesktop/lock/lockprocess.h
@@ -23,6 +23,7 @@
#include <X11/Xlib.h>
class KLibrary;
+class KWinModule;
struct GreeterPluginHandle {
KLibrary *library;
@@ -79,6 +80,7 @@ private slots:
void suspend();
void checkDPMSActive();
void slotDeadTimePassed();
+ void windowAdded( WId );
private:
void configure();
@@ -103,6 +105,11 @@ private:
void stayOnTop();
void lockXF86();
void unlockXF86();
+ void showVkbd();
+ void hideVkbd();
+ bool forwardVkbdEvent( XEvent* event );
+ void sendVkbdFocusInOut( WId window, Time t );
+ void windowAdded( WId window, bool managed );
void resume( bool force );
static TQVariant getConf(void *ctx, const char *key, const TQVariant &dflt);
@@ -135,18 +142,29 @@ private:
int mAutoLogoutTimerId;
int mAutoLogoutTimeout;
bool mAutoLogout;
- bool mInfoMessageDisplayed;
- TQDialog *currentDialog;
- bool mDialogControlLock;
- bool mForceReject;
+
+ TQTimer *resizeTimer;
+ unsigned int mkeyCode;
+
+ KProcess* mVkbdProcess;
+ KWinModule* mKWinModule;
+ struct VkbdWindow
+ {
+ WId id;
+ QRect rect;
+ };
+ QValueList< VkbdWindow > mVkbdWindows;
+ WId mVkbdLastEventWindow;
bool mPipeOpen;
int mPipe_fd;
bool mPipeOpen_out;
int mPipe_fd_out;
- TQTimer *resizeTimer;
- unsigned int mkeyCode;
+ bool mInfoMessageDisplayed;
+ TQDialog *currentDialog;
+ bool mDialogControlLock;
+ bool mForceReject;
};
#endif
diff --git a/kdesktop/minicli.cpp b/kdesktop/minicli.cpp
index caef6197a..027aa0bfc 100644
--- a/kdesktop/minicli.cpp
+++ b/kdesktop/minicli.cpp
@@ -145,6 +145,9 @@ Minicli::Minicli( TQWidget *parent, const char *name)
connect( m_dlg->cbCommand, TQT_SIGNAL( returnPressed() ),
m_dlg->pbRun, TQT_SLOT( animateClick() ) );
+ m_dlg->cbCommand->setHistoryEditorEnabled( true );
+ connect( m_dlg->cbCommand, TQT_SIGNAL(removed( const TQString&) ), TQT_SLOT(saveConfig()) );
+
// Advanced group box...
connect(m_dlg->cbPriority, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotChangeScheduler(bool)));
connect(m_dlg->slPriority, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotPriority(int)));
@@ -295,7 +298,9 @@ void Minicli::accept()
}
bool logout = (cmd == "logout");
- if( !logout && runCommand() == 1 )
+ bool lock = (cmd == "lock");
+
+ if( !logout && !lock && runCommand() == 1 )
return;
m_dlg->cbCommand->addToHistory( m_dlg->cbCommand->currentText().stripWhiteSpace() );
@@ -308,6 +313,14 @@ void Minicli::accept()
kapp->propagateSessionManager();
kapp->requestShutDown();
}
+ if ( lock )
+ {
+ TQCString appname( "kdesktop" );
+ int kicker_screen_number = qt_xscreen();
+ if ( kicker_screen_number )
+ appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
+ kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", "");
+ }
}
void Minicli::reject()
diff --git a/kdesktop/minicli.h b/kdesktop/minicli.h
index ddbe868c0..4ae49cf7c 100644
--- a/kdesktop/minicli.h
+++ b/kdesktop/minicli.h
@@ -54,12 +54,14 @@ public:
void setCommand(const TQString& command);
void reset();
- void saveConfig();
void clearHistory();
virtual void show();
virtual TQSize sizeHint() const;
+public slots:
+ void saveConfig();
+
protected slots:
virtual void accept();
virtual void reject();