From kde-devel Sat Jul 20 03:24:44 2002 From: aviv bergman (by way of aviv bergman ) Date: Sat, 20 Jul 2002 03:24:44 +0000 To: kde-devel Subject: opaque drag/XGrabPointer latency/kwin patch X-MARC-Message: https://marc.info/?l=kde-devel&m=102713563318789 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_8fNO9SQYSYmpOY0" --Boundary-00=_8fNO9SQYSYmpOY0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline hi everybody i think i've found why opaque drag in xfree is so "jumpy" - it seems that when a client issues an XGrabPointer (or XGrabButton) to a grab window (as all window managers do), and moving the mouse outside the grab window, the motion event reach the client with a noticable latency. it seems that the worse latency is when draging a window with a lot of sub-windows (try xcalc). is this a bug ? (as far as i understand, when a client grabs the pointer, all motion events should go to it, there is no need in complex processing, right?) anyway, this behavior can be worked-around in the window manager: instead of using the caption the grab window, create a full screen inputOnly window as the grab window, and redirect the motion events to the right window. i have tried this and now my system "feels" a lot faster (in fact, it feels a lot faster then winXp :-) attached below is a patch for kwin (against kde 3.1alpha1) - this is a hack/proof of concept patch (it's NOT commit material...) but it works for = me :-) comments? aviv b.t.w. - kde 3.1a1 looks/feels great! (and it's even stable...) --Boundary-00=_8fNO9SQYSYmpOY0 Content-Type: text/x-diff; charset="us-ascii"; name=" " Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kwin.patch" Common subdirectories: kwin.orig/.deps and kwin/.deps Common subdirectories: kwin.orig/CVS and kwin/CVS diff -U 3 -H -b -B -d -N -a -- kwin.orig/client.cpp kwin/client.cpp --- kwin.orig/client.cpp Mon Jul 1 21:54:15 2002 +++ kwin/client.cpp Sat Jul 20 04:53:17 2002 @@ -34,6 +34,8 @@ #include #include #include +#include "main.h" +#include // Needed for --enable-final // XIconincState is defined in workspace.cpp @@ -593,6 +596,10 @@ { moveResizeMode = true; workspace()->setClientIsMoving(this); + + if (isMove()) + return; + grabMouse( cursor() ); grabKeyboard(); if ( ( isMove() && options->moveMode != Options::Opaque ) @@ -602,11 +609,15 @@ void Client::stopMoveResize() { + if (!isMove()) { + if ( ( isMove() && options->moveMode != Options::Opaque ) || ( isResize() && options->resizeMode != Options::Opaque ) ) XUngrabServer( qt_xdisplay() ); releaseKeyboard(); releaseMouse(); + } + buttonDown = FALSE; workspace()->setClientIsMoving(0); moveResizeMode = false; } @@ -1591,6 +1602,10 @@ } startMoveResize(); Events::raise( isResize() ? Events::ResizeStart : Events::MoveStart ); + if (isMove()) + ((Application*)kapp)->startDrag(this,moveOffset.x(),moveOffset.y()); + + } else { return; } @@ -2640,8 +2655,13 @@ Events::raise( Events::UnMaximize ); info->setState( 0, NET::Max ); } - buttonDown = TRUE; + moveOffset = mapFromGlobal( globalPos ); + ((Application*)kapp)->startDrag(this,moveOffset.x(),moveOffset.y()); + break; + + buttonDown = TRUE; + invertedMoveOffset = rect().bottomRight() - moveOffset; startMoveResize(); break; diff -U 3 -H -b -B -d -N -a -- kwin.orig/client.h kwin/client.h --- kwin.orig/client.h Fri Mar 8 03:16:56 2002 +++ kwin/client.h Sat Jul 20 02:05:06 2002 @@ -90,7 +90,7 @@ virtual bool windowEvent( XEvent * ); bool manage( bool isMapped = FALSE, bool doNotShow = FALSE, bool isInitial = TRUE ); - + void stopMoveResize(); void setMappingState( int s ); int mappingState() const; @@ -281,7 +281,7 @@ unsigned long userTime(); void startMoveResize(); - void stopMoveResize(); + WId win; WindowWrapper* wwrap; Common subdirectories: kwin.orig/clients and kwin/clients Common subdirectories: kwin.orig/images and kwin/images Common subdirectories: kwin.orig/kcmkwin and kwin/kcmkwin diff -U 3 -H -b -B -d -N -a -- kwin.orig/main.cpp kwin/main.cpp --- kwin.orig/main.cpp Mon Jul 1 21:54:15 2002 +++ kwin/main.cpp Sat Jul 20 04:50:10 2002 @@ -112,6 +114,7 @@ if (kwin_screen_number == -1) kwin_screen_number = DefaultScreen(qt_xdisplay()); + m_pDrag = NULL; initting = TRUE; // startup.... // install X11 error handler @@ -130,6 +134,21 @@ syncX(); // trigger possible errors, there's still a chance to abort initting = FALSE; // startup done, we are up and running now. + + unsigned long attr_mask = CWEventMask; + + XSetWindowAttributes attributes; + attributes.event_mask = ButtonMotionMask; + + m_EventWindow = XCreateWindow(qt_xdisplay(), + RootWindow(qt_xdisplay(), DefaultScreen(qt_xdisplay())), + 0, 0, + QApplication::desktop()->width(), QApplication::desktop()->height(), + 0, + 0,InputOnly,CopyFromParent, + attr_mask,&attributes); + + dcopClient()->send( "ksplash", "", "upAndRunning(QString)", QString("wm started")); if ( isSessionRestored() ) @@ -143,12 +162,55 @@ delete options; } +void Application::startDrag(Client *pDragMe,int xOffset,int yOffset) +{ + if (m_pDrag != NULL) { + // report error + return; + } + + m_pDrag = pDragMe; + m_xOffset = xOffset; + m_yOffset = yOffset; + + XMapRaised(qt_xdisplay(),m_EventWindow); + XGrabPointer(qt_xdisplay(),m_EventWindow,FALSE,ButtonMotionMask|ButtonReleaseMask, + GrabModeAsync,GrabModeAsync,m_EventWindow,None,CurrentTime); + +// printf("start drag!\n"); +} bool Application::x11EventFilter( XEvent *e ) { if ( Workspace::self()->workspaceEvent( e ) ) return TRUE; + + if (e->xany.window == m_EventWindow) { + + if (m_pDrag == NULL) { + // report error + return TRUE; + } + + if (e->type == ButtonRelease) { +// printf("end drag\n"); + XUngrabPointer(qt_xdisplay(),CurrentTime); + XUnmapWindow(qt_xdisplay(),m_EventWindow); + m_pDrag->stopMoveResize(); + m_pDrag = NULL; + return TRUE; + } + + if (e->type == MotionNotify) { + XMotionEvent *m = (XMotionEvent*)e; + XMoveWindow(qt_xdisplay(),m_pDrag->winId(),m->x-m_xOffset,m->y-m_yOffset); + return TRUE; + } + + return TRUE; + } + return KApplication::x11EventFilter( e ); } @@ -253,6 +315,7 @@ signal(SIGHUP, SIG_IGN); Application a; + SessionManaged weAreIndeed; // KCrash::setCrashHandler(crashHandler); // Try to restart on crash fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1); diff -U 3 -H -b -B -d -N -a -- kwin.orig/main.h kwin/main.h --- kwin.orig/main.h Mon Jul 1 21:54:15 2002 +++ kwin/main.h Sat Jul 20 02:03:36 2002 @@ -8,6 +8,11 @@ #include #include "workspace.h" +#include +#include +#include + +#include "client.h" class Application : public KApplication { @@ -15,8 +20,14 @@ Application(); ~Application(); + void startDrag(KWinInternal::Client *pDragMe,int xOffset,int yOffset); + protected: bool x11EventFilter( XEvent * ); + Window m_EventWindow; + KWinInternal::Client *m_pDrag; + int m_xOffset; + int m_yOffset; }; Common subdirectories: kwin.orig/pics and kwin/pics Common subdirectories: kwin.orig/wm-spec and kwin/wm-spec --Boundary-00=_8fNO9SQYSYmpOY0-- >> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<