diff options
author | Robert Xu <robxu9@gmail.com> | 2011-11-10 18:04:39 -0500 |
---|---|---|
committer | Robert Xu <robxu9@gmail.com> | 2011-11-10 18:04:39 -0500 |
commit | 21fcfa3348213aa87f0e3aef62ca4720c6d31cb7 (patch) | |
tree | 2cfb64c59322628e613ed0895e3c3694d3abe6bd /opensuse/tdebase/lock-xvkbd.diff | |
parent | 8667643bff14a60d8571c599efd3e48bed3e3b12 (diff) | |
download | tde-packaging-21fcfa3348213aa87f0e3aef62ca4720c6d31cb7.tar.gz tde-packaging-21fcfa3348213aa87f0e3aef62ca4720c6d31cb7.zip |
initial commit to suse branch: eclipse integration
Diffstat (limited to 'opensuse/tdebase/lock-xvkbd.diff')
-rw-r--r-- | opensuse/tdebase/lock-xvkbd.diff | 380 |
1 files changed, 0 insertions, 380 deletions
diff --git a/opensuse/tdebase/lock-xvkbd.diff b/opensuse/tdebase/lock-xvkbd.diff deleted file mode 100644 index 9b5faae8a..000000000 --- a/opensuse/tdebase/lock-xvkbd.diff +++ /dev/null @@ -1,380 +0,0 @@ -Index: kdesktop/lock/lockprocess.cc -=================================================================== ---- kdesktop/lock/lockprocess.cc.orig -+++ kdesktop/lock/lockprocess.cc -@@ -36,6 +36,8 @@ - #include <kstdguiitem.h> - #include <kpixmapeffect.h> - #include <kpixmap.h> -+#include <kwin.h> -+#include <kwinmodule.h> - - #include <qframe.h> - #include <qlabel.h> -@@ -93,6 +95,8 @@ static Window gVRootData = 0; - static Atom gXA_VROOT; - static Atom gXA_SCREENSAVER_VERSION; - -+extern Atom qt_wm_state; -+ - //=========================================================================== - // - // Screen saver handling process. Handles screensaver window, -@@ -108,7 +112,9 @@ LockProcess::LockProcess(bool child, boo - mVisibility(false), - mRestoreXF86Lock(false), - mForbidden(false), -- mAutoLogout(false) -+ mAutoLogout(false), -+ mVkbdProcess(NULL), -+ mKWinModule(NULL) - { - setupSignals(); - -@@ -909,10 +915,14 @@ bool LockProcess::checkPass() - { - if (mAutoLogout) - killTimer(mAutoLogoutTimerId); -+ -+ showVkbd(); - - PasswordDlg passDlg( this, &greetPlugin); - - int ret = execDialog( &passDlg ); -+ -+ hideVkbd(); - - XWindowAttributes rootAttr; - XGetWindowAttributes(qt_xdisplay(), RootWindow(qt_xdisplay(), -@@ -992,9 +1002,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; -@@ -1031,11 +1045,30 @@ bool LockProcess::x11Event(XEvent *event - case ConfigureNotify: // from SubstructureNotifyMask on the root window - if(event->xconfigure.event == qt_xrootwin()) - stayOnTop(); -+ for( QValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin(); -+ it != mVkbdWindows.end(); -+ ++it ) { -+ if( (*it).id == event->xconfigure.window ) { -+ (*it).rect = QRect( 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( QValueList< 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. -@@ -1060,17 +1093,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( QValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin(); -+ it != mVkbdWindows.end(); -+ ++it ) -+ stack[ count++ ] = (*it).id; - for( QValueList< QWidget* >::ConstIterator it = mDialogs.begin(); - it != mDialogs.end(); - ++it ) -@@ -1169,4 +1209,200 @@ void LockProcess::msgBox( QMessageBox::I - 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, SIGNAL( windowAdded( WId )), 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 = QRect( x, y, attr_geom.width, attr_geom.height ); -+ mVkbdWindows.prepend( data ); -+} -+ -+bool LockProcess::forwardVkbdEvent( XEvent* event ) -+{ -+ if( mVkbdProcess == NULL ) -+ return false; -+ QPoint pos; -+ Time time; -+ switch( event->type ) -+ { -+ case ButtonPress: -+ case ButtonRelease: -+ pos = QPoint( event->xbutton.x, event->xbutton.y ); -+ time = event->xbutton.time; -+ break; -+ case MotionNotify: -+ pos = QPoint( 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( QValueList< 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" -Index: kdesktop/lock/lockprocess.h -=================================================================== ---- kdesktop/lock/lockprocess.h.orig -+++ kdesktop/lock/lockprocess.h -@@ -23,6 +23,7 @@ - #include <X11/Xlib.h> - - class KLibrary; -+class KWinModule; - - struct GreeterPluginHandle { - KLibrary *library; -@@ -53,7 +54,7 @@ public: - - void msgBox( QMessageBox::Icon type, const QString &txt ); - int execDialog( QDialog* dlg ); -- -+ - public slots: - void quitSaver(); - void preparePopup(); -@@ -70,6 +71,7 @@ private slots: - void suspend(); - void checkDPMSActive(); - void slotDeadTimePassed(); -+ void windowAdded( WId ); - - private: - void configure(); -@@ -93,6 +95,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 QVariant getConf(void *ctx, const char *key, const QVariant &dflt); - -@@ -125,6 +132,15 @@ private: - int mAutoLogoutTimerId; - int mAutoLogoutTimeout; - bool mAutoLogout; -+ KProcess* mVkbdProcess; -+ KWinModule* mKWinModule; -+ struct VkbdWindow -+ { -+ WId id; -+ QRect rect; -+ }; -+ QValueList< VkbdWindow > mVkbdWindows; -+ WId mVkbdLastEventWindow; - }; - - #endif |