[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