[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    opaque drag/XGrabPointer latency/kwin patch
From:       aviv bergman <avivb () actcom ! co ! il>(by way of aviv bergman <avivb () actcom ! co ! il>)
Date:       2002-07-20 3:24:44
[Download RAW message or body]

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...)


[" " (text/x-diff)]

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 <X11/Xutil.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/shape.h>
+#include "main.h"
+#include <kapp.h>
 
 // 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 <kapplication.h>
 #include "workspace.h"
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+
+#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

>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic